From 996cef6db2f4f2c3dbfaddfa85ce5bf11ac16ac3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kin=C4=8Dl?= Date: Wed, 10 Jul 2019 18:26:43 +0200 Subject: [PATCH 001/649] Added stdio.h include to types.h. --- wolfssl/wolfcrypt/types.h | 1 + 1 file changed, 1 insertion(+) diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index cc54ada78..72dd258da 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -446,6 +446,7 @@ Windows 10, snprintf is no longer identical to _snprintf. The snprintf function behavior is now C99 standard compliant. */ + #include #define XSNPRINTF snprintf #else /* 4996 warning to use MS extensions e.g., _sprintf_s From c01cd808da3a41ce7f60e88241c10f224f304cf2 Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Fri, 10 Jan 2020 09:42:25 -0800 Subject: [PATCH 002/649] changes for build with s7g2 add project info add project info adjust wolfssl library template change TRNG collection fix include.am fix argument for TRNG rename example templates comment out DEBUG_WOLFSSL change include.am update license --- IDE/Renesas/e2studio/DK-S7G2/README.md | 27 ++ .../DK-S7G2/benchmark-template/.cproject | 400 ++++++++++++++++++ .../DK-S7G2/benchmark-template/.project | 34 ++ .../benchmark-template/src/app_entry.c | 298 +++++++++++++ .../DK-S7G2/example_server-template/.cproject | 391 +++++++++++++++++ .../DK-S7G2/example_server-template/.project | 27 ++ .../example_server-template/src/app_entry.c | 181 ++++++++ IDE/Renesas/e2studio/DK-S7G2/include.am | 22 + IDE/Renesas/e2studio/DK-S7G2/user_settings.h | 64 +++ .../DK-S7G2/wolfcrypttest-template/.cproject | 392 +++++++++++++++++ .../DK-S7G2/wolfcrypttest-template/.project | 34 ++ .../wolfcrypttest-template/src/app_entry.c | 76 ++++ .../DK-S7G2/wolfssl-template-project/.project | 49 +++ .../configuration.xml | 352 +++++++++++++++ IDE/include.am | 1 + wolfcrypt/benchmark/benchmark.c | 26 ++ wolfcrypt/src/random.c | 49 ++- wolfcrypt/src/wc_port.c | 15 +- wolfssl/wolfio.h | 13 + 19 files changed, 2448 insertions(+), 3 deletions(-) create mode 100644 IDE/Renesas/e2studio/DK-S7G2/README.md create mode 100644 IDE/Renesas/e2studio/DK-S7G2/benchmark-template/.cproject create mode 100644 IDE/Renesas/e2studio/DK-S7G2/benchmark-template/.project create mode 100644 IDE/Renesas/e2studio/DK-S7G2/benchmark-template/src/app_entry.c create mode 100644 IDE/Renesas/e2studio/DK-S7G2/example_server-template/.cproject create mode 100644 IDE/Renesas/e2studio/DK-S7G2/example_server-template/.project create mode 100644 IDE/Renesas/e2studio/DK-S7G2/example_server-template/src/app_entry.c create mode 100644 IDE/Renesas/e2studio/DK-S7G2/include.am create mode 100644 IDE/Renesas/e2studio/DK-S7G2/user_settings.h create mode 100644 IDE/Renesas/e2studio/DK-S7G2/wolfcrypttest-template/.cproject create mode 100644 IDE/Renesas/e2studio/DK-S7G2/wolfcrypttest-template/.project create mode 100644 IDE/Renesas/e2studio/DK-S7G2/wolfcrypttest-template/src/app_entry.c create mode 100644 IDE/Renesas/e2studio/DK-S7G2/wolfssl-template-project/.project create mode 100644 IDE/Renesas/e2studio/DK-S7G2/wolfssl-template-project/configuration.xml diff --git a/IDE/Renesas/e2studio/DK-S7G2/README.md b/IDE/Renesas/e2studio/DK-S7G2/README.md new file mode 100644 index 000000000..4c999418e --- /dev/null +++ b/IDE/Renesas/e2studio/DK-S7G2/README.md @@ -0,0 +1,27 @@ + +## Building wolfSSL For DK-S7G2 + +- First physically toggle the ENET1 and JTAG switch to on with the DK-S7G2 board. +- Open e2studio and set the workspace to be wolfssl-X.X.X/IDE/Renesas/e2studio/DK-S7G2/ +- Create a Synergy library project named wolfssl "File->New->Synergy C/C++ Project", "Renesas Synergy C Library Project" then "Next", set wolfssl as the "Project Name" then "Next", set Board to "S7G2 DK" then "Next", finally select the BSP radius and click "Finish" +- Copy configuration.xml and .project from wolfssl-X.X.X/IDE/Renesas/e2studio/DK-S7G2/wolfssl-template-project/ into the wolfssl-X.X.X/IDE/Renesas/e2studio/DK-S7G2/wolfssl directory +- (optional but necessary for production) Add TRNG support by clicking on Threads tab and highlight HAL/Common click "New Stack > Driver > Crypto > TRNG Driver on r_sce_trng". Then uncomment WOLFSSL_SCE define in wolfssl project src/user_settings.h +- Generate the changes by clicking on "Generate Project Content" +- Exclude src/wolfcrypt/port and all src/wolfcrypt/*.S and src/wolfcrypt/*.asm files from the build +- Exclude src/wolfcrypt/evp.c, src/wolfcrypt/misc.c and src/wolfssl/bio.c +- Set the Preprocessor define in wolfssl proejct to have WOLFSSL_USER_SETTINGS. Right click on wolfssl project "Properties -> C/C++ Build -> GNU ARM Cross C Compiler -> Preprocessor" add WOLFSSL_USER_SETTINGS under "Defined symbols" +- Set include to wolfssl directory. Right click on project "Properties -> C/C++Build -> GNU ARM Cross Compiler -> Includes". Add "${ProjDirPath}/../../../../.." and "${ProjDirPath}/../" +- Build wolfssl by right clicking on wolfssl project and selecting "Build Project" + +## Example Projects and Building + +- Create a new Synergy project "Renesas Synergy C Project Using Synergy Library" +- Set it to use the wolfssl library +- Copy in the .cproject, .project and source file from the template desired i.e. wolfssl-X.X.X/IDE/Renesas/e2studio/DK-S7G2/wolfcrypttest-template/ +- Right click on the created project and select "Build Project" + +The example_server loops looking to accept connections and closes immediatly after a successful connection was made. + +The benchmark example tries to do a TCP connection to SERVER_IP on port 11112 and a TLS connection to SERVER_IP on port 11111 then does wolfCrypt benchmark collection. + +The wolfcryptest runs through all of the unit tests from wolfcrypt/test/test.c \ No newline at end of file diff --git a/IDE/Renesas/e2studio/DK-S7G2/benchmark-template/.cproject b/IDE/Renesas/e2studio/DK-S7G2/benchmark-template/.cproject new file mode 100644 index 000000000..09d87045d --- /dev/null +++ b/IDE/Renesas/e2studio/DK-S7G2/benchmark-template/.cproject @@ -0,0 +1,400 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/IDE/Renesas/e2studio/DK-S7G2/benchmark-template/.project b/IDE/Renesas/e2studio/DK-S7G2/benchmark-template/.project new file mode 100644 index 000000000..1b60e8e4f --- /dev/null +++ b/IDE/Renesas/e2studio/DK-S7G2/benchmark-template/.project @@ -0,0 +1,34 @@ + + + benchmark + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + com.renesas.cdt.synergy.contentgen.synergyExecutableNature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + src/benchmark + 2 + PARENT-5-PROJECT_LOC/wolfcrypt/benchmark + + + 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 new file mode 100644 index 000000000..1bcbc55ee --- /dev/null +++ b/IDE/Renesas/e2studio/DK-S7G2/benchmark-template/src/app_entry.c @@ -0,0 +1,298 @@ +/* app_entry.c + * + * 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 + */ + +#include "app.h" +#include "stdio.h" +extern void initialise_monitor_handles(void); + +#include + +#ifndef WOLFCRYPT_ONLY + +#include + +#define USE_CERT_BUFFERS_2048 +#define USE_CERT_BUFFERS_256 +#include + +#include "nx_api.h" +#define CONNECTION_TIMES 100 +#define SERVER_IP IP_ADDRESS(10,22,73,128) +#define TLS_PORT 11111 +#define TCP_PORT 11112 + +static double miliseconds = 0; +void timer_callback(timer_callback_args_t * args) +{ + miliseconds++; + (void)args; +} + +/* version is the type of TLS version to use. For example TLS1.2 = version 2 + * and TLS1.3 = version 3 + * + * suites is a null terminated string containing the cipher suites to us, or + * can be NULL for default*/ +static void benchmark_TLS(int version, char* suites, int group) +{ + UINT TEST_PORT = TLS_PORT; + ULONG TEST_IP = SERVER_IP; + int i; + NX_TCP_SOCKET sockfd; + int ret; + int groups[1]; + double start; + WOLFSSL_METHOD* method = NULL; + + WOLFSSL_CTX* ctx; + WOLFSSL* ssl; + + switch (version) { + case 2: method = wolfTLSv1_2_client_method(); break; +#ifdef WOLFSSL_TLS13 + case 3: method = wolfTLSv1_3_client_method(); break; +#endif + default: + printf("Unknown TLS version (Check if wolfSSL was built with it supported)\n"); + return; + } + + ctx = wolfSSL_CTX_new(method); + if (ctx == NULL) { + printf("unable to create ctx\n"); + return; + } + +#ifndef NO_RSA + /* add default RSA CA */ + ret = wolfSSL_CTX_load_verify_buffer(ctx, ca_cert_der_2048, + sizeof_ca_cert_der_2048, SSL_FILETYPE_ASN1); + if (ret != WOLFSSL_SUCCESS) { + printf("error %d loading CA\n", ret); + return; + } +#endif + +#ifdef HAVE_ECC + /* add default ECDSA CA */ + ret = wolfSSL_CTX_load_verify_buffer(ctx, ca_ecc_cert_der_256, + sizeof_ca_ecc_cert_der_256, SSL_FILETYPE_ASN1); + if (ret != WOLFSSL_SUCCESS) { + printf("error %d loading CA\n", ret); + return; + } + +#endif + + if (suites != NULL) { + ret = wolfSSL_CTX_set_cipher_list(ctx, suites); + if (ret != WOLFSSL_SUCCESS) { + printf("error %d setting cipher suites %s\n", ret, suites); + return; + } + } + +#ifdef WOLFSSL_TLS13 + if (version == 3) { + groups[0] = group; + ret = wolfSSL_CTX_set_groups(ctx, groups, 1); + if (ret != WOLFSSL_SUCCESS) { + printf("error setting group\n"); + return; + } + } +#endif + + printf("Trying to connect to 0x%lX on port %d\n", TEST_IP, TEST_PORT); + + miliseconds = 0; + g_timer0.p_api->open(g_timer0.p_ctrl, g_timer0.p_cfg); + g_timer0.p_api->start(g_timer0.p_ctrl); + + start = (double)tx_time_get(); // TX_TIMER_TICKS_PER_SECOND = 100 + ret = (int)nx_tcp_socket_create(&g_ip0, &sockfd, "TLS_CLIENT", NX_IP_NORMAL, + NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1500, NX_NULL, NX_NULL); + if (ret != NX_SUCCESS) { + printf("failed to create socket err = 0x%X\n", ret); + return; + } + for (i = 0; i < CONNECTION_TIMES; i++) { + + ret = (int)nx_tcp_client_socket_bind(&sockfd, NX_ANY_PORT, NX_WAIT_FOREVER); + if (ret != NX_SUCCESS) { + printf("failed to bind socket\n"); + return; + } + + ret = (int)nx_tcp_client_socket_connect(&sockfd, TEST_IP, TEST_PORT, NX_WAIT_FOREVER); + if (ret != NX_SUCCESS) { + printf("failed to connect with error 0x%X\n", ret); + return; + } + + ssl = wolfSSL_new(ctx); + if (ssl == NULL) { + printf("Error creating ssl\n"); + return; + } + +#ifdef WOLFSSL_TLS13 + if (version == 3) { + ret = wolfSSL_UseKeyShare(ssl, group); + if (ret != WOLFSSL_SUCCESS) { + printf("Error %d with set key share\n", ret); + return; + } + } +#endif + + wolfSSL_SetIO_NetX(ssl, &sockfd, NX_WAIT_FOREVER); + + ret = wolfSSL_connect(ssl); + if (ret != WOLFSSL_SUCCESS) { + printf("Error %d with wolfssl connect\n", ret); + return; + } + wolfSSL_free(ssl); + + nx_tcp_socket_disconnect(&sockfd, NX_WAIT_FOREVER); + + ret = nx_tcp_client_socket_unbind(&sockfd); + if (ret != NX_SUCCESS) { + printf("failed to unbind with error 0x%X\n", ret); + return; + } + + } + nx_tcp_socket_delete(&sockfd); + + g_timer0.p_api->stop(g_timer0.p_ctrl); + start = (double)tx_time_get() - start; + g_timer0.p_api->close(g_timer0.p_ctrl); + + printf("%d TLS connections took %f seconds and %f tx_time ticks\n", + CONNECTION_TIMES, (miliseconds / 10), start); + wolfSSL_CTX_free(ctx); +} + + +static void benchmark_TCP() +{ + UINT TEST_PORT = TCP_PORT; + ULONG TEST_IP = SERVER_IP; + int i; + NX_TCP_SOCKET sockfd; + int ret; + double start; + + + { + NX_PACKET* response; + printf("Pinging server to see if up .. "); + fflush(stdout); + ret = (int)nx_icmp_ping(&g_ip0, TEST_IP, "Hello", strlen("Hello"), &response, 2000); + if (ret != NX_SUCCESS) { + printf("Unable to ping server, error = 0x%X\n", ret); + return; + } + printf("got response from server\n"); + nx_packet_release(response); + } + + printf("Benchmarking client TCP connection\n"); + printf("Trying to connect to 0x%lX on port %d\n", TEST_IP, TEST_PORT); + start = (double)tx_time_get() / TX_TIMER_TICKS_PER_SECOND; + ret = (int)nx_tcp_socket_create(&g_ip0, &sockfd, "TCP_CLIENT", NX_IP_NORMAL, + NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 256, NX_NULL, NX_NULL); + if (ret != NX_SUCCESS) { + printf("failed to create socket err = 0x%X\n", ret); + return; + } + + for (i = 0; i < CONNECTION_TIMES; i++) { + ret = (int)nx_tcp_client_socket_bind(&sockfd, NX_ANY_PORT, NX_WAIT_FOREVER); + if (ret != NX_SUCCESS) { + printf("failed to bind socket\n"); + return; + } + + ret = (int)nx_tcp_client_socket_connect(&sockfd, TEST_IP, TEST_PORT, NX_WAIT_FOREVER); + if (ret != NX_SUCCESS) { + printf("failed to connect with error 0x%X\n", ret); + return; + } + + nx_tcp_socket_disconnect(&sockfd, NX_WAIT_FOREVER); + + ret = (int)nx_tcp_client_socket_unbind(&sockfd); + if (ret != NX_SUCCESS) { + printf("failed to unbind with error 0x%X\n", ret); + return; + } + } + nx_tcp_socket_delete(&sockfd); + + start = ((double)tx_time_get() / TX_TIMER_TICKS_PER_SECOND) - start; + printf("%d TCP connections took %f seconds\n", CONNECTION_TIMES, start); +} +#endif /* WOLFCRYPT_ONLY */ + +/* Benchmark entry function */ +void app_entry(void) +{ + initialise_monitor_handles(); + +#ifdef DEBUG_WOLFSSL + wolfSSL_Debugging_ON(); +#endif + + wolfSSL_Init(); + +#ifndef WOLFCRYPT_ONLY + benchmark_TCP(); + + printf("\nBenchmarking client TLSv1.2 connection using ECDHE-RSA-AES128-GCM-SHA256\n"); + benchmark_TLS(2, "ECDHE-RSA-AES128-GCM-SHA256", 0); + #ifdef WOLFSSL_TLS13 + #ifdef HAVE_CURVE25519 + printf("\nBenchmarking client TLSv1.3 WOLFSSL_ECC_X25519 connection using TLS13_AES128_GCM_SHA256\n"); + benchmark_TLS(3, "TLS13-AES128-GCM-SHA256", (int)WOLFSSL_ECC_X25519); + #endif + #ifdef HAVE_ECC + printf("\nBenchmarking client TLSv1.3 WOLFSSL_ECC_SECP256R1 connection using TLS13_AES128_GCM_SHA256\n"); + benchmark_TLS(3, "TLS13-AES128-GCM-SHA256", (int)WOLFSSL_ECC_SECP256R1); + #endif + printf("\nBenchmarking client TLSv1.3 WOLFSSL_FFDHE_2048 connection using TLS13_AES128_GCM_SHA256\n"); + benchmark_TLS(3, "TLS13-AES128-GCM-SHA256", (int)WOLFSSL_FFDHE_2048); + #endif +#endif + +#if 1 + /* run wolfcrypt benchmarks */ + benchmark_test(NULL); +#endif + + wolfSSL_Cleanup(); + while (1) + { + tx_thread_sleep (100); + } +} diff --git a/IDE/Renesas/e2studio/DK-S7G2/example_server-template/.cproject b/IDE/Renesas/e2studio/DK-S7G2/example_server-template/.cproject new file mode 100644 index 000000000..3b026ad59 --- /dev/null +++ b/IDE/Renesas/e2studio/DK-S7G2/example_server-template/.cproject @@ -0,0 +1,391 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/IDE/Renesas/e2studio/DK-S7G2/example_server-template/.project b/IDE/Renesas/e2studio/DK-S7G2/example_server-template/.project new file mode 100644 index 000000000..aaff6e3d7 --- /dev/null +++ b/IDE/Renesas/e2studio/DK-S7G2/example_server-template/.project @@ -0,0 +1,27 @@ + + + example_server + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + com.renesas.cdt.synergy.contentgen.synergyExecutableNature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + 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 new file mode 100644 index 000000000..92a32d8d7 --- /dev/null +++ b/IDE/Renesas/e2studio/DK-S7G2/example_server-template/src/app_entry.c @@ -0,0 +1,181 @@ +/* app_entry.c + * + * 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 + */ + + +#include "app.h" +#include "nx_api.h" +#include "stdio.h" +extern void initialise_monitor_handles(void); + +#include +#define USE_CERT_BUFFERS_2048 +#define USE_CERT_BUFFERS_256 +#include +#define TLS_PORT 11111 + +static void server() +{ + UINT TEST_PORT = TLS_PORT; + NX_TCP_SOCKET sockfd; + int ret; + unsigned char* cert; + int certSz; + + unsigned char* key; + int keySz; + + WOLFSSL_CTX* ctx; + WOLFSSL* ssl; + + ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()); + if (ctx == NULL) { + printf("Unable to create ctx\n"); + return; + } + +#ifndef NO_RSA + cert = server_cert_der_2048; + certSz = sizeof_server_cert_der_2048; + key = server_key_der_2048; + keySz = sizeof_server_key_der_2048; +#endif + +#if 0 + /* Use ECDSA */ + cert = serv_ecc_der_256; + certSz = sizeof_serv_ecc_der_256; + key = ecc_key_der_256; + keySz = sizeof_ecc_key_der_256; +#endif + + ret = wolfSSL_CTX_use_certificate_buffer(ctx, cert, + certSz, SSL_FILETYPE_ASN1); + if (ret != WOLFSSL_SUCCESS) { + printf("Unable to load certificate ret = %d\n", ret); + wolfSSL_CTX_free(ctx); + return; + } + + ret = wolfSSL_CTX_use_PrivateKey_buffer(ctx, key, + keySz, SSL_FILETYPE_ASN1); + if (ret != WOLFSSL_SUCCESS) { + printf("Unable to load key ret = %d\n", ret); + wolfSSL_CTX_free(ctx); + return; + } + +#ifdef WOLFSSL_TLS13 + { + int groups[3]; + int idx = 0; + + #ifdef HAVE_CURVE25519 + groups[idx++] = WOLFSSL_ECC_X25519; + #endif + #ifdef HAVE_ECC + groups[idx++] = WOLFSSL_ECC_SECP256R1; + #endif + groups[idx++] = WOLFSSL_FFDHE_2048; + + ret = wolfSSL_CTX_set_groups(ctx, groups, idx); + if (ret != WOLFSSL_SUCCESS) { + printf("Unable to set groups\n"); + } + } +#endif + printf("Waiting for connections on port %d\n", TEST_PORT); + + ret = (int)nx_tcp_socket_create(&g_ip0, &sockfd, "TLS_SERVER", NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1500, NX_NULL, NX_NULL); + if (ret != NX_SUCCESS) { + printf("failed to create socket err = 0x%X\n", ret); + } + + ret = (int)nx_tcp_server_socket_listen(&g_ip0, TEST_PORT, &sockfd, + NX_MAX_LISTEN_REQUESTS, NULL); + if (ret != NX_SUCCESS) { + printf("failed to listen\n"); + } + + while (1) { + ret = (int)nx_tcp_server_socket_accept(&sockfd, NX_WAIT_FOREVER); + if (ret != NX_SUCCESS) { + printf("failed to accept with error 0x%X\n", ret); + break; + } + + ssl = wolfSSL_new(ctx); + if (ssl == NULL) { + printf("Error creating ssl\n"); + break; + } + + wolfSSL_SetIO_NetX(ssl, &sockfd, NX_WAIT_FOREVER); + + ret = wolfSSL_accept(ssl); + if (ret != WOLFSSL_SUCCESS) { + printf("Error %d with wolfssl accept\n", wolfSSL_get_error(ssl, ret)); + wolfSSL_free(ssl); + break; + } + wolfSSL_free(ssl); + + nx_tcp_socket_disconnect(&sockfd, NX_WAIT_FOREVER); + + ret = (int)nx_tcp_server_socket_unaccept(&sockfd); + if (ret != NX_SUCCESS) { + printf("failed to unaccept with error 0x%X\n", ret); + break; + } + + ret = (int)nx_tcp_server_socket_relisten(&g_ip0, TEST_PORT, &sockfd); + if (ret != NX_SUCCESS && ret != NX_CONNECTION_PENDING) { + printf("failed to relisten 0x%X\n", ret); + break; + } + } + ret = (int)nx_tcp_server_socket_unlisten(&g_ip0, TEST_PORT); + if (ret != NX_SUCCESS) { + printf("failed to unlisten\n"); + return; + } + + nx_tcp_socket_delete(&sockfd); + + wolfSSL_CTX_free(ctx); +} + +/* app entry function */ +void app_entry(void) +{ + initialise_monitor_handles(); + wolfSSL_Init(); + +#ifdef DEBUG_WOLFSSL + wolfSSL_Debugging_ON(); +#endif + server(); + wolfSSL_Cleanup(); + printf("Server closed down\n"); + while (1) + { + tx_thread_sleep (1); + } +} diff --git a/IDE/Renesas/e2studio/DK-S7G2/include.am b/IDE/Renesas/e2studio/DK-S7G2/include.am new file mode 100644 index 000000000..739be2cab --- /dev/null +++ b/IDE/Renesas/e2studio/DK-S7G2/include.am @@ -0,0 +1,22 @@ +# vim:ft=automake +# included from Top Level Makefile.am +# All paths should be given relative to the root + +EXTRA_DIST+= IDE/Renesas/e2studio/DK-S7G2/README.md +EXTRA_DIST+= IDE/Renesas/e2studio/DK-S7G2/user_settings.h + +EXTRA_DIST+= IDE/Renesas/e2studio/DK-S7G2/wolfssl-template-project/.project +EXTRA_DIST+= IDE/Renesas/e2studio/DK-S7G2/wolfssl-template-project/configuration.xml + +EXTRA_DIST+= IDE/Renesas/e2studio/DK-S7G2/wolfcrypttest-template/.cproject +EXTRA_DIST+= IDE/Renesas/e2studio/DK-S7G2/wolfcrypttest-template/.project +EXTRA_DIST+= IDE/Renesas/e2studio/DK-S7G2/wolfcrypttest-template/src/app_entry.c + +EXTRA_DIST+= IDE/Renesas/e2studio/DK-S7G2/example_server-template/.cproject +EXTRA_DIST+= IDE/Renesas/e2studio/DK-S7G2/example_server-template/.project +EXTRA_DIST+= IDE/Renesas/e2studio/DK-S7G2/example_server-template/src/app_entry.c + +EXTRA_DIST+= IDE/Renesas/e2studio/DK-S7G2/benchmark-template/.cproject +EXTRA_DIST+= IDE/Renesas/e2studio/DK-S7G2/benchmark-template/.project +EXTRA_DIST+= IDE/Renesas/e2studio/DK-S7G2/benchmark-template/src/app_entry.c + diff --git a/IDE/Renesas/e2studio/DK-S7G2/user_settings.h b/IDE/Renesas/e2studio/DK-S7G2/user_settings.h new file mode 100644 index 000000000..ad58cd67f --- /dev/null +++ b/IDE/Renesas/e2studio/DK-S7G2/user_settings.h @@ -0,0 +1,64 @@ + +#ifndef USER_SETTINGS_H +#define USER_SETTINGS_H + +//#define DEBUG_WOLFSSL + +#define NO_MAIN_DRIVER +#define USE_CERT_BUFFERS_2048 +#define USE_CERT_BUFFERS_256 + +/* print out cycles per byte with benchmark when component r_wdt WDT is enabled */ +#define SYNERGY_CYCLE_COUNT +#define BENCH_EMBEDDED + +/* Use TRNG */ +//#define WOLFSSL_SCE +#ifndef WOLFSSL_SCE + /* use unsafe test seed if TRNG not used (not for production) */ + #define WOLFSSL_GENSEED_FORTEST +#endif + +#define HAVE_ECC +#define ALT_ECC_SIZE + +#define HAVE_CHACHA +#define HAVE_POLY1305 +#define HAVE_ONE_TIME_AUTH +#define HAVE_AESGCM + +#define USE_FAST_MATH + +#define TFM_TIMING_RESISTANT +#define WC_RSA_BLINDING +#define ECC_TIMING_RESISTANT + +#define NO_WOLFSSL_DIR + +#define HAVE_NETX +#define THREADX +#define THREADX_NO_DC_PRINTF +#define NO_WRITEV +#define SIZEOF_LONG 4 +#define SIZEOF_LONG_LONG 8 + +#if 1 + /* Optimizations */ + #define WOLFSSL_HAVE_SP_RSA + #define WOLFSSL_HAVE_SP_ECC + #define WOLFSSL_SP_ARM_CORTEX_M_ASM +#endif + +/* TLS 1.3 */ +#define WOLFSSL_TLS13 +#define HAVE_TLS_EXTENSIONS +#define HAVE_SUPPORTED_CURVES +#define HAVE_FFDHE_2048 +#define HAVE_HKDF +#define WC_RSA_PSS + +#define HAVE_CURVE25519 +#define HAVE_ED25519 +#define WOLFSSL_SHA512 + +#endif diff --git a/IDE/Renesas/e2studio/DK-S7G2/wolfcrypttest-template/.cproject b/IDE/Renesas/e2studio/DK-S7G2/wolfcrypttest-template/.cproject new file mode 100644 index 000000000..67ebabc0d --- /dev/null +++ b/IDE/Renesas/e2studio/DK-S7G2/wolfcrypttest-template/.cproject @@ -0,0 +1,392 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/IDE/Renesas/e2studio/DK-S7G2/wolfcrypttest-template/.project b/IDE/Renesas/e2studio/DK-S7G2/wolfcrypttest-template/.project new file mode 100644 index 000000000..24fa740ee --- /dev/null +++ b/IDE/Renesas/e2studio/DK-S7G2/wolfcrypttest-template/.project @@ -0,0 +1,34 @@ + + + wolfcrypttest + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + com.renesas.cdt.synergy.contentgen.synergyExecutableNature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + src/test + 2 + PARENT-5-PROJECT_LOC/wolfcrypt/test + + + 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 new file mode 100644 index 000000000..c9eee735e --- /dev/null +++ b/IDE/Renesas/e2studio/DK-S7G2/wolfcrypttest-template/src/app_entry.c @@ -0,0 +1,76 @@ +/* app_entry.c + * + * 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 + */ + + +#include +#include "stdio.h" +extern void initialise_monitor_handles(void); + +#include +#include +#include "wolfcrypt/test/test.h" + +typedef struct func_args { + int argc; + char** argv; + int return_code; +} func_args; + +void app_entry(void) +{ + func_args args; + + args.argc = 0; + args.argv = NULL; + args.return_code = 0; + + initialise_monitor_handles(); + wolfCrypt_Init(); + +#if 1 + /* sanity check on RNG */ + printf("Doing quick sanity check on RNG\n"); + { + int i; + for (i = 0; i < 10; i++) { + int j, ret; + WC_RNG rng; + unsigned char buffer[20] = {0}; + + wc_InitRng(&rng); + ret = wc_RNG_GenerateBlock(&rng, buffer, 20); + if (ret != 0) { + printf("Error generating random block\n"); + } + for (j = 0; j < 20; j++) { + printf("%02X", buffer[j]); + } + printf("\n"); + wc_FreeRng(&rng); + } + } + printf("\n"); +#endif + + wolfcrypt_test(&args); + wolfCrypt_Cleanup(); + printf("done with wolfcrypt test, ret = %d\n", args.return_code); +} diff --git a/IDE/Renesas/e2studio/DK-S7G2/wolfssl-template-project/.project b/IDE/Renesas/e2studio/DK-S7G2/wolfssl-template-project/.project new file mode 100644 index 000000000..11745f883 --- /dev/null +++ b/IDE/Renesas/e2studio/DK-S7G2/wolfssl-template-project/.project @@ -0,0 +1,49 @@ + + + wolfssl + + + + + + com.renesas.cdt.synergy.contentgen.synergyBuilder + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + com.renesas.cdt.synergy.contentgen.synergyNature + + + + src/user_settings.h + 1 + PARENT-1-PROJECT_LOC/user_settings.h + + + src/wolfcrypt + 2 + PARENT-5-PROJECT_LOC/wolfcrypt/src + + + src/wolfssl + 2 + PARENT-5-PROJECT_LOC/src + + + diff --git a/IDE/Renesas/e2studio/DK-S7G2/wolfssl-template-project/configuration.xml b/IDE/Renesas/e2studio/DK-S7G2/wolfssl-template-project/configuration.xml new file mode 100644 index 000000000..6622d9f67 --- /dev/null +++ b/IDE/Renesas/e2studio/DK-S7G2/wolfssl-template-project/configuration.xml @@ -0,0 +1,352 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SSP Common Code + Renesas.Synergy.1.7.0.pack + + + Clock Generation Circuit: Provides=[CGC] + Renesas.Synergy.1.7.0.pack + + + Event Link Controller: Provides=[ELC] + Renesas.Synergy.1.7.0.pack + + + Factory MCU Information Module: Provides=[FMI] + Renesas.Synergy.1.7.0.pack + + + I/O Port: Provides=[IO Port] + Renesas.Synergy.1.7.0.pack + + + Board support package for R7FS7G27H2A01CBD + Renesas.Synergy_mcu_s7g2.1.7.0.pack + + + Board support package for S7G2 + Renesas.Synergy_mcu_s7g2.1.7.0.pack + + + Board support package for S7G2 + Renesas.Synergy_mcu_s7g2.1.7.0.pack + + + S7G2_DK Board Support Files + Renesas.Synergy_board_s7g2_dk.1.7.0.pack + + + Real Time Clock: Provides=[RTC] + Renesas.Synergy.1.7.0.pack + + + General Purpose Timer: Provides=[Timer ,GPT] + Renesas.Synergy.1.7.0.pack + + + Watchdog Timer: Provides=[WDT] + Renesas.Synergy.1.7.0.pack + + + Express Logic NetX: Provides=[NetX] , Requires=[ThreadX ,NetX Driver] + Renesas.Synergy.1.7.0.pack + + + Express Logic NetX Synergy Port: Provides=[NetX Driver] , Requires=[NetX] + Renesas.Synergy.1.7.0.pack + + + Express Logic ThreadX: Provides=[ThreadX] + Renesas.Synergy.1.7.0.pack + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/IDE/include.am b/IDE/include.am index 2ea00f2de..fe260fb6a 100644 --- a/IDE/include.am +++ b/IDE/include.am @@ -21,6 +21,7 @@ include IDE/ECLIPSE/DEOS/include.am include IDE/ECLIPSE/MICRIUM/include.am include IDE/ECLIPSE/SIFIVE/include.am include IDE/mynewt/include.am +include IDE/Renesas/e2studio/DK-S7G2/include.am include IDE/Renesas/cs+/Projects/include.am include IDE/Renesas/e2studio/Projects/include.am include IDE/WICED-STUDIO/include.am diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index 7a905e59c..d48395296 100755 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -618,6 +618,24 @@ static const char* bench_desc_words[][9] = { XSNPRINTF(b + XSTRLEN(b), n - XSTRLEN(b), "%.2f,\n", \ (float)total_cycles / (count*s)) +#elif defined(SYNERGY_CYCLE_COUNT) + #include "hal_data.h" + static THREAD_LS_T word64 begin_cycles; + static THREAD_LS_T word64 total_cycles; + + #define INIT_CYCLE_COUNTER + #define BEGIN_INTEL_CYCLES begin_cycles = DWT->CYCCNT = 0; + #define END_INTEL_CYCLES total_cycles = DWT->CYCCNT - begin_cycles; + + /* s == size in bytes that 1 count represents, normally BENCH_SIZE */ + #define SHOW_INTEL_CYCLES(b, n, s) \ + XSNPRINTF(b + XSTRLEN(b), n - XSTRLEN(b), " %s = %6.2f\n", \ + bench_result_words1[lng_index][2], \ + (float)total_cycles / (count*s)) + #define SHOW_INTEL_CYCLES_CSV(b, n, s) \ + XSNPRINTF(b + XSTRLEN(b), n - XSTRLEN(b), "%.2f,\n", \ + (float)total_cycles / (count*s)) + #else #define INIT_CYCLE_COUNTER #define BEGIN_INTEL_CYCLES @@ -5694,6 +5712,14 @@ exit_ed_verify: return (double) ticks/TICKS_PER_SECOND; } + +#elif defined(THREADX) + #include "tx_api.h" + double current_time(int reset) + { + (void)reset; + return (double) tx_time_get() / TX_TIMER_TICKS_PER_SECOND; + } #else #include diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index a9dcac362..50cfab564 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -155,6 +155,7 @@ int wc_RNG_GenerateByte(WC_RNG* rng, byte* b) #elif defined(WOLFSSL_PB) #elif defined(WOLFSSL_ZEPHYR) #elif defined(WOLFSSL_TELIT_M2MB) +#elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_TRNG) #else /* include headers that may be needed to get good seed */ #include @@ -2312,8 +2313,52 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) } return ret; } - - + +#elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_TRNG) + #include "hal_data.h" + + int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) + { + uint32_t ret; + uint32_t blocks; + word32 len = sz; + + ret = g_sce_trng.p_api->open(g_sce_trng.p_ctrl, g_sce_trng.p_cfg); + if (ret != SSP_SUCCESS) { + /* error opening TRNG driver */ + return -1; + } + + blocks = sz / sizeof(uint32_t); + if (blocks > 0) { + ret = g_sce_trng.p_api->read(g_sce_trng.p_ctrl, (uint32_t*)output, + blocks); + if (ret != SSP_SUCCESS) { + return -1; + } + } + + len = len - (blocks * sizeof(uint32_t)); + if (len > 0) { + uint32_t tmp; + + if (len > sizeof(uint32_t)) { + return -1; + } + ret = g_sce_trng.p_api->read(g_sce_trng.p_ctrl, (uint32_t*)tmp, 1); + if (ret != SSP_SUCCESS) { + return -1; + } + XMEMCPY(output + (blocks * sizeof(uint32_t)), (byte*)&tmp, len); + } + + ret = g_sce_trng.p_api->close(g_sce_trng.p_ctrl); + if (ret != SSP_SUCCESS) { + /* error opening TRNG driver */ + return -1; + } + return 0; + } #elif defined(CUSTOM_RAND_GENERATE_BLOCK) /* #define CUSTOM_RAND_GENERATE_BLOCK myRngFunc * extern int myRngFunc(byte* output, word32 sz); diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index a23d4449b..2265416c8 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -82,6 +82,10 @@ #include #endif +#ifdef WOLFSSL_SCE + #include "hal_data.h" +#endif + #if defined(WOLFSSL_DSP) && !defined(WOLFSSL_DSP_BUILD) #include "rpcmem.h" #endif @@ -224,6 +228,13 @@ int wolfCrypt_Init(void) #endif #endif +#ifdef WOLFSSL_SCE + if ((ret = g_sce.p_api->open(g_sce.p_ctrl, g_sce.p_cfg)) != SSP_SUCCESS) { + WOLFSSL_MSG("Error opening SCE\n"); + return -1; /* FATAL_ERROR */ + } +#endif + #if defined(WOLFSSL_IMX6_CAAM) || defined(WOLFSSL_IMX6_CAAM_RNG) || \ defined(WOLFSSL_IMX6_CAAM_BLOB) if ((ret = wc_caamInit()) != 0) { @@ -276,7 +287,9 @@ int wolfCrypt_Cleanup(void) #ifdef WOLFSSL_ASYNC_CRYPT wolfAsync_HardwareStop(); #endif - + #ifdef WOLFSSL_SCE + g_sce.p_api->close(g_sce.p_ctrl); + #endif #if defined(WOLFSSL_IMX6_CAAM) || defined(WOLFSSL_IMX6_CAAM_RNG) || \ defined(WOLFSSL_IMX6_CAAM_BLOB) wc_caamFree(); diff --git a/wolfssl/wolfio.h b/wolfssl/wolfio.h index 9ea0a0322..d0d17a093 100644 --- a/wolfssl/wolfio.h +++ b/wolfssl/wolfio.h @@ -82,6 +82,8 @@ #include "FreeRTOS_Sockets.h" #elif defined(WOLFSSL_IAR_ARM) /* nothing */ + #elif defined(HAVE_NETX_BSD) + #include "nx_bsd.h" #elif defined(WOLFSSL_VXWORKS) #include #include @@ -120,6 +122,9 @@ #include #elif defined(WOLFSSL_ZEPHYR) #include + #elif defined(HAVE_NETX) + #include "nx_api.h" + #include "errno.h" #elif !defined(WOLFSSL_NO_SOCK) #include #include @@ -233,6 +238,14 @@ #define SOCKET_EPIPE EPIPE #define SOCKET_ECONNREFUSED SOCKET_ERROR #define SOCKET_ECONNABORTED SOCKET_ERROR +#elif defined(HAVE_NETX) + #define SOCKET_EWOULDBLOCK NX_NOT_CONNECTED + #define SOCKET_EAGAIN NX_NOT_CONNECTED + #define SOCKET_ECONNRESET NX_NOT_CONNECTED + #define SOCKET_EINTR NX_NOT_CONNECTED + #define SOCKET_EPIPE NX_NOT_CONNECTED + #define SOCKET_ECONNREFUSED NX_NOT_CONNECTED + #define SOCKET_ECONNABORTED NX_NOT_CONNECTED #else #define SOCKET_EWOULDBLOCK EWOULDBLOCK #define SOCKET_EAGAIN EAGAIN From 3508579f4c100d3dcd6a606fd75816027ab624ef Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Mon, 20 Jan 2020 09:33:14 -0700 Subject: [PATCH 003/649] add check on NETX duo build and return value of opening driver --- wolfcrypt/src/random.c | 2 +- wolfcrypt/src/wc_port.c | 3 ++- wolfssl/wolfio.h | 6 +++++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 50cfab564..056baa536 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -2324,7 +2324,7 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) word32 len = sz; ret = g_sce_trng.p_api->open(g_sce_trng.p_ctrl, g_sce_trng.p_cfg); - if (ret != SSP_SUCCESS) { + if (ret != SSP_SUCCESS && ret != SSP_ERR_CRYPTO_ALREADY_OPEN) { /* error opening TRNG driver */ return -1; } diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index 2265416c8..860422fcb 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -229,7 +229,8 @@ int wolfCrypt_Init(void) #endif #ifdef WOLFSSL_SCE - if ((ret = g_sce.p_api->open(g_sce.p_ctrl, g_sce.p_cfg)) != SSP_SUCCESS) { + ret = (int)g_sce.p_api->open(g_sce.p_ctrl, g_sce.p_cfg); + if (ret != SSP_SUCCESS && ret != SSP_ERR_CRYPTO_ALREADY_OPEN) { WOLFSSL_MSG("Error opening SCE\n"); return -1; /* FATAL_ERROR */ } diff --git a/wolfssl/wolfio.h b/wolfssl/wolfio.h index d0d17a093..b6487c20b 100644 --- a/wolfssl/wolfio.h +++ b/wolfssl/wolfio.h @@ -83,7 +83,11 @@ #elif defined(WOLFSSL_IAR_ARM) /* nothing */ #elif defined(HAVE_NETX_BSD) - #include "nx_bsd.h" + #ifdef NETX_DUO + #include "nxd_bsd.h" + #else + #include "nx_bsd.h" + #endif #elif defined(WOLFSSL_VXWORKS) #include #include From 91a9117e1b7e7ca316299cef6dfc2243aa127651 Mon Sep 17 00:00:00 2001 From: Aaron Jense Date: Mon, 27 Jan 2020 13:22:32 -0700 Subject: [PATCH 004/649] Renesas RA e2studio projects for Client, Server, Test and Benchmark --- IDE/Renesas/e2studio/RA6M3G/README.md | 175 ++++++ .../RA6M3G/benchmark-wolfcrypt/.cproject | 309 ++++++++++ .../RA6M3G/benchmark-wolfcrypt/.project | 59 ++ .../benchmark-wolfcrypt/common/.gitkeep | 0 .../benchmark-wolfcrypt/script/.gitkeep | 0 .../src/wolfssl_thread_entry.c | 30 + .../e2studio/RA6M3G/client-wolfssl/.cproject | 325 ++++++++++ .../e2studio/RA6M3G/client-wolfssl/.project | 54 ++ .../RA6M3G/client-wolfssl/common/src/.gitkeep | 0 .../RA6M3G/client-wolfssl/script/.gitkeep | 0 .../client-wolfssl/src/wolfssl_thread_entry.c | 150 +++++ .../client-wolfssl/wolfssl_thread_entry.h | 41 ++ .../e2studio/RA6M3G/common/ra6m3g/README.md | 4 + .../RA6M3G/common/src/freertos_tcp_port.c | 65 ++ .../e2studio/RA6M3G/common/user_settings.h | 77 +++ IDE/Renesas/e2studio/RA6M3G/common/util.h | 48 ++ IDE/Renesas/e2studio/RA6M3G/include.am | 32 + .../e2studio/RA6M3G/server-wolfssl/.cproject | 320 ++++++++++ .../e2studio/RA6M3G/server-wolfssl/.project | 60 ++ .../RA6M3G/server-wolfssl/common/src/.gitkeep | 0 .../RA6M3G/server-wolfssl/script/.gitkeep | 0 .../server-wolfssl/src/wolfssl_thread_entry.c | 172 ++++++ .../server-wolfssl/wolfssl_thread_entry.h | 43 ++ .../e2studio/RA6M3G/test-wolfcrypt/.cproject | 305 ++++++++++ .../e2studio/RA6M3G/test-wolfcrypt/.project | 54 ++ .../RA6M3G/test-wolfcrypt/common/.gitkeep | 0 .../RA6M3G/test-wolfcrypt/script/.gitkeep | 0 .../test-wolfcrypt/src/wolfssl_thread_entry.c | 32 + IDE/Renesas/e2studio/RA6M3G/wolfssl/.cproject | 334 +++++++++++ IDE/Renesas/e2studio/RA6M3G/wolfssl/.project | 554 ++++++++++++++++++ .../e2studio/RA6M3G/wolfssl/configuration.xml | 368 ++++++++++++ .../e2studio/RA6M3G/wolfssl/src/.gitkeep | 0 .../RA6M3G/wolfssl/wolfcrypt/.gitkeep | 0 IDE/include.am | 1 + src/internal.c | 9 + wolfssl/wolfcrypt/settings.h | 4 + wolfssl/wolfio.h | 5 + 37 files changed, 3630 insertions(+) create mode 100644 IDE/Renesas/e2studio/RA6M3G/README.md create mode 100644 IDE/Renesas/e2studio/RA6M3G/benchmark-wolfcrypt/.cproject create mode 100644 IDE/Renesas/e2studio/RA6M3G/benchmark-wolfcrypt/.project create mode 100644 IDE/Renesas/e2studio/RA6M3G/benchmark-wolfcrypt/common/.gitkeep create mode 100644 IDE/Renesas/e2studio/RA6M3G/benchmark-wolfcrypt/script/.gitkeep create mode 100644 IDE/Renesas/e2studio/RA6M3G/benchmark-wolfcrypt/src/wolfssl_thread_entry.c create mode 100644 IDE/Renesas/e2studio/RA6M3G/client-wolfssl/.cproject create mode 100644 IDE/Renesas/e2studio/RA6M3G/client-wolfssl/.project create mode 100644 IDE/Renesas/e2studio/RA6M3G/client-wolfssl/common/src/.gitkeep create mode 100644 IDE/Renesas/e2studio/RA6M3G/client-wolfssl/script/.gitkeep create mode 100644 IDE/Renesas/e2studio/RA6M3G/client-wolfssl/src/wolfssl_thread_entry.c create mode 100755 IDE/Renesas/e2studio/RA6M3G/client-wolfssl/wolfssl_thread_entry.h create mode 100755 IDE/Renesas/e2studio/RA6M3G/common/ra6m3g/README.md create mode 100644 IDE/Renesas/e2studio/RA6M3G/common/src/freertos_tcp_port.c create mode 100644 IDE/Renesas/e2studio/RA6M3G/common/user_settings.h create mode 100644 IDE/Renesas/e2studio/RA6M3G/common/util.h create mode 100644 IDE/Renesas/e2studio/RA6M3G/include.am create mode 100644 IDE/Renesas/e2studio/RA6M3G/server-wolfssl/.cproject create mode 100644 IDE/Renesas/e2studio/RA6M3G/server-wolfssl/.project create mode 100644 IDE/Renesas/e2studio/RA6M3G/server-wolfssl/common/src/.gitkeep create mode 100644 IDE/Renesas/e2studio/RA6M3G/server-wolfssl/script/.gitkeep create mode 100644 IDE/Renesas/e2studio/RA6M3G/server-wolfssl/src/wolfssl_thread_entry.c create mode 100755 IDE/Renesas/e2studio/RA6M3G/server-wolfssl/wolfssl_thread_entry.h create mode 100644 IDE/Renesas/e2studio/RA6M3G/test-wolfcrypt/.cproject create mode 100644 IDE/Renesas/e2studio/RA6M3G/test-wolfcrypt/.project create mode 100644 IDE/Renesas/e2studio/RA6M3G/test-wolfcrypt/common/.gitkeep create mode 100644 IDE/Renesas/e2studio/RA6M3G/test-wolfcrypt/script/.gitkeep create mode 100644 IDE/Renesas/e2studio/RA6M3G/test-wolfcrypt/src/wolfssl_thread_entry.c create mode 100644 IDE/Renesas/e2studio/RA6M3G/wolfssl/.cproject create mode 100644 IDE/Renesas/e2studio/RA6M3G/wolfssl/.project create mode 100644 IDE/Renesas/e2studio/RA6M3G/wolfssl/configuration.xml create mode 100644 IDE/Renesas/e2studio/RA6M3G/wolfssl/src/.gitkeep create mode 100644 IDE/Renesas/e2studio/RA6M3G/wolfssl/wolfcrypt/.gitkeep diff --git a/IDE/Renesas/e2studio/RA6M3G/README.md b/IDE/Renesas/e2studio/RA6M3G/README.md new file mode 100644 index 000000000..03170ffb9 --- /dev/null +++ b/IDE/Renesas/e2studio/RA6M3G/README.md @@ -0,0 +1,175 @@ +wolfSSL for Renesas RA Evaluation Kit (EK-RA6M3G) +================================================= + +## Description + +This directory contains e2studio projects targeted at the Renesas RA 32-bit MCUs.\ +The example projects include a wolfSSL TLS 1.2 client and server.\ +They also include benchmark and cryptography tests for the wolfCrypt library. + +The wolfssl project contains both the wolfSSL and wolfCrypt libraries.\ +It is built as a `Renesas RA C Library Project` and contains the Renesas RA\ +configuration. + +The other projects (benchmark, client, server and test) are built as a\ +`Renesas RA C Project Using RA Library`, where the RA library is the wolfssl project.\ +The wolfssl Project Summary is listed below and is relevant for every project. + +#### Project Summary + +`Board: EK-RA6M3G`\ +`Device: R7FA6M3AH3CFC`\ +`Toolchain: GCC ARM Embedded`\ +`FSP Version: 0.8.0` + +##### Selected software components + +`Board Support Package Common Files v0.8.0`\ +`Arm CMSIS Version 5 - Core (M) v5.5.1`\ +`Amazon FreeRTOS v0.8.0`\ +`RA6M3G-EK Board Support Files v0.8.0`\ +`Board support package for R7FA6M3AH3CFC v0.8.0`\ +`Board support package for RA6M3 v0.8.0`\ +`Board support package for RA6M3 v0.8.0`\ +`Amazon FreeRTOS - Memory Management - Heap 4 v0.8.0`\ +`r_ether to FreeRTOS+TCP Wrapper v0.8.0`\ +`Ethernet v0.8.0`\ +`Ethernet PHY v0.8.0`\ +`FreeRTOS+TCP v0.8.0`\ +`Amazon FreeRTOS - Buffer Allocation 2 v0.8.0` + + +## Setup Steps + +The project directories are missing files necessary to build the project.\ +These files can be generated when creating a new Renesas RA Project.\ +The following steps explain how to generate the missing files and where to place them. + +1.) Create a 'dummy' Renesas RA C Library Project. + + Click File->New->`RA C/C++ Project` + + Click `Renesas RA C Library Project`. Click Next + + Enter `dummy_library` as the project name. Click Next. + + Under `Board: Custom User Board`, select `EK-RA6M3G`. + + Under `RTOS: No RTOS`, select `Amazon FreeRTOS`. + + Click Next. Select `Amazon FreeRTOS - Minimal - Static Allocation` + + Click Finish. + +2.) Create a 'dummy' Renesas RA C Project Using RA Library. + + Click File->New->`RA C/C++ Project` + + Click `Renesas RA C Project Using RA Library`. Click Next + + Enter `dummy_app` as the project name. Click Next. + + Under `RA library project`, select `dummy_library`. + + Click Finish. + +3.) Import all the wolfSSL Projects into e2studio workspace. + + Click File->`Open Projects from File System` + + Click `Directory...` to the right of Import source + + Select the RA6M3G folder location that contains the projects\ + example path: wolfssl/IDE/Renesas/e2studio/RA6M3G + + Deselect the Non-Eclipse project, RA6M3G, by clicking the checkbox\ + Only the folders with 'Eclipse project' under 'Import as' need to be selected. + + Click Finish. + +4.) Copy files from `dummy_library` into `wolfSSL_RA6M3G` + + Expand the dummy_library and wolfSSL_RA6M3G projects\ + (Click the drop-down arrow to the left of the project name.) + + Select and Copy the following folders/files inside dummy_library\ +` ra/`\ +` ra_gen/`\ +` ra_cfg/`\ +` script/`\ +` R7FA6M3AH3CFC.pincfg`\ +` RA6M3G-EK.pingcfg` + + Paste the copied folders/files into wolfSSL_RA6M3G + + The `dummy_library` project can now be deleted. + + Generate Project Content. + + Click `Open RA Configuration` in the top bar (Grey Settings Cog) + + Click `Generate Project Content` at top right (Green Icon) + + Build wolfSSL_RA6M3G. + +5.) Copy files from `dummy_app` into `./IDE/Renesas/e2studio/RA6M3G/common/ra6m3g/`\ + **NOTE:** This may need to be done outside of the e2studio environment (e.g. File Explorer). + + Select and Copy the followng folder inside dummy_app\ +` src/`\ +` script/` + + Paste the copied folders into `./IDE/Renesas/e2studio/RA6M3G/common/ra6m3g/`\ +` (The test, benchmark, client and server projects link to this folder.)` + + The `dummy_app` project can now be deleted. + +6.) Setup Network Environment + + The client and server projects have defines inside their wolfssl_thread_entry.h. + These defines (ucIPAddress ... ucDNSServerAddress) may need to be changed + based on your internal network environment. The g_ether0_mac_address is the default + mac address found inside the RA configuration inside the wolfssl project. + The client wolfssl_thread_entry.h has defines (SERVER_IP and DEFAULT_PORT) that + will need to be changed based on the server you're trying to connect to over + the ethernet connection. + +## Build and Run + +### Build Each Project +Right-Click each Project and select Build. + +### Run wolfCrypt Test and Benchmark +1.) Right-Click the Project name.\ +2.) Select `Debug As` -> `Renesas GDB Hardware Debugging`\ +3.) Select J-Link ARM. Click OK.\ +4.) Select R7Fa6M3AH. Click OK. + +### Run the wolfSSL TLS Server Example. +1.) Right-Click the Project name.\ +2.) Select `Debug As` -> `Renesas GDB Hardware Debugging`\ +3.) Select J-Link ARM. Click OK.\ +4.) Select R7Fa6M3AH. Click OK.\ +5.) Run the following wolfSSL example client command inside the base of the wolfssl directory. + +``` +./examples/client/client -h "ucIPAddress" -p 11111 -A ./certs/1024/ca-cert.pem +``` +**NOTE:** "ucIPAddress" is "192.168.1.241" by default. (See wolfssl_thread_entry.h) + +### Run the wolfSSL TLS Client Example. + 1.) Run the following wolfSSL example server command inside the base of the wolfssl directory. + +``` +./examples/server/server -b -d -p 11111 -c ./certs/1024/server-cert.pem -k ./certs/1024/server-key.pem +``` +**NOTE:** The port 11111 is the DEFAULT_PORT inside wolfssl_thread_entry.h.\ +If DEFAULT_PORT was changed then the above command will need to match it. + + 2.) Right-Click the Project name.\ + 3.) Select `Debug As` -> `Renesas GDB Hardware Debugging`\ + 4.) Select J-Link ARM. Click OK.\ + 5.) Select R7Fa6M3AH. Click OK. + + +## Troubleshooting + +* The commands for the example client/server assumes it is being run from the + base directory of wolfssl. + +* Enter "#define DEBUG_WOLFSSL" inside user_settings.h or wolfssl_thread_entry.c\ + to enable wolfssl debug messages to the Renesas Virtual Debug Console. + +* Some linking errors can be caused by the e2studio project files needing to be rebuilt and freshened. +Right-Click a project, select Index, click Rebuild and then click Freshen Files. Repeat for each project. + +[Support Forum](https://www.wolfssl.com/forums/) + +Support Email: support@wolfssl.com + + +## Resources + +[wolfSSL Website](https://www.wolfssl.com/) + +[wolfSSL Wiki](https://github.com/wolfSSL/wolfssl/wiki) + +[wolfSSL Manual](https://wolfssl.com/wolfSSL/Docs-wolfssl-manual-toc.html) + +[wolfSSL API Reference](https://wolfssl.com/wolfSSL/Docs-wolfssl-manual-17-wolfssl-api-reference.html) + +[wolfCrypt API Reference](https://wolfssl.com/wolfSSL/Docs-wolfssl-manual-18-wolfcrypt-api-reference.html) + +[TLS 1.3](https://www.wolfssl.com/docs/tls13/) diff --git a/IDE/Renesas/e2studio/RA6M3G/benchmark-wolfcrypt/.cproject b/IDE/Renesas/e2studio/RA6M3G/benchmark-wolfcrypt/.cproject new file mode 100644 index 000000000..f8e135a28 --- /dev/null +++ b/IDE/Renesas/e2studio/RA6M3G/benchmark-wolfcrypt/.cproject @@ -0,0 +1,309 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/IDE/Renesas/e2studio/RA6M3G/benchmark-wolfcrypt/.project b/IDE/Renesas/e2studio/RA6M3G/benchmark-wolfcrypt/.project new file mode 100644 index 000000000..9b1353df6 --- /dev/null +++ b/IDE/Renesas/e2studio/RA6M3G/benchmark-wolfcrypt/.project @@ -0,0 +1,59 @@ + + + benchmark_wolfCrypt_RA6M3G + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + com.renesas.cdt.ra.contentgen.raExecutableNature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + common/src + 2 + virtual:/virtual + + + common/user_settings.h + 1 + PARENT-1-PROJECT_LOC/common/user_settings.h + + + common/util.h + 1 + PARENT-1-PROJECT_LOC/common/util.h + + + script/ra6m3.ld + 1 + PARENT-1-PROJECT_LOC/common/ra6m3g/script/ra6m3.ld + + + src/benchmark.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/benchmark/benchmark.c + + + common/src/freertos_tcp_port.c + 1 + PARENT-1-PROJECT_LOC/common/src/freertos_tcp_port.c + + + diff --git a/IDE/Renesas/e2studio/RA6M3G/benchmark-wolfcrypt/common/.gitkeep b/IDE/Renesas/e2studio/RA6M3G/benchmark-wolfcrypt/common/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/IDE/Renesas/e2studio/RA6M3G/benchmark-wolfcrypt/script/.gitkeep b/IDE/Renesas/e2studio/RA6M3G/benchmark-wolfcrypt/script/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/IDE/Renesas/e2studio/RA6M3G/benchmark-wolfcrypt/src/wolfssl_thread_entry.c b/IDE/Renesas/e2studio/RA6M3G/benchmark-wolfcrypt/src/wolfssl_thread_entry.c new file mode 100644 index 000000000..67629b1c4 --- /dev/null +++ b/IDE/Renesas/e2studio/RA6M3G/benchmark-wolfcrypt/src/wolfssl_thread_entry.c @@ -0,0 +1,30 @@ +/* wolfssl_thread_entry.c + * + * 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 + */ +#include +#include "wolfcrypt/benchmark/benchmark.h" +#include "common/util.h" + +void wolfssl_thread_entry(void *pvParameters) { + FSP_PARAMETER_NOT_USED(pvParameters); + initialise_monitor_handles(); + benchmark_test(0); + while (1); +} diff --git a/IDE/Renesas/e2studio/RA6M3G/client-wolfssl/.cproject b/IDE/Renesas/e2studio/RA6M3G/client-wolfssl/.cproject new file mode 100644 index 000000000..b4d519106 --- /dev/null +++ b/IDE/Renesas/e2studio/RA6M3G/client-wolfssl/.cproject @@ -0,0 +1,325 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/IDE/Renesas/e2studio/RA6M3G/client-wolfssl/.project b/IDE/Renesas/e2studio/RA6M3G/client-wolfssl/.project new file mode 100644 index 000000000..0f84e0838 --- /dev/null +++ b/IDE/Renesas/e2studio/RA6M3G/client-wolfssl/.project @@ -0,0 +1,54 @@ + + + client_wolfSSL_RA6M3G + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + com.renesas.cdt.ra.contentgen.raExecutableNature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + common/user_settings.h + 1 + PARENT-1-PROJECT_LOC/common/user_settings.h + + + common/util.h + 1 + PARENT-1-PROJECT_LOC/common/util.h + + + script/ra6m3.ld + 1 + PARENT-1-PROJECT_LOC/common/ra6m3g/script/ra6m3.ld + + + src/hal_entry.c + 1 + PARENT-1-PROJECT_LOC/common/ra6m3g/src/hal_entry.c + + + common/src/freertos_tcp_port.c + 1 + PARENT-1-PROJECT_LOC/common/src/freertos_tcp_port.c + + + diff --git a/IDE/Renesas/e2studio/RA6M3G/client-wolfssl/common/src/.gitkeep b/IDE/Renesas/e2studio/RA6M3G/client-wolfssl/common/src/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/IDE/Renesas/e2studio/RA6M3G/client-wolfssl/script/.gitkeep b/IDE/Renesas/e2studio/RA6M3G/client-wolfssl/script/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/IDE/Renesas/e2studio/RA6M3G/client-wolfssl/src/wolfssl_thread_entry.c b/IDE/Renesas/e2studio/RA6M3G/client-wolfssl/src/wolfssl_thread_entry.c new file mode 100644 index 000000000..461cfab5b --- /dev/null +++ b/IDE/Renesas/e2studio/RA6M3G/client-wolfssl/src/wolfssl_thread_entry.c @@ -0,0 +1,150 @@ +/* wolfssl_thread_entry.c + * + * 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 + */ + +/* wolfSSL */ +#include +#include +#include +#include "wolfssl_thread_entry.h" + +/* FreeRTOS */ +#include "FreeRTOS_IP.h" +#include "FreeRTOS_Sockets.h" + +/* Project Specific */ +#include "common/util.h" +#include + +void wolfssl_thread_entry(void *pvParameters) { + FSP_PARAMETER_NOT_USED(pvParameters); + + /* FreeRTOS+TCP Objects */ + BaseType_t fr_status; + socklen_t xSize = sizeof(struct freertos_sockaddr); + xSocket_t xClientSocket = NULL; + struct freertos_sockaddr xRemoteAddress; + + /* Return status */ + int ret = WOLFSSL_FAILURE; + + /* Message to send and buffer for receive. */ + const char msg[] = "Hello from wolfSSL client."; + char buff[256]; + + /* wolfSSL objects */ + WOLFSSL_CTX *ctx = NULL; + WOLFSSL *ssl = NULL; + + /* Output to Renesas Debug Virtual Console */ + initialise_monitor_handles(); +#ifdef DEBUG_WOLFSSL + wolfSSL_Debugging_ON(); +#endif + + /* FreeRTOS+TCP Ethernet and IP Setup */ + fr_status = FreeRTOS_IPInit(ucIPAddress, + ucNetMask, + ucGatewayAddress, + ucDNSServerAddress, + g_ether0_mac_address); + if (pdPASS != fr_status) { + printf("Error [%ld]: FreeRTOS_IPInit.\n",fr_status); + util_inf_loop(xClientSocket, ctx, ssl); + } + + /* Client Socket Setup */ + xRemoteAddress.sin_port = FreeRTOS_htons(DEFAULT_PORT); + xRemoteAddress.sin_addr = FreeRTOS_inet_addr(SERVER_IP); + + /* Create a FreeRTOS TCP Socket and connect */ + xClientSocket = FreeRTOS_socket(FREERTOS_AF_INET, + FREERTOS_SOCK_STREAM, + FREERTOS_IPPROTO_TCP); + configASSERT(xClientSocket != FREERTOS_INVALID_SOCKET); + FreeRTOS_bind(xClientSocket, &xRemoteAddress, sizeof(xSize)); + + /* Client Socket Connect */ + ret = FreeRTOS_connect(xClientSocket, + &xRemoteAddress, + sizeof(xRemoteAddress)); + if (ret != FR_SOCKET_SUCCESS) { + printf("Error [%d]: FreeRTOS_connect.\n",ret); + util_inf_loop(xClientSocket, ctx, ssl); + } + + /* TLS Connection Setup */ + /* Initialize wolfSSL */ + wolfSSL_Init(); + + /* Create and initialize WOLFSSL_CTX */ + ctx = wolfSSL_CTX_new(wolfTLSv1_2_client_method()); + if (ctx == NULL) { + printf("Error: wolfSSL_CTX_new.\n"); + util_inf_loop(xClientSocket, ctx, ssl); + } + + /* Load client certificates into WOLFSSL_CTX */ + ret = wolfSSL_CTX_load_verify_buffer(ctx, CERT, SIZEOF_CERT, + WOLFSSL_FILETYPE_ASN1); + if (ret != WOLFSSL_SUCCESS) { + printf("Error [%d]: wolfSSL_CTX_load_verify_buffer.\n",ret); + util_inf_loop(xClientSocket, ctx, ssl); + } + + /* Create a WOLFSSL object */ + ssl = wolfSSL_new(ctx); + if (ssl == NULL) { + printf("Error: wolfSSL_new.\n"); + util_inf_loop(xClientSocket, ctx, ssl); + } + + /* Attach wolfSSL to the socket */ + ret = wolfSSL_set_fd(ssl, (int) xClientSocket); + if (ret != WOLFSSL_SUCCESS) { + printf("Error [%d]: wolfSSL_set_fd.\n",ret); + util_inf_loop(xClientSocket, ctx, ssl); + } + + /* Connect to wolfSSL on the server side */ + ret = wolfSSL_connect(ssl); + if (ret != WOLFSSL_SUCCESS) { + ret = wolfSSL_get_error(ssl, ret); + printf("Error [%d]: wolfSSL_connect.\n",ret); + util_inf_loop(xClientSocket, ctx, ssl); + } + + /* Send the message to the server */ + ret = wolfSSL_write(ssl, msg, (int) XSTRLEN(msg)); + if (ret < 0) { + printf("Error: wolfSSL_write.\n"); + util_inf_loop(xClientSocket, ctx, ssl); + } + + /* Read the server data into buff array */ + XMEMSET(buff, 0, sizeof(buff)); + ret = wolfSSL_read(ssl, buff, sizeof(buff) - 1); + + /* Shutdown TLS connection */ + wolfSSL_shutdown(ssl); + + /* Cleanup */ + util_inf_loop(xClientSocket, ctx, ssl); +} diff --git a/IDE/Renesas/e2studio/RA6M3G/client-wolfssl/wolfssl_thread_entry.h b/IDE/Renesas/e2studio/RA6M3G/client-wolfssl/wolfssl_thread_entry.h new file mode 100755 index 000000000..d63d66952 --- /dev/null +++ b/IDE/Renesas/e2studio/RA6M3G/client-wolfssl/wolfssl_thread_entry.h @@ -0,0 +1,41 @@ +/* wolfssl_thread_entry.h + * + * 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 + */ +#ifndef WOLFSSL_THREAD_ENTRY_H_ +#define WOLFSSL_THREAD_ENTRY_H_ + +#include +#include + +static const byte ucIPAddress[4] = { 192, 168, 1, 241 }; +static const byte ucNetMask[4] = { 255, 255, 255, 0 }; +static const byte ucGatewayAddress[4] = { 192, 168, 1, 1 }; +static const byte ucDNSServerAddress[4] = { 192, 168, 1, 1 }; +static const byte g_ether0_mac_address[6] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 }; + +/* Client connects to the server with these details. */ +#define SERVER_IP "192.168.1.240" +#define DEFAULT_PORT 11111 +#define CERT ca_cert_der_1024 +#define SIZEOF_CERT sizeof_ca_cert_der_1024 + +#define FR_SOCKET_SUCCESS 0 + +#endif /* WOLFSSL_THREAD_ENTRY_H_ */ diff --git a/IDE/Renesas/e2studio/RA6M3G/common/ra6m3g/README.md b/IDE/Renesas/e2studio/RA6M3G/common/ra6m3g/README.md new file mode 100755 index 000000000..d509cca84 --- /dev/null +++ b/IDE/Renesas/e2studio/RA6M3G/common/ra6m3g/README.md @@ -0,0 +1,4 @@ +Create a 'dummy' Renesas RA C Project Using RA Library. +Copy and Paste the generated 'script' and 'src' folder into this folder. + +These are linked to in other projects. diff --git a/IDE/Renesas/e2studio/RA6M3G/common/src/freertos_tcp_port.c b/IDE/Renesas/e2studio/RA6M3G/common/src/freertos_tcp_port.c new file mode 100644 index 000000000..9e5715316 --- /dev/null +++ b/IDE/Renesas/e2studio/RA6M3G/common/src/freertos_tcp_port.c @@ -0,0 +1,65 @@ +/* freertos_tcp_port.c + * + * 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 + */ + +#include "bsp_api.h" +#include "FreeRTOS.h" +#include "FreeRTOS_sockets.h" +#include "FreeRTOS_IP.h" +#include + +#define HOSTNAME "wolfssl_ra6m3g" + +/* + * Contains callback functions for FreeRTOS+TCP + * The following implementations are NOT SUITABLE FOR PRODUCTION. + * They currently serve to build the projects and are not secure. + */ + +uint32_t ulApplicationGetNextSequenceNumber(uint32_t ulSourceAddress, + uint16_t usSourcePort, + uint32_t ulDestinationAddress, + uint16_t usDestinationPort); + +const char *pcApplicationHostnameHook(void) { + return HOSTNAME; +} + +uint32_t ulRand(void) { + return (uint32_t) rand(); +} + +/* Disabled in RA Configuration. Re-Enable within FreeRTOS+TCP Stack Properties */ +void vApplicationIPNetworkEventHook(eIPCallbackEvent_t eNetworkEvent) { + (void) eNetworkEvent; +} + +uint32_t ulApplicationGetNextSequenceNumber(uint32_t ulSourceAddress, + uint16_t usSourcePort, + uint32_t ulDestinationAddress, + uint16_t usDestinationPort) +{ + (void) ulSourceAddress; + (void) usSourcePort; + (void) ulDestinationAddress; + (void) usDestinationPort; + + return ulRand(); +} diff --git a/IDE/Renesas/e2studio/RA6M3G/common/user_settings.h b/IDE/Renesas/e2studio/RA6M3G/common/user_settings.h new file mode 100644 index 000000000..161e52c1b --- /dev/null +++ b/IDE/Renesas/e2studio/RA6M3G/common/user_settings.h @@ -0,0 +1,77 @@ +/* user_settings.h + * + * 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 + */ +#ifndef USER_SETTINGS_H_ +#define USER_SETTINGS_H_ + +/* Temporary defines. Not suitable for production. */ +#define WOLFSSL_GENSEED_FORTEST /* Warning: define your own seed gen */ +/* End temporary defines */ + +/* Operating Environment and Threading */ +#define FREERTOS +#define FREERTOS_TCP +#define NO_DEV_RANDOM +#define NO_WRITEV +#define NO_MAIN_DRIVER +#define BENCH_EMBEDDED + +/* Filesystem and IO */ +#define NO_WOLFSSL_DIR +#define WOLFSSL_NO_CURRDIR +#define NO_FILESYSTEM + +/* Cryptography Enable Options */ +#define HAVE_CHACHA +#define HAVE_POLY1305 +#define HAVE_ECC +#define HAVE_RSA +#define HAVE_SHA256 +#define HAVE_SUPPORTED_CURVES +#define HAVE_TLS_EXTENSIONS +#define HAVE_TRUNCATED_HMAC +#define HAVE_EXTENDED_MASTER +#define HAVE_ALPN +#define HAVE_SNI +#define HAVE_OCSP +#define HAVE_AESGCM +#define HAVE_ONE_TIME_AUTH + +/* Non-Fast Math may call realloc. This project has no realloc support */ +#define USE_FAST_MATH +#define ALT_ECC_SIZE +#define TFM_TIMING_RESISTANT +#define ECC_TIMING_RESISTANT +#define WC_RSA_BLINDING +#define WOLFSSL_SMALL_STACK +#define WOLFSSL_DH_CONST + +/* Cryptography Disable options */ +#define NO_PWDBASED +#define NO_DSA +#define NO_DES3 +#define NO_RABBIT +#define NO_RC4 +#define NO_MD4 + +void wolfssl_thread_entry(void *pvParameters); +extern void initialise_monitor_handles(void); + +#endif /* USER_SETTINGS_H_ */ diff --git a/IDE/Renesas/e2studio/RA6M3G/common/util.h b/IDE/Renesas/e2studio/RA6M3G/common/util.h new file mode 100644 index 000000000..805415b04 --- /dev/null +++ b/IDE/Renesas/e2studio/RA6M3G/common/util.h @@ -0,0 +1,48 @@ +/* util.h + * + * 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 + */ + +#ifndef _UTIL_H_ +#define _UTIL_H_ +#include "common/user_settings.h" +#include +#include "FreeRTOS_IP.h" +#include + +static void util_Cleanup(xSocket_t xSock, WOLFSSL_CTX *ctx, WOLFSSL *ssl) { + printf("Cleaning up socket and wolfSSL objects.\n"); + if (xSock != NULL) + FreeRTOS_closesocket(xSock); + if (ssl != NULL) + wolfSSL_free(ssl); + if (ctx != NULL) + wolfSSL_CTX_free(ctx); + wolfSSL_Cleanup(); +} + +static inline void util_inf_loop(xSocket_t xClientSocket, WOLFSSL_CTX *ctx, + WOLFSSL *ssl) { + util_Cleanup(xClientSocket, ctx, ssl); + printf("Reached infinite loop.\n"); + while (1) + ; +} + +#endif /* _UTIL_H */ diff --git a/IDE/Renesas/e2studio/RA6M3G/include.am b/IDE/Renesas/e2studio/RA6M3G/include.am new file mode 100644 index 000000000..c0bab82b8 --- /dev/null +++ b/IDE/Renesas/e2studio/RA6M3G/include.am @@ -0,0 +1,32 @@ +# vim:ft=automake +# included from Top Level Makefile.am +# All paths should be given relative to the root + +EXTRA_DIST+= IDE/Renesas/e2studio/RA6M3G/benchmark-wolfcrypt/src/wolfssl_thread_entry.c +EXTRA_DIST+= IDE/Renesas/e2studio/RA6M3G/benchmark-wolfcrypt/.cproject +EXTRA_DIST+= IDE/Renesas/e2studio/RA6M3G/benchmark-wolfcrypt/.project + +EXTRA_DIST+= IDE/Renesas/e2studio/RA6M3G/client-wolfssl/src/wolfssl_thread_entry.c +EXTRA_DIST+= IDE/Renesas/e2studio/RA6M3G/client-wolfssl/.cproject +EXTRA_DIST+= IDE/Renesas/e2studio/RA6M3G/client-wolfssl/.project +EXTRA_DIST+= IDE/Renesas/e2studio/RA6M3G/client-wolfssl/wolfssl_thread_entry.h + +EXTRA_DIST+= IDE/Renesas/e2studio/RA6M3G/common/ra6m3g/README.md +EXTRA_DIST+= IDE/Renesas/e2studio/RA6M3G/common/src/freertos_tcp_port.c +EXTRA_DIST+= IDE/Renesas/e2studio/RA6M3G/common/user_settings.h +EXTRA_DIST+= IDE/Renesas/e2studio/RA6M3G/common/util.h + +EXTRA_DIST+= IDE/Renesas/e2studio/RA6M3G/server-wolfssl/src/wolfssl_thread_entry.c +EXTRA_DIST+= IDE/Renesas/e2studio/RA6M3G/server-wolfssl/.cproject +EXTRA_DIST+= IDE/Renesas/e2studio/RA6M3G/server-wolfssl/.project +EXTRA_DIST+= IDE/Renesas/e2studio/RA6M3G/server-wolfssl/wolfssl_thread_entry.h + +EXTRA_DIST+= IDE/Renesas/e2studio/RA6M3G/test-wolfcrypt/src/wolfssl_thread_entry.c +EXTRA_DIST+= IDE/Renesas/e2studio/RA6M3G/test-wolfcrypt/.cproject +EXTRA_DIST+= IDE/Renesas/e2studio/RA6M3G/test-wolfcrypt/.project + +EXTRA_DIST+= IDE/Renesas/e2studio/RA6M3G/wolfssl/.cproject +EXTRA_DIST+= IDE/Renesas/e2studio/RA6M3G/wolfssl/.project +EXTRA_DIST+= IDE/Renesas/e2studio/RA6M3G/wolfssl/configuration.xml + +EXTRA_DIST+= IDE/Renesas/e2studio/RA6M3G/README.md diff --git a/IDE/Renesas/e2studio/RA6M3G/server-wolfssl/.cproject b/IDE/Renesas/e2studio/RA6M3G/server-wolfssl/.cproject new file mode 100644 index 000000000..402e450b8 --- /dev/null +++ b/IDE/Renesas/e2studio/RA6M3G/server-wolfssl/.cproject @@ -0,0 +1,320 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/IDE/Renesas/e2studio/RA6M3G/server-wolfssl/.project b/IDE/Renesas/e2studio/RA6M3G/server-wolfssl/.project new file mode 100644 index 000000000..70c1bd5f9 --- /dev/null +++ b/IDE/Renesas/e2studio/RA6M3G/server-wolfssl/.project @@ -0,0 +1,60 @@ + + + server_wolfSSL_RA6M3G + + + + + + org.eclipse.xtext.ui.shared.xtextBuilder + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + com.renesas.cdt.ra.contentgen.raExecutableNature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + org.eclipse.xtext.ui.shared.xtextNature + + + + common/user_settings.h + 1 + PARENT-1-PROJECT_LOC/common/user_settings.h + + + common/util.h + 1 + PARENT-1-PROJECT_LOC/common/util.h + + + script/ra6m3.ld + 1 + PARENT-1-PROJECT_LOC/common/ra6m3g/script/ra6m3.ld + + + src/hal_entry.c + 1 + PARENT-1-PROJECT_LOC/common/ra6m3g/src/hal_entry.c + + + common/src/freertos_tcp_port.c + 1 + PARENT-1-PROJECT_LOC/common/src/freertos_tcp_port.c + + + diff --git a/IDE/Renesas/e2studio/RA6M3G/server-wolfssl/common/src/.gitkeep b/IDE/Renesas/e2studio/RA6M3G/server-wolfssl/common/src/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/IDE/Renesas/e2studio/RA6M3G/server-wolfssl/script/.gitkeep b/IDE/Renesas/e2studio/RA6M3G/server-wolfssl/script/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/IDE/Renesas/e2studio/RA6M3G/server-wolfssl/src/wolfssl_thread_entry.c b/IDE/Renesas/e2studio/RA6M3G/server-wolfssl/src/wolfssl_thread_entry.c new file mode 100644 index 000000000..6e9bba82a --- /dev/null +++ b/IDE/Renesas/e2studio/RA6M3G/server-wolfssl/src/wolfssl_thread_entry.c @@ -0,0 +1,172 @@ +/* wolfssl_thread_entry.c + * + * 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 + */ +#include +#include +#include +#include "wolfssl_thread_entry.h" + +/* FreeRTOS+TCP */ +#include "FreeRTOS_IP.h" +#include "FreeRTOS_Sockets.h" + +/* Project Tools */ +#include "common/util.h" +#include + +void wolfssl_thread_entry(void *pvParameters) { + FSP_PARAMETER_NOT_USED(pvParameters); + + /* FreeRTOS+TCP parameters and objects */ + BaseType_t fr_status; + struct freertos_sockaddr xClient, xBindAddress; + Socket_t xListeningSocket, xConnectedSocket; + socklen_t xSize = sizeof(xClient); + const BaseType_t xBacklog = 1; /* Max number of connections */ + static const TickType_t xReceiveTimeOut = portMAX_DELAY; + + /* Return Code */ + int ret = WOLFSSL_FAILURE; + + /* Send/Receive Message */ + const char *reply = "I hear ya fa shizzle!\n"; + char buff[256]; + + /* wolfSSL objects */ + WOLFSSL_CTX *ctx = NULL; + WOLFSSL *ssl = NULL; + + /* Output to Renesas Debug Virtual Console */ + initialise_monitor_handles(); +#ifdef DEBUG_WOLFSSL + wolfSSL_Debugging_ON(); +#endif + + fr_status = FreeRTOS_IPInit(ucIPAddress,ucNetMask, ucGatewayAddress, + ucDNSServerAddress, g_ether0_mac_address); + + if (pdPASS != fr_status) { + printf("Error [%ld]: FreeRTOS_IPInit.\n",fr_status); + while (1); + } + /* Attempt to open the socket. */ + xListeningSocket = FreeRTOS_socket(FREERTOS_AF_INET, + FREERTOS_SOCK_STREAM, + FREERTOS_IPPROTO_TCP); + configASSERT(xListeningSocket != FREERTOS_INVALID_SOCKET); + + /* Set a time out so accept() will just wait for a connection. */ + FreeRTOS_setsockopt(xListeningSocket, 0, + FREERTOS_SO_RCVTIMEO, &xReceiveTimeOut, sizeof(xReceiveTimeOut)); + + xBindAddress.sin_port = (uint16_t) DEFAULT_PORT; + xBindAddress.sin_port = FreeRTOS_htons(xBindAddress.sin_port); + + configASSERT(xListeningSocket != FREERTOS_INVALID_SOCKET); + + ret = FreeRTOS_bind(xListeningSocket, &xBindAddress, sizeof(xBindAddress)); + if (ret == FR_SOCKET_SUCCESS) + ret = FreeRTOS_listen(xListeningSocket, xBacklog); + + if (ret != FR_SOCKET_SUCCESS) { + printf("Error [%d]: FreeRTOS_bind.\n",ret); + while (1); + } + + while (1) { + ret = WOLFSSL_FAILURE; + xConnectedSocket = FreeRTOS_accept(xListeningSocket, &xClient, &xSize); + configASSERT(xConnectedSocket != FREERTOS_INVALID_SOCKET); + + /* Create WOLFSSL_CTX object */ + ctx = wolfSSL_CTX_new(wolfTLSv1_2_server_method()); + + /* Load server certificates into WOLFSSL_CTX */ + if (ctx == NULL) { + printf("Error: wolfSSL_CTX_new.\n"); + break; + } + ret = wolfSSL_CTX_use_certificate_buffer(ctx, CERT_BUF, SIZEOF_CERT_BUF, + SSL_FILETYPE_ASN1); + + /* Load server key into WOLFSSL_CTX */ + if (ret != WOLFSSL_SUCCESS) { + printf("Error [%d]: wolfSSL_CTX_use_certificate_buffer.\n",ret); + break; + } + ret = wolfSSL_CTX_use_PrivateKey_buffer(ctx, KEY_BUF, SIZEOF_KEY_BUF, + SSL_FILETYPE_ASN1); + + /* Create a WOLFSSL object */ + if (ret != WOLFSSL_SUCCESS) { + printf("Error [%d]: wolfSSL_CTX_use_PrivateKey_buffer.\n",ret); + break; + } + ssl = wolfSSL_new(ctx); + + /* Attach wolfSSL to the socket */ + if (ssl == NULL) { + printf("Error: wolfSSL_new.\n"); + break; + } + ret = wolfSSL_set_fd(ssl, (int) xConnectedSocket); + + /* Establish TLS connection */ + if (ret != WOLFSSL_SUCCESS) { + printf("Error [%d]: wolfSSL_set_fd.\n",ret); + break; + } + ret = wolfSSL_accept(ssl); + + /* Read the client data into our buff array */ + if (ret != WOLFSSL_SUCCESS) { + printf("Error [%d]: wolfSSL_set_fd.\n",ret); + break; + } + memset(buff, 0, sizeof(buff)); + ret = wolfSSL_read(ssl, buff, sizeof(buff) - 1); + + if (ret < 0) + break; + + /* Check for server shutdown command */ + if (strncmp(buff, "shutdown", 8) == 0) + break; + + /* Write our reply into buff */ + memset(buff, 0, sizeof(buff)); + memcpy(buff, reply, strlen(reply)); + + /* Reply back to the client */ + ret = wolfSSL_write(ssl, buff, (int) strlen(buff)); + + /* Cleanup after this connection */ + util_Cleanup(xConnectedSocket, ctx, ssl); + } + + /* Shutdown TLS Server */ + ret = wolfSSL_shutdown(ssl); + if (ret == WOLFSSL_SHUTDOWN_NOT_DONE) { + wolfSSL_shutdown(ssl); + } + + /* Cleanup connection */ + util_inf_loop(xConnectedSocket, ctx, ssl); +} diff --git a/IDE/Renesas/e2studio/RA6M3G/server-wolfssl/wolfssl_thread_entry.h b/IDE/Renesas/e2studio/RA6M3G/server-wolfssl/wolfssl_thread_entry.h new file mode 100755 index 000000000..6e459ca8c --- /dev/null +++ b/IDE/Renesas/e2studio/RA6M3G/server-wolfssl/wolfssl_thread_entry.h @@ -0,0 +1,43 @@ +/* wolfssl_thread_entry.h + * + * 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 + */ +#ifndef WOLFSSL_THREAD_ENTRY_H_ +#define WOLFSSL_THREAD_ENTRY_H_ + +#include + +static const byte ucIPAddress[4] = { 192, 168, 1, 241 }; +static const byte ucNetMask[4] = { 255, 255, 255, 0 }; +static const byte ucGatewayAddress[4] = { 192, 168, 1, 1 }; +static const byte ucDNSServerAddress[4] = { 192, 168, 1, 1 }; +static const byte g_ether0_mac_address[6] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 }; + +/* Server Cert and Key */ +#define CERT_BUF server_cert_der_1024 +#define SIZEOF_CERT_BUF sizeof_server_cert_der_1024 +#define KEY_BUF server_key_der_1024 +#define SIZEOF_KEY_BUF sizeof_server_key_der_1024 + +/* Port That the wolfSSL Server connects to. */ +#define DEFAULT_PORT 11111 + +#define FR_SOCKET_SUCCESS 0 + +#endif /* WOLFSSL_THREAD_ENTRY_H_ */ diff --git a/IDE/Renesas/e2studio/RA6M3G/test-wolfcrypt/.cproject b/IDE/Renesas/e2studio/RA6M3G/test-wolfcrypt/.cproject new file mode 100644 index 000000000..bfcbafd28 --- /dev/null +++ b/IDE/Renesas/e2studio/RA6M3G/test-wolfcrypt/.cproject @@ -0,0 +1,305 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/IDE/Renesas/e2studio/RA6M3G/test-wolfcrypt/.project b/IDE/Renesas/e2studio/RA6M3G/test-wolfcrypt/.project new file mode 100644 index 000000000..507e93cab --- /dev/null +++ b/IDE/Renesas/e2studio/RA6M3G/test-wolfcrypt/.project @@ -0,0 +1,54 @@ + + + test_wolfCrypt_RA6M3G + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + com.renesas.cdt.ra.contentgen.raExecutableNature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + + + common/user_settings.h + 1 + PARENT-1-PROJECT_LOC/common/user_settings.h + + + common/util.h + 1 + PARENT-1-PROJECT_LOC/common/util.h + + + script/ra6m3.ld + 1 + PARENT-1-PROJECT_LOC/common/ra6m3g/script/ra6m3.ld + + + src/hal_entry.c + 1 + PARENT-1-PROJECT_LOC/common/ra6m3g/src/hal_entry.c + + + src/test.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/test/test.c + + + diff --git a/IDE/Renesas/e2studio/RA6M3G/test-wolfcrypt/common/.gitkeep b/IDE/Renesas/e2studio/RA6M3G/test-wolfcrypt/common/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/IDE/Renesas/e2studio/RA6M3G/test-wolfcrypt/script/.gitkeep b/IDE/Renesas/e2studio/RA6M3G/test-wolfcrypt/script/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/IDE/Renesas/e2studio/RA6M3G/test-wolfcrypt/src/wolfssl_thread_entry.c b/IDE/Renesas/e2studio/RA6M3G/test-wolfcrypt/src/wolfssl_thread_entry.c new file mode 100644 index 000000000..257a1d479 --- /dev/null +++ b/IDE/Renesas/e2studio/RA6M3G/test-wolfcrypt/src/wolfssl_thread_entry.c @@ -0,0 +1,32 @@ +/* wolfssl_thread_entry.c + * + * 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 + */ + +#include +#include "wolfcrypt/test/test.h" + +void wolfssl_thread_entry(void* pvParameters) +{ + FSP_PARAMETER_NOT_USED (pvParameters); + /* Benchmark output is displayed to Renesas Debug Virtual Console */ + initialise_monitor_handles(); + wolfcrypt_test(0); + while(1); +} diff --git a/IDE/Renesas/e2studio/RA6M3G/wolfssl/.cproject b/IDE/Renesas/e2studio/RA6M3G/wolfssl/.cproject new file mode 100644 index 000000000..a28b9e11d --- /dev/null +++ b/IDE/Renesas/e2studio/RA6M3G/wolfssl/.cproject @@ -0,0 +1,334 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/IDE/Renesas/e2studio/RA6M3G/wolfssl/.project b/IDE/Renesas/e2studio/RA6M3G/wolfssl/.project new file mode 100644 index 000000000..c3fda822f --- /dev/null +++ b/IDE/Renesas/e2studio/RA6M3G/wolfssl/.project @@ -0,0 +1,554 @@ + + + wolfSSL_RA6M3G + + + + + + com.renesas.cdt.ra.contentgen.raBuilder + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + com.renesas.cdt.ra.contentgen.raNature + + + + src/bio.c + 1 + PARENT-5-PROJECT_LOC/src/bio.c + + + src/crl.c + 1 + PARENT-5-PROJECT_LOC/src/crl.c + + + src/include.am + 1 + PARENT-5-PROJECT_LOC/src/include.am + + + src/internal.c + 1 + PARENT-5-PROJECT_LOC/src/internal.c + + + src/keys.c + 1 + PARENT-5-PROJECT_LOC/src/keys.c + + + src/ocsp.c + 1 + PARENT-5-PROJECT_LOC/src/ocsp.c + + + src/sniffer.c + 1 + PARENT-5-PROJECT_LOC/src/sniffer.c + + + src/ssl.c + 1 + PARENT-5-PROJECT_LOC/src/ssl.c + + + src/tls.c + 1 + PARENT-5-PROJECT_LOC/src/tls.c + + + src/tls13.c + 1 + PARENT-5-PROJECT_LOC/src/tls13.c + + + src/wolfio.c + 1 + PARENT-5-PROJECT_LOC/src/wolfio.c + + + wolfcrypt/aes.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/aes.c + + + wolfcrypt/arc4.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/arc4.c + + + wolfcrypt/asm.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/asm.c + + + wolfcrypt/asn.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/asn.c + + + wolfcrypt/blake2b.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/blake2b.c + + + wolfcrypt/blake2s.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/blake2s.c + + + wolfcrypt/camellia.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/camellia.c + + + wolfcrypt/chacha.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/chacha.c + + + wolfcrypt/chacha20_poly1305.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/chacha20_poly1305.c + + + wolfcrypt/cmac.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/cmac.c + + + wolfcrypt/coding.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/coding.c + + + wolfcrypt/compress.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/compress.c + + + wolfcrypt/cpuid.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/cpuid.c + + + wolfcrypt/cryptocb.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/cryptocb.c + + + wolfcrypt/curve25519.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/curve25519.c + + + wolfcrypt/des3.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/des3.c + + + wolfcrypt/dh.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/dh.c + + + wolfcrypt/dsa.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/dsa.c + + + wolfcrypt/ecc.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/ecc.c + + + wolfcrypt/ecc_fp.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/ecc_fp.c + + + wolfcrypt/ed25519.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/ed25519.c + + + wolfcrypt/error.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/error.c + + + wolfcrypt/evp.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/evp.c + + + wolfcrypt/fe_low_mem.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/fe_low_mem.c + + + wolfcrypt/fe_operations.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/fe_operations.c + + + wolfcrypt/ge_low_mem.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/ge_low_mem.c + + + wolfcrypt/ge_operations.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/ge_operations.c + + + wolfcrypt/hash.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/hash.c + + + wolfcrypt/hc128.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/hc128.c + + + wolfcrypt/hmac.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/hmac.c + + + wolfcrypt/idea.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/idea.c + + + wolfcrypt/include.am + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/include.am + + + wolfcrypt/integer.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/integer.c + + + wolfcrypt/logging.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/logging.c + + + wolfcrypt/md2.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/md2.c + + + wolfcrypt/md4.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/md4.c + + + wolfcrypt/md5.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/md5.c + + + wolfcrypt/memory.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/memory.c + + + wolfcrypt/misc.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/misc.c + + + wolfcrypt/pkcs12.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/pkcs12.c + + + wolfcrypt/pkcs7.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/pkcs7.c + + + wolfcrypt/poly1305.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/poly1305.c + + + wolfcrypt/port + 2 + virtual:/virtual + + + wolfcrypt/pwdbased.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/pwdbased.c + + + wolfcrypt/rabbit.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/rabbit.c + + + wolfcrypt/random.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/random.c + + + wolfcrypt/ripemd.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/ripemd.c + + + wolfcrypt/rsa.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/rsa.c + + + wolfcrypt/sha.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/sha.c + + + wolfcrypt/sha256.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/sha256.c + + + wolfcrypt/sha3.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/sha3.c + + + wolfcrypt/sha512.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/sha512.c + + + wolfcrypt/signature.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/signature.c + + + wolfcrypt/sp_arm32.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/sp_arm32.c + + + wolfcrypt/sp_arm64.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/sp_arm64.c + + + wolfcrypt/sp_armthumb.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/sp_armthumb.c + + + wolfcrypt/sp_c32.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/sp_c32.c + + + wolfcrypt/sp_c64.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/sp_c64.c + + + wolfcrypt/sp_cortexm.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/sp_cortexm.c + + + wolfcrypt/sp_int.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/sp_int.c + + + wolfcrypt/sp_x86_64.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/sp_x86_64.c + + + wolfcrypt/srp.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/srp.c + + + wolfcrypt/tfm.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/tfm.c + + + wolfcrypt/wc_encrypt.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/wc_encrypt.c + + + wolfcrypt/wc_pkcs11.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/wc_pkcs11.c + + + wolfcrypt/wc_port.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/wc_port.c + + + wolfcrypt/wolfevent.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/wolfevent.c + + + wolfcrypt/wolfmath.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/wolfmath.c + + + wolfcrypt/port/Renesas + 2 + virtual:/virtual + + + wolfcrypt/port/af_alg + 2 + virtual:/virtual + + + wolfcrypt/port/arm + 2 + virtual:/virtual + + + wolfcrypt/port/Renesas/README.md + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/port/Renesas/README.md + + + wolfcrypt/port/Renesas/renesas_tsip_aes.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/port/Renesas/renesas_tsip_aes.c + + + wolfcrypt/port/Renesas/renesas_tsip_sha.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/port/Renesas/renesas_tsip_sha.c + + + wolfcrypt/port/Renesas/renesas_tsip_util.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/port/Renesas/renesas_tsip_util.c + + + wolfcrypt/port/af_alg/afalg_aes.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/port/af_alg/afalg_aes.c + + + wolfcrypt/port/af_alg/afalg_hash.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/port/af_alg/afalg_hash.c + + + wolfcrypt/port/af_alg/wc_afalg.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/port/af_alg/wc_afalg.c + + + wolfcrypt/port/arm/armv8-32-curve25519.S + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/port/arm/armv8-32-curve25519.S + + + wolfcrypt/port/arm/armv8-32-curve25519.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/port/arm/armv8-32-curve25519.c + + + wolfcrypt/port/arm/armv8-32-sha512-asm.S + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/port/arm/armv8-32-sha512-asm.S + + + wolfcrypt/port/arm/armv8-32-sha512-asm.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/port/arm/armv8-32-sha512-asm.c + + + wolfcrypt/port/arm/armv8-aes.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/port/arm/armv8-aes.c + + + wolfcrypt/port/arm/armv8-chacha.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/port/arm/armv8-chacha.c + + + wolfcrypt/port/arm/armv8-curve25519.S + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/port/arm/armv8-curve25519.S + + + wolfcrypt/port/arm/armv8-curve25519.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/port/arm/armv8-curve25519.c + + + wolfcrypt/port/arm/armv8-poly1305.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/port/arm/armv8-poly1305.c + + + wolfcrypt/port/arm/armv8-sha256.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/port/arm/armv8-sha256.c + + + wolfcrypt/port/arm/armv8-sha512-asm.S + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/port/arm/armv8-sha512-asm.S + + + wolfcrypt/port/arm/armv8-sha512-asm.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/port/arm/armv8-sha512-asm.c + + + wolfcrypt/port/arm/armv8-sha512.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/port/arm/armv8-sha512.c + + + wolfcrypt/port/arm/cryptoCell.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/port/arm/cryptoCell.c + + + wolfcrypt/port/arm/cryptoCellHash.c + 1 + PARENT-5-PROJECT_LOC/wolfcrypt/src/port/arm/cryptoCellHash.c + + + diff --git a/IDE/Renesas/e2studio/RA6M3G/wolfssl/configuration.xml b/IDE/Renesas/e2studio/RA6M3G/wolfssl/configuration.xml new file mode 100644 index 000000000..8a0c408b9 --- /dev/null +++ b/IDE/Renesas/e2studio/RA6M3G/wolfssl/configuration.xml @@ -0,0 +1,368 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + I/O Port + Renesas.RA.0.8.0.pack + + + Board Support Package Common Files + Renesas.RA.0.8.0.pack + + + Arm CMSIS Version 5 - Core (M) + Arm.CMSIS5.5.5.1.pack + + + Amazon FreeRTOS + Amazon.AWS.0.8.0.pack + + + RA6M3G-EK Board Support Files + Renesas.RA_board_ra6m3g_ek.0.8.0.pack + + + Board support package for R7FA6M3AH3CFC + Renesas.RA_mcu_ra6m3.0.8.0.pack + + + Board support package for RA6M3 + Renesas.RA_mcu_ra6m3.0.8.0.pack + + + Board support package for RA6M3 + Renesas.RA_mcu_ra6m3.0.8.0.pack + + + Amazon FreeRTOS - Memory Management - Heap 4 + Amazon.AWS.0.8.0.pack + + + r_ether to FreeRTOS+TCP Wrapper + Renesas.RA.0.8.0.pack + + + Ethernet + Renesas.RA.0.8.0.pack + + + Ethernet PHY + Renesas.RA.0.8.0.pack + + + FreeRTOS+TCP + Amazon.AWS.0.8.0.pack + + + Amazon FreeRTOS - Buffer Allocation 2 + Amazon.AWS.0.8.0.pack + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/IDE/Renesas/e2studio/RA6M3G/wolfssl/src/.gitkeep b/IDE/Renesas/e2studio/RA6M3G/wolfssl/src/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/IDE/Renesas/e2studio/RA6M3G/wolfssl/wolfcrypt/.gitkeep b/IDE/Renesas/e2studio/RA6M3G/wolfssl/wolfcrypt/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/IDE/include.am b/IDE/include.am index 2ea00f2de..d4d774a07 100644 --- a/IDE/include.am +++ b/IDE/include.am @@ -23,6 +23,7 @@ include IDE/ECLIPSE/SIFIVE/include.am include IDE/mynewt/include.am include IDE/Renesas/cs+/Projects/include.am include IDE/Renesas/e2studio/Projects/include.am +include IDE/Renesas/e2studio/RA6M3G/include.am include IDE/WICED-STUDIO/include.am include IDE/CRYPTOCELL/include.am include IDE/M68K/include.am diff --git a/src/internal.c b/src/internal.c index a75ef67b3..535596dc0 100644 --- a/src/internal.c +++ b/src/internal.c @@ -7002,6 +7002,15 @@ ProtocolVersion MakeDTLSv1_2(void) return (unsigned int)(((float)xTaskGetTickCount())/configTICK_RATE_HZ); } +#elif defined(FREERTOS) + + #include "task.h" + + unsigned int LowResTimer(void) + { + return (unsigned int)(((float)xTaskGetTickCount())/configTICK_RATE_HZ); + } + #elif defined(FREESCALE_KSDK_BM) #include "lwip/sys.h" /* lwIP */ diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 1ea96c7f5..6ac821eb0 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -285,6 +285,10 @@ #endif #endif +#if defined(WOLFSSL_RENESAS_RA6M3G) + /* settings in user_settings.h */ +#endif + #if defined(HAVE_LWIP_NATIVE) /* using LwIP native TCP socket */ #define WOLFSSL_LWIP #define NO_WRITEV diff --git a/wolfssl/wolfio.h b/wolfssl/wolfio.h index 9ea0a0322..0faac3887 100644 --- a/wolfssl/wolfio.h +++ b/wolfssl/wolfio.h @@ -148,6 +148,11 @@ #endif #endif #endif + + #if defined(WOLFSSL_RENESAS_RA6M3G) /* Uses FREERTOS_TCP */ + #include + #endif + #endif /* USE_WINDOWS_API */ #ifdef __sun From 044ad957e5d415a545bb6c287628c207c16cf791 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 28 Jan 2020 15:29:24 +0100 Subject: [PATCH 005/649] Add --enable-openvpn build option --- configure.ac | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index d76287b07..f3f27dfcb 100644 --- a/configure.ac +++ b/configure.ac @@ -180,6 +180,7 @@ then enable_haproxy=yes enable_stunnel=yes enable_nginx=yes + enable_openvpn=yes enable_asio=yes enable_libwebsockets=yes enable_qt=yes @@ -426,6 +427,7 @@ AC_ARG_ENABLE([mcast], # List of open source project defines using our openssl compatibility layer: # openssh (--enable-openssh) +# openvpn (--enable-openvpn) # nginix (--enable-nginx) WOLFSSL_NGINX # haproxy (--enable-haproxy) WOLFSSL_HAPROXY # wpa_supplicant (--enable-wpas) WOLFSSL_WPAS @@ -449,6 +451,12 @@ AC_ARG_ENABLE([openssh], [ENABLED_OPENSSH=$enableval], [ENABLED_OPENSSH=no]) +# OpenVPN compatibility Build +AC_ARG_ENABLE([openvpn], + [AS_HELP_STRING([--enable-openvpn],[Enable OpenVPN compatibility build (default: disabled)])], + [ENABLED_OPENVPN=$enableval], + [ENABLED_OPENVPN=no]) + # nginx compatibility build AC_ARG_ENABLE([nginx], [AS_HELP_STRING([--enable-nginx],[Enable nginx (default: disabled)])], @@ -543,7 +551,7 @@ AC_ARG_ENABLE([opensslall], [ ENABLED_OPENSSLALL=$enableval ], [ ENABLED_OPENSSLALL=no ] ) -if test "$ENABLED_LIBWEBSOCKETS" = "yes" +if test "$ENABLED_LIBWEBSOCKETS" = "yes" || test "$ENABLED_OPENVPN" = "yes" then ENABLED_OPENSSLALL="yes" fi @@ -941,6 +949,10 @@ AC_ARG_ENABLE([aesctr], [ ENABLED_AESCTR=$enableval ], [ ENABLED_AESCTR=no ] ) +if test "$ENABLED_OPENVPN" = "yes" +then + ENABLED_AESCTR=yes +fi if test "$ENABLED_AESCTR" = "yes" then @@ -1328,7 +1340,7 @@ AC_ARG_ENABLE([sessioncerts], [ ENABLED_SESSIONCERTS=no ] ) -if test "x$ENABLED_NGINX" = "xyes" +if test "x$ENABLED_NGINX" = "xyes" || test "x$ENABLED_OPENVPN" = "xyes" then ENABLED_SESSIONCERTS=yes fi @@ -1362,6 +1374,10 @@ AC_ARG_ENABLE([certgen], [ ENABLED_CERTGEN=$enableval ], [ ENABLED_CERTGEN=no ] ) +if test "$ENABLED_OPENVPN" = "yes" +then + ENABLED_CERTGEN=yes +fi if test "$ENABLED_CERTGEN" = "yes" then @@ -1392,6 +1408,10 @@ AC_ARG_ENABLE([certext], [ ENABLED_CERTEXT=$enableval ], [ ENABLED_CERTEXT=no ] ) +if test "$ENABLED_OPENVPN" = "yes" +then + ENABLED_CERTEXT=yes +fi if test "$ENABLED_CERTEXT" = "yes" then @@ -2190,7 +2210,7 @@ AC_ARG_ENABLE([des3], [ ENABLED_DES3=no ] ) -if test "$ENABLED_OPENSSH" = "yes" || test "$ENABLED_QT" = "yes" +if test "$ENABLED_OPENSSH" = "yes" || test "$ENABLED_QT" = "yes" || test "$ENABLED_OPENVPN" = "yes" then ENABLED_DES3="yes" fi @@ -2687,7 +2707,7 @@ AC_ARG_ENABLE([crl], ) -if test "x$ENABLED_NGINX" = "xyes" || test "x$ENABLED_HAPROXY" = "xyes" +if test "x$ENABLED_NGINX" = "xyes" || test "x$ENABLED_HAPROXY" = "xyes" || test "x$ENABLED_OPENVPN" = "xyes" then ENABLED_CRL=yes fi @@ -3401,6 +3421,12 @@ then fi fi +if test "$ENABLED_OPENVPN" = "yes" +then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_DES_ECB -DHAVE_EX_DATA" +fi + + if test "$ENABLED_NGINX" = "yes"|| test "x$ENABLED_HAPROXY" = "xyes" || test "x$ENABLED_LIGHTY" = "xyes" then AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_ALWAYS_VERIFY_CB" From a9e9120fa040983d33b0a775cd886b04e51dccdf Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Tue, 28 Jan 2020 17:11:46 -0700 Subject: [PATCH 006/649] change public Timeval to WOLFSSL_TIMEVAL --- doc/dox_comments/header_files/ssl.h | 4 ++-- examples/client/client.c | 2 +- examples/server/server.c | 3 ++- src/internal.c | 2 +- src/ssl.c | 16 ++++++++-------- wolfssl/callbacks.h | 10 +++++----- wolfssl/openssl/ssl.h | 2 +- wolfssl/ssl.h | 9 +++++---- 8 files changed, 25 insertions(+), 23 deletions(-) diff --git a/doc/dox_comments/header_files/ssl.h b/doc/dox_comments/header_files/ssl.h index e04b8e335..1ba412f60 100644 --- a/doc/dox_comments/header_files/ssl.h +++ b/doc/dox_comments/header_files/ssl.h @@ -11278,7 +11278,7 @@ int wolfSSL_DeriveTlsKeys(unsigned char* key_data, word32 keyLen, \sa wolfSSL_accept_ex */ WOLFSSL_API int wolfSSL_connect_ex(WOLFSSL*, HandShakeCallBack, TimeoutCallBack, - Timeval); + WOLFSSL_TIMEVAL); /*! \brief wolfSSL_accept_ex() is an extension that allows a HandShake Callback @@ -11310,7 +11310,7 @@ WOLFSSL_API int wolfSSL_connect_ex(WOLFSSL*, HandShakeCallBack, TimeoutCallBack, \sa wolfSSL_connect_ex */ WOLFSSL_API int wolfSSL_accept_ex(WOLFSSL*, HandShakeCallBack, TimeoutCallBack, - Timeval); + WOLFSSL_TIMEVAL); /*! \ingroup IO diff --git a/examples/client/client.c b/examples/client/client.c index 85d082574..0def90d50 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -72,7 +72,7 @@ static int lng_index = 0; #ifdef WOLFSSL_CALLBACKS - Timeval timeout; + WOLFSSL_TIMEVAL timeout; static int handShakeCB(HandShakeInfo* info) { (void)info; diff --git a/examples/server/server.c b/examples/server/server.c index 3f1129184..08843c539 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -81,7 +81,7 @@ int catastrophic = 0; /* Use with -x flag to still exit when an error is static int lng_index = 0; #ifdef WOLFSSL_CALLBACKS - Timeval srvTo; + WOLFSSL_TIMEVAL srvTo; static int srvHandShakeCB(HandShakeInfo* info) { (void)info; @@ -1049,6 +1049,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) (void)mcastID; (void)loadCertKeyIntoSSLObj; (void)overrideDateErrors; + (void)nonBlocking; #ifdef WOLFSSL_TIRTOS fdOpenSession(Task_self()); diff --git a/src/internal.c b/src/internal.c index 2097f3ff1..f520aa56c 100644 --- a/src/internal.c +++ b/src/internal.c @@ -18587,7 +18587,7 @@ int PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, word32 hashSigAlgoSz) TimeoutInfo* info = &ssl->timeoutInfo; if (info->numberPackets < (MAX_PACKETS_HANDSHAKE - 1)) { - Timeval currTime; + WOLFSSL_TIMEVAL currTime; /* may add name after */ if (name) { diff --git a/src/ssl.c b/src/ssl.c index 149594eb0..4f57210b6 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -11427,10 +11427,10 @@ int wolfSSL_dtls_get_current_timeout(WOLFSSL* ssl) return timeout; } -int wolfSSL_DTLSv1_get_timeout(WOLFSSL* ssl, Timeval* timeleft) +int wolfSSL_DTLSv1_get_timeout(WOLFSSL* ssl, WOLFSSL_TIMEVAL* timeleft) { if (ssl && timeleft) { - XMEMSET(timeleft, 0, sizeof(Timeval)); + XMEMSET(timeleft, 0, sizeof(WOLFSSL_TIMEVAL)); timeleft->tv_sec = ssl->dtls_timeout; } return 0; @@ -13542,13 +13542,13 @@ int wolfSSL_set_compression(WOLFSSL* ssl) static int wolfSSL_ex_wrapper(WOLFSSL* ssl, HandShakeCallBack hsCb, - TimeoutCallBack toCb, Timeval timeout) + TimeoutCallBack toCb, WOLFSSL_TIMEVAL timeout) { int ret = WOLFSSL_FATAL_ERROR; int oldTimerOn = 0; /* was timer already on */ - Timeval startTime; - Timeval endTime; - Timeval totalTime; + WOLFSSL_TIMEVAL startTime; + WOLFSSL_TIMEVAL endTime; + WOLFSSL_TIMEVAL totalTime; Itimerval myTimeout; Itimerval oldTimeout; /* if old timer adjust from total time to reset */ struct sigaction act, oact; @@ -13656,7 +13656,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) #ifndef NO_WOLFSSL_CLIENT int wolfSSL_connect_ex(WOLFSSL* ssl, HandShakeCallBack hsCb, - TimeoutCallBack toCb, Timeval timeout) + TimeoutCallBack toCb, WOLFSSL_TIMEVAL timeout) { WOLFSSL_ENTER("wolfSSL_connect_ex"); return wolfSSL_ex_wrapper(ssl, hsCb, toCb, timeout); @@ -13668,7 +13668,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) #ifndef NO_WOLFSSL_SERVER int wolfSSL_accept_ex(WOLFSSL* ssl, HandShakeCallBack hsCb, - TimeoutCallBack toCb,Timeval timeout) + TimeoutCallBack toCb, WOLFSSL_TIMEVAL timeout) { WOLFSSL_ENTER("wolfSSL_accept_ex"); return wolfSSL_ex_wrapper(ssl, hsCb, toCb, timeout); diff --git a/wolfssl/callbacks.h b/wolfssl/callbacks.h index c8801ca06..3d1702a01 100644 --- a/wolfssl/callbacks.h +++ b/wolfssl/callbacks.h @@ -53,19 +53,19 @@ typedef struct handShakeInfo_st { #if defined(HAVE_SYS_TIME_H) && !defined(NO_TIMEVAL) - typedef struct timeval Timeval; + typedef struct timeval WOLFSSL_TIMEVAL; #else /* HAVE_SYS_TIME_H */ - /* Define the Timeval explicitly. */ + /* Define the timeval explicitly. */ typedef struct { long tv_sec; /* Seconds. */ long tv_usec; /* Microseconds. */ - } Timeval; + } WOLFSSL_TIMEVAL; #endif /* HAVE_SYS_TIME_H */ typedef struct packetInfo_st { char packetName[MAX_PACKETNAME_SZ + 1]; /* SSL packet name */ - Timeval timestamp; /* when it occurred */ + WOLFSSL_TIMEVAL timestamp; /* when it occurred */ unsigned char value[MAX_VALUE_SZ]; /* if fits, it's here */ unsigned char* bufferValue; /* otherwise here (non 0) */ int valueSz; /* sz of value or buffer */ @@ -77,7 +77,7 @@ typedef struct timeoutInfo_st { int flags; /* for future use */ int numberPackets; /* actual # of packets */ PacketInfo packets[MAX_PACKETS_HANDSHAKE]; /* list of all packets */ - Timeval timeoutValue; /* timer that caused it */ + WOLFSSL_TIMEVAL timeoutValue; /* timer that caused it */ } TimeoutInfo; diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index b5d016117..39a834990 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -844,7 +844,7 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ /* yassl had set the default to be 500 */ #define SSL_get_default_timeout(ctx) 500 -#define DTLSv1_get_timeout(ssl, timeleft) wolfSSL_DTLSv1_get_timeout((ssl), (Timeval*)(timeleft)) +#define DTLSv1_get_timeout(ssl, timeleft) wolfSSL_DTLSv1_get_timeout((ssl), (WOLFSSL_TIMEVAL*)(timeleft)) #define DTLSv1_handle_timeout wolfSSL_DTLSv1_handle_timeout #define DTLSv1_set_initial_timeout_duration wolfSSL_DTLSv1_set_initial_timeout_duration diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 356bf6185..5f18cf091 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -984,7 +984,8 @@ WOLFSSL_API int wolfSSL_dtls_get_using_nonblock(WOLFSSL*); #define wolfSSL_get_using_nonblock wolfSSL_dtls_get_using_nonblock /* The old names are deprecated. */ WOLFSSL_API int wolfSSL_dtls_get_current_timeout(WOLFSSL* ssl); -WOLFSSL_API int wolfSSL_DTLSv1_get_timeout(WOLFSSL* ssl, Timeval* timeleft); +WOLFSSL_API int wolfSSL_DTLSv1_get_timeout(WOLFSSL* ssl, + WOLFSSL_TIMEVAL* timeleft); WOLFSSL_API void wolfSSL_DTLSv1_set_initial_timeout_duration(WOLFSSL* ssl, word32 duration_ms); WOLFSSL_API int wolfSSL_DTLSv1_handle_timeout(WOLFSSL* ssl); @@ -2040,7 +2041,7 @@ WOLFSSL_API int wolfSSL_set_compression(WOLFSSL* ssl); WOLFSSL_ABI WOLFSSL_API int wolfSSL_set_timeout(WOLFSSL*, unsigned int); WOLFSSL_ABI WOLFSSL_API int wolfSSL_CTX_set_timeout(WOLFSSL_CTX*, unsigned int); WOLFSSL_API void wolfSSL_CTX_set_current_time_cb(WOLFSSL_CTX* ctx, - void (*cb)(const WOLFSSL* ssl, Timeval* out_clock)); + void (*cb)(const WOLFSSL* ssl, WOLFSSL_TIMEVAL* out_clock)); /* get wolfSSL peer X509_CHAIN */ WOLFSSL_API WOLFSSL_X509_CHAIN* wolfSSL_get_peer_chain(WOLFSSL* ssl); @@ -3085,9 +3086,9 @@ typedef int (*TimeoutCallBack)(TimeoutInfo*); /* wolfSSL connect extension allowing HandShakeCallBack and/or TimeoutCallBack for diagnostics */ WOLFSSL_API int wolfSSL_connect_ex(WOLFSSL*, HandShakeCallBack, TimeoutCallBack, - Timeval); + WOLFSSL_TIMEVAL); WOLFSSL_API int wolfSSL_accept_ex(WOLFSSL*, HandShakeCallBack, TimeoutCallBack, - Timeval); + WOLFSSL_TIMEVAL); #endif /* WOLFSSL_CALLBACKS */ From 77b69ebf568f30dc9256630c316d232083539564 Mon Sep 17 00:00:00 2001 From: Stanislav Klima Date: Wed, 29 Jan 2020 17:29:23 +0100 Subject: [PATCH 007/649] Logically dead code. --- wolfcrypt/src/dh.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/wolfcrypt/src/dh.c b/wolfcrypt/src/dh.c index 65fd76973..094a090e6 100644 --- a/wolfcrypt/src/dh.c +++ b/wolfcrypt/src/dh.c @@ -2143,7 +2143,6 @@ static int _DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g, int ret = 0; mp_int* keyP = NULL; mp_int* keyG = NULL; - mp_int* keyQ = NULL; if (key == NULL || p == NULL || g == NULL || pSz == 0 || gSz == 0) { ret = BAD_FUNC_ARG; @@ -2203,13 +2202,9 @@ static int _DhSetKey(DhKey* key, const byte* p, word32 pSz, const byte* g, if (ret == 0 && q != NULL) { if (mp_read_unsigned_bin(&key->q, q, qSz) != MP_OKAY) ret = MP_INIT_E; - else - keyQ = &key->q; } if (ret != 0 && key != NULL) { - if (keyQ) - mp_clear(keyQ); if (keyG) mp_clear(keyG); if (keyP) From 96d1593735d928ee7e42d26b1c26ce6e9b27f668 Mon Sep 17 00:00:00 2001 From: Stanislav Klima Date: Wed, 29 Jan 2020 17:29:52 +0100 Subject: [PATCH 008/649] Possible use after free. --- src/ssl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ssl.c b/src/ssl.c index 149594eb0..783689da9 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -24436,6 +24436,7 @@ err_exit: #if !defined(NO_ASN) && !defined(NO_PWDBASED) if ((newx509 != NULL) && (type == PKCS12_TYPE)) { wc_PKCS12_free((WC_PKCS12*)newx509); + newx509 = NULL; } #endif _exit: From 451d0a470a5de9cb27d408f127eb934cfe4d77a0 Mon Sep 17 00:00:00 2001 From: Stanislav Klima Date: Wed, 29 Jan 2020 17:30:14 +0100 Subject: [PATCH 009/649] Resource leak. --- src/ssl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ssl.c b/src/ssl.c index 783689da9..ad120b1a9 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -35848,6 +35848,7 @@ int wolfSSL_i2d_RSAPrivateKey(WOLFSSL_RSA *rsa, unsigned char **pp) /* create buffer and return it */ *pp = (unsigned char*)XMALLOC(ret, NULL, DYNAMIC_TYPE_OPENSSL); if (*pp == NULL) { + XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); return WOLFSSL_FATAL_ERROR; } XMEMCPY(*pp, der, ret); From 972790fb8660fec7bd517e841464b90cd83596f1 Mon Sep 17 00:00:00 2001 From: Stanislav Klima Date: Wed, 29 Jan 2020 17:30:35 +0100 Subject: [PATCH 010/649] Resource leak. --- src/ssl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ssl.c b/src/ssl.c index ad120b1a9..e107a2386 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -25011,6 +25011,7 @@ WOLFSSL_ASN1_INTEGER* wolfSSL_ASN1_INTEGER_dup(const WOLFSSL_ASN1_INTEGER* src) dup->data = (unsigned char*) XMALLOC(src->dataMax,NULL,DYNAMIC_TYPE_OPENSSL); if (dup->data == NULL) { + wolfSSL_ASN1_INTEGER_free(dup); return NULL; } XMEMCPY(dup->data,src->data,dup->dataMax); From 70cb97c1163a68951e4447d79bcdf133390bb68f Mon Sep 17 00:00:00 2001 From: Stanislav Klima Date: Wed, 29 Jan 2020 17:30:57 +0100 Subject: [PATCH 011/649] NULL dereference. --- src/ssl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ssl.c b/src/ssl.c index e107a2386..1639e1ef6 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -24999,6 +24999,10 @@ WOLFSSL_ASN1_INTEGER* wolfSSL_ASN1_INTEGER_dup(const WOLFSSL_ASN1_INTEGER* src) return NULL; dup = wolfSSL_ASN1_INTEGER_new(); + + if (dup == NULL) + return NULL; + dup->negative = src->negative; dup->dataMax = src->dataMax; dup->isDynamic = src->isDynamic; From df0b0a6e9185e37b61e868afe5a362bb58377328 Mon Sep 17 00:00:00 2001 From: Stanislav Klima Date: Wed, 29 Jan 2020 17:31:14 +0100 Subject: [PATCH 012/649] NULL dereference. --- src/ssl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ssl.c b/src/ssl.c index 1639e1ef6..afb102a05 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -29172,6 +29172,10 @@ WOLFSSL_ASN1_INTEGER* wolfSSL_BN_to_ASN1_INTEGER(const WOLFSSL_BIGNUM *bn, WOLFS if (ai == NULL) { a = wolfSSL_ASN1_INTEGER_new(); + + if (a == NULL) + return NULL; + a->type = V_ASN1_INTEGER; } else { From c3fabb1da6675d4e0005cc70e590810ab3c895c7 Mon Sep 17 00:00:00 2001 From: Stanislav Klima Date: Wed, 29 Jan 2020 17:33:21 +0100 Subject: [PATCH 013/649] NULL dereference. --- wolfcrypt/src/evp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 11d1c229c..89c0707c3 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -1244,6 +1244,9 @@ int wolfSSL_EVP_PKEY_keygen(WOLFSSL_EVP_PKEY_CTX *ctx, if (pkey == NULL) { ownPkey = 1; pkey = wolfSSL_PKEY_new(); + + if (pkey == NULL) + return ret; } switch (pkey->type) { From 2d36624d84f37e73e5d6446e50a330319f39d12d Mon Sep 17 00:00:00 2001 From: Stanislav Klima Date: Wed, 29 Jan 2020 17:33:38 +0100 Subject: [PATCH 014/649] NULL dereference. --- src/ssl.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ssl.c b/src/ssl.c index afb102a05..e1ece6f86 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -24901,6 +24901,9 @@ int wolfSSL_X509_cmp_time(const WOLFSSL_ASN1_TIME* asnTime, time_t* cmpTime) /* Convert to time struct*/ ct = XGMTIME(pTime, tmpTs); + if (ct == NULL) + return GETTIME_ERROR; + /* DateGreaterThan returns 1 for >; 0 for <= */ ret = DateGreaterThan(&ts, ct) ? 1 : -1; } From 670ba75ea4010813b19167d4f325b0b4fe84f9af Mon Sep 17 00:00:00 2001 From: Stanislav Klima Date: Wed, 29 Jan 2020 17:33:59 +0100 Subject: [PATCH 015/649] Missing varargs cleanup. --- src/ssl.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ssl.c b/src/ssl.c index e1ece6f86..6f1cdf2ae 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -27714,8 +27714,10 @@ int wolfSSL_BIO_printf(WOLFSSL_BIO* bio, const char* format, ...) va_start(args, format); switch (bio->type) { case WOLFSSL_BIO_FILE: - if (bio->ptr == NULL) + if (bio->ptr == NULL) { + va_end(args); return -1; + } ret = vfprintf((XFILE)bio->ptr, format, args); break; From 37386f5fb5301e61ae8ac0373299124aa343dad1 Mon Sep 17 00:00:00 2001 From: Stanislav Klima Date: Wed, 29 Jan 2020 17:34:19 +0100 Subject: [PATCH 016/649] NULL dereference. --- src/internal.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/internal.c b/src/internal.c index 2097f3ff1..7ef2d8769 100644 --- a/src/internal.c +++ b/src/internal.c @@ -11548,7 +11548,8 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type) #ifndef NO_PSK if (ssl->specs.kea == psk_kea && - ssl->arrays->server_hint[0] == 0) + ssl->arrays != NULL && + ssl->arrays->server_hint[0] == 0) pskNoServerHint = 1; #endif if (ssl->specs.static_ecdh == 1 || From 2db62f744ab72df4e00c89093c034616b53b4184 Mon Sep 17 00:00:00 2001 From: Stanislav Klima Date: Wed, 29 Jan 2020 17:34:40 +0100 Subject: [PATCH 017/649] Logically dead code. --- src/ssl.c | 29 ++--------------------------- 1 file changed, 2 insertions(+), 27 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 6f1cdf2ae..b05103274 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -17125,39 +17125,14 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) case AES_256_GCM_TYPE : WOLFSSL_MSG("AES GCM"); if (ctx->enc) { - if (dst){ - /* encrypt confidential data*/ - ret = wc_AesGcmEncrypt(&ctx->cipher.aes, dst, src, len, + ret = wc_AesGcmEncrypt(&ctx->cipher.aes, dst, src, len, ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz, NULL, 0); - } - else { - /* authenticated, non-confidential data */ - ret = wc_AesGcmEncrypt(&ctx->cipher.aes, NULL, NULL, 0, - ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz, - src, len); - /* Reset partial authTag error for AAD*/ - if (ret == AES_GCM_AUTH_E) - ret = 0; - } } else { - if (dst){ - /* decrypt confidential data*/ - ret = wc_AesGcmDecrypt(&ctx->cipher.aes, dst, src, len, + ret = wc_AesGcmDecrypt(&ctx->cipher.aes, dst, src, len, ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz, NULL, 0); - } - else { - /* authenticated, non-confidential data*/ - ret = wc_AesGcmDecrypt(&ctx->cipher.aes, NULL, NULL, 0, - ctx->iv, ctx->ivSz, - ctx->authTag, ctx->authTagSz, - src, len); - /* Reset partial authTag error for AAD*/ - if (ret == AES_GCM_AUTH_E) - ret = 0; - } } break; #endif /* HAVE_AESGCM */ From ed88e8d1c5dfc07376049384347697961e96b187 Mon Sep 17 00:00:00 2001 From: Stanislav Klima Date: Wed, 29 Jan 2020 17:34:58 +0100 Subject: [PATCH 018/649] Logically dead code. --- src/ssl.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index b05103274..4ee162b99 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -3640,9 +3640,6 @@ WOLFSSL_STACK* wolfSSL_X509_STORE_GetCerts(WOLFSSL_X509_STORE_CTX* s) /* get certificate buffer */ cert = &s->certs[certIdx]; - if (cert == NULL) - break; - dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), NULL, DYNAMIC_TYPE_DCERT); if (dCert == NULL) { From c938cb35caab61a8f4f3400ec711209520ac547f Mon Sep 17 00:00:00 2001 From: Stanislav Klima Date: Wed, 29 Jan 2020 17:35:15 +0100 Subject: [PATCH 019/649] Logically dead code. --- src/ssl.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 4ee162b99..a67bbeafb 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -42539,11 +42539,6 @@ int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name, return WOLFSSL_SUCCESS; #endif /* WOLFSSL_APACHE_HTTPD || OPENSSL_ALL || WOLFSSL_NGINX */ } - else if (flags == XN_FLAG_RFC2253) { - if (wolfSSL_BIO_write(bio, name->name + 1, name->sz - 2) - != name->sz - 2) - return WOLFSSL_FAILURE; - } else if (wolfSSL_BIO_write(bio, name->name, name->sz - 1) != name->sz - 1) return WOLFSSL_FAILURE; From 81bebd8e5c561a947faba52c9b5361e94e2ec2c7 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Thu, 30 Jan 2020 12:23:38 +1000 Subject: [PATCH 020/649] Improve performance of SP Intel 64-bit asm RSA: Only constant time copy out when doing private key op Improve performance of sp_count_bits --- wolfcrypt/src/rsa.c | 24 +- wolfcrypt/src/sp_int.c | 17 +- wolfcrypt/src/sp_x86_64.c | 753 ++--- wolfcrypt/src/sp_x86_64_asm.S | 5714 +++++++++++++++++++++++---------- 4 files changed, 4248 insertions(+), 2260 deletions(-) diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index 5ffb3b98c..f6559f0ba 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -2951,19 +2951,23 @@ static int RsaPrivateDecryptEx(byte* in, word32 inLen, byte* out, /* only copy output if not inline */ if (outPtr == NULL) { #if !defined(WOLFSSL_RSA_VERIFY_ONLY) && !defined(WOLFSSL_RSA_VERIFY_INLINE) - word32 i, j; - int start = (int)((size_t)pad - (size_t)key->data); + if (rsa_type == RSA_PRIVATE_DECRYPT) { + word32 i, j; + int start = (int)((size_t)pad - (size_t)key->data); - for (i = 0, j = 0; j < key->dataLen; j++) { - out[i] = key->data[j]; - c = ctMaskGTE(j, start); - c &= ctMaskLT(i, outLen); - /* 0 - no add, -1 add */ - i += (word32)((byte)(-c)); + for (i = 0, j = 0; j < key->dataLen; j++) { + out[i] = key->data[j]; + c = ctMaskGTE(j, start); + c &= ctMaskLT(i, outLen); + /* 0 - no add, -1 add */ + i += (word32)((byte)(-c)); + } } -#else - XMEMCPY(out, pad, ret); + else #endif + { + XMEMCPY(out, pad, ret); + } } else *outPtr = pad; diff --git a/wolfcrypt/src/sp_int.c b/wolfcrypt/src/sp_int.c index 9ae17419f..92f877b76 100644 --- a/wolfcrypt/src/sp_int.c +++ b/wolfcrypt/src/sp_int.c @@ -306,10 +306,19 @@ int sp_count_bits(sp_int* a) r = 0; else { d = a->dp[r]; - r *= DIGIT_BIT; - while (d != 0) { - r++; - d >>= 1; + r *= SP_WORD_SIZE; + if (d >= (1L << (SP_WORD_SIZE / 2))) { + r += SP_WORD_SIZE; + while ((d & (1L << (SP_WORD_SIZE - 1))) == 0) { + r--; + d <<= 1; + } + } + else { + while (d != 0) { + r++; + d >>= 1; + } } } diff --git a/wolfcrypt/src/sp_x86_64.c b/wolfcrypt/src/sp_x86_64.c index 9a73e225f..58238e204 100644 --- a/wolfcrypt/src/sp_x86_64.c +++ b/wolfcrypt/src/sp_x86_64.c @@ -49,40 +49,7 @@ #ifdef WOLFSSL_SP_X86_64_ASM #if defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH) #ifndef WOLFSSL_SP_NO_2048 -/* 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_2048_from_bin(sp_digit* r, int size, const byte* a, int n) -{ - int i, j = 0; - word32 s = 0; - - r[0] = 0; - for (i = n-1; i >= 0; i--) { - r[j] |= (((sp_digit)a[i]) << s); - if (s >= 56U) { - r[j] &= 0xffffffffffffffffl; - s = 64U - 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; - } -} - +extern void sp_2048_from_bin(sp_digit* r, int size, const byte* a, int n); /* Convert an mp_int to an array of sp_digit. * * r A single precision integer. @@ -165,41 +132,7 @@ static void sp_2048_from_mp(sp_digit* r, int size, const mp_int* a) #endif } -/* Write r as big endian to byte array. - * Fixed length number of bytes written: 256 - * - * r A single precision integer. - * a Byte array. - */ -static void sp_2048_to_bin(sp_digit* r, byte* a) -{ - int i, j, s = 0, b; - - j = 2048 / 8 - 1; - a[j] = 0; - for (i=0; i<32 && j>=0; i++) { - b = 0; - /* lint allow cast of mismatch sp_digit and int */ - a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ - if (j < 0) { - break; - } - while (b < 64) { - a[j--] = r[i] >> b; b += 8; - if (j < 0) { - break; - } - } - s = 8 - (b - 64); - if (j >= 0) { - a[j] = 0; - } - if (s != 0) { - j++; - } - } -} - +extern void sp_2048_to_bin(sp_digit* r, byte* a); extern void sp_2048_mul_16(sp_digit* r, const sp_digit* a, const sp_digit* b); extern void sp_2048_sqr_16(sp_digit* r, const sp_digit* a); extern void sp_2048_mul_avx2_16(sp_digit* r, const sp_digit* a, const sp_digit* b); @@ -251,25 +184,26 @@ 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 o, ca, cb; - ca = sp_2048_add_16(a1, a, &a[16]); - cb = sp_2048_add_16(b1, b, &b[16]); - u = ca & cb; + ca = sp_2048_add_16(a1, a, a + 16); + cb = sp_2048_add_16(b1, b, b + 16); + o = ca & cb; sp_2048_mul_16(z1, a1, b1); - sp_2048_mul_16(z2, &a[16], &b[16]); + sp_2048_mul_16(z2, a + 16, b + 16); sp_2048_mul_16(z0, a, b); sp_2048_mask_16(r + 32, a1, 0 - cb); sp_2048_mask_16(b1, b1, 0 - ca); - u += sp_2048_add_16(r + 32, r + 32, b1); - u += sp_2048_sub_in_place_32(z1, z2); - u += sp_2048_sub_in_place_32(z1, z0); - u += sp_2048_add_32(r + 16, r + 16, z1); - r[48] = u; + o += sp_2048_add_16(r + 32, r + 32, b1); + o += sp_2048_sub_in_place_32(z1, z2); + o += sp_2048_sub_in_place_32(z1, z0); + o += sp_2048_add_32(r + 16, r + 16, z1); + r[48] = o; XMEMSET(r + 48 + 1, 0, sizeof(sp_digit) * (16 - 1)); sp_2048_add_32(r + 32, r + 32, z2); } +extern sp_digit sp_2048_dbl_16(sp_digit* r, const sp_digit* a); /* Square a and put result in r. (r = a * a) * * r A single precision integer. @@ -281,18 +215,18 @@ SP_NOINLINE static void sp_2048_sqr_32(sp_digit* r, const sp_digit* a) sp_digit z2[32]; sp_digit z1[32]; sp_digit a1[16]; - sp_digit u; + sp_digit o; - u = sp_2048_add_16(a1, a, &a[16]); + o = sp_2048_add_16(a1, a, a + 16); sp_2048_sqr_16(z1, a1); - sp_2048_sqr_16(z2, &a[16]); + sp_2048_sqr_16(z2, a + 16); sp_2048_sqr_16(z0, a); - sp_2048_mask_16(r + 32, a1, 0 - u); - u += sp_2048_add_16(r + 32, r + 32, r + 32); - u += sp_2048_sub_in_place_32(z1, z2); - u += sp_2048_sub_in_place_32(z1, z0); - u += sp_2048_add_32(r + 16, r + 16, z1); - r[48] = u; + sp_2048_mask_16(r + 32, a1, 0 - o); + o += sp_2048_dbl_16(r + 32, r + 32); + o += sp_2048_sub_in_place_32(z1, z2); + o += sp_2048_sub_in_place_32(z1, z0); + o += sp_2048_add_32(r + 16, r + 16, z1); + r[48] = o; XMEMSET(r + 48 + 1, 0, sizeof(sp_digit) * (16 - 1)); sp_2048_add_32(r + 32, r + 32, z2); } @@ -312,21 +246,21 @@ SP_NOINLINE static void sp_2048_mul_avx2_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 o, ca, cb; - ca = sp_2048_add_16(a1, a, &a[16]); - cb = sp_2048_add_16(b1, b, &b[16]); - u = ca & cb; + ca = sp_2048_add_16(a1, a, a + 16); + cb = sp_2048_add_16(b1, b, b + 16); + o = ca & cb; sp_2048_mul_avx2_16(z1, a1, b1); - sp_2048_mul_avx2_16(z2, &a[16], &b[16]); + sp_2048_mul_avx2_16(z2, a + 16, b + 16); sp_2048_mul_avx2_16(z0, a, b); sp_2048_mask_16(r + 32, a1, 0 - cb); sp_2048_mask_16(b1, b1, 0 - ca); - u += sp_2048_add_16(r + 32, r + 32, b1); - u += sp_2048_sub_in_place_32(z1, z2); - u += sp_2048_sub_in_place_32(z1, z0); - u += sp_2048_add_32(r + 16, r + 16, z1); - r[48] = u; + o += sp_2048_add_16(r + 32, r + 32, b1); + o += sp_2048_sub_in_place_32(z1, z2); + o += sp_2048_sub_in_place_32(z1, z0); + o += sp_2048_add_32(r + 16, r + 16, z1); + r[48] = o; XMEMSET(r + 48 + 1, 0, sizeof(sp_digit) * (16 - 1)); sp_2048_add_32(r + 32, r + 32, z2); } @@ -344,18 +278,18 @@ SP_NOINLINE static void sp_2048_sqr_avx2_32(sp_digit* r, const sp_digit* a) sp_digit z2[32]; sp_digit z1[32]; sp_digit a1[16]; - sp_digit u; + sp_digit o; - u = sp_2048_add_16(a1, a, &a[16]); + o = sp_2048_add_16(a1, a, a + 16); sp_2048_sqr_avx2_16(z1, a1); - sp_2048_sqr_avx2_16(z2, &a[16]); + sp_2048_sqr_avx2_16(z2, a + 16); sp_2048_sqr_avx2_16(z0, a); - sp_2048_mask_16(r + 32, a1, 0 - u); - u += sp_2048_add_16(r + 32, r + 32, r + 32); - u += sp_2048_sub_in_place_32(z1, z2); - u += sp_2048_sub_in_place_32(z1, z0); - u += sp_2048_add_32(r + 16, r + 16, z1); - r[48] = u; + sp_2048_mask_16(r + 32, a1, 0 - o); + o += sp_2048_dbl_16(r + 32, r + 32); + o += sp_2048_sub_in_place_32(z1, z2); + o += sp_2048_sub_in_place_32(z1, z0); + o += sp_2048_add_32(r + 16, r + 16, z1); + r[48] = o; XMEMSET(r + 48 + 1, 0, sizeof(sp_digit) * (16 - 1)); sp_2048_add_32(r + 32, r + 32, z2); } @@ -433,6 +367,7 @@ static void sp_2048_mont_sqr_16(sp_digit* r, const sp_digit* a, const sp_digit* sp_2048_mont_reduce_16(r, m, mp); } +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); /* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) @@ -496,7 +431,12 @@ static WC_INLINE int sp_2048_div_16(const sp_digit* a, const sp_digit* d, sp_dig } r1 = sp_2048_cmp_16(t1, d) >= 0; - sp_2048_cond_sub_16(r, t1, d, (sp_digit)0 - r1); +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_2048_cond_sub_avx2_16(r, t1, d, (sp_digit)0 - r1); + else +#endif + sp_2048_cond_sub_16(r, t1, d, (sp_digit)0 - r1); return MP_OKAY; } @@ -527,8 +467,10 @@ static int sp_2048_mod_exp_16(sp_digit* r, const sp_digit* a, const sp_digit* e, { #ifndef WOLFSSL_SMALL_STACK sp_digit t[32][32]; + sp_digit rt[32]; #else sp_digit* t[32]; + sp_digit* rt; sp_digit* td; #endif sp_digit* norm; @@ -540,7 +482,7 @@ static int sp_2048_mod_exp_16(sp_digit* r, const sp_digit* a, const sp_digit* e, int err = MP_OKAY; #ifdef WOLFSSL_SMALL_STACK - td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 32, NULL, + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 33 * 32, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (td == NULL) { err = MEMORY_E; @@ -551,6 +493,7 @@ static int sp_2048_mod_exp_16(sp_digit* r, const sp_digit* a, const sp_digit* e, #ifdef WOLFSSL_SMALL_STACK for (i=0; i<32; i++) t[i] = td + i * 32; + rt = td + 1024; #endif norm = t[0]; @@ -631,10 +574,10 @@ static int sp_2048_mod_exp_16(sp_digit* r, const sp_digit* a, const sp_digit* e, c -= 5; } - sp_2048_mont_sqr_16(r, r, m, mp); - sp_2048_mont_sqr_16(r, r, m, mp); - sp_2048_mont_sqr_16(r, r, m, mp); - sp_2048_mont_sqr_16(r, r, m, mp); + sp_2048_mont_sqr_16(rt, r, m, mp); + sp_2048_mont_sqr_16(r, rt, m, mp); + sp_2048_mont_sqr_16(rt, r, m, mp); + sp_2048_mont_sqr_16(r, rt, m, mp); sp_2048_mont_sqr_16(r, r, m, mp); sp_2048_mont_mul_16(r, r, t[y], m, mp); @@ -705,8 +648,10 @@ static int sp_2048_mod_exp_avx2_16(sp_digit* r, const sp_digit* a, const sp_digi { #ifndef WOLFSSL_SMALL_STACK sp_digit t[32][32]; + sp_digit rt[32]; #else sp_digit* t[32]; + sp_digit* rt; sp_digit* td; #endif sp_digit* norm; @@ -718,7 +663,7 @@ static int sp_2048_mod_exp_avx2_16(sp_digit* r, const sp_digit* a, const sp_digi int err = MP_OKAY; #ifdef WOLFSSL_SMALL_STACK - td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 32, NULL, + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 33 * 32, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (td == NULL) { err = MEMORY_E; @@ -729,6 +674,7 @@ static int sp_2048_mod_exp_avx2_16(sp_digit* r, const sp_digit* a, const sp_digi #ifdef WOLFSSL_SMALL_STACK for (i=0; i<32; i++) t[i] = td + i * 32; + rt = td + 1024; #endif norm = t[0]; @@ -809,10 +755,10 @@ static int sp_2048_mod_exp_avx2_16(sp_digit* r, const sp_digit* a, const sp_digi c -= 5; } - sp_2048_mont_sqr_avx2_16(r, r, m, mp); - sp_2048_mont_sqr_avx2_16(r, r, m, mp); - sp_2048_mont_sqr_avx2_16(r, r, m, mp); - sp_2048_mont_sqr_avx2_16(r, r, m, mp); + sp_2048_mont_sqr_avx2_16(rt, r, m, mp); + sp_2048_mont_sqr_avx2_16(r, rt, m, mp); + sp_2048_mont_sqr_avx2_16(rt, r, m, mp); + sp_2048_mont_sqr_avx2_16(r, rt, m, mp); sp_2048_mont_sqr_avx2_16(r, r, m, mp); sp_2048_mont_mul_avx2_16(r, r, t[y], m, mp); @@ -822,7 +768,7 @@ static int sp_2048_mod_exp_avx2_16(sp_digit* r, const sp_digit* a, const sp_digi sp_2048_mont_reduce_avx2_16(r, m, mp); mask = 0 - (sp_2048_cmp_16(r, m) >= 0); - sp_2048_cond_sub_16(r, r, m, mask); + sp_2048_cond_sub_avx2_16(r, r, m, mask); } #ifdef WOLFSSL_SMALL_STACK @@ -885,6 +831,7 @@ static void sp_2048_mont_sqr_32(sp_digit* r, const sp_digit* a, const sp_digit* } #ifndef 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); /* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) * @@ -977,7 +924,12 @@ static WC_INLINE int sp_2048_div_32(const sp_digit* a, const sp_digit* d, sp_dig } r1 = sp_2048_cmp_32(t1, d) >= 0; - sp_2048_cond_sub_32(r, t1, d, (sp_digit)0 - r1); +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_2048_cond_sub_avx2_32(r, t1, d, (sp_digit)0 - r1); + else +#endif + sp_2048_cond_sub_32(r, t1, d, (sp_digit)0 - r1); return MP_OKAY; } @@ -995,6 +947,7 @@ static WC_INLINE int sp_2048_mod_32(sp_digit* r, const sp_digit* a, const sp_dig } #endif /* WOLFSSL_RSA_PUBLIC_ONLY */ +extern sp_digit sp_2048_sub_32(sp_digit* r, 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. * @@ -1036,8 +989,16 @@ static WC_INLINE int sp_2048_div_32_cond(const sp_digit* a, const sp_digit* d, s } } - r1 = sp_2048_cmp_32(t1, d) >= 0; - sp_2048_cond_sub_32(r, t1, d, (sp_digit)0 - r1); + for (i = 31; i > 0; i--) { + if (t1[i] != d[i]) + break; + } + if (t1[i] >= d[i]) { + sp_2048_sub_32(r, t1, d); + } + else { + XMEMCPY(r, t1, sizeof(*t1) * 32); + } return MP_OKAY; } @@ -1069,8 +1030,10 @@ static int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e, { #ifndef WOLFSSL_SMALL_STACK sp_digit t[32][64]; + sp_digit rt[64]; #else sp_digit* t[32]; + sp_digit* rt; sp_digit* td; #endif sp_digit* norm; @@ -1082,7 +1045,7 @@ static int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e, int err = MP_OKAY; #ifdef WOLFSSL_SMALL_STACK - td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 64, NULL, + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 33 * 64, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (td == NULL) { err = MEMORY_E; @@ -1093,6 +1056,7 @@ static int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e, #ifdef WOLFSSL_SMALL_STACK for (i=0; i<32; i++) t[i] = td + i * 64; + rt = td + 2048; #endif norm = t[0]; @@ -1173,10 +1137,10 @@ static int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e, c -= 5; } - sp_2048_mont_sqr_32(r, r, m, mp); - sp_2048_mont_sqr_32(r, r, m, mp); - sp_2048_mont_sqr_32(r, r, m, mp); - sp_2048_mont_sqr_32(r, r, m, mp); + sp_2048_mont_sqr_32(rt, r, m, mp); + sp_2048_mont_sqr_32(r, rt, m, mp); + sp_2048_mont_sqr_32(rt, r, m, mp); + sp_2048_mont_sqr_32(r, rt, m, mp); sp_2048_mont_sqr_32(r, r, m, mp); sp_2048_mont_mul_32(r, r, t[y], m, mp); @@ -1249,8 +1213,10 @@ static int sp_2048_mod_exp_avx2_32(sp_digit* r, const sp_digit* a, const sp_digi { #ifndef WOLFSSL_SMALL_STACK sp_digit t[32][64]; + sp_digit rt[64]; #else sp_digit* t[32]; + sp_digit* rt; sp_digit* td; #endif sp_digit* norm; @@ -1262,7 +1228,7 @@ static int sp_2048_mod_exp_avx2_32(sp_digit* r, const sp_digit* a, const sp_digi int err = MP_OKAY; #ifdef WOLFSSL_SMALL_STACK - td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 64, NULL, + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 33 * 64, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (td == NULL) { err = MEMORY_E; @@ -1273,6 +1239,7 @@ static int sp_2048_mod_exp_avx2_32(sp_digit* r, const sp_digit* a, const sp_digi #ifdef WOLFSSL_SMALL_STACK for (i=0; i<32; i++) t[i] = td + i * 64; + rt = td + 2048; #endif norm = t[0]; @@ -1353,10 +1320,10 @@ static int sp_2048_mod_exp_avx2_32(sp_digit* r, const sp_digit* a, const sp_digi c -= 5; } - sp_2048_mont_sqr_avx2_32(r, r, m, mp); - sp_2048_mont_sqr_avx2_32(r, r, m, mp); - sp_2048_mont_sqr_avx2_32(r, r, m, mp); - sp_2048_mont_sqr_avx2_32(r, r, m, mp); + sp_2048_mont_sqr_avx2_32(rt, r, m, mp); + sp_2048_mont_sqr_avx2_32(r, rt, m, mp); + sp_2048_mont_sqr_avx2_32(rt, r, m, mp); + sp_2048_mont_sqr_avx2_32(r, rt, m, mp); sp_2048_mont_sqr_avx2_32(r, r, m, mp); sp_2048_mont_mul_avx2_32(r, r, t[y], m, mp); @@ -1366,7 +1333,7 @@ static int sp_2048_mod_exp_avx2_32(sp_digit* r, const sp_digit* a, const sp_digi sp_2048_mont_reduce_avx2_32(r, m, mp); mask = 0 - (sp_2048_cmp_32(r, m) >= 0); - sp_2048_cond_sub_32(r, r, m, mask); + sp_2048_cond_sub_avx2_32(r, r, m, mask); } #ifdef WOLFSSL_SMALL_STACK @@ -1899,14 +1866,14 @@ static int sp_2048_mod_exp_2_avx2_32(sp_digit* r, const sp_digit* e, int bits, sp_2048_mul_d_avx2_32(tmp, norm, r[32]); r[32] = 0; o = sp_2048_add_32(r, r, tmp); - sp_2048_cond_sub_32(r, r, m, (sp_digit)0 - o); + sp_2048_cond_sub_avx2_32(r, r, m, (sp_digit)0 - o); } XMEMSET(&r[32], 0, sizeof(sp_digit) * 32); sp_2048_mont_reduce_avx2_32(r, m, mp); mask = 0 - (sp_2048_cmp_32(r, m) >= 0); - sp_2048_cond_sub_32(r, r, m, mask); + sp_2048_cond_sub_avx2_32(r, r, m, mask); } #ifdef WOLFSSL_SMALL_STACK @@ -2145,40 +2112,7 @@ int sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) #endif /* !WOLFSSL_SP_NO_2048 */ #ifndef WOLFSSL_SP_NO_3072 -/* 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_3072_from_bin(sp_digit* r, int size, const byte* a, int n) -{ - int i, j = 0; - word32 s = 0; - - r[0] = 0; - for (i = n-1; i >= 0; i--) { - r[j] |= (((sp_digit)a[i]) << s); - if (s >= 56U) { - r[j] &= 0xffffffffffffffffl; - s = 64U - 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; - } -} - +extern void sp_3072_from_bin(sp_digit* r, int size, const byte* a, int n); /* Convert an mp_int to an array of sp_digit. * * r A single precision integer. @@ -2261,41 +2195,7 @@ static void sp_3072_from_mp(sp_digit* r, int size, const mp_int* a) #endif } -/* Write r as big endian to byte array. - * Fixed length number of bytes written: 384 - * - * r A single precision integer. - * a Byte array. - */ -static void sp_3072_to_bin(sp_digit* r, byte* a) -{ - int i, j, s = 0, b; - - j = 3072 / 8 - 1; - a[j] = 0; - for (i=0; i<48 && j>=0; i++) { - b = 0; - /* lint allow cast of mismatch sp_digit and int */ - a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ - if (j < 0) { - break; - } - while (b < 64) { - a[j--] = r[i] >> b; b += 8; - if (j < 0) { - break; - } - } - s = 8 - (b - 64); - if (j >= 0) { - a[j] = 0; - } - if (s != 0) { - j++; - } - } -} - +extern void sp_3072_to_bin(sp_digit* r, byte* a); extern void sp_3072_mul_24(sp_digit* r, const sp_digit* a, const sp_digit* b); extern void sp_3072_sqr_24(sp_digit* r, const sp_digit* a); extern void sp_3072_mul_avx2_24(sp_digit* r, const sp_digit* a, const sp_digit* b); @@ -2347,25 +2247,26 @@ 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 o, ca, cb; - ca = sp_3072_add_24(a1, a, &a[24]); - cb = sp_3072_add_24(b1, b, &b[24]); - u = ca & cb; + ca = sp_3072_add_24(a1, a, a + 24); + cb = sp_3072_add_24(b1, b, b + 24); + o = ca & cb; sp_3072_mul_24(z1, a1, b1); - sp_3072_mul_24(z2, &a[24], &b[24]); + sp_3072_mul_24(z2, a + 24, b + 24); sp_3072_mul_24(z0, a, b); sp_3072_mask_24(r + 48, a1, 0 - cb); sp_3072_mask_24(b1, b1, 0 - ca); - u += sp_3072_add_24(r + 48, r + 48, b1); - u += sp_3072_sub_in_place_48(z1, z2); - u += sp_3072_sub_in_place_48(z1, z0); - u += sp_3072_add_48(r + 24, r + 24, z1); - r[72] = u; + o += sp_3072_add_24(r + 48, r + 48, b1); + o += sp_3072_sub_in_place_48(z1, z2); + o += sp_3072_sub_in_place_48(z1, z0); + o += sp_3072_add_48(r + 24, r + 24, z1); + r[72] = o; XMEMSET(r + 72 + 1, 0, sizeof(sp_digit) * (24 - 1)); sp_3072_add_48(r + 48, r + 48, z2); } +extern sp_digit sp_3072_dbl_24(sp_digit* r, const sp_digit* a); /* Square a and put result in r. (r = a * a) * * r A single precision integer. @@ -2377,18 +2278,18 @@ SP_NOINLINE static void sp_3072_sqr_48(sp_digit* r, const sp_digit* a) sp_digit z2[48]; sp_digit z1[48]; sp_digit a1[24]; - sp_digit u; + sp_digit o; - u = sp_3072_add_24(a1, a, &a[24]); + o = sp_3072_add_24(a1, a, a + 24); sp_3072_sqr_24(z1, a1); - sp_3072_sqr_24(z2, &a[24]); + sp_3072_sqr_24(z2, a + 24); sp_3072_sqr_24(z0, a); - sp_3072_mask_24(r + 48, a1, 0 - u); - u += sp_3072_add_24(r + 48, r + 48, r + 48); - u += sp_3072_sub_in_place_48(z1, z2); - u += sp_3072_sub_in_place_48(z1, z0); - u += sp_3072_add_48(r + 24, r + 24, z1); - r[72] = u; + sp_3072_mask_24(r + 48, a1, 0 - o); + o += sp_3072_dbl_24(r + 48, r + 48); + o += sp_3072_sub_in_place_48(z1, z2); + o += sp_3072_sub_in_place_48(z1, z0); + o += sp_3072_add_48(r + 24, r + 24, z1); + r[72] = o; XMEMSET(r + 72 + 1, 0, sizeof(sp_digit) * (24 - 1)); sp_3072_add_48(r + 48, r + 48, z2); } @@ -2408,21 +2309,21 @@ SP_NOINLINE static void sp_3072_mul_avx2_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 o, ca, cb; - ca = sp_3072_add_24(a1, a, &a[24]); - cb = sp_3072_add_24(b1, b, &b[24]); - u = ca & cb; + ca = sp_3072_add_24(a1, a, a + 24); + cb = sp_3072_add_24(b1, b, b + 24); + o = ca & cb; sp_3072_mul_avx2_24(z1, a1, b1); - sp_3072_mul_avx2_24(z2, &a[24], &b[24]); + sp_3072_mul_avx2_24(z2, a + 24, b + 24); sp_3072_mul_avx2_24(z0, a, b); sp_3072_mask_24(r + 48, a1, 0 - cb); sp_3072_mask_24(b1, b1, 0 - ca); - u += sp_3072_add_24(r + 48, r + 48, b1); - u += sp_3072_sub_in_place_48(z1, z2); - u += sp_3072_sub_in_place_48(z1, z0); - u += sp_3072_add_48(r + 24, r + 24, z1); - r[72] = u; + o += sp_3072_add_24(r + 48, r + 48, b1); + o += sp_3072_sub_in_place_48(z1, z2); + o += sp_3072_sub_in_place_48(z1, z0); + o += sp_3072_add_48(r + 24, r + 24, z1); + r[72] = o; XMEMSET(r + 72 + 1, 0, sizeof(sp_digit) * (24 - 1)); sp_3072_add_48(r + 48, r + 48, z2); } @@ -2440,18 +2341,18 @@ SP_NOINLINE static void sp_3072_sqr_avx2_48(sp_digit* r, const sp_digit* a) sp_digit z2[48]; sp_digit z1[48]; sp_digit a1[24]; - sp_digit u; + sp_digit o; - u = sp_3072_add_24(a1, a, &a[24]); + o = sp_3072_add_24(a1, a, a + 24); sp_3072_sqr_avx2_24(z1, a1); - sp_3072_sqr_avx2_24(z2, &a[24]); + sp_3072_sqr_avx2_24(z2, a + 24); sp_3072_sqr_avx2_24(z0, a); - sp_3072_mask_24(r + 48, a1, 0 - u); - u += sp_3072_add_24(r + 48, r + 48, r + 48); - u += sp_3072_sub_in_place_48(z1, z2); - u += sp_3072_sub_in_place_48(z1, z0); - u += sp_3072_add_48(r + 24, r + 24, z1); - r[72] = u; + sp_3072_mask_24(r + 48, a1, 0 - o); + o += sp_3072_dbl_24(r + 48, r + 48); + o += sp_3072_sub_in_place_48(z1, z2); + o += sp_3072_sub_in_place_48(z1, z0); + o += sp_3072_add_48(r + 24, r + 24, z1); + r[72] = o; XMEMSET(r + 72 + 1, 0, sizeof(sp_digit) * (24 - 1)); sp_3072_add_48(r + 48, r + 48, z2); } @@ -2529,6 +2430,7 @@ static void sp_3072_mont_sqr_24(sp_digit* r, const sp_digit* a, const sp_digit* sp_3072_mont_reduce_24(r, m, mp); } +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); /* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) @@ -2592,7 +2494,12 @@ static WC_INLINE int sp_3072_div_24(const sp_digit* a, const sp_digit* d, sp_dig } r1 = sp_3072_cmp_24(t1, d) >= 0; - sp_3072_cond_sub_24(r, t1, d, (sp_digit)0 - r1); +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_3072_cond_sub_avx2_24(r, t1, d, (sp_digit)0 - r1); + else +#endif + sp_3072_cond_sub_24(r, t1, d, (sp_digit)0 - r1); return MP_OKAY; } @@ -2623,8 +2530,10 @@ static int sp_3072_mod_exp_24(sp_digit* r, const sp_digit* a, const sp_digit* e, { #ifndef WOLFSSL_SMALL_STACK sp_digit t[32][48]; + sp_digit rt[48]; #else sp_digit* t[32]; + sp_digit* rt; sp_digit* td; #endif sp_digit* norm; @@ -2636,7 +2545,7 @@ static int sp_3072_mod_exp_24(sp_digit* r, const sp_digit* a, const sp_digit* e, int err = MP_OKAY; #ifdef WOLFSSL_SMALL_STACK - td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 48, NULL, + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 33 * 48, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (td == NULL) { err = MEMORY_E; @@ -2647,6 +2556,7 @@ static int sp_3072_mod_exp_24(sp_digit* r, const sp_digit* a, const sp_digit* e, #ifdef WOLFSSL_SMALL_STACK for (i=0; i<32; i++) t[i] = td + i * 48; + rt = td + 1536; #endif norm = t[0]; @@ -2727,10 +2637,10 @@ static int sp_3072_mod_exp_24(sp_digit* r, const sp_digit* a, const sp_digit* e, c -= 5; } - sp_3072_mont_sqr_24(r, r, m, mp); - sp_3072_mont_sqr_24(r, r, m, mp); - sp_3072_mont_sqr_24(r, r, m, mp); - sp_3072_mont_sqr_24(r, r, m, mp); + sp_3072_mont_sqr_24(rt, r, m, mp); + sp_3072_mont_sqr_24(r, rt, m, mp); + sp_3072_mont_sqr_24(rt, r, m, mp); + sp_3072_mont_sqr_24(r, rt, m, mp); sp_3072_mont_sqr_24(r, r, m, mp); sp_3072_mont_mul_24(r, r, t[y], m, mp); @@ -2801,8 +2711,10 @@ static int sp_3072_mod_exp_avx2_24(sp_digit* r, const sp_digit* a, const sp_digi { #ifndef WOLFSSL_SMALL_STACK sp_digit t[32][48]; + sp_digit rt[48]; #else sp_digit* t[32]; + sp_digit* rt; sp_digit* td; #endif sp_digit* norm; @@ -2814,7 +2726,7 @@ static int sp_3072_mod_exp_avx2_24(sp_digit* r, const sp_digit* a, const sp_digi int err = MP_OKAY; #ifdef WOLFSSL_SMALL_STACK - td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 48, NULL, + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 33 * 48, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (td == NULL) { err = MEMORY_E; @@ -2825,6 +2737,7 @@ static int sp_3072_mod_exp_avx2_24(sp_digit* r, const sp_digit* a, const sp_digi #ifdef WOLFSSL_SMALL_STACK for (i=0; i<32; i++) t[i] = td + i * 48; + rt = td + 1536; #endif norm = t[0]; @@ -2905,10 +2818,10 @@ static int sp_3072_mod_exp_avx2_24(sp_digit* r, const sp_digit* a, const sp_digi c -= 5; } - sp_3072_mont_sqr_avx2_24(r, r, m, mp); - sp_3072_mont_sqr_avx2_24(r, r, m, mp); - sp_3072_mont_sqr_avx2_24(r, r, m, mp); - sp_3072_mont_sqr_avx2_24(r, r, m, mp); + sp_3072_mont_sqr_avx2_24(rt, r, m, mp); + sp_3072_mont_sqr_avx2_24(r, rt, m, mp); + sp_3072_mont_sqr_avx2_24(rt, r, m, mp); + sp_3072_mont_sqr_avx2_24(r, rt, m, mp); sp_3072_mont_sqr_avx2_24(r, r, m, mp); sp_3072_mont_mul_avx2_24(r, r, t[y], m, mp); @@ -2918,7 +2831,7 @@ static int sp_3072_mod_exp_avx2_24(sp_digit* r, const sp_digit* a, const sp_digi sp_3072_mont_reduce_avx2_24(r, m, mp); mask = 0 - (sp_3072_cmp_24(r, m) >= 0); - sp_3072_cond_sub_24(r, r, m, mask); + sp_3072_cond_sub_avx2_24(r, r, m, mask); } #ifdef WOLFSSL_SMALL_STACK @@ -2981,6 +2894,7 @@ static void sp_3072_mont_sqr_48(sp_digit* r, const sp_digit* a, const sp_digit* } #ifndef 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); /* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) * @@ -3073,7 +2987,12 @@ static WC_INLINE int sp_3072_div_48(const sp_digit* a, const sp_digit* d, sp_dig } r1 = sp_3072_cmp_48(t1, d) >= 0; - sp_3072_cond_sub_48(r, t1, d, (sp_digit)0 - r1); +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_3072_cond_sub_avx2_48(r, t1, d, (sp_digit)0 - r1); + else +#endif + sp_3072_cond_sub_48(r, t1, d, (sp_digit)0 - r1); return MP_OKAY; } @@ -3091,6 +3010,7 @@ static WC_INLINE int sp_3072_mod_48(sp_digit* r, const sp_digit* a, const sp_dig } #endif /* WOLFSSL_RSA_PUBLIC_ONLY */ +extern sp_digit sp_3072_sub_48(sp_digit* r, 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. * @@ -3132,8 +3052,16 @@ static WC_INLINE int sp_3072_div_48_cond(const sp_digit* a, const sp_digit* d, s } } - r1 = sp_3072_cmp_48(t1, d) >= 0; - sp_3072_cond_sub_48(r, t1, d, (sp_digit)0 - r1); + for (i = 47; i > 0; i--) { + if (t1[i] != d[i]) + break; + } + if (t1[i] >= d[i]) { + sp_3072_sub_48(r, t1, d); + } + else { + XMEMCPY(r, t1, sizeof(*t1) * 48); + } return MP_OKAY; } @@ -3165,8 +3093,10 @@ static int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e, { #ifndef WOLFSSL_SMALL_STACK sp_digit t[32][96]; + sp_digit rt[96]; #else sp_digit* t[32]; + sp_digit* rt; sp_digit* td; #endif sp_digit* norm; @@ -3178,7 +3108,7 @@ static int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e, int err = MP_OKAY; #ifdef WOLFSSL_SMALL_STACK - td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 96, NULL, + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 33 * 96, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (td == NULL) { err = MEMORY_E; @@ -3189,6 +3119,7 @@ static int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e, #ifdef WOLFSSL_SMALL_STACK for (i=0; i<32; i++) t[i] = td + i * 96; + rt = td + 3072; #endif norm = t[0]; @@ -3269,10 +3200,10 @@ static int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e, c -= 5; } - sp_3072_mont_sqr_48(r, r, m, mp); - sp_3072_mont_sqr_48(r, r, m, mp); - sp_3072_mont_sqr_48(r, r, m, mp); - sp_3072_mont_sqr_48(r, r, m, mp); + sp_3072_mont_sqr_48(rt, r, m, mp); + sp_3072_mont_sqr_48(r, rt, m, mp); + sp_3072_mont_sqr_48(rt, r, m, mp); + sp_3072_mont_sqr_48(r, rt, m, mp); sp_3072_mont_sqr_48(r, r, m, mp); sp_3072_mont_mul_48(r, r, t[y], m, mp); @@ -3345,8 +3276,10 @@ static int sp_3072_mod_exp_avx2_48(sp_digit* r, const sp_digit* a, const sp_digi { #ifndef WOLFSSL_SMALL_STACK sp_digit t[32][96]; + sp_digit rt[96]; #else sp_digit* t[32]; + sp_digit* rt; sp_digit* td; #endif sp_digit* norm; @@ -3358,7 +3291,7 @@ static int sp_3072_mod_exp_avx2_48(sp_digit* r, const sp_digit* a, const sp_digi int err = MP_OKAY; #ifdef WOLFSSL_SMALL_STACK - td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 96, NULL, + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 33 * 96, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (td == NULL) { err = MEMORY_E; @@ -3369,6 +3302,7 @@ static int sp_3072_mod_exp_avx2_48(sp_digit* r, const sp_digit* a, const sp_digi #ifdef WOLFSSL_SMALL_STACK for (i=0; i<32; i++) t[i] = td + i * 96; + rt = td + 3072; #endif norm = t[0]; @@ -3449,10 +3383,10 @@ static int sp_3072_mod_exp_avx2_48(sp_digit* r, const sp_digit* a, const sp_digi c -= 5; } - sp_3072_mont_sqr_avx2_48(r, r, m, mp); - sp_3072_mont_sqr_avx2_48(r, r, m, mp); - sp_3072_mont_sqr_avx2_48(r, r, m, mp); - sp_3072_mont_sqr_avx2_48(r, r, m, mp); + sp_3072_mont_sqr_avx2_48(rt, r, m, mp); + sp_3072_mont_sqr_avx2_48(r, rt, m, mp); + sp_3072_mont_sqr_avx2_48(rt, r, m, mp); + sp_3072_mont_sqr_avx2_48(r, rt, m, mp); sp_3072_mont_sqr_avx2_48(r, r, m, mp); sp_3072_mont_mul_avx2_48(r, r, t[y], m, mp); @@ -3462,7 +3396,7 @@ static int sp_3072_mod_exp_avx2_48(sp_digit* r, const sp_digit* a, const sp_digi sp_3072_mont_reduce_avx2_48(r, m, mp); mask = 0 - (sp_3072_cmp_48(r, m) >= 0); - sp_3072_cond_sub_48(r, r, m, mask); + sp_3072_cond_sub_avx2_48(r, r, m, mask); } #ifdef WOLFSSL_SMALL_STACK @@ -3995,14 +3929,14 @@ static int sp_3072_mod_exp_2_avx2_48(sp_digit* r, const sp_digit* e, int bits, sp_3072_mul_d_avx2_48(tmp, norm, r[48]); r[48] = 0; o = sp_3072_add_48(r, r, tmp); - sp_3072_cond_sub_48(r, r, m, (sp_digit)0 - o); + sp_3072_cond_sub_avx2_48(r, r, m, (sp_digit)0 - o); } XMEMSET(&r[48], 0, sizeof(sp_digit) * 48); sp_3072_mont_reduce_avx2_48(r, m, mp); mask = 0 - (sp_3072_cmp_48(r, m) >= 0); - sp_3072_cond_sub_48(r, r, m, mask); + sp_3072_cond_sub_avx2_48(r, r, m, mask); } #ifdef WOLFSSL_SMALL_STACK @@ -4241,40 +4175,7 @@ int sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) #endif /* !WOLFSSL_SP_NO_3072 */ #ifdef WOLFSSL_SP_4096 -/* 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_4096_from_bin(sp_digit* r, int size, const byte* a, int n) -{ - int i, j = 0; - word32 s = 0; - - r[0] = 0; - for (i = n-1; i >= 0; i--) { - r[j] |= (((sp_digit)a[i]) << s); - if (s >= 56U) { - r[j] &= 0xffffffffffffffffl; - s = 64U - 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; - } -} - +extern void sp_4096_from_bin(sp_digit* r, int size, const byte* a, int n); /* Convert an mp_int to an array of sp_digit. * * r A single precision integer. @@ -4357,41 +4258,7 @@ static void sp_4096_from_mp(sp_digit* r, int size, const mp_int* a) #endif } -/* Write r as big endian to byte array. - * Fixed length number of bytes written: 512 - * - * r A single precision integer. - * a Byte array. - */ -static void sp_4096_to_bin(sp_digit* r, byte* a) -{ - int i, j, s = 0, b; - - j = 4096 / 8 - 1; - a[j] = 0; - for (i=0; i<64 && j>=0; i++) { - b = 0; - /* lint allow cast of mismatch sp_digit and int */ - a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ - if (j < 0) { - break; - } - while (b < 64) { - a[j--] = r[i] >> b; b += 8; - if (j < 0) { - break; - } - } - s = 8 - (b - 64); - if (j >= 0) { - a[j] = 0; - } - if (s != 0) { - j++; - } - } -} - +extern void sp_4096_to_bin(sp_digit* r, byte* a); extern sp_digit sp_4096_sub_in_place_64(sp_digit* a, const sp_digit* b); extern sp_digit sp_4096_add_64(sp_digit* r, const sp_digit* a, const sp_digit* b); /* Multiply a and b into r. (r = a * b) @@ -4408,21 +4275,21 @@ SP_NOINLINE static void sp_4096_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 o, ca, cb; - ca = sp_2048_add_32(a1, a, &a[32]); - cb = sp_2048_add_32(b1, b, &b[32]); - u = ca & cb; + ca = sp_2048_add_32(a1, a, a + 32); + cb = sp_2048_add_32(b1, b, b + 32); + o = ca & cb; sp_2048_mul_32(z1, a1, b1); - sp_2048_mul_32(z2, &a[32], &b[32]); + sp_2048_mul_32(z2, a + 32, b + 32); sp_2048_mul_32(z0, a, b); sp_2048_mask_32(r + 64, a1, 0 - cb); sp_2048_mask_32(b1, b1, 0 - ca); - u += sp_2048_add_32(r + 64, r + 64, b1); - u += sp_4096_sub_in_place_64(z1, z2); - u += sp_4096_sub_in_place_64(z1, z0); - u += sp_4096_add_64(r + 32, r + 32, z1); - r[96] = u; + o += sp_2048_add_32(r + 64, r + 64, b1); + o += sp_4096_sub_in_place_64(z1, z2); + o += sp_4096_sub_in_place_64(z1, z0); + o += sp_4096_add_64(r + 32, r + 32, z1); + r[96] = o; XMEMSET(r + 96 + 1, 0, sizeof(sp_digit) * (32 - 1)); sp_4096_add_64(r + 64, r + 64, z2); } @@ -4438,18 +4305,18 @@ SP_NOINLINE static void sp_4096_sqr_64(sp_digit* r, const sp_digit* a) sp_digit z2[64]; sp_digit z1[64]; sp_digit a1[32]; - sp_digit u; + sp_digit o; - u = sp_2048_add_32(a1, a, &a[32]); + o = sp_2048_add_32(a1, a, a + 32); sp_2048_sqr_32(z1, a1); - sp_2048_sqr_32(z2, &a[32]); + sp_2048_sqr_32(z2, a + 32); sp_2048_sqr_32(z0, a); - sp_2048_mask_32(r + 64, a1, 0 - u); - u += sp_2048_add_32(r + 64, r + 64, r + 64); - u += sp_4096_sub_in_place_64(z1, z2); - u += sp_4096_sub_in_place_64(z1, z0); - u += sp_4096_add_64(r + 32, r + 32, z1); - r[96] = u; + sp_2048_mask_32(r + 64, a1, 0 - o); + o += sp_2048_dbl_32(r + 64, r + 64); + o += sp_4096_sub_in_place_64(z1, z2); + o += sp_4096_sub_in_place_64(z1, z0); + o += sp_4096_add_64(r + 32, r + 32, z1); + r[96] = o; XMEMSET(r + 96 + 1, 0, sizeof(sp_digit) * (32 - 1)); sp_4096_add_64(r + 64, r + 64, z2); } @@ -4469,21 +4336,21 @@ SP_NOINLINE static void sp_4096_mul_avx2_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 o, ca, cb; - ca = sp_2048_add_32(a1, a, &a[32]); - cb = sp_2048_add_32(b1, b, &b[32]); - u = ca & cb; + ca = sp_2048_add_32(a1, a, a + 32); + cb = sp_2048_add_32(b1, b, b + 32); + o = ca & cb; sp_2048_mul_avx2_32(z1, a1, b1); - sp_2048_mul_avx2_32(z2, &a[32], &b[32]); + sp_2048_mul_avx2_32(z2, a + 32, b + 32); sp_2048_mul_avx2_32(z0, a, b); sp_2048_mask_32(r + 64, a1, 0 - cb); sp_2048_mask_32(b1, b1, 0 - ca); - u += sp_2048_add_32(r + 64, r + 64, b1); - u += sp_4096_sub_in_place_64(z1, z2); - u += sp_4096_sub_in_place_64(z1, z0); - u += sp_4096_add_64(r + 32, r + 32, z1); - r[96] = u; + o += sp_2048_add_32(r + 64, r + 64, b1); + o += sp_4096_sub_in_place_64(z1, z2); + o += sp_4096_sub_in_place_64(z1, z0); + o += sp_4096_add_64(r + 32, r + 32, z1); + r[96] = o; XMEMSET(r + 96 + 1, 0, sizeof(sp_digit) * (32 - 1)); sp_4096_add_64(r + 64, r + 64, z2); } @@ -4501,18 +4368,18 @@ SP_NOINLINE static void sp_4096_sqr_avx2_64(sp_digit* r, const sp_digit* a) sp_digit z2[64]; sp_digit z1[64]; sp_digit a1[32]; - sp_digit u; + sp_digit o; - u = sp_2048_add_32(a1, a, &a[32]); + o = sp_2048_add_32(a1, a, a + 32); sp_2048_sqr_avx2_32(z1, a1); - sp_2048_sqr_avx2_32(z2, &a[32]); + sp_2048_sqr_avx2_32(z2, a + 32); sp_2048_sqr_avx2_32(z0, a); - sp_2048_mask_32(r + 64, a1, 0 - u); - u += sp_2048_add_32(r + 64, r + 64, r + 64); - u += sp_4096_sub_in_place_64(z1, z2); - u += sp_4096_sub_in_place_64(z1, z0); - u += sp_4096_add_64(r + 32, r + 32, z1); - r[96] = u; + sp_2048_mask_32(r + 64, a1, 0 - o); + o += sp_2048_dbl_32(r + 64, r + 64); + o += sp_4096_sub_in_place_64(z1, z2); + o += sp_4096_sub_in_place_64(z1, z0); + o += sp_4096_add_64(r + 32, r + 32, z1); + r[96] = o; XMEMSET(r + 96 + 1, 0, sizeof(sp_digit) * (32 - 1)); sp_4096_add_64(r + 64, r + 64, z2); } @@ -4588,6 +4455,7 @@ static void sp_4096_mont_sqr_64(sp_digit* r, const sp_digit* a, const sp_digit* } #ifndef 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); /* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) * @@ -4680,7 +4548,12 @@ static WC_INLINE int sp_4096_div_64(const sp_digit* a, const sp_digit* d, sp_dig } r1 = sp_4096_cmp_64(t1, d) >= 0; - sp_4096_cond_sub_64(r, t1, d, (sp_digit)0 - r1); +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_4096_cond_sub_avx2_64(r, t1, d, (sp_digit)0 - r1); + else +#endif + sp_4096_cond_sub_64(r, t1, d, (sp_digit)0 - r1); return MP_OKAY; } @@ -4698,6 +4571,7 @@ static WC_INLINE int sp_4096_mod_64(sp_digit* r, const sp_digit* a, const sp_dig } #endif /* WOLFSSL_RSA_PUBLIC_ONLY */ +extern sp_digit sp_4096_sub_64(sp_digit* r, 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. * @@ -4739,8 +4613,16 @@ static WC_INLINE int sp_4096_div_64_cond(const sp_digit* a, const sp_digit* d, s } } - r1 = sp_4096_cmp_64(t1, d) >= 0; - sp_4096_cond_sub_64(r, t1, d, (sp_digit)0 - r1); + for (i = 63; i > 0; i--) { + if (t1[i] != d[i]) + break; + } + if (t1[i] >= d[i]) { + sp_4096_sub_64(r, t1, d); + } + else { + XMEMCPY(r, t1, sizeof(*t1) * 64); + } return MP_OKAY; } @@ -4772,8 +4654,10 @@ static int sp_4096_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e, { #ifndef WOLFSSL_SMALL_STACK sp_digit t[32][128]; + sp_digit rt[128]; #else sp_digit* t[32]; + sp_digit* rt; sp_digit* td; #endif sp_digit* norm; @@ -4785,7 +4669,7 @@ static int sp_4096_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e, int err = MP_OKAY; #ifdef WOLFSSL_SMALL_STACK - td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 128, NULL, + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 33 * 128, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (td == NULL) { err = MEMORY_E; @@ -4796,6 +4680,7 @@ static int sp_4096_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e, #ifdef WOLFSSL_SMALL_STACK for (i=0; i<32; i++) t[i] = td + i * 128; + rt = td + 4096; #endif norm = t[0]; @@ -4876,10 +4761,10 @@ static int sp_4096_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e, c -= 5; } - sp_4096_mont_sqr_64(r, r, m, mp); - sp_4096_mont_sqr_64(r, r, m, mp); - sp_4096_mont_sqr_64(r, r, m, mp); - sp_4096_mont_sqr_64(r, r, m, mp); + sp_4096_mont_sqr_64(rt, r, m, mp); + sp_4096_mont_sqr_64(r, rt, m, mp); + sp_4096_mont_sqr_64(rt, r, m, mp); + sp_4096_mont_sqr_64(r, rt, m, mp); sp_4096_mont_sqr_64(r, r, m, mp); sp_4096_mont_mul_64(r, r, t[y], m, mp); @@ -4952,8 +4837,10 @@ static int sp_4096_mod_exp_avx2_64(sp_digit* r, const sp_digit* a, const sp_digi { #ifndef WOLFSSL_SMALL_STACK sp_digit t[32][128]; + sp_digit rt[128]; #else sp_digit* t[32]; + sp_digit* rt; sp_digit* td; #endif sp_digit* norm; @@ -4965,7 +4852,7 @@ static int sp_4096_mod_exp_avx2_64(sp_digit* r, const sp_digit* a, const sp_digi int err = MP_OKAY; #ifdef WOLFSSL_SMALL_STACK - td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 32 * 128, NULL, + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * 33 * 128, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (td == NULL) { err = MEMORY_E; @@ -4976,6 +4863,7 @@ static int sp_4096_mod_exp_avx2_64(sp_digit* r, const sp_digit* a, const sp_digi #ifdef WOLFSSL_SMALL_STACK for (i=0; i<32; i++) t[i] = td + i * 128; + rt = td + 4096; #endif norm = t[0]; @@ -5056,10 +4944,10 @@ static int sp_4096_mod_exp_avx2_64(sp_digit* r, const sp_digit* a, const sp_digi c -= 5; } - sp_4096_mont_sqr_avx2_64(r, r, m, mp); - sp_4096_mont_sqr_avx2_64(r, r, m, mp); - sp_4096_mont_sqr_avx2_64(r, r, m, mp); - sp_4096_mont_sqr_avx2_64(r, r, m, mp); + sp_4096_mont_sqr_avx2_64(rt, r, m, mp); + sp_4096_mont_sqr_avx2_64(r, rt, m, mp); + sp_4096_mont_sqr_avx2_64(rt, r, m, mp); + sp_4096_mont_sqr_avx2_64(r, rt, m, mp); sp_4096_mont_sqr_avx2_64(r, r, m, mp); sp_4096_mont_mul_avx2_64(r, r, t[y], m, mp); @@ -5069,7 +4957,7 @@ static int sp_4096_mod_exp_avx2_64(sp_digit* r, const sp_digit* a, const sp_digi sp_4096_mont_reduce_avx2_64(r, m, mp); mask = 0 - (sp_4096_cmp_64(r, m) >= 0); - sp_4096_cond_sub_64(r, r, m, mask); + sp_4096_cond_sub_avx2_64(r, r, m, mask); } #ifdef WOLFSSL_SMALL_STACK @@ -5602,14 +5490,14 @@ static int sp_4096_mod_exp_2_avx2_64(sp_digit* r, const sp_digit* e, int bits, sp_4096_mul_d_avx2_64(tmp, norm, r[64]); r[64] = 0; o = sp_4096_add_64(r, r, tmp); - sp_4096_cond_sub_64(r, r, m, (sp_digit)0 - o); + sp_4096_cond_sub_avx2_64(r, r, m, (sp_digit)0 - o); } XMEMSET(&r[64], 0, sizeof(sp_digit) * 64); sp_4096_mont_reduce_avx2_64(r, m, mp); mask = 0 - (sp_4096_cmp_64(r, m) >= 0); - sp_4096_cond_sub_64(r, r, m, mask); + sp_4096_cond_sub_avx2_64(r, r, m, mask); } #ifdef WOLFSSL_SMALL_STACK @@ -21996,40 +21884,7 @@ static int sp_256_iszero_4(const sp_digit* a) #endif /* WOLFSSL_VALIDATE_ECC_KEYGEN || HAVE_ECC_SIGN || HAVE_ECC_VERIFY */ extern void sp_256_add_one_4(sp_digit* a); -/* 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_256_from_bin(sp_digit* r, int size, const byte* a, int n) -{ - int i, j = 0; - word32 s = 0; - - r[0] = 0; - for (i = n-1; i >= 0; i--) { - r[j] |= (((sp_digit)a[i]) << s); - if (s >= 56U) { - r[j] &= 0xffffffffffffffffl; - s = 64U - 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; - } -} - +extern void sp_256_from_bin(sp_digit* r, int size, const byte* a, int n); /* Generates a scalar that is in the range 1..order-1. * * rng Random number generator. @@ -22156,41 +22011,7 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) } #ifdef HAVE_ECC_DHE -/* Write r as big endian to byte array. - * Fixed length number of bytes written: 32 - * - * r A single precision integer. - * a Byte array. - */ -static void sp_256_to_bin(sp_digit* r, byte* a) -{ - int i, j, s = 0, b; - - j = 256 / 8 - 1; - a[j] = 0; - for (i=0; i<4 && j>=0; i++) { - b = 0; - /* lint allow cast of mismatch sp_digit and int */ - a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ - if (j < 0) { - break; - } - while (b < 64) { - a[j--] = r[i] >> b; b += 8; - if (j < 0) { - break; - } - } - s = 8 - (b - 64); - if (j >= 0) { - a[j] = 0; - } - if (s != 0) { - j++; - } - } -} - +extern void sp_256_to_bin(sp_digit* r, byte* a); /* Multiply the point by the scalar and serialize the X ordinate. * The number is 0 padded to maximum size on output. * @@ -22272,6 +22093,7 @@ extern void sp_256_mul_avx2_4(sp_digit* r, const sp_digit* a, const sp_digit* b) #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); /* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) @@ -22356,7 +22178,12 @@ static WC_INLINE int sp_256_div_4(const sp_digit* a, const sp_digit* d, sp_digit } r1 = sp_256_cmp_4(t1, d) >= 0; - sp_256_cond_sub_4(r, t1, d, (sp_digit)0 - r1); +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_256_cond_sub_avx2_4(r, t1, d, (sp_digit)0 - r1); + else +#endif + sp_256_cond_sub_4(r, t1, d, (sp_digit)0 - r1); return MP_OKAY; } diff --git a/wolfcrypt/src/sp_x86_64_asm.S b/wolfcrypt/src/sp_x86_64_asm.S index f62442ecb..1591e62a3 100644 --- a/wolfcrypt/src/sp_x86_64_asm.S +++ b/wolfcrypt/src/sp_x86_64_asm.S @@ -21,6 +21,172 @@ #define HAVE_INTEL_AVX2 #ifndef WOLFSSL_SP_NO_2048 +/* 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. + */ +#ifndef __APPLE__ +.globl sp_2048_from_bin +.type sp_2048_from_bin,@function +.align 16 +sp_2048_from_bin: +#else +.globl _sp_2048_from_bin +.p2align 4 +_sp_2048_from_bin: +#endif /* __APPLE__ */ + movq %rdx, %r9 + movq %rdi, %r10 + addq %rcx, %r9 + addq $256, %r10 + xorq %r11, %r11 + jmp L_2048_from_bin_64_end +L_2048_from_bin_64_start: + subq $64, %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 $64, %rdi + subq $64, %rcx +L_2048_from_bin_64_end: + cmpq $63, %rcx + jg L_2048_from_bin_64_start + jmp L_2048_from_bin_8_end +L_2048_from_bin_8_start: + subq $8, %r9 + movbeq (%r9), %rax + movq %rax, (%rdi) + addq $8, %rdi + subq $8, %rcx +L_2048_from_bin_8_end: + cmpq $7, %rcx + jg L_2048_from_bin_8_start + cmpq %r11, %rcx + je L_2048_from_bin_hi_end + movq %r11, %r8 + movq %r11, %rax +L_2048_from_bin_hi_start: + movb (%rdx), %al + shlq $8, %r8 + incq %rdx + addq %rax, %r8 + decq %rcx + jg L_2048_from_bin_hi_start + movq %r8, (%rdi) + addq $8, %rdi +L_2048_from_bin_hi_end: + cmpq %r10, %rdi + je L_2048_from_bin_zero_end +L_2048_from_bin_zero_start: + movq %r11, (%rdi) + addq $8, %rdi + cmpq %r10, %rdi + jl L_2048_from_bin_zero_start +L_2048_from_bin_zero_end: + repz retq +#ifndef __APPLE__ +.size sp_2048_from_bin,.-sp_2048_from_bin +#endif /* __APPLE__ */ +/* Write r as big endian to byte array. + * Fixed length number of bytes written: 256 + * + * r A single precision integer. + * a Byte array. + */ +#ifndef __APPLE__ +.globl sp_2048_to_bin +.type sp_2048_to_bin,@function +.align 16 +sp_2048_to_bin: +#else +.globl _sp_2048_to_bin +.p2align 4 +_sp_2048_to_bin: +#endif /* __APPLE__ */ + movbeq 248(%rdi), %rdx + movbeq 240(%rdi), %rax + movq %rdx, (%rsi) + movq %rax, 8(%rsi) + movbeq 232(%rdi), %rdx + movbeq 224(%rdi), %rax + movq %rdx, 16(%rsi) + movq %rax, 24(%rsi) + movbeq 216(%rdi), %rdx + movbeq 208(%rdi), %rax + movq %rdx, 32(%rsi) + movq %rax, 40(%rsi) + movbeq 200(%rdi), %rdx + movbeq 192(%rdi), %rax + movq %rdx, 48(%rsi) + movq %rax, 56(%rsi) + movbeq 184(%rdi), %rdx + movbeq 176(%rdi), %rax + movq %rdx, 64(%rsi) + movq %rax, 72(%rsi) + movbeq 168(%rdi), %rdx + movbeq 160(%rdi), %rax + movq %rdx, 80(%rsi) + movq %rax, 88(%rsi) + movbeq 152(%rdi), %rdx + movbeq 144(%rdi), %rax + movq %rdx, 96(%rsi) + movq %rax, 104(%rsi) + movbeq 136(%rdi), %rdx + movbeq 128(%rdi), %rax + movq %rdx, 112(%rsi) + movq %rax, 120(%rsi) + movbeq 120(%rdi), %rdx + movbeq 112(%rdi), %rax + movq %rdx, 128(%rsi) + movq %rax, 136(%rsi) + movbeq 104(%rdi), %rdx + movbeq 96(%rdi), %rax + movq %rdx, 144(%rsi) + movq %rax, 152(%rsi) + movbeq 88(%rdi), %rdx + movbeq 80(%rdi), %rax + movq %rdx, 160(%rsi) + movq %rax, 168(%rsi) + movbeq 72(%rdi), %rdx + movbeq 64(%rdi), %rax + movq %rdx, 176(%rsi) + movq %rax, 184(%rsi) + movbeq 56(%rdi), %rdx + movbeq 48(%rdi), %rax + movq %rdx, 192(%rsi) + movq %rax, 200(%rsi) + movbeq 40(%rdi), %rdx + movbeq 32(%rdi), %rax + movq %rdx, 208(%rsi) + movq %rax, 216(%rsi) + movbeq 24(%rdi), %rdx + movbeq 16(%rdi), %rax + movq %rdx, 224(%rsi) + movq %rax, 232(%rsi) + movbeq 8(%rdi), %rdx + movbeq (%rdi), %rax + movq %rdx, 240(%rsi) + movq %rax, 248(%rsi) + repz retq +#ifndef __APPLE__ +.size sp_2048_to_bin,.-sp_2048_to_bin +#endif /* __APPLE__ */ /* Multiply a and b into r. (r = a * b) * * r A single precision integer. @@ -4399,38 +4565,16 @@ _sp_2048_mul_avx2_16: adcxq %r13, %r9 movq %r8, 240(%rdi) movq %r9, 248(%rdi) - movq (%rsp), %r8 - movq 8(%rsp), %r9 - movq 16(%rsp), %r10 - movq 24(%rsp), %r11 - movq %r8, (%rdi) - movq %r9, 8(%rdi) - movq %r10, 16(%rdi) - movq %r11, 24(%rdi) - movq 32(%rsp), %r8 - movq 40(%rsp), %r9 - movq 48(%rsp), %r10 - movq 56(%rsp), %r11 - movq %r8, 32(%rdi) - movq %r9, 40(%rdi) - movq %r10, 48(%rdi) - movq %r11, 56(%rdi) - movq 64(%rsp), %r8 - movq 72(%rsp), %r9 - movq 80(%rsp), %r10 - movq 88(%rsp), %r11 - movq %r8, 64(%rdi) - movq %r9, 72(%rdi) - movq %r10, 80(%rdi) - movq %r11, 88(%rdi) - movq 96(%rsp), %r8 - movq 104(%rsp), %r9 - movq %r15, %r10 - movq %rbx, %r11 - movq %r8, 96(%rdi) - movq %r9, 104(%rdi) - movq %r10, 112(%rdi) - movq %r11, 120(%rdi) + vmovdqu (%rsp), %ymm0 + vmovdqu 32(%rsp), %ymm1 + vmovdqu 64(%rsp), %ymm2 + vmovdqu 96(%rsp), %xmm3 + vmovdqu %ymm0, (%rdi) + vmovdqu %ymm1, 32(%rdi) + vmovdqu %ymm2, 64(%rdi) + vmovdqu %xmm3, 96(%rdi) + movq %r15, 112(%rdi) + movq %rbx, 120(%rdi) addq $128, %rsp pop %rbx pop %r15 @@ -5443,38 +5587,16 @@ _sp_2048_sqr_avx2_16: movq %r9, 248(%rdi) cmpq %rdi, %rsi jne L_end_2048_sqr_avx2_16 - movq (%rbp), %r8 - movq 8(%rbp), %r9 - movq 16(%rbp), %r10 - movq 24(%rbp), %r11 - movq %r8, (%rdi) - movq %r9, 8(%rdi) - movq %r10, 16(%rdi) - movq %r11, 24(%rdi) - movq 32(%rbp), %r8 - movq 40(%rbp), %r9 - movq 48(%rbp), %r10 - movq 56(%rbp), %r11 - movq %r8, 32(%rdi) - movq %r9, 40(%rdi) - movq %r10, 48(%rdi) - movq %r11, 56(%rdi) - movq 64(%rbp), %r8 - movq 72(%rbp), %r9 - movq 80(%rbp), %r10 - movq 88(%rbp), %r11 - movq %r8, 64(%rdi) - movq %r9, 72(%rdi) - movq %r10, 80(%rdi) - movq %r11, 88(%rdi) - movq 96(%rbp), %r8 - movq 104(%rbp), %r9 - movq 112(%rbp), %r10 - movq 120(%rbp), %r11 - movq %r8, 96(%rdi) - movq %r9, 104(%rdi) - movq %r10, 112(%rdi) - movq %r11, 120(%rdi) + vmovdqu (%rbp), %ymm0 + vmovdqu 32(%rbp), %ymm1 + vmovdqu 64(%rbp), %ymm2 + vmovdqu 96(%rbp), %ymm3 + vmovdqu 128(%rdi), %ymm4 + vmovdqu %ymm0, (%rdi) + vmovdqu %ymm1, 32(%rdi) + vmovdqu %ymm2, 64(%rdi) + vmovdqu %ymm3, 96(%rdi) + vmovdqu %ymm4, 128(%rdi) L_end_2048_sqr_avx2_16: addq $128, %rsp pop %r13 @@ -5501,55 +5623,55 @@ sp_2048_add_16: .p2align 4 _sp_2048_add_16: #endif /* __APPLE__ */ - xorq %rax, %rax movq (%rsi), %rcx + xorq %rax, %rax addq (%rdx), %rcx + movq 8(%rsi), %r8 movq %rcx, (%rdi) - movq 8(%rsi), %rcx - adcq 8(%rdx), %rcx - movq %rcx, 8(%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) - movq 24(%rsi), %rcx - adcq 24(%rdx), %rcx - movq %rcx, 24(%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) - movq 40(%rsi), %rcx - adcq 40(%rdx), %rcx - movq %rcx, 40(%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) - movq 56(%rsi), %rcx - adcq 56(%rdx), %rcx - movq %rcx, 56(%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) - movq 72(%rsi), %rcx - adcq 72(%rdx), %rcx - movq %rcx, 72(%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) - movq 88(%rsi), %rcx - adcq 88(%rdx), %rcx - movq %rcx, 88(%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) - movq 104(%rsi), %rcx - adcq 104(%rdx), %rcx - movq %rcx, 104(%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) - movq 120(%rsi), %rcx - adcq 120(%rdx), %rcx - movq %rcx, 120(%rdi) + adcq 120(%rdx), %r8 + movq %r8, 120(%rdi) adcq $0, %rax repz retq #ifndef __APPLE__ @@ -5570,134 +5692,102 @@ sp_2048_sub_in_place_32: .p2align 4 _sp_2048_sub_in_place_32: #endif /* __APPLE__ */ - xorq %rax, %rax movq (%rdi), %rdx + xorq %rax, %rax + subq (%rsi), %rdx movq 8(%rdi), %rcx - movq (%rsi), %r8 - movq 8(%rsi), %r9 - subq %r8, %rdx - movq 16(%rsi), %r8 movq %rdx, (%rdi) + sbbq 8(%rsi), %rcx movq 16(%rdi), %rdx - sbbq %r9, %rcx - movq 24(%rsi), %r9 movq %rcx, 8(%rdi) + sbbq 16(%rsi), %rdx movq 24(%rdi), %rcx - sbbq %r8, %rdx - movq 32(%rsi), %r8 movq %rdx, 16(%rdi) + sbbq 24(%rsi), %rcx movq 32(%rdi), %rdx - sbbq %r9, %rcx - movq 40(%rsi), %r9 movq %rcx, 24(%rdi) + sbbq 32(%rsi), %rdx movq 40(%rdi), %rcx - sbbq %r8, %rdx - movq 48(%rsi), %r8 movq %rdx, 32(%rdi) + sbbq 40(%rsi), %rcx movq 48(%rdi), %rdx - sbbq %r9, %rcx - movq 56(%rsi), %r9 movq %rcx, 40(%rdi) + sbbq 48(%rsi), %rdx movq 56(%rdi), %rcx - sbbq %r8, %rdx - movq 64(%rsi), %r8 movq %rdx, 48(%rdi) + sbbq 56(%rsi), %rcx movq 64(%rdi), %rdx - sbbq %r9, %rcx - movq 72(%rsi), %r9 movq %rcx, 56(%rdi) + sbbq 64(%rsi), %rdx movq 72(%rdi), %rcx - sbbq %r8, %rdx - movq 80(%rsi), %r8 movq %rdx, 64(%rdi) + sbbq 72(%rsi), %rcx movq 80(%rdi), %rdx - sbbq %r9, %rcx - movq 88(%rsi), %r9 movq %rcx, 72(%rdi) + sbbq 80(%rsi), %rdx movq 88(%rdi), %rcx - sbbq %r8, %rdx - movq 96(%rsi), %r8 movq %rdx, 80(%rdi) + sbbq 88(%rsi), %rcx movq 96(%rdi), %rdx - sbbq %r9, %rcx - movq 104(%rsi), %r9 movq %rcx, 88(%rdi) + sbbq 96(%rsi), %rdx movq 104(%rdi), %rcx - sbbq %r8, %rdx - movq 112(%rsi), %r8 movq %rdx, 96(%rdi) + sbbq 104(%rsi), %rcx movq 112(%rdi), %rdx - sbbq %r9, %rcx - movq 120(%rsi), %r9 movq %rcx, 104(%rdi) + sbbq 112(%rsi), %rdx movq 120(%rdi), %rcx - sbbq %r8, %rdx - movq 128(%rsi), %r8 movq %rdx, 112(%rdi) + sbbq 120(%rsi), %rcx movq 128(%rdi), %rdx - sbbq %r9, %rcx - movq 136(%rsi), %r9 movq %rcx, 120(%rdi) + sbbq 128(%rsi), %rdx movq 136(%rdi), %rcx - sbbq %r8, %rdx - movq 144(%rsi), %r8 movq %rdx, 128(%rdi) + sbbq 136(%rsi), %rcx movq 144(%rdi), %rdx - sbbq %r9, %rcx - movq 152(%rsi), %r9 movq %rcx, 136(%rdi) + sbbq 144(%rsi), %rdx movq 152(%rdi), %rcx - sbbq %r8, %rdx - movq 160(%rsi), %r8 movq %rdx, 144(%rdi) + sbbq 152(%rsi), %rcx movq 160(%rdi), %rdx - sbbq %r9, %rcx - movq 168(%rsi), %r9 movq %rcx, 152(%rdi) + sbbq 160(%rsi), %rdx movq 168(%rdi), %rcx - sbbq %r8, %rdx - movq 176(%rsi), %r8 movq %rdx, 160(%rdi) + sbbq 168(%rsi), %rcx movq 176(%rdi), %rdx - sbbq %r9, %rcx - movq 184(%rsi), %r9 movq %rcx, 168(%rdi) + sbbq 176(%rsi), %rdx movq 184(%rdi), %rcx - sbbq %r8, %rdx - movq 192(%rsi), %r8 movq %rdx, 176(%rdi) + sbbq 184(%rsi), %rcx movq 192(%rdi), %rdx - sbbq %r9, %rcx - movq 200(%rsi), %r9 movq %rcx, 184(%rdi) + sbbq 192(%rsi), %rdx movq 200(%rdi), %rcx - sbbq %r8, %rdx - movq 208(%rsi), %r8 movq %rdx, 192(%rdi) + sbbq 200(%rsi), %rcx movq 208(%rdi), %rdx - sbbq %r9, %rcx - movq 216(%rsi), %r9 movq %rcx, 200(%rdi) + sbbq 208(%rsi), %rdx movq 216(%rdi), %rcx - sbbq %r8, %rdx - movq 224(%rsi), %r8 movq %rdx, 208(%rdi) + sbbq 216(%rsi), %rcx movq 224(%rdi), %rdx - sbbq %r9, %rcx - movq 232(%rsi), %r9 movq %rcx, 216(%rdi) + sbbq 224(%rsi), %rdx movq 232(%rdi), %rcx - sbbq %r8, %rdx - movq 240(%rsi), %r8 movq %rdx, 224(%rdi) + sbbq 232(%rsi), %rcx movq 240(%rdi), %rdx - sbbq %r9, %rcx - movq 248(%rsi), %r9 movq %rcx, 232(%rdi) + sbbq 240(%rsi), %rdx movq 248(%rdi), %rcx - sbbq %r8, %rdx movq %rdx, 240(%rdi) - sbbq %r9, %rcx + sbbq 248(%rsi), %rcx movq %rcx, 248(%rdi) sbbq $0, %rax repz retq @@ -5720,108 +5810,177 @@ sp_2048_add_32: .p2align 4 _sp_2048_add_32: #endif /* __APPLE__ */ - xorq %rax, %rax movq (%rsi), %rcx + xorq %rax, %rax addq (%rdx), %rcx + movq 8(%rsi), %r8 movq %rcx, (%rdi) - movq 8(%rsi), %rcx - adcq 8(%rdx), %rcx - movq %rcx, 8(%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) - movq 24(%rsi), %rcx - adcq 24(%rdx), %rcx - movq %rcx, 24(%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) - movq 40(%rsi), %rcx - adcq 40(%rdx), %rcx - movq %rcx, 40(%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) - movq 56(%rsi), %rcx - adcq 56(%rdx), %rcx - movq %rcx, 56(%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) - movq 72(%rsi), %rcx - adcq 72(%rdx), %rcx - movq %rcx, 72(%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) - movq 88(%rsi), %rcx - adcq 88(%rdx), %rcx - movq %rcx, 88(%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) - movq 104(%rsi), %rcx - adcq 104(%rdx), %rcx - movq %rcx, 104(%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) - movq 120(%rsi), %rcx - adcq 120(%rdx), %rcx - movq %rcx, 120(%rdi) + adcq 120(%rdx), %r8 movq 128(%rsi), %rcx + movq %r8, 120(%rdi) adcq 128(%rdx), %rcx + movq 136(%rsi), %r8 movq %rcx, 128(%rdi) - movq 136(%rsi), %rcx - adcq 136(%rdx), %rcx - movq %rcx, 136(%rdi) + adcq 136(%rdx), %r8 movq 144(%rsi), %rcx + movq %r8, 136(%rdi) adcq 144(%rdx), %rcx + movq 152(%rsi), %r8 movq %rcx, 144(%rdi) - movq 152(%rsi), %rcx - adcq 152(%rdx), %rcx - movq %rcx, 152(%rdi) + adcq 152(%rdx), %r8 movq 160(%rsi), %rcx + movq %r8, 152(%rdi) adcq 160(%rdx), %rcx + movq 168(%rsi), %r8 movq %rcx, 160(%rdi) - movq 168(%rsi), %rcx - adcq 168(%rdx), %rcx - movq %rcx, 168(%rdi) + adcq 168(%rdx), %r8 movq 176(%rsi), %rcx + movq %r8, 168(%rdi) adcq 176(%rdx), %rcx + movq 184(%rsi), %r8 movq %rcx, 176(%rdi) - movq 184(%rsi), %rcx - adcq 184(%rdx), %rcx - movq %rcx, 184(%rdi) + adcq 184(%rdx), %r8 movq 192(%rsi), %rcx + movq %r8, 184(%rdi) adcq 192(%rdx), %rcx + movq 200(%rsi), %r8 movq %rcx, 192(%rdi) - movq 200(%rsi), %rcx - adcq 200(%rdx), %rcx - movq %rcx, 200(%rdi) + adcq 200(%rdx), %r8 movq 208(%rsi), %rcx + movq %r8, 200(%rdi) adcq 208(%rdx), %rcx + movq 216(%rsi), %r8 movq %rcx, 208(%rdi) - movq 216(%rsi), %rcx - adcq 216(%rdx), %rcx - movq %rcx, 216(%rdi) + adcq 216(%rdx), %r8 movq 224(%rsi), %rcx + movq %r8, 216(%rdi) adcq 224(%rdx), %rcx + movq 232(%rsi), %r8 movq %rcx, 224(%rdi) - movq 232(%rsi), %rcx - adcq 232(%rdx), %rcx - movq %rcx, 232(%rdi) + adcq 232(%rdx), %r8 movq 240(%rsi), %rcx + movq %r8, 232(%rdi) adcq 240(%rdx), %rcx + movq 248(%rsi), %r8 movq %rcx, 240(%rdi) - movq 248(%rsi), %rcx - adcq 248(%rdx), %rcx - movq %rcx, 248(%rdi) + adcq 248(%rdx), %r8 + movq %r8, 248(%rdi) adcq $0, %rax repz retq #ifndef __APPLE__ .size sp_2048_add_32,.-sp_2048_add_32 #endif /* __APPLE__ */ +/* Add a to a into r. (r = a + a) + * + * r A single precision integer. + * a A single precision integer. + */ +#ifndef __APPLE__ +.globl sp_2048_dbl_16 +.type sp_2048_dbl_16,@function +.align 16 +sp_2048_dbl_16: +#else +.globl _sp_2048_dbl_16 +.p2align 4 +_sp_2048_dbl_16: +#endif /* __APPLE__ */ + movq (%rsi), %rdx + xorq %rax, %rax + addq %rdx, %rdx + movq 8(%rsi), %rcx + movq %rdx, (%rdi) + adcq %rcx, %rcx + movq 16(%rsi), %rdx + movq %rcx, 8(%rdi) + adcq %rdx, %rdx + movq 24(%rsi), %rcx + movq %rdx, 16(%rdi) + adcq %rcx, %rcx + movq 32(%rsi), %rdx + movq %rcx, 24(%rdi) + adcq %rdx, %rdx + movq 40(%rsi), %rcx + movq %rdx, 32(%rdi) + adcq %rcx, %rcx + movq 48(%rsi), %rdx + movq %rcx, 40(%rdi) + adcq %rdx, %rdx + movq 56(%rsi), %rcx + movq %rdx, 48(%rdi) + adcq %rcx, %rcx + movq 64(%rsi), %rdx + movq %rcx, 56(%rdi) + adcq %rdx, %rdx + movq 72(%rsi), %rcx + movq %rdx, 64(%rdi) + adcq %rcx, %rcx + movq 80(%rsi), %rdx + movq %rcx, 72(%rdi) + adcq %rdx, %rdx + movq 88(%rsi), %rcx + movq %rdx, 80(%rdi) + adcq %rcx, %rcx + movq 96(%rsi), %rdx + movq %rcx, 88(%rdi) + adcq %rdx, %rdx + movq 104(%rsi), %rcx + movq %rdx, 96(%rdi) + adcq %rcx, %rcx + movq 112(%rsi), %rdx + movq %rcx, 104(%rdi) + adcq %rdx, %rdx + movq 120(%rsi), %rcx + movq %rdx, 112(%rdi) + adcq %rcx, %rcx + movq %rcx, 120(%rdi) + adcq $0, %rax + repz retq +#ifndef __APPLE__ +.size sp_2048_dbl_16,.-sp_2048_dbl_16 +#endif /* __APPLE__ */ /* Mul a by digit b into r. (r = a * b) * * r A single precision integer. @@ -6112,70 +6271,54 @@ sp_2048_sub_in_place_16: .p2align 4 _sp_2048_sub_in_place_16: #endif /* __APPLE__ */ - xorq %rax, %rax movq (%rdi), %rdx + xorq %rax, %rax + subq (%rsi), %rdx movq 8(%rdi), %rcx - movq (%rsi), %r8 - movq 8(%rsi), %r9 - subq %r8, %rdx - movq 16(%rsi), %r8 movq %rdx, (%rdi) + sbbq 8(%rsi), %rcx movq 16(%rdi), %rdx - sbbq %r9, %rcx - movq 24(%rsi), %r9 movq %rcx, 8(%rdi) + sbbq 16(%rsi), %rdx movq 24(%rdi), %rcx - sbbq %r8, %rdx - movq 32(%rsi), %r8 movq %rdx, 16(%rdi) + sbbq 24(%rsi), %rcx movq 32(%rdi), %rdx - sbbq %r9, %rcx - movq 40(%rsi), %r9 movq %rcx, 24(%rdi) + sbbq 32(%rsi), %rdx movq 40(%rdi), %rcx - sbbq %r8, %rdx - movq 48(%rsi), %r8 movq %rdx, 32(%rdi) + sbbq 40(%rsi), %rcx movq 48(%rdi), %rdx - sbbq %r9, %rcx - movq 56(%rsi), %r9 movq %rcx, 40(%rdi) + sbbq 48(%rsi), %rdx movq 56(%rdi), %rcx - sbbq %r8, %rdx - movq 64(%rsi), %r8 movq %rdx, 48(%rdi) + sbbq 56(%rsi), %rcx movq 64(%rdi), %rdx - sbbq %r9, %rcx - movq 72(%rsi), %r9 movq %rcx, 56(%rdi) + sbbq 64(%rsi), %rdx movq 72(%rdi), %rcx - sbbq %r8, %rdx - movq 80(%rsi), %r8 movq %rdx, 64(%rdi) + sbbq 72(%rsi), %rcx movq 80(%rdi), %rdx - sbbq %r9, %rcx - movq 88(%rsi), %r9 movq %rcx, 72(%rdi) + sbbq 80(%rsi), %rdx movq 88(%rdi), %rcx - sbbq %r8, %rdx - movq 96(%rsi), %r8 movq %rdx, 80(%rdi) + sbbq 88(%rsi), %rcx movq 96(%rdi), %rdx - sbbq %r9, %rcx - movq 104(%rsi), %r9 movq %rcx, 88(%rdi) + sbbq 96(%rsi), %rdx movq 104(%rdi), %rcx - sbbq %r8, %rdx - movq 112(%rsi), %r8 movq %rdx, 96(%rdi) + sbbq 104(%rsi), %rcx movq 112(%rdi), %rdx - sbbq %r9, %rcx - movq 120(%rsi), %r9 movq %rcx, 104(%rdi) + sbbq 112(%rsi), %rdx movq 120(%rdi), %rcx - sbbq %r8, %rdx movq %rdx, 112(%rdi) - sbbq %r9, %rcx + sbbq 120(%rsi), %rcx movq %rcx, 120(%rdi) sbbq $0, %rax repz retq @@ -6531,6 +6674,110 @@ L_mont_loop_16: #ifndef __APPLE__ .size sp_2048_mont_reduce_16,.-sp_2048_mont_reduce_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__ +.globl sp_2048_cond_sub_avx2_16 +.type sp_2048_cond_sub_avx2_16,@function +.align 16 +sp_2048_cond_sub_avx2_16: +#else +.globl _sp_2048_cond_sub_avx2_16 +.p2align 4 +_sp_2048_cond_sub_avx2_16: +#endif /* __APPLE__ */ + movq $0, %rax + movq (%rsi), %r8 + movq (%rdx), %r10 + pextq %rcx, %r10, %r10 + subq %r10, %r8 + movq 8(%rsi), %r9 + movq 8(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, (%rdi) + sbbq %r10, %r9 + movq 16(%rsi), %r8 + movq 16(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 8(%rdi) + sbbq %r10, %r8 + movq 24(%rsi), %r9 + movq 24(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 16(%rdi) + sbbq %r10, %r9 + movq 32(%rsi), %r8 + movq 32(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 24(%rdi) + sbbq %r10, %r8 + movq 40(%rsi), %r9 + movq 40(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 32(%rdi) + sbbq %r10, %r9 + movq 48(%rsi), %r8 + movq 48(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 40(%rdi) + sbbq %r10, %r8 + movq 56(%rsi), %r9 + movq 56(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 48(%rdi) + sbbq %r10, %r9 + movq 64(%rsi), %r8 + movq 64(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 56(%rdi) + sbbq %r10, %r8 + movq 72(%rsi), %r9 + movq 72(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 64(%rdi) + sbbq %r10, %r9 + movq 80(%rsi), %r8 + movq 80(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 72(%rdi) + sbbq %r10, %r8 + movq 88(%rsi), %r9 + movq 88(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 80(%rdi) + sbbq %r10, %r9 + movq 96(%rsi), %r8 + movq 96(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 88(%rdi) + sbbq %r10, %r8 + movq 104(%rsi), %r9 + movq 104(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 96(%rdi) + sbbq %r10, %r9 + movq 112(%rsi), %r8 + movq 112(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 104(%rdi) + sbbq %r10, %r8 + movq 120(%rsi), %r9 + movq 120(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 112(%rdi) + sbbq %r10, %r9 + movq %r9, 120(%rdi) + sbbq $0, %rax + repz retq +#ifndef __APPLE__ +.size sp_2048_cond_sub_avx2_16,.-sp_2048_cond_sub_avx2_16 +#endif /* __APPLE__ */ /* Mul a by digit b into r. (r = a * b) * * r A single precision integer. @@ -6695,104 +6942,102 @@ sp_2048_mul_d_avx2_16: .p2align 4 _sp_2048_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) + xorq %r10, %r10 + mulxq (%rsi), %r8, %r9 + movq %r8, (%rdi) # A[1] * B - mulxq 8(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 8(%rdi) - adoxq %r8, %r9 + mulxq 8(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 8(%rdi) + adoxq %rcx, %r8 # A[2] * B - mulxq 16(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 16(%rdi) - adoxq %r8, %r10 + mulxq 16(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 16(%rdi) + adoxq %rcx, %r9 # A[3] * B - mulxq 24(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 24(%rdi) - adoxq %r8, %r9 + mulxq 24(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 24(%rdi) + adoxq %rcx, %r8 # A[4] * B - mulxq 32(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 32(%rdi) - adoxq %r8, %r10 + mulxq 32(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 32(%rdi) + adoxq %rcx, %r9 # A[5] * B - mulxq 40(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 40(%rdi) - adoxq %r8, %r9 + mulxq 40(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 40(%rdi) + adoxq %rcx, %r8 # A[6] * B - mulxq 48(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 48(%rdi) - adoxq %r8, %r10 + mulxq 48(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 48(%rdi) + adoxq %rcx, %r9 # A[7] * B - mulxq 56(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 56(%rdi) - adoxq %r8, %r9 + mulxq 56(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 56(%rdi) + adoxq %rcx, %r8 # A[8] * B - mulxq 64(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 64(%rdi) - adoxq %r8, %r10 + mulxq 64(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 64(%rdi) + adoxq %rcx, %r9 # A[9] * B - mulxq 72(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 72(%rdi) - adoxq %r8, %r9 + mulxq 72(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 72(%rdi) + adoxq %rcx, %r8 # A[10] * B - mulxq 80(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 80(%rdi) - adoxq %r8, %r10 + mulxq 80(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 80(%rdi) + adoxq %rcx, %r9 # A[11] * B - mulxq 88(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 88(%rdi) - adoxq %r8, %r9 + mulxq 88(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 88(%rdi) + adoxq %rcx, %r8 # A[12] * B - mulxq 96(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 96(%rdi) - adoxq %r8, %r10 + mulxq 96(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 96(%rdi) + adoxq %rcx, %r9 # A[13] * B - mulxq 104(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 104(%rdi) - adoxq %r8, %r9 + mulxq 104(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 104(%rdi) + adoxq %rcx, %r8 # A[14] * B - mulxq 112(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 112(%rdi) - adoxq %r8, %r10 + mulxq 112(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 112(%rdi) + adoxq %rcx, %r9 # 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) + mulxq 120(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + adoxq %rcx, %r8 + adcxq %r10, %r8 + movq %r9, 120(%rdi) + movq %r8, 128(%rdi) repz retq #ifndef __APPLE__ .size sp_2048_mul_d_avx2_16,.-sp_2048_mul_d_avx2_16 @@ -7094,9 +7339,9 @@ L_mont_loop_avx2_16: movq %rdi, %rdi subq $128, %rdi #ifndef __APPLE__ - callq sp_2048_cond_sub_16@plt + callq sp_2048_cond_sub_avx2_16@plt #else - callq _sp_2048_cond_sub_16 + callq _sp_2048_cond_sub_avx2_16 #endif /* __APPLE__ */ pop %r14 pop %r13 @@ -7727,6 +7972,190 @@ L_mont_loop_32: #ifndef __APPLE__ .size sp_2048_mont_reduce_32,.-sp_2048_mont_reduce_32 #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__ +.globl sp_2048_cond_sub_avx2_32 +.type sp_2048_cond_sub_avx2_32,@function +.align 16 +sp_2048_cond_sub_avx2_32: +#else +.globl _sp_2048_cond_sub_avx2_32 +.p2align 4 +_sp_2048_cond_sub_avx2_32: +#endif /* __APPLE__ */ + movq $0, %rax + movq (%rsi), %r8 + movq (%rdx), %r10 + pextq %rcx, %r10, %r10 + subq %r10, %r8 + movq 8(%rsi), %r9 + movq 8(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, (%rdi) + sbbq %r10, %r9 + movq 16(%rsi), %r8 + movq 16(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 8(%rdi) + sbbq %r10, %r8 + movq 24(%rsi), %r9 + movq 24(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 16(%rdi) + sbbq %r10, %r9 + movq 32(%rsi), %r8 + movq 32(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 24(%rdi) + sbbq %r10, %r8 + movq 40(%rsi), %r9 + movq 40(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 32(%rdi) + sbbq %r10, %r9 + movq 48(%rsi), %r8 + movq 48(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 40(%rdi) + sbbq %r10, %r8 + movq 56(%rsi), %r9 + movq 56(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 48(%rdi) + sbbq %r10, %r9 + movq 64(%rsi), %r8 + movq 64(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 56(%rdi) + sbbq %r10, %r8 + movq 72(%rsi), %r9 + movq 72(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 64(%rdi) + sbbq %r10, %r9 + movq 80(%rsi), %r8 + movq 80(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 72(%rdi) + sbbq %r10, %r8 + movq 88(%rsi), %r9 + movq 88(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 80(%rdi) + sbbq %r10, %r9 + movq 96(%rsi), %r8 + movq 96(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 88(%rdi) + sbbq %r10, %r8 + movq 104(%rsi), %r9 + movq 104(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 96(%rdi) + sbbq %r10, %r9 + movq 112(%rsi), %r8 + movq 112(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 104(%rdi) + sbbq %r10, %r8 + movq 120(%rsi), %r9 + movq 120(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 112(%rdi) + sbbq %r10, %r9 + movq 128(%rsi), %r8 + movq 128(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 120(%rdi) + sbbq %r10, %r8 + movq 136(%rsi), %r9 + movq 136(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 128(%rdi) + sbbq %r10, %r9 + movq 144(%rsi), %r8 + movq 144(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 136(%rdi) + sbbq %r10, %r8 + movq 152(%rsi), %r9 + movq 152(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 144(%rdi) + sbbq %r10, %r9 + movq 160(%rsi), %r8 + movq 160(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 152(%rdi) + sbbq %r10, %r8 + movq 168(%rsi), %r9 + movq 168(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 160(%rdi) + sbbq %r10, %r9 + movq 176(%rsi), %r8 + movq 176(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 168(%rdi) + sbbq %r10, %r8 + movq 184(%rsi), %r9 + movq 184(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 176(%rdi) + sbbq %r10, %r9 + movq 192(%rsi), %r8 + movq 192(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 184(%rdi) + sbbq %r10, %r8 + movq 200(%rsi), %r9 + movq 200(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 192(%rdi) + sbbq %r10, %r9 + movq 208(%rsi), %r8 + movq 208(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 200(%rdi) + sbbq %r10, %r8 + movq 216(%rsi), %r9 + movq 216(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 208(%rdi) + sbbq %r10, %r9 + movq 224(%rsi), %r8 + movq 224(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 216(%rdi) + sbbq %r10, %r8 + movq 232(%rsi), %r9 + movq 232(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 224(%rdi) + sbbq %r10, %r9 + movq 240(%rsi), %r8 + movq 240(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 232(%rdi) + sbbq %r10, %r8 + movq 248(%rsi), %r9 + movq 248(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 240(%rdi) + sbbq %r10, %r9 + movq %r9, 248(%rdi) + sbbq $0, %rax + repz retq +#ifndef __APPLE__ +.size sp_2048_cond_sub_avx2_32,.-sp_2048_cond_sub_avx2_32 +#endif /* __APPLE__ */ #ifdef HAVE_INTEL_AVX2 /* Mul a by digit b into r. (r = a * b) * @@ -7744,200 +8173,198 @@ sp_2048_mul_d_avx2_32: .p2align 4 _sp_2048_mul_d_avx2_32: #endif /* __APPLE__ */ - movq %rdx, %rax # A[0] * B - movq %rax, %rdx - xorq %r11, %r11 - mulxq (%rsi), %r9, %r10 - movq %r9, (%rdi) + xorq %r10, %r10 + mulxq (%rsi), %r8, %r9 + movq %r8, (%rdi) # A[1] * B - mulxq 8(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 8(%rdi) - adoxq %r8, %r9 + mulxq 8(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 8(%rdi) + adoxq %rcx, %r8 # A[2] * B - mulxq 16(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 16(%rdi) - adoxq %r8, %r10 + mulxq 16(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 16(%rdi) + adoxq %rcx, %r9 # A[3] * B - mulxq 24(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 24(%rdi) - adoxq %r8, %r9 + mulxq 24(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 24(%rdi) + adoxq %rcx, %r8 # A[4] * B - mulxq 32(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 32(%rdi) - adoxq %r8, %r10 + mulxq 32(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 32(%rdi) + adoxq %rcx, %r9 # A[5] * B - mulxq 40(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 40(%rdi) - adoxq %r8, %r9 + mulxq 40(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 40(%rdi) + adoxq %rcx, %r8 # A[6] * B - mulxq 48(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 48(%rdi) - adoxq %r8, %r10 + mulxq 48(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 48(%rdi) + adoxq %rcx, %r9 # A[7] * B - mulxq 56(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 56(%rdi) - adoxq %r8, %r9 + mulxq 56(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 56(%rdi) + adoxq %rcx, %r8 # A[8] * B - mulxq 64(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 64(%rdi) - adoxq %r8, %r10 + mulxq 64(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 64(%rdi) + adoxq %rcx, %r9 # A[9] * B - mulxq 72(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 72(%rdi) - adoxq %r8, %r9 + mulxq 72(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 72(%rdi) + adoxq %rcx, %r8 # A[10] * B - mulxq 80(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 80(%rdi) - adoxq %r8, %r10 + mulxq 80(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 80(%rdi) + adoxq %rcx, %r9 # A[11] * B - mulxq 88(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 88(%rdi) - adoxq %r8, %r9 + mulxq 88(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 88(%rdi) + adoxq %rcx, %r8 # A[12] * B - mulxq 96(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 96(%rdi) - adoxq %r8, %r10 + mulxq 96(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 96(%rdi) + adoxq %rcx, %r9 # A[13] * B - mulxq 104(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 104(%rdi) - adoxq %r8, %r9 + mulxq 104(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 104(%rdi) + adoxq %rcx, %r8 # A[14] * B - mulxq 112(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 112(%rdi) - adoxq %r8, %r10 + mulxq 112(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 112(%rdi) + adoxq %rcx, %r9 # A[15] * B - mulxq 120(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 120(%rdi) - adoxq %r8, %r9 + mulxq 120(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 120(%rdi) + adoxq %rcx, %r8 # A[16] * B - mulxq 128(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 128(%rdi) - adoxq %r8, %r10 + mulxq 128(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 128(%rdi) + adoxq %rcx, %r9 # A[17] * B - mulxq 136(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 136(%rdi) - adoxq %r8, %r9 + mulxq 136(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 136(%rdi) + adoxq %rcx, %r8 # A[18] * B - mulxq 144(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 144(%rdi) - adoxq %r8, %r10 + mulxq 144(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 144(%rdi) + adoxq %rcx, %r9 # A[19] * B - mulxq 152(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 152(%rdi) - adoxq %r8, %r9 + mulxq 152(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 152(%rdi) + adoxq %rcx, %r8 # A[20] * B - mulxq 160(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 160(%rdi) - adoxq %r8, %r10 + mulxq 160(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 160(%rdi) + adoxq %rcx, %r9 # A[21] * B - mulxq 168(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 168(%rdi) - adoxq %r8, %r9 + mulxq 168(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 168(%rdi) + adoxq %rcx, %r8 # A[22] * B - mulxq 176(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 176(%rdi) - adoxq %r8, %r10 + mulxq 176(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 176(%rdi) + adoxq %rcx, %r9 # A[23] * B - mulxq 184(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 184(%rdi) - adoxq %r8, %r9 + mulxq 184(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 184(%rdi) + adoxq %rcx, %r8 # A[24] * B - mulxq 192(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 192(%rdi) - adoxq %r8, %r10 + mulxq 192(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 192(%rdi) + adoxq %rcx, %r9 # A[25] * B - mulxq 200(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 200(%rdi) - adoxq %r8, %r9 + mulxq 200(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 200(%rdi) + adoxq %rcx, %r8 # A[26] * B - mulxq 208(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 208(%rdi) - adoxq %r8, %r10 + mulxq 208(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 208(%rdi) + adoxq %rcx, %r9 # A[27] * B - mulxq 216(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 216(%rdi) - adoxq %r8, %r9 + mulxq 216(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 216(%rdi) + adoxq %rcx, %r8 # A[28] * B - mulxq 224(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 224(%rdi) - adoxq %r8, %r10 + mulxq 224(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 224(%rdi) + adoxq %rcx, %r9 # A[29] * B - mulxq 232(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 232(%rdi) - adoxq %r8, %r9 + mulxq 232(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 232(%rdi) + adoxq %rcx, %r8 # A[30] * B - mulxq 240(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 240(%rdi) - adoxq %r8, %r10 + mulxq 240(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 240(%rdi) + adoxq %rcx, %r9 # A[31] * B - mulxq 248(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - adoxq %r8, %r9 - adcxq %r11, %r9 - movq %r10, 248(%rdi) - movq %r9, 256(%rdi) + mulxq 248(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + adoxq %rcx, %r8 + adcxq %r10, %r8 + movq %r9, 248(%rdi) + movq %r8, 256(%rdi) repz retq #ifndef __APPLE__ .size sp_2048_mul_d_avx2_32,.-sp_2048_mul_d_avx2_32 @@ -8225,6 +8652,124 @@ _sp_2048_cmp_32: #ifndef __APPLE__ .size sp_2048_cmp_32,.-sp_2048_cmp_32 #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__ +.globl sp_2048_sub_32 +.type sp_2048_sub_32,@function +.align 16 +sp_2048_sub_32: +#else +.globl _sp_2048_sub_32 +.p2align 4 +_sp_2048_sub_32: +#endif /* __APPLE__ */ + movq (%rsi), %r8 + xorq %rax, %rax + subq (%rdx), %r8 + movq 8(%rsi), %r9 + movq %r8, (%rdi) + sbbq 8(%rdx), %r9 + movq 16(%rsi), %r8 + movq %r9, 8(%rdi) + sbbq 16(%rdx), %r8 + movq 24(%rsi), %r9 + movq %r8, 16(%rdi) + sbbq 24(%rdx), %r9 + movq 32(%rsi), %r8 + movq %r9, 24(%rdi) + sbbq 32(%rdx), %r8 + movq 40(%rsi), %r9 + movq %r8, 32(%rdi) + sbbq 40(%rdx), %r9 + movq 48(%rsi), %r8 + movq %r9, 40(%rdi) + sbbq 48(%rdx), %r8 + movq 56(%rsi), %r9 + movq %r8, 48(%rdi) + sbbq 56(%rdx), %r9 + movq 64(%rsi), %r8 + movq %r9, 56(%rdi) + sbbq 64(%rdx), %r8 + movq 72(%rsi), %r9 + movq %r8, 64(%rdi) + sbbq 72(%rdx), %r9 + movq 80(%rsi), %r8 + movq %r9, 72(%rdi) + sbbq 80(%rdx), %r8 + movq 88(%rsi), %r9 + movq %r8, 80(%rdi) + sbbq 88(%rdx), %r9 + movq 96(%rsi), %r8 + movq %r9, 88(%rdi) + sbbq 96(%rdx), %r8 + movq 104(%rsi), %r9 + movq %r8, 96(%rdi) + sbbq 104(%rdx), %r9 + movq 112(%rsi), %r8 + movq %r9, 104(%rdi) + sbbq 112(%rdx), %r8 + movq 120(%rsi), %r9 + movq %r8, 112(%rdi) + sbbq 120(%rdx), %r9 + movq 128(%rsi), %r8 + movq %r9, 120(%rdi) + sbbq 128(%rdx), %r8 + movq 136(%rsi), %r9 + movq %r8, 128(%rdi) + sbbq 136(%rdx), %r9 + movq 144(%rsi), %r8 + movq %r9, 136(%rdi) + sbbq 144(%rdx), %r8 + movq 152(%rsi), %r9 + movq %r8, 144(%rdi) + sbbq 152(%rdx), %r9 + movq 160(%rsi), %r8 + movq %r9, 152(%rdi) + sbbq 160(%rdx), %r8 + movq 168(%rsi), %r9 + movq %r8, 160(%rdi) + sbbq 168(%rdx), %r9 + movq 176(%rsi), %r8 + movq %r9, 168(%rdi) + sbbq 176(%rdx), %r8 + movq 184(%rsi), %r9 + movq %r8, 176(%rdi) + sbbq 184(%rdx), %r9 + movq 192(%rsi), %r8 + movq %r9, 184(%rdi) + sbbq 192(%rdx), %r8 + movq 200(%rsi), %r9 + movq %r8, 192(%rdi) + sbbq 200(%rdx), %r9 + movq 208(%rsi), %r8 + movq %r9, 200(%rdi) + sbbq 208(%rdx), %r8 + movq 216(%rsi), %r9 + movq %r8, 208(%rdi) + sbbq 216(%rdx), %r9 + movq 224(%rsi), %r8 + movq %r9, 216(%rdi) + sbbq 224(%rdx), %r8 + movq 232(%rsi), %r9 + movq %r8, 224(%rdi) + sbbq 232(%rdx), %r9 + movq 240(%rsi), %r8 + movq %r9, 232(%rdi) + sbbq 240(%rdx), %r8 + movq 248(%rsi), %r9 + movq %r8, 240(%rdi) + sbbq 248(%rdx), %r9 + movq %r9, 248(%rdi) + sbbq $0, %rax + repz retq +#ifndef __APPLE__ +.size sp_2048_sub_32,.-sp_2048_sub_32 +#endif /* __APPLE__ */ #ifdef HAVE_INTEL_AVX2 /* Reduce the number back to 2048 bits using Montgomery reduction. * @@ -8463,9 +9008,9 @@ L_mont_loop_avx2_32: movq %rdi, %rdi subq $256, %rdi #ifndef __APPLE__ - callq sp_2048_cond_sub_32@plt + callq sp_2048_cond_sub_avx2_32@plt #else - callq _sp_2048_cond_sub_32 + callq _sp_2048_cond_sub_avx2_32 #endif /* __APPLE__ */ pop %r14 pop %r13 @@ -8594,6 +9139,204 @@ _sp_2048_lshift_32: repz retq #endif /* !WOLFSSL_SP_NO_2048 */ #ifndef WOLFSSL_SP_NO_3072 +/* 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. + */ +#ifndef __APPLE__ +.globl sp_3072_from_bin +.type sp_3072_from_bin,@function +.align 16 +sp_3072_from_bin: +#else +.globl _sp_3072_from_bin +.p2align 4 +_sp_3072_from_bin: +#endif /* __APPLE__ */ + movq %rdx, %r9 + movq %rdi, %r10 + addq %rcx, %r9 + addq $384, %r10 + xorq %r11, %r11 + jmp L_3072_from_bin_64_end +L_3072_from_bin_64_start: + subq $64, %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 $64, %rdi + subq $64, %rcx +L_3072_from_bin_64_end: + cmpq $63, %rcx + jg L_3072_from_bin_64_start + jmp L_3072_from_bin_8_end +L_3072_from_bin_8_start: + subq $8, %r9 + movbeq (%r9), %rax + movq %rax, (%rdi) + addq $8, %rdi + subq $8, %rcx +L_3072_from_bin_8_end: + cmpq $7, %rcx + jg L_3072_from_bin_8_start + cmpq %r11, %rcx + je L_3072_from_bin_hi_end + movq %r11, %r8 + movq %r11, %rax +L_3072_from_bin_hi_start: + movb (%rdx), %al + shlq $8, %r8 + incq %rdx + addq %rax, %r8 + decq %rcx + jg L_3072_from_bin_hi_start + movq %r8, (%rdi) + addq $8, %rdi +L_3072_from_bin_hi_end: + cmpq %r10, %rdi + je L_3072_from_bin_zero_end +L_3072_from_bin_zero_start: + movq %r11, (%rdi) + addq $8, %rdi + cmpq %r10, %rdi + jl L_3072_from_bin_zero_start +L_3072_from_bin_zero_end: + repz retq +#ifndef __APPLE__ +.size sp_3072_from_bin,.-sp_3072_from_bin +#endif /* __APPLE__ */ +/* Write r as big endian to byte array. + * Fixed length number of bytes written: 384 + * + * r A single precision integer. + * a Byte array. + */ +#ifndef __APPLE__ +.globl sp_3072_to_bin +.type sp_3072_to_bin,@function +.align 16 +sp_3072_to_bin: +#else +.globl _sp_3072_to_bin +.p2align 4 +_sp_3072_to_bin: +#endif /* __APPLE__ */ + movbeq 376(%rdi), %rdx + movbeq 368(%rdi), %rax + movq %rdx, (%rsi) + movq %rax, 8(%rsi) + movbeq 360(%rdi), %rdx + movbeq 352(%rdi), %rax + movq %rdx, 16(%rsi) + movq %rax, 24(%rsi) + movbeq 344(%rdi), %rdx + movbeq 336(%rdi), %rax + movq %rdx, 32(%rsi) + movq %rax, 40(%rsi) + movbeq 328(%rdi), %rdx + movbeq 320(%rdi), %rax + movq %rdx, 48(%rsi) + movq %rax, 56(%rsi) + movbeq 312(%rdi), %rdx + movbeq 304(%rdi), %rax + movq %rdx, 64(%rsi) + movq %rax, 72(%rsi) + movbeq 296(%rdi), %rdx + movbeq 288(%rdi), %rax + movq %rdx, 80(%rsi) + movq %rax, 88(%rsi) + movbeq 280(%rdi), %rdx + movbeq 272(%rdi), %rax + movq %rdx, 96(%rsi) + movq %rax, 104(%rsi) + movbeq 264(%rdi), %rdx + movbeq 256(%rdi), %rax + movq %rdx, 112(%rsi) + movq %rax, 120(%rsi) + movbeq 248(%rdi), %rdx + movbeq 240(%rdi), %rax + movq %rdx, 128(%rsi) + movq %rax, 136(%rsi) + movbeq 232(%rdi), %rdx + movbeq 224(%rdi), %rax + movq %rdx, 144(%rsi) + movq %rax, 152(%rsi) + movbeq 216(%rdi), %rdx + movbeq 208(%rdi), %rax + movq %rdx, 160(%rsi) + movq %rax, 168(%rsi) + movbeq 200(%rdi), %rdx + movbeq 192(%rdi), %rax + movq %rdx, 176(%rsi) + movq %rax, 184(%rsi) + movbeq 184(%rdi), %rdx + movbeq 176(%rdi), %rax + movq %rdx, 192(%rsi) + movq %rax, 200(%rsi) + movbeq 168(%rdi), %rdx + movbeq 160(%rdi), %rax + movq %rdx, 208(%rsi) + movq %rax, 216(%rsi) + movbeq 152(%rdi), %rdx + movbeq 144(%rdi), %rax + movq %rdx, 224(%rsi) + movq %rax, 232(%rsi) + movbeq 136(%rdi), %rdx + movbeq 128(%rdi), %rax + movq %rdx, 240(%rsi) + movq %rax, 248(%rsi) + movbeq 120(%rdi), %rdx + movbeq 112(%rdi), %rax + movq %rdx, 256(%rsi) + movq %rax, 264(%rsi) + movbeq 104(%rdi), %rdx + movbeq 96(%rdi), %rax + movq %rdx, 272(%rsi) + movq %rax, 280(%rsi) + movbeq 88(%rdi), %rdx + movbeq 80(%rdi), %rax + movq %rdx, 288(%rsi) + movq %rax, 296(%rsi) + movbeq 72(%rdi), %rdx + movbeq 64(%rdi), %rax + movq %rdx, 304(%rsi) + movq %rax, 312(%rsi) + movbeq 56(%rdi), %rdx + movbeq 48(%rdi), %rax + movq %rdx, 320(%rsi) + movq %rax, 328(%rsi) + movbeq 40(%rdi), %rdx + movbeq 32(%rdi), %rax + movq %rdx, 336(%rsi) + movq %rax, 344(%rsi) + movbeq 24(%rdi), %rdx + movbeq 16(%rdi), %rax + movq %rdx, 352(%rsi) + movq %rax, 360(%rsi) + movbeq 8(%rdi), %rdx + movbeq (%rdi), %rax + movq %rdx, 368(%rsi) + movq %rax, 376(%rsi) + repz retq +#ifndef __APPLE__ +.size sp_3072_to_bin,.-sp_3072_to_bin +#endif /* __APPLE__ */ /* Multiply a and b into r. (r = a * b) * * r A single precision integer. @@ -18028,54 +18771,20 @@ _sp_3072_mul_avx2_24: adcxq %r13, %r10 movq %r9, 368(%rdi) movq %r10, 376(%rdi) - movq (%rsp), %r8 - movq 8(%rsp), %r9 - movq 16(%rsp), %r10 - movq 24(%rsp), %r11 - movq %r8, (%rdi) - movq %r9, 8(%rdi) - movq %r10, 16(%rdi) - movq %r11, 24(%rdi) - movq 32(%rsp), %r8 - movq 40(%rsp), %r9 - movq 48(%rsp), %r10 - movq 56(%rsp), %r11 - movq %r8, 32(%rdi) - movq %r9, 40(%rdi) - movq %r10, 48(%rdi) - movq %r11, 56(%rdi) - movq 64(%rsp), %r8 - movq 72(%rsp), %r9 - movq 80(%rsp), %r10 - movq 88(%rsp), %r11 - movq %r8, 64(%rdi) - movq %r9, 72(%rdi) - movq %r10, 80(%rdi) - movq %r11, 88(%rdi) - movq 96(%rsp), %r8 - movq 104(%rsp), %r9 - movq 112(%rsp), %r10 - movq 120(%rsp), %r11 - movq %r8, 96(%rdi) - movq %r9, 104(%rdi) - movq %r10, 112(%rdi) - movq %r11, 120(%rdi) - movq 128(%rsp), %r8 - movq 136(%rsp), %r9 - movq 144(%rsp), %r10 - movq 152(%rsp), %r11 - movq %r8, 128(%rdi) - movq %r9, 136(%rdi) - movq %r10, 144(%rdi) - movq %r11, 152(%rdi) - movq 160(%rsp), %r8 - movq 168(%rsp), %r9 - movq %r15, %r10 - movq %rbx, %r11 - movq %r8, 160(%rdi) - movq %r9, 168(%rdi) - movq %r10, 176(%rdi) - movq %r11, 184(%rdi) + vmovdqu (%rsp), %ymm0 + vmovdqu 32(%rsp), %ymm1 + vmovdqu 64(%rsp), %ymm2 + vmovdqu 96(%rsp), %ymm3 + vmovdqu 128(%rsp), %ymm4 + vmovdqu 160(%rsp), %xmm5 + vmovdqu %ymm0, (%rdi) + vmovdqu %ymm1, 32(%rdi) + vmovdqu %ymm2, 64(%rdi) + vmovdqu %ymm3, 96(%rdi) + vmovdqu %ymm4, 128(%rdi) + vmovdqu %xmm5, 160(%rdi) + movq %r15, 176(%rdi) + movq %rbx, 184(%rdi) addq $192, %rsp pop %rbx pop %r15 @@ -20154,54 +20863,20 @@ _sp_3072_sqr_avx2_24: movq %r9, 376(%rdi) cmpq %rdi, %rsi jne L_end_3072_sqr_avx2_24 - movq (%rbp), %r8 - movq 8(%rbp), %r9 - movq 16(%rbp), %r10 - movq 24(%rbp), %r11 - movq %r8, (%rdi) - movq %r9, 8(%rdi) - movq %r10, 16(%rdi) - movq %r11, 24(%rdi) - movq 32(%rbp), %r8 - movq 40(%rbp), %r9 - movq 48(%rbp), %r10 - movq 56(%rbp), %r11 - movq %r8, 32(%rdi) - movq %r9, 40(%rdi) - movq %r10, 48(%rdi) - movq %r11, 56(%rdi) - movq 64(%rbp), %r8 - movq 72(%rbp), %r9 - movq 80(%rbp), %r10 - movq 88(%rbp), %r11 - movq %r8, 64(%rdi) - movq %r9, 72(%rdi) - movq %r10, 80(%rdi) - movq %r11, 88(%rdi) - movq 96(%rbp), %r8 - movq 104(%rbp), %r9 - movq 112(%rbp), %r10 - movq 120(%rbp), %r11 - movq %r8, 96(%rdi) - movq %r9, 104(%rdi) - movq %r10, 112(%rdi) - movq %r11, 120(%rdi) - movq 128(%rbp), %r8 - movq 136(%rbp), %r9 - movq 144(%rbp), %r10 - movq 152(%rbp), %r11 - movq %r8, 128(%rdi) - movq %r9, 136(%rdi) - movq %r10, 144(%rdi) - movq %r11, 152(%rdi) - movq 160(%rbp), %r8 - movq 168(%rbp), %r9 - movq 176(%rbp), %r10 - movq 184(%rbp), %r11 - movq %r8, 160(%rdi) - movq %r9, 168(%rdi) - movq %r10, 176(%rdi) - movq %r11, 184(%rdi) + vmovdqu (%rbp), %ymm0 + vmovdqu 32(%rbp), %ymm1 + vmovdqu 64(%rbp), %ymm2 + vmovdqu 96(%rbp), %ymm3 + vmovdqu 128(%rbp), %ymm4 + vmovdqu 160(%rbp), %ymm5 + vmovdqu 192(%rdi), %ymm6 + vmovdqu %ymm0, (%rdi) + vmovdqu %ymm1, 32(%rdi) + vmovdqu %ymm2, 64(%rdi) + vmovdqu %ymm3, 96(%rdi) + vmovdqu %ymm4, 128(%rdi) + vmovdqu %ymm5, 160(%rdi) + vmovdqu %ymm6, 192(%rdi) L_end_3072_sqr_avx2_24: addq $192, %rsp pop %r13 @@ -20228,79 +20903,79 @@ sp_3072_add_24: .p2align 4 _sp_3072_add_24: #endif /* __APPLE__ */ - xorq %rax, %rax movq (%rsi), %rcx + xorq %rax, %rax addq (%rdx), %rcx + movq 8(%rsi), %r8 movq %rcx, (%rdi) - movq 8(%rsi), %rcx - adcq 8(%rdx), %rcx - movq %rcx, 8(%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) - movq 24(%rsi), %rcx - adcq 24(%rdx), %rcx - movq %rcx, 24(%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) - movq 40(%rsi), %rcx - adcq 40(%rdx), %rcx - movq %rcx, 40(%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) - movq 56(%rsi), %rcx - adcq 56(%rdx), %rcx - movq %rcx, 56(%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) - movq 72(%rsi), %rcx - adcq 72(%rdx), %rcx - movq %rcx, 72(%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) - movq 88(%rsi), %rcx - adcq 88(%rdx), %rcx - movq %rcx, 88(%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) - movq 104(%rsi), %rcx - adcq 104(%rdx), %rcx - movq %rcx, 104(%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) - movq 120(%rsi), %rcx - adcq 120(%rdx), %rcx - movq %rcx, 120(%rdi) + adcq 120(%rdx), %r8 movq 128(%rsi), %rcx + movq %r8, 120(%rdi) adcq 128(%rdx), %rcx + movq 136(%rsi), %r8 movq %rcx, 128(%rdi) - movq 136(%rsi), %rcx - adcq 136(%rdx), %rcx - movq %rcx, 136(%rdi) + adcq 136(%rdx), %r8 movq 144(%rsi), %rcx + movq %r8, 136(%rdi) adcq 144(%rdx), %rcx + movq 152(%rsi), %r8 movq %rcx, 144(%rdi) - movq 152(%rsi), %rcx - adcq 152(%rdx), %rcx - movq %rcx, 152(%rdi) + adcq 152(%rdx), %r8 movq 160(%rsi), %rcx + movq %r8, 152(%rdi) adcq 160(%rdx), %rcx + movq 168(%rsi), %r8 movq %rcx, 160(%rdi) - movq 168(%rsi), %rcx - adcq 168(%rdx), %rcx - movq %rcx, 168(%rdi) + adcq 168(%rdx), %r8 movq 176(%rsi), %rcx + movq %r8, 168(%rdi) adcq 176(%rdx), %rcx + movq 184(%rsi), %r8 movq %rcx, 176(%rdi) - movq 184(%rsi), %rcx - adcq 184(%rdx), %rcx - movq %rcx, 184(%rdi) + adcq 184(%rdx), %r8 + movq %r8, 184(%rdi) adcq $0, %rax repz retq #ifndef __APPLE__ @@ -20321,198 +20996,150 @@ sp_3072_sub_in_place_48: .p2align 4 _sp_3072_sub_in_place_48: #endif /* __APPLE__ */ - xorq %rax, %rax movq (%rdi), %rdx + xorq %rax, %rax + subq (%rsi), %rdx movq 8(%rdi), %rcx - movq (%rsi), %r8 - movq 8(%rsi), %r9 - subq %r8, %rdx - movq 16(%rsi), %r8 movq %rdx, (%rdi) + sbbq 8(%rsi), %rcx movq 16(%rdi), %rdx - sbbq %r9, %rcx - movq 24(%rsi), %r9 movq %rcx, 8(%rdi) + sbbq 16(%rsi), %rdx movq 24(%rdi), %rcx - sbbq %r8, %rdx - movq 32(%rsi), %r8 movq %rdx, 16(%rdi) + sbbq 24(%rsi), %rcx movq 32(%rdi), %rdx - sbbq %r9, %rcx - movq 40(%rsi), %r9 movq %rcx, 24(%rdi) + sbbq 32(%rsi), %rdx movq 40(%rdi), %rcx - sbbq %r8, %rdx - movq 48(%rsi), %r8 movq %rdx, 32(%rdi) + sbbq 40(%rsi), %rcx movq 48(%rdi), %rdx - sbbq %r9, %rcx - movq 56(%rsi), %r9 movq %rcx, 40(%rdi) + sbbq 48(%rsi), %rdx movq 56(%rdi), %rcx - sbbq %r8, %rdx - movq 64(%rsi), %r8 movq %rdx, 48(%rdi) + sbbq 56(%rsi), %rcx movq 64(%rdi), %rdx - sbbq %r9, %rcx - movq 72(%rsi), %r9 movq %rcx, 56(%rdi) + sbbq 64(%rsi), %rdx movq 72(%rdi), %rcx - sbbq %r8, %rdx - movq 80(%rsi), %r8 movq %rdx, 64(%rdi) + sbbq 72(%rsi), %rcx movq 80(%rdi), %rdx - sbbq %r9, %rcx - movq 88(%rsi), %r9 movq %rcx, 72(%rdi) + sbbq 80(%rsi), %rdx movq 88(%rdi), %rcx - sbbq %r8, %rdx - movq 96(%rsi), %r8 movq %rdx, 80(%rdi) + sbbq 88(%rsi), %rcx movq 96(%rdi), %rdx - sbbq %r9, %rcx - movq 104(%rsi), %r9 movq %rcx, 88(%rdi) + sbbq 96(%rsi), %rdx movq 104(%rdi), %rcx - sbbq %r8, %rdx - movq 112(%rsi), %r8 movq %rdx, 96(%rdi) + sbbq 104(%rsi), %rcx movq 112(%rdi), %rdx - sbbq %r9, %rcx - movq 120(%rsi), %r9 movq %rcx, 104(%rdi) + sbbq 112(%rsi), %rdx movq 120(%rdi), %rcx - sbbq %r8, %rdx - movq 128(%rsi), %r8 movq %rdx, 112(%rdi) + sbbq 120(%rsi), %rcx movq 128(%rdi), %rdx - sbbq %r9, %rcx - movq 136(%rsi), %r9 movq %rcx, 120(%rdi) + sbbq 128(%rsi), %rdx movq 136(%rdi), %rcx - sbbq %r8, %rdx - movq 144(%rsi), %r8 movq %rdx, 128(%rdi) + sbbq 136(%rsi), %rcx movq 144(%rdi), %rdx - sbbq %r9, %rcx - movq 152(%rsi), %r9 movq %rcx, 136(%rdi) + sbbq 144(%rsi), %rdx movq 152(%rdi), %rcx - sbbq %r8, %rdx - movq 160(%rsi), %r8 movq %rdx, 144(%rdi) + sbbq 152(%rsi), %rcx movq 160(%rdi), %rdx - sbbq %r9, %rcx - movq 168(%rsi), %r9 movq %rcx, 152(%rdi) + sbbq 160(%rsi), %rdx movq 168(%rdi), %rcx - sbbq %r8, %rdx - movq 176(%rsi), %r8 movq %rdx, 160(%rdi) + sbbq 168(%rsi), %rcx movq 176(%rdi), %rdx - sbbq %r9, %rcx - movq 184(%rsi), %r9 movq %rcx, 168(%rdi) + sbbq 176(%rsi), %rdx movq 184(%rdi), %rcx - sbbq %r8, %rdx - movq 192(%rsi), %r8 movq %rdx, 176(%rdi) + sbbq 184(%rsi), %rcx movq 192(%rdi), %rdx - sbbq %r9, %rcx - movq 200(%rsi), %r9 movq %rcx, 184(%rdi) + sbbq 192(%rsi), %rdx movq 200(%rdi), %rcx - sbbq %r8, %rdx - movq 208(%rsi), %r8 movq %rdx, 192(%rdi) + sbbq 200(%rsi), %rcx movq 208(%rdi), %rdx - sbbq %r9, %rcx - movq 216(%rsi), %r9 movq %rcx, 200(%rdi) + sbbq 208(%rsi), %rdx movq 216(%rdi), %rcx - sbbq %r8, %rdx - movq 224(%rsi), %r8 movq %rdx, 208(%rdi) + sbbq 216(%rsi), %rcx movq 224(%rdi), %rdx - sbbq %r9, %rcx - movq 232(%rsi), %r9 movq %rcx, 216(%rdi) + sbbq 224(%rsi), %rdx movq 232(%rdi), %rcx - sbbq %r8, %rdx - movq 240(%rsi), %r8 movq %rdx, 224(%rdi) + sbbq 232(%rsi), %rcx movq 240(%rdi), %rdx - sbbq %r9, %rcx - movq 248(%rsi), %r9 movq %rcx, 232(%rdi) + sbbq 240(%rsi), %rdx movq 248(%rdi), %rcx - sbbq %r8, %rdx - movq 256(%rsi), %r8 movq %rdx, 240(%rdi) + sbbq 248(%rsi), %rcx movq 256(%rdi), %rdx - sbbq %r9, %rcx - movq 264(%rsi), %r9 movq %rcx, 248(%rdi) + sbbq 256(%rsi), %rdx movq 264(%rdi), %rcx - sbbq %r8, %rdx - movq 272(%rsi), %r8 movq %rdx, 256(%rdi) + sbbq 264(%rsi), %rcx movq 272(%rdi), %rdx - sbbq %r9, %rcx - movq 280(%rsi), %r9 movq %rcx, 264(%rdi) + sbbq 272(%rsi), %rdx movq 280(%rdi), %rcx - sbbq %r8, %rdx - movq 288(%rsi), %r8 movq %rdx, 272(%rdi) + sbbq 280(%rsi), %rcx movq 288(%rdi), %rdx - sbbq %r9, %rcx - movq 296(%rsi), %r9 movq %rcx, 280(%rdi) + sbbq 288(%rsi), %rdx movq 296(%rdi), %rcx - sbbq %r8, %rdx - movq 304(%rsi), %r8 movq %rdx, 288(%rdi) + sbbq 296(%rsi), %rcx movq 304(%rdi), %rdx - sbbq %r9, %rcx - movq 312(%rsi), %r9 movq %rcx, 296(%rdi) + sbbq 304(%rsi), %rdx movq 312(%rdi), %rcx - sbbq %r8, %rdx - movq 320(%rsi), %r8 movq %rdx, 304(%rdi) + sbbq 312(%rsi), %rcx movq 320(%rdi), %rdx - sbbq %r9, %rcx - movq 328(%rsi), %r9 movq %rcx, 312(%rdi) + sbbq 320(%rsi), %rdx movq 328(%rdi), %rcx - sbbq %r8, %rdx - movq 336(%rsi), %r8 movq %rdx, 320(%rdi) + sbbq 328(%rsi), %rcx movq 336(%rdi), %rdx - sbbq %r9, %rcx - movq 344(%rsi), %r9 movq %rcx, 328(%rdi) + sbbq 336(%rsi), %rdx movq 344(%rdi), %rcx - sbbq %r8, %rdx - movq 352(%rsi), %r8 movq %rdx, 336(%rdi) + sbbq 344(%rsi), %rcx movq 352(%rdi), %rdx - sbbq %r9, %rcx - movq 360(%rsi), %r9 movq %rcx, 344(%rdi) + sbbq 352(%rsi), %rdx movq 360(%rdi), %rcx - sbbq %r8, %rdx - movq 368(%rsi), %r8 movq %rdx, 352(%rdi) + sbbq 360(%rsi), %rcx movq 368(%rdi), %rdx - sbbq %r9, %rcx - movq 376(%rsi), %r9 movq %rcx, 360(%rdi) + sbbq 368(%rsi), %rdx movq 376(%rdi), %rcx - sbbq %r8, %rdx movq %rdx, 368(%rdi) - sbbq %r9, %rcx + sbbq 376(%rsi), %rcx movq %rcx, 376(%rdi) sbbq $0, %rax repz retq @@ -20535,156 +21162,249 @@ sp_3072_add_48: .p2align 4 _sp_3072_add_48: #endif /* __APPLE__ */ - xorq %rax, %rax movq (%rsi), %rcx + xorq %rax, %rax addq (%rdx), %rcx + movq 8(%rsi), %r8 movq %rcx, (%rdi) - movq 8(%rsi), %rcx - adcq 8(%rdx), %rcx - movq %rcx, 8(%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) - movq 24(%rsi), %rcx - adcq 24(%rdx), %rcx - movq %rcx, 24(%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) - movq 40(%rsi), %rcx - adcq 40(%rdx), %rcx - movq %rcx, 40(%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) - movq 56(%rsi), %rcx - adcq 56(%rdx), %rcx - movq %rcx, 56(%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) - movq 72(%rsi), %rcx - adcq 72(%rdx), %rcx - movq %rcx, 72(%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) - movq 88(%rsi), %rcx - adcq 88(%rdx), %rcx - movq %rcx, 88(%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) - movq 104(%rsi), %rcx - adcq 104(%rdx), %rcx - movq %rcx, 104(%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) - movq 120(%rsi), %rcx - adcq 120(%rdx), %rcx - movq %rcx, 120(%rdi) + adcq 120(%rdx), %r8 movq 128(%rsi), %rcx + movq %r8, 120(%rdi) adcq 128(%rdx), %rcx + movq 136(%rsi), %r8 movq %rcx, 128(%rdi) - movq 136(%rsi), %rcx - adcq 136(%rdx), %rcx - movq %rcx, 136(%rdi) + adcq 136(%rdx), %r8 movq 144(%rsi), %rcx + movq %r8, 136(%rdi) adcq 144(%rdx), %rcx + movq 152(%rsi), %r8 movq %rcx, 144(%rdi) - movq 152(%rsi), %rcx - adcq 152(%rdx), %rcx - movq %rcx, 152(%rdi) + adcq 152(%rdx), %r8 movq 160(%rsi), %rcx + movq %r8, 152(%rdi) adcq 160(%rdx), %rcx + movq 168(%rsi), %r8 movq %rcx, 160(%rdi) - movq 168(%rsi), %rcx - adcq 168(%rdx), %rcx - movq %rcx, 168(%rdi) + adcq 168(%rdx), %r8 movq 176(%rsi), %rcx + movq %r8, 168(%rdi) adcq 176(%rdx), %rcx + movq 184(%rsi), %r8 movq %rcx, 176(%rdi) - movq 184(%rsi), %rcx - adcq 184(%rdx), %rcx - movq %rcx, 184(%rdi) + adcq 184(%rdx), %r8 movq 192(%rsi), %rcx + movq %r8, 184(%rdi) adcq 192(%rdx), %rcx + movq 200(%rsi), %r8 movq %rcx, 192(%rdi) - movq 200(%rsi), %rcx - adcq 200(%rdx), %rcx - movq %rcx, 200(%rdi) + adcq 200(%rdx), %r8 movq 208(%rsi), %rcx + movq %r8, 200(%rdi) adcq 208(%rdx), %rcx + movq 216(%rsi), %r8 movq %rcx, 208(%rdi) - movq 216(%rsi), %rcx - adcq 216(%rdx), %rcx - movq %rcx, 216(%rdi) + adcq 216(%rdx), %r8 movq 224(%rsi), %rcx + movq %r8, 216(%rdi) adcq 224(%rdx), %rcx + movq 232(%rsi), %r8 movq %rcx, 224(%rdi) - movq 232(%rsi), %rcx - adcq 232(%rdx), %rcx - movq %rcx, 232(%rdi) + adcq 232(%rdx), %r8 movq 240(%rsi), %rcx + movq %r8, 232(%rdi) adcq 240(%rdx), %rcx + movq 248(%rsi), %r8 movq %rcx, 240(%rdi) - movq 248(%rsi), %rcx - adcq 248(%rdx), %rcx - movq %rcx, 248(%rdi) + adcq 248(%rdx), %r8 movq 256(%rsi), %rcx + movq %r8, 248(%rdi) adcq 256(%rdx), %rcx + movq 264(%rsi), %r8 movq %rcx, 256(%rdi) - movq 264(%rsi), %rcx - adcq 264(%rdx), %rcx - movq %rcx, 264(%rdi) + adcq 264(%rdx), %r8 movq 272(%rsi), %rcx + movq %r8, 264(%rdi) adcq 272(%rdx), %rcx + movq 280(%rsi), %r8 movq %rcx, 272(%rdi) - movq 280(%rsi), %rcx - adcq 280(%rdx), %rcx - movq %rcx, 280(%rdi) + adcq 280(%rdx), %r8 movq 288(%rsi), %rcx + movq %r8, 280(%rdi) adcq 288(%rdx), %rcx + movq 296(%rsi), %r8 movq %rcx, 288(%rdi) - movq 296(%rsi), %rcx - adcq 296(%rdx), %rcx - movq %rcx, 296(%rdi) + adcq 296(%rdx), %r8 movq 304(%rsi), %rcx + movq %r8, 296(%rdi) adcq 304(%rdx), %rcx + movq 312(%rsi), %r8 movq %rcx, 304(%rdi) - movq 312(%rsi), %rcx - adcq 312(%rdx), %rcx - movq %rcx, 312(%rdi) + adcq 312(%rdx), %r8 movq 320(%rsi), %rcx + movq %r8, 312(%rdi) adcq 320(%rdx), %rcx + movq 328(%rsi), %r8 movq %rcx, 320(%rdi) - movq 328(%rsi), %rcx - adcq 328(%rdx), %rcx - movq %rcx, 328(%rdi) + adcq 328(%rdx), %r8 movq 336(%rsi), %rcx + movq %r8, 328(%rdi) adcq 336(%rdx), %rcx + movq 344(%rsi), %r8 movq %rcx, 336(%rdi) - movq 344(%rsi), %rcx - adcq 344(%rdx), %rcx - movq %rcx, 344(%rdi) + adcq 344(%rdx), %r8 movq 352(%rsi), %rcx + movq %r8, 344(%rdi) adcq 352(%rdx), %rcx + movq 360(%rsi), %r8 movq %rcx, 352(%rdi) - movq 360(%rsi), %rcx - adcq 360(%rdx), %rcx - movq %rcx, 360(%rdi) + adcq 360(%rdx), %r8 movq 368(%rsi), %rcx + movq %r8, 360(%rdi) adcq 368(%rdx), %rcx + movq 376(%rsi), %r8 movq %rcx, 368(%rdi) - movq 376(%rsi), %rcx - adcq 376(%rdx), %rcx - movq %rcx, 376(%rdi) + adcq 376(%rdx), %r8 + movq %r8, 376(%rdi) adcq $0, %rax repz retq #ifndef __APPLE__ .size sp_3072_add_48,.-sp_3072_add_48 #endif /* __APPLE__ */ +/* Add a to a into r. (r = a + a) + * + * r A single precision integer. + * a A single precision integer. + */ +#ifndef __APPLE__ +.globl sp_3072_dbl_24 +.type sp_3072_dbl_24,@function +.align 16 +sp_3072_dbl_24: +#else +.globl _sp_3072_dbl_24 +.p2align 4 +_sp_3072_dbl_24: +#endif /* __APPLE__ */ + movq (%rsi), %rdx + xorq %rax, %rax + addq %rdx, %rdx + movq 8(%rsi), %rcx + movq %rdx, (%rdi) + adcq %rcx, %rcx + movq 16(%rsi), %rdx + movq %rcx, 8(%rdi) + adcq %rdx, %rdx + movq 24(%rsi), %rcx + movq %rdx, 16(%rdi) + adcq %rcx, %rcx + movq 32(%rsi), %rdx + movq %rcx, 24(%rdi) + adcq %rdx, %rdx + movq 40(%rsi), %rcx + movq %rdx, 32(%rdi) + adcq %rcx, %rcx + movq 48(%rsi), %rdx + movq %rcx, 40(%rdi) + adcq %rdx, %rdx + movq 56(%rsi), %rcx + movq %rdx, 48(%rdi) + adcq %rcx, %rcx + movq 64(%rsi), %rdx + movq %rcx, 56(%rdi) + adcq %rdx, %rdx + movq 72(%rsi), %rcx + movq %rdx, 64(%rdi) + adcq %rcx, %rcx + movq 80(%rsi), %rdx + movq %rcx, 72(%rdi) + adcq %rdx, %rdx + movq 88(%rsi), %rcx + movq %rdx, 80(%rdi) + adcq %rcx, %rcx + movq 96(%rsi), %rdx + movq %rcx, 88(%rdi) + adcq %rdx, %rdx + movq 104(%rsi), %rcx + movq %rdx, 96(%rdi) + adcq %rcx, %rcx + movq 112(%rsi), %rdx + movq %rcx, 104(%rdi) + adcq %rdx, %rdx + movq 120(%rsi), %rcx + movq %rdx, 112(%rdi) + adcq %rcx, %rcx + movq 128(%rsi), %rdx + movq %rcx, 120(%rdi) + adcq %rdx, %rdx + movq 136(%rsi), %rcx + movq %rdx, 128(%rdi) + adcq %rcx, %rcx + movq 144(%rsi), %rdx + movq %rcx, 136(%rdi) + adcq %rdx, %rdx + movq 152(%rsi), %rcx + movq %rdx, 144(%rdi) + adcq %rcx, %rcx + movq 160(%rsi), %rdx + movq %rcx, 152(%rdi) + adcq %rdx, %rdx + movq 168(%rsi), %rcx + movq %rdx, 160(%rdi) + adcq %rcx, %rcx + movq 176(%rsi), %rdx + movq %rcx, 168(%rdi) + adcq %rdx, %rdx + movq 184(%rsi), %rcx + movq %rdx, 176(%rdi) + adcq %rcx, %rcx + movq %rcx, 184(%rdi) + adcq $0, %rax + repz retq +#ifndef __APPLE__ +.size sp_3072_dbl_24,.-sp_3072_dbl_24 +#endif /* __APPLE__ */ /* Mul a by digit b into r. (r = a * b) * * r A single precision integer. @@ -21103,102 +21823,78 @@ sp_3072_sub_in_place_24: .p2align 4 _sp_3072_sub_in_place_24: #endif /* __APPLE__ */ - xorq %rax, %rax movq (%rdi), %rdx + xorq %rax, %rax + subq (%rsi), %rdx movq 8(%rdi), %rcx - movq (%rsi), %r8 - movq 8(%rsi), %r9 - subq %r8, %rdx - movq 16(%rsi), %r8 movq %rdx, (%rdi) + sbbq 8(%rsi), %rcx movq 16(%rdi), %rdx - sbbq %r9, %rcx - movq 24(%rsi), %r9 movq %rcx, 8(%rdi) + sbbq 16(%rsi), %rdx movq 24(%rdi), %rcx - sbbq %r8, %rdx - movq 32(%rsi), %r8 movq %rdx, 16(%rdi) + sbbq 24(%rsi), %rcx movq 32(%rdi), %rdx - sbbq %r9, %rcx - movq 40(%rsi), %r9 movq %rcx, 24(%rdi) + sbbq 32(%rsi), %rdx movq 40(%rdi), %rcx - sbbq %r8, %rdx - movq 48(%rsi), %r8 movq %rdx, 32(%rdi) + sbbq 40(%rsi), %rcx movq 48(%rdi), %rdx - sbbq %r9, %rcx - movq 56(%rsi), %r9 movq %rcx, 40(%rdi) + sbbq 48(%rsi), %rdx movq 56(%rdi), %rcx - sbbq %r8, %rdx - movq 64(%rsi), %r8 movq %rdx, 48(%rdi) + sbbq 56(%rsi), %rcx movq 64(%rdi), %rdx - sbbq %r9, %rcx - movq 72(%rsi), %r9 movq %rcx, 56(%rdi) + sbbq 64(%rsi), %rdx movq 72(%rdi), %rcx - sbbq %r8, %rdx - movq 80(%rsi), %r8 movq %rdx, 64(%rdi) + sbbq 72(%rsi), %rcx movq 80(%rdi), %rdx - sbbq %r9, %rcx - movq 88(%rsi), %r9 movq %rcx, 72(%rdi) + sbbq 80(%rsi), %rdx movq 88(%rdi), %rcx - sbbq %r8, %rdx - movq 96(%rsi), %r8 movq %rdx, 80(%rdi) + sbbq 88(%rsi), %rcx movq 96(%rdi), %rdx - sbbq %r9, %rcx - movq 104(%rsi), %r9 movq %rcx, 88(%rdi) + sbbq 96(%rsi), %rdx movq 104(%rdi), %rcx - sbbq %r8, %rdx - movq 112(%rsi), %r8 movq %rdx, 96(%rdi) + sbbq 104(%rsi), %rcx movq 112(%rdi), %rdx - sbbq %r9, %rcx - movq 120(%rsi), %r9 movq %rcx, 104(%rdi) + sbbq 112(%rsi), %rdx movq 120(%rdi), %rcx - sbbq %r8, %rdx - movq 128(%rsi), %r8 movq %rdx, 112(%rdi) + sbbq 120(%rsi), %rcx movq 128(%rdi), %rdx - sbbq %r9, %rcx - movq 136(%rsi), %r9 movq %rcx, 120(%rdi) + sbbq 128(%rsi), %rdx movq 136(%rdi), %rcx - sbbq %r8, %rdx - movq 144(%rsi), %r8 movq %rdx, 128(%rdi) + sbbq 136(%rsi), %rcx movq 144(%rdi), %rdx - sbbq %r9, %rcx - movq 152(%rsi), %r9 movq %rcx, 136(%rdi) + sbbq 144(%rsi), %rdx movq 152(%rdi), %rcx - sbbq %r8, %rdx - movq 160(%rsi), %r8 movq %rdx, 144(%rdi) + sbbq 152(%rsi), %rcx movq 160(%rdi), %rdx - sbbq %r9, %rcx - movq 168(%rsi), %r9 movq %rcx, 152(%rdi) + sbbq 160(%rsi), %rdx movq 168(%rdi), %rcx - sbbq %r8, %rdx - movq 176(%rsi), %r8 movq %rdx, 160(%rdi) + sbbq 168(%rsi), %rcx movq 176(%rdi), %rdx - sbbq %r9, %rcx - movq 184(%rsi), %r9 movq %rcx, 168(%rdi) + sbbq 176(%rsi), %rdx movq 184(%rdi), %rcx - sbbq %r8, %rdx movq %rdx, 176(%rdi) - sbbq %r9, %rcx + sbbq 184(%rsi), %rcx movq %rcx, 184(%rdi) sbbq $0, %rax repz retq @@ -21690,6 +22386,150 @@ L_mont_loop_24: #ifndef __APPLE__ .size sp_3072_mont_reduce_24,.-sp_3072_mont_reduce_24 #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__ +.globl sp_3072_cond_sub_avx2_24 +.type sp_3072_cond_sub_avx2_24,@function +.align 16 +sp_3072_cond_sub_avx2_24: +#else +.globl _sp_3072_cond_sub_avx2_24 +.p2align 4 +_sp_3072_cond_sub_avx2_24: +#endif /* __APPLE__ */ + movq $0, %rax + movq (%rsi), %r8 + movq (%rdx), %r10 + pextq %rcx, %r10, %r10 + subq %r10, %r8 + movq 8(%rsi), %r9 + movq 8(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, (%rdi) + sbbq %r10, %r9 + movq 16(%rsi), %r8 + movq 16(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 8(%rdi) + sbbq %r10, %r8 + movq 24(%rsi), %r9 + movq 24(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 16(%rdi) + sbbq %r10, %r9 + movq 32(%rsi), %r8 + movq 32(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 24(%rdi) + sbbq %r10, %r8 + movq 40(%rsi), %r9 + movq 40(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 32(%rdi) + sbbq %r10, %r9 + movq 48(%rsi), %r8 + movq 48(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 40(%rdi) + sbbq %r10, %r8 + movq 56(%rsi), %r9 + movq 56(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 48(%rdi) + sbbq %r10, %r9 + movq 64(%rsi), %r8 + movq 64(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 56(%rdi) + sbbq %r10, %r8 + movq 72(%rsi), %r9 + movq 72(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 64(%rdi) + sbbq %r10, %r9 + movq 80(%rsi), %r8 + movq 80(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 72(%rdi) + sbbq %r10, %r8 + movq 88(%rsi), %r9 + movq 88(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 80(%rdi) + sbbq %r10, %r9 + movq 96(%rsi), %r8 + movq 96(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 88(%rdi) + sbbq %r10, %r8 + movq 104(%rsi), %r9 + movq 104(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 96(%rdi) + sbbq %r10, %r9 + movq 112(%rsi), %r8 + movq 112(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 104(%rdi) + sbbq %r10, %r8 + movq 120(%rsi), %r9 + movq 120(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 112(%rdi) + sbbq %r10, %r9 + movq 128(%rsi), %r8 + movq 128(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 120(%rdi) + sbbq %r10, %r8 + movq 136(%rsi), %r9 + movq 136(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 128(%rdi) + sbbq %r10, %r9 + movq 144(%rsi), %r8 + movq 144(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 136(%rdi) + sbbq %r10, %r8 + movq 152(%rsi), %r9 + movq 152(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 144(%rdi) + sbbq %r10, %r9 + movq 160(%rsi), %r8 + movq 160(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 152(%rdi) + sbbq %r10, %r8 + movq 168(%rsi), %r9 + movq 168(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 160(%rdi) + sbbq %r10, %r9 + movq 176(%rsi), %r8 + movq 176(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 168(%rdi) + sbbq %r10, %r8 + movq 184(%rsi), %r9 + movq 184(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 176(%rdi) + sbbq %r10, %r9 + movq %r9, 184(%rdi) + sbbq $0, %rax + repz retq +#ifndef __APPLE__ +.size sp_3072_cond_sub_avx2_24,.-sp_3072_cond_sub_avx2_24 +#endif /* __APPLE__ */ /* Mul a by digit b into r. (r = a * b) * * r A single precision integer. @@ -21918,152 +22758,150 @@ sp_3072_mul_d_avx2_24: .p2align 4 _sp_3072_mul_d_avx2_24: #endif /* __APPLE__ */ - movq %rdx, %rax # A[0] * B - movq %rax, %rdx - xorq %r11, %r11 - mulxq (%rsi), %r9, %r10 - movq %r9, (%rdi) + xorq %r10, %r10 + mulxq (%rsi), %r8, %r9 + movq %r8, (%rdi) # A[1] * B - mulxq 8(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 8(%rdi) - adoxq %r8, %r9 + mulxq 8(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 8(%rdi) + adoxq %rcx, %r8 # A[2] * B - mulxq 16(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 16(%rdi) - adoxq %r8, %r10 + mulxq 16(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 16(%rdi) + adoxq %rcx, %r9 # A[3] * B - mulxq 24(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 24(%rdi) - adoxq %r8, %r9 + mulxq 24(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 24(%rdi) + adoxq %rcx, %r8 # A[4] * B - mulxq 32(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 32(%rdi) - adoxq %r8, %r10 + mulxq 32(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 32(%rdi) + adoxq %rcx, %r9 # A[5] * B - mulxq 40(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 40(%rdi) - adoxq %r8, %r9 + mulxq 40(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 40(%rdi) + adoxq %rcx, %r8 # A[6] * B - mulxq 48(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 48(%rdi) - adoxq %r8, %r10 + mulxq 48(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 48(%rdi) + adoxq %rcx, %r9 # A[7] * B - mulxq 56(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 56(%rdi) - adoxq %r8, %r9 + mulxq 56(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 56(%rdi) + adoxq %rcx, %r8 # A[8] * B - mulxq 64(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 64(%rdi) - adoxq %r8, %r10 + mulxq 64(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 64(%rdi) + adoxq %rcx, %r9 # A[9] * B - mulxq 72(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 72(%rdi) - adoxq %r8, %r9 + mulxq 72(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 72(%rdi) + adoxq %rcx, %r8 # A[10] * B - mulxq 80(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 80(%rdi) - adoxq %r8, %r10 + mulxq 80(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 80(%rdi) + adoxq %rcx, %r9 # A[11] * B - mulxq 88(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 88(%rdi) - adoxq %r8, %r9 + mulxq 88(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 88(%rdi) + adoxq %rcx, %r8 # A[12] * B - mulxq 96(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 96(%rdi) - adoxq %r8, %r10 + mulxq 96(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 96(%rdi) + adoxq %rcx, %r9 # A[13] * B - mulxq 104(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 104(%rdi) - adoxq %r8, %r9 + mulxq 104(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 104(%rdi) + adoxq %rcx, %r8 # A[14] * B - mulxq 112(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 112(%rdi) - adoxq %r8, %r10 + mulxq 112(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 112(%rdi) + adoxq %rcx, %r9 # A[15] * B - mulxq 120(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 120(%rdi) - adoxq %r8, %r9 + mulxq 120(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 120(%rdi) + adoxq %rcx, %r8 # A[16] * B - mulxq 128(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 128(%rdi) - adoxq %r8, %r10 + mulxq 128(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 128(%rdi) + adoxq %rcx, %r9 # A[17] * B - mulxq 136(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 136(%rdi) - adoxq %r8, %r9 + mulxq 136(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 136(%rdi) + adoxq %rcx, %r8 # A[18] * B - mulxq 144(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 144(%rdi) - adoxq %r8, %r10 + mulxq 144(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 144(%rdi) + adoxq %rcx, %r9 # A[19] * B - mulxq 152(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 152(%rdi) - adoxq %r8, %r9 + mulxq 152(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 152(%rdi) + adoxq %rcx, %r8 # A[20] * B - mulxq 160(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 160(%rdi) - adoxq %r8, %r10 + mulxq 160(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 160(%rdi) + adoxq %rcx, %r9 # A[21] * B - mulxq 168(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 168(%rdi) - adoxq %r8, %r9 + mulxq 168(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 168(%rdi) + adoxq %rcx, %r8 # A[22] * B - mulxq 176(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 176(%rdi) - adoxq %r8, %r10 + mulxq 176(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 176(%rdi) + adoxq %rcx, %r9 # A[23] * B - mulxq 184(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - adoxq %r8, %r9 - adcxq %r11, %r9 - movq %r10, 184(%rdi) - movq %r9, 192(%rdi) + mulxq 184(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + adoxq %rcx, %r8 + adcxq %r10, %r8 + movq %r9, 184(%rdi) + movq %r8, 192(%rdi) repz retq #ifndef __APPLE__ .size sp_3072_mul_d_avx2_24,.-sp_3072_mul_d_avx2_24 @@ -22477,9 +23315,9 @@ L_mont_loop_avx2_24: movq %rdi, %rdi subq $192, %rdi #ifndef __APPLE__ - callq sp_3072_cond_sub_24@plt + callq sp_3072_cond_sub_avx2_24@plt #else - callq _sp_3072_cond_sub_24 + callq _sp_3072_cond_sub_avx2_24 #endif /* __APPLE__ */ pop %r14 pop %r13 @@ -23382,6 +24220,270 @@ L_mont_loop_48: #ifndef __APPLE__ .size sp_3072_mont_reduce_48,.-sp_3072_mont_reduce_48 #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__ +.globl sp_3072_cond_sub_avx2_48 +.type sp_3072_cond_sub_avx2_48,@function +.align 16 +sp_3072_cond_sub_avx2_48: +#else +.globl _sp_3072_cond_sub_avx2_48 +.p2align 4 +_sp_3072_cond_sub_avx2_48: +#endif /* __APPLE__ */ + movq $0, %rax + movq (%rsi), %r8 + movq (%rdx), %r10 + pextq %rcx, %r10, %r10 + subq %r10, %r8 + movq 8(%rsi), %r9 + movq 8(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, (%rdi) + sbbq %r10, %r9 + movq 16(%rsi), %r8 + movq 16(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 8(%rdi) + sbbq %r10, %r8 + movq 24(%rsi), %r9 + movq 24(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 16(%rdi) + sbbq %r10, %r9 + movq 32(%rsi), %r8 + movq 32(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 24(%rdi) + sbbq %r10, %r8 + movq 40(%rsi), %r9 + movq 40(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 32(%rdi) + sbbq %r10, %r9 + movq 48(%rsi), %r8 + movq 48(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 40(%rdi) + sbbq %r10, %r8 + movq 56(%rsi), %r9 + movq 56(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 48(%rdi) + sbbq %r10, %r9 + movq 64(%rsi), %r8 + movq 64(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 56(%rdi) + sbbq %r10, %r8 + movq 72(%rsi), %r9 + movq 72(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 64(%rdi) + sbbq %r10, %r9 + movq 80(%rsi), %r8 + movq 80(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 72(%rdi) + sbbq %r10, %r8 + movq 88(%rsi), %r9 + movq 88(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 80(%rdi) + sbbq %r10, %r9 + movq 96(%rsi), %r8 + movq 96(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 88(%rdi) + sbbq %r10, %r8 + movq 104(%rsi), %r9 + movq 104(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 96(%rdi) + sbbq %r10, %r9 + movq 112(%rsi), %r8 + movq 112(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 104(%rdi) + sbbq %r10, %r8 + movq 120(%rsi), %r9 + movq 120(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 112(%rdi) + sbbq %r10, %r9 + movq 128(%rsi), %r8 + movq 128(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 120(%rdi) + sbbq %r10, %r8 + movq 136(%rsi), %r9 + movq 136(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 128(%rdi) + sbbq %r10, %r9 + movq 144(%rsi), %r8 + movq 144(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 136(%rdi) + sbbq %r10, %r8 + movq 152(%rsi), %r9 + movq 152(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 144(%rdi) + sbbq %r10, %r9 + movq 160(%rsi), %r8 + movq 160(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 152(%rdi) + sbbq %r10, %r8 + movq 168(%rsi), %r9 + movq 168(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 160(%rdi) + sbbq %r10, %r9 + movq 176(%rsi), %r8 + movq 176(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 168(%rdi) + sbbq %r10, %r8 + movq 184(%rsi), %r9 + movq 184(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 176(%rdi) + sbbq %r10, %r9 + movq 192(%rsi), %r8 + movq 192(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 184(%rdi) + sbbq %r10, %r8 + movq 200(%rsi), %r9 + movq 200(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 192(%rdi) + sbbq %r10, %r9 + movq 208(%rsi), %r8 + movq 208(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 200(%rdi) + sbbq %r10, %r8 + movq 216(%rsi), %r9 + movq 216(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 208(%rdi) + sbbq %r10, %r9 + movq 224(%rsi), %r8 + movq 224(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 216(%rdi) + sbbq %r10, %r8 + movq 232(%rsi), %r9 + movq 232(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 224(%rdi) + sbbq %r10, %r9 + movq 240(%rsi), %r8 + movq 240(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 232(%rdi) + sbbq %r10, %r8 + movq 248(%rsi), %r9 + movq 248(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 240(%rdi) + sbbq %r10, %r9 + movq 256(%rsi), %r8 + movq 256(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 248(%rdi) + sbbq %r10, %r8 + movq 264(%rsi), %r9 + movq 264(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 256(%rdi) + sbbq %r10, %r9 + movq 272(%rsi), %r8 + movq 272(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 264(%rdi) + sbbq %r10, %r8 + movq 280(%rsi), %r9 + movq 280(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 272(%rdi) + sbbq %r10, %r9 + movq 288(%rsi), %r8 + movq 288(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 280(%rdi) + sbbq %r10, %r8 + movq 296(%rsi), %r9 + movq 296(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 288(%rdi) + sbbq %r10, %r9 + movq 304(%rsi), %r8 + movq 304(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 296(%rdi) + sbbq %r10, %r8 + movq 312(%rsi), %r9 + movq 312(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 304(%rdi) + sbbq %r10, %r9 + movq 320(%rsi), %r8 + movq 320(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 312(%rdi) + sbbq %r10, %r8 + movq 328(%rsi), %r9 + movq 328(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 320(%rdi) + sbbq %r10, %r9 + movq 336(%rsi), %r8 + movq 336(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 328(%rdi) + sbbq %r10, %r8 + movq 344(%rsi), %r9 + movq 344(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 336(%rdi) + sbbq %r10, %r9 + movq 352(%rsi), %r8 + movq 352(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 344(%rdi) + sbbq %r10, %r8 + movq 360(%rsi), %r9 + movq 360(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 352(%rdi) + sbbq %r10, %r9 + movq 368(%rsi), %r8 + movq 368(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 360(%rdi) + sbbq %r10, %r8 + movq 376(%rsi), %r9 + movq 376(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 368(%rdi) + sbbq %r10, %r9 + movq %r9, 376(%rdi) + sbbq $0, %rax + repz retq +#ifndef __APPLE__ +.size sp_3072_cond_sub_avx2_48,.-sp_3072_cond_sub_avx2_48 +#endif /* __APPLE__ */ #ifdef HAVE_INTEL_AVX2 /* Mul a by digit b into r. (r = a * b) * @@ -23399,296 +24501,294 @@ sp_3072_mul_d_avx2_48: .p2align 4 _sp_3072_mul_d_avx2_48: #endif /* __APPLE__ */ - movq %rdx, %rax # A[0] * B - movq %rax, %rdx - xorq %r11, %r11 - mulxq (%rsi), %r9, %r10 - movq %r9, (%rdi) + xorq %r10, %r10 + mulxq (%rsi), %r8, %r9 + movq %r8, (%rdi) # A[1] * B - mulxq 8(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 8(%rdi) - adoxq %r8, %r9 + mulxq 8(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 8(%rdi) + adoxq %rcx, %r8 # A[2] * B - mulxq 16(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 16(%rdi) - adoxq %r8, %r10 + mulxq 16(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 16(%rdi) + adoxq %rcx, %r9 # A[3] * B - mulxq 24(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 24(%rdi) - adoxq %r8, %r9 + mulxq 24(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 24(%rdi) + adoxq %rcx, %r8 # A[4] * B - mulxq 32(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 32(%rdi) - adoxq %r8, %r10 + mulxq 32(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 32(%rdi) + adoxq %rcx, %r9 # A[5] * B - mulxq 40(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 40(%rdi) - adoxq %r8, %r9 + mulxq 40(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 40(%rdi) + adoxq %rcx, %r8 # A[6] * B - mulxq 48(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 48(%rdi) - adoxq %r8, %r10 + mulxq 48(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 48(%rdi) + adoxq %rcx, %r9 # A[7] * B - mulxq 56(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 56(%rdi) - adoxq %r8, %r9 + mulxq 56(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 56(%rdi) + adoxq %rcx, %r8 # A[8] * B - mulxq 64(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 64(%rdi) - adoxq %r8, %r10 + mulxq 64(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 64(%rdi) + adoxq %rcx, %r9 # A[9] * B - mulxq 72(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 72(%rdi) - adoxq %r8, %r9 + mulxq 72(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 72(%rdi) + adoxq %rcx, %r8 # A[10] * B - mulxq 80(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 80(%rdi) - adoxq %r8, %r10 + mulxq 80(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 80(%rdi) + adoxq %rcx, %r9 # A[11] * B - mulxq 88(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 88(%rdi) - adoxq %r8, %r9 + mulxq 88(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 88(%rdi) + adoxq %rcx, %r8 # A[12] * B - mulxq 96(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 96(%rdi) - adoxq %r8, %r10 + mulxq 96(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 96(%rdi) + adoxq %rcx, %r9 # A[13] * B - mulxq 104(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 104(%rdi) - adoxq %r8, %r9 + mulxq 104(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 104(%rdi) + adoxq %rcx, %r8 # A[14] * B - mulxq 112(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 112(%rdi) - adoxq %r8, %r10 + mulxq 112(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 112(%rdi) + adoxq %rcx, %r9 # A[15] * B - mulxq 120(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 120(%rdi) - adoxq %r8, %r9 + mulxq 120(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 120(%rdi) + adoxq %rcx, %r8 # A[16] * B - mulxq 128(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 128(%rdi) - adoxq %r8, %r10 + mulxq 128(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 128(%rdi) + adoxq %rcx, %r9 # A[17] * B - mulxq 136(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 136(%rdi) - adoxq %r8, %r9 + mulxq 136(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 136(%rdi) + adoxq %rcx, %r8 # A[18] * B - mulxq 144(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 144(%rdi) - adoxq %r8, %r10 + mulxq 144(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 144(%rdi) + adoxq %rcx, %r9 # A[19] * B - mulxq 152(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 152(%rdi) - adoxq %r8, %r9 + mulxq 152(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 152(%rdi) + adoxq %rcx, %r8 # A[20] * B - mulxq 160(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 160(%rdi) - adoxq %r8, %r10 + mulxq 160(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 160(%rdi) + adoxq %rcx, %r9 # A[21] * B - mulxq 168(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 168(%rdi) - adoxq %r8, %r9 + mulxq 168(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 168(%rdi) + adoxq %rcx, %r8 # A[22] * B - mulxq 176(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 176(%rdi) - adoxq %r8, %r10 + mulxq 176(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 176(%rdi) + adoxq %rcx, %r9 # A[23] * B - mulxq 184(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 184(%rdi) - adoxq %r8, %r9 + mulxq 184(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 184(%rdi) + adoxq %rcx, %r8 # A[24] * B - mulxq 192(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 192(%rdi) - adoxq %r8, %r10 + mulxq 192(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 192(%rdi) + adoxq %rcx, %r9 # A[25] * B - mulxq 200(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 200(%rdi) - adoxq %r8, %r9 + mulxq 200(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 200(%rdi) + adoxq %rcx, %r8 # A[26] * B - mulxq 208(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 208(%rdi) - adoxq %r8, %r10 + mulxq 208(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 208(%rdi) + adoxq %rcx, %r9 # A[27] * B - mulxq 216(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 216(%rdi) - adoxq %r8, %r9 + mulxq 216(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 216(%rdi) + adoxq %rcx, %r8 # A[28] * B - mulxq 224(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 224(%rdi) - adoxq %r8, %r10 + mulxq 224(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 224(%rdi) + adoxq %rcx, %r9 # A[29] * B - mulxq 232(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 232(%rdi) - adoxq %r8, %r9 + mulxq 232(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 232(%rdi) + adoxq %rcx, %r8 # A[30] * B - mulxq 240(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 240(%rdi) - adoxq %r8, %r10 + mulxq 240(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 240(%rdi) + adoxq %rcx, %r9 # A[31] * B - mulxq 248(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 248(%rdi) - adoxq %r8, %r9 + mulxq 248(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 248(%rdi) + adoxq %rcx, %r8 # A[32] * B - mulxq 256(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 256(%rdi) - adoxq %r8, %r10 + mulxq 256(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 256(%rdi) + adoxq %rcx, %r9 # A[33] * B - mulxq 264(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 264(%rdi) - adoxq %r8, %r9 + mulxq 264(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 264(%rdi) + adoxq %rcx, %r8 # A[34] * B - mulxq 272(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 272(%rdi) - adoxq %r8, %r10 + mulxq 272(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 272(%rdi) + adoxq %rcx, %r9 # A[35] * B - mulxq 280(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 280(%rdi) - adoxq %r8, %r9 + mulxq 280(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 280(%rdi) + adoxq %rcx, %r8 # A[36] * B - mulxq 288(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 288(%rdi) - adoxq %r8, %r10 + mulxq 288(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 288(%rdi) + adoxq %rcx, %r9 # A[37] * B - mulxq 296(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 296(%rdi) - adoxq %r8, %r9 + mulxq 296(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 296(%rdi) + adoxq %rcx, %r8 # A[38] * B - mulxq 304(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 304(%rdi) - adoxq %r8, %r10 + mulxq 304(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 304(%rdi) + adoxq %rcx, %r9 # A[39] * B - mulxq 312(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 312(%rdi) - adoxq %r8, %r9 + mulxq 312(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 312(%rdi) + adoxq %rcx, %r8 # A[40] * B - mulxq 320(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 320(%rdi) - adoxq %r8, %r10 + mulxq 320(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 320(%rdi) + adoxq %rcx, %r9 # A[41] * B - mulxq 328(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 328(%rdi) - adoxq %r8, %r9 + mulxq 328(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 328(%rdi) + adoxq %rcx, %r8 # A[42] * B - mulxq 336(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 336(%rdi) - adoxq %r8, %r10 + mulxq 336(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 336(%rdi) + adoxq %rcx, %r9 # A[43] * B - mulxq 344(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 344(%rdi) - adoxq %r8, %r9 + mulxq 344(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 344(%rdi) + adoxq %rcx, %r8 # A[44] * B - mulxq 352(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 352(%rdi) - adoxq %r8, %r10 + mulxq 352(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 352(%rdi) + adoxq %rcx, %r9 # A[45] * B - mulxq 360(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 360(%rdi) - adoxq %r8, %r9 + mulxq 360(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 360(%rdi) + adoxq %rcx, %r8 # A[46] * B - mulxq 368(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 368(%rdi) - adoxq %r8, %r10 + mulxq 368(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 368(%rdi) + adoxq %rcx, %r9 # A[47] * B - mulxq 376(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - adoxq %r8, %r9 - adcxq %r11, %r9 - movq %r10, 376(%rdi) - movq %r9, 384(%rdi) + mulxq 376(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + adoxq %rcx, %r8 + adcxq %r10, %r8 + movq %r9, 376(%rdi) + movq %r8, 384(%rdi) repz retq #ifndef __APPLE__ .size sp_3072_mul_d_avx2_48,.-sp_3072_mul_d_avx2_48 @@ -24104,6 +25204,172 @@ _sp_3072_cmp_48: #ifndef __APPLE__ .size sp_3072_cmp_48,.-sp_3072_cmp_48 #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__ +.globl sp_3072_sub_48 +.type sp_3072_sub_48,@function +.align 16 +sp_3072_sub_48: +#else +.globl _sp_3072_sub_48 +.p2align 4 +_sp_3072_sub_48: +#endif /* __APPLE__ */ + movq (%rsi), %r8 + xorq %rax, %rax + subq (%rdx), %r8 + movq 8(%rsi), %r9 + movq %r8, (%rdi) + sbbq 8(%rdx), %r9 + movq 16(%rsi), %r8 + movq %r9, 8(%rdi) + sbbq 16(%rdx), %r8 + movq 24(%rsi), %r9 + movq %r8, 16(%rdi) + sbbq 24(%rdx), %r9 + movq 32(%rsi), %r8 + movq %r9, 24(%rdi) + sbbq 32(%rdx), %r8 + movq 40(%rsi), %r9 + movq %r8, 32(%rdi) + sbbq 40(%rdx), %r9 + movq 48(%rsi), %r8 + movq %r9, 40(%rdi) + sbbq 48(%rdx), %r8 + movq 56(%rsi), %r9 + movq %r8, 48(%rdi) + sbbq 56(%rdx), %r9 + movq 64(%rsi), %r8 + movq %r9, 56(%rdi) + sbbq 64(%rdx), %r8 + movq 72(%rsi), %r9 + movq %r8, 64(%rdi) + sbbq 72(%rdx), %r9 + movq 80(%rsi), %r8 + movq %r9, 72(%rdi) + sbbq 80(%rdx), %r8 + movq 88(%rsi), %r9 + movq %r8, 80(%rdi) + sbbq 88(%rdx), %r9 + movq 96(%rsi), %r8 + movq %r9, 88(%rdi) + sbbq 96(%rdx), %r8 + movq 104(%rsi), %r9 + movq %r8, 96(%rdi) + sbbq 104(%rdx), %r9 + movq 112(%rsi), %r8 + movq %r9, 104(%rdi) + sbbq 112(%rdx), %r8 + movq 120(%rsi), %r9 + movq %r8, 112(%rdi) + sbbq 120(%rdx), %r9 + movq 128(%rsi), %r8 + movq %r9, 120(%rdi) + sbbq 128(%rdx), %r8 + movq 136(%rsi), %r9 + movq %r8, 128(%rdi) + sbbq 136(%rdx), %r9 + movq 144(%rsi), %r8 + movq %r9, 136(%rdi) + sbbq 144(%rdx), %r8 + movq 152(%rsi), %r9 + movq %r8, 144(%rdi) + sbbq 152(%rdx), %r9 + movq 160(%rsi), %r8 + movq %r9, 152(%rdi) + sbbq 160(%rdx), %r8 + movq 168(%rsi), %r9 + movq %r8, 160(%rdi) + sbbq 168(%rdx), %r9 + movq 176(%rsi), %r8 + movq %r9, 168(%rdi) + sbbq 176(%rdx), %r8 + movq 184(%rsi), %r9 + movq %r8, 176(%rdi) + sbbq 184(%rdx), %r9 + movq 192(%rsi), %r8 + movq %r9, 184(%rdi) + sbbq 192(%rdx), %r8 + movq 200(%rsi), %r9 + movq %r8, 192(%rdi) + sbbq 200(%rdx), %r9 + movq 208(%rsi), %r8 + movq %r9, 200(%rdi) + sbbq 208(%rdx), %r8 + movq 216(%rsi), %r9 + movq %r8, 208(%rdi) + sbbq 216(%rdx), %r9 + movq 224(%rsi), %r8 + movq %r9, 216(%rdi) + sbbq 224(%rdx), %r8 + movq 232(%rsi), %r9 + movq %r8, 224(%rdi) + sbbq 232(%rdx), %r9 + movq 240(%rsi), %r8 + movq %r9, 232(%rdi) + sbbq 240(%rdx), %r8 + movq 248(%rsi), %r9 + movq %r8, 240(%rdi) + sbbq 248(%rdx), %r9 + movq 256(%rsi), %r8 + movq %r9, 248(%rdi) + sbbq 256(%rdx), %r8 + movq 264(%rsi), %r9 + movq %r8, 256(%rdi) + sbbq 264(%rdx), %r9 + movq 272(%rsi), %r8 + movq %r9, 264(%rdi) + sbbq 272(%rdx), %r8 + movq 280(%rsi), %r9 + movq %r8, 272(%rdi) + sbbq 280(%rdx), %r9 + movq 288(%rsi), %r8 + movq %r9, 280(%rdi) + sbbq 288(%rdx), %r8 + movq 296(%rsi), %r9 + movq %r8, 288(%rdi) + sbbq 296(%rdx), %r9 + movq 304(%rsi), %r8 + movq %r9, 296(%rdi) + sbbq 304(%rdx), %r8 + movq 312(%rsi), %r9 + movq %r8, 304(%rdi) + sbbq 312(%rdx), %r9 + movq 320(%rsi), %r8 + movq %r9, 312(%rdi) + sbbq 320(%rdx), %r8 + movq 328(%rsi), %r9 + movq %r8, 320(%rdi) + sbbq 328(%rdx), %r9 + movq 336(%rsi), %r8 + movq %r9, 328(%rdi) + sbbq 336(%rdx), %r8 + movq 344(%rsi), %r9 + movq %r8, 336(%rdi) + sbbq 344(%rdx), %r9 + movq 352(%rsi), %r8 + movq %r9, 344(%rdi) + sbbq 352(%rdx), %r8 + movq 360(%rsi), %r9 + movq %r8, 352(%rdi) + sbbq 360(%rdx), %r9 + movq 368(%rsi), %r8 + movq %r9, 360(%rdi) + sbbq 368(%rdx), %r8 + movq 376(%rsi), %r9 + movq %r8, 368(%rdi) + sbbq 376(%rdx), %r9 + movq %r9, 376(%rdi) + sbbq $0, %rax + repz retq +#ifndef __APPLE__ +.size sp_3072_sub_48,.-sp_3072_sub_48 +#endif /* __APPLE__ */ #ifdef HAVE_INTEL_AVX2 /* Reduce the number back to 3072 bits using Montgomery reduction. * @@ -24438,9 +25704,9 @@ L_mont_loop_avx2_48: movq %rdi, %rdi subq $384, %rdi #ifndef __APPLE__ - callq sp_3072_cond_sub_48@plt + callq sp_3072_cond_sub_avx2_48@plt #else - callq _sp_3072_cond_sub_48 + callq _sp_3072_cond_sub_avx2_48 #endif /* __APPLE__ */ pop %r14 pop %r13 @@ -24617,6 +25883,236 @@ _sp_3072_lshift_48: repz retq #endif /* !WOLFSSL_SP_NO_3072 */ #ifdef WOLFSSL_SP_4096 +/* 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. + */ +#ifndef __APPLE__ +.globl sp_4096_from_bin +.type sp_4096_from_bin,@function +.align 16 +sp_4096_from_bin: +#else +.globl _sp_4096_from_bin +.p2align 4 +_sp_4096_from_bin: +#endif /* __APPLE__ */ + movq %rdx, %r9 + movq %rdi, %r10 + addq %rcx, %r9 + addq $512, %r10 + xorq %r11, %r11 + jmp L_4096_from_bin_64_end +L_4096_from_bin_64_start: + subq $64, %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 $64, %rdi + subq $64, %rcx +L_4096_from_bin_64_end: + cmpq $63, %rcx + jg L_4096_from_bin_64_start + jmp L_4096_from_bin_8_end +L_4096_from_bin_8_start: + subq $8, %r9 + movbeq (%r9), %rax + movq %rax, (%rdi) + addq $8, %rdi + subq $8, %rcx +L_4096_from_bin_8_end: + cmpq $7, %rcx + jg L_4096_from_bin_8_start + cmpq %r11, %rcx + je L_4096_from_bin_hi_end + movq %r11, %r8 + movq %r11, %rax +L_4096_from_bin_hi_start: + movb (%rdx), %al + shlq $8, %r8 + incq %rdx + addq %rax, %r8 + decq %rcx + jg L_4096_from_bin_hi_start + movq %r8, (%rdi) + addq $8, %rdi +L_4096_from_bin_hi_end: + cmpq %r10, %rdi + je L_4096_from_bin_zero_end +L_4096_from_bin_zero_start: + movq %r11, (%rdi) + addq $8, %rdi + cmpq %r10, %rdi + jl L_4096_from_bin_zero_start +L_4096_from_bin_zero_end: + repz retq +#ifndef __APPLE__ +.size sp_4096_from_bin,.-sp_4096_from_bin +#endif /* __APPLE__ */ +/* Write r as big endian to byte array. + * Fixed length number of bytes written: 512 + * + * r A single precision integer. + * a Byte array. + */ +#ifndef __APPLE__ +.globl sp_4096_to_bin +.type sp_4096_to_bin,@function +.align 16 +sp_4096_to_bin: +#else +.globl _sp_4096_to_bin +.p2align 4 +_sp_4096_to_bin: +#endif /* __APPLE__ */ + movbeq 504(%rdi), %rdx + movbeq 496(%rdi), %rax + movq %rdx, (%rsi) + movq %rax, 8(%rsi) + movbeq 488(%rdi), %rdx + movbeq 480(%rdi), %rax + movq %rdx, 16(%rsi) + movq %rax, 24(%rsi) + movbeq 472(%rdi), %rdx + movbeq 464(%rdi), %rax + movq %rdx, 32(%rsi) + movq %rax, 40(%rsi) + movbeq 456(%rdi), %rdx + movbeq 448(%rdi), %rax + movq %rdx, 48(%rsi) + movq %rax, 56(%rsi) + movbeq 440(%rdi), %rdx + movbeq 432(%rdi), %rax + movq %rdx, 64(%rsi) + movq %rax, 72(%rsi) + movbeq 424(%rdi), %rdx + movbeq 416(%rdi), %rax + movq %rdx, 80(%rsi) + movq %rax, 88(%rsi) + movbeq 408(%rdi), %rdx + movbeq 400(%rdi), %rax + movq %rdx, 96(%rsi) + movq %rax, 104(%rsi) + movbeq 392(%rdi), %rdx + movbeq 384(%rdi), %rax + movq %rdx, 112(%rsi) + movq %rax, 120(%rsi) + movbeq 376(%rdi), %rdx + movbeq 368(%rdi), %rax + movq %rdx, 128(%rsi) + movq %rax, 136(%rsi) + movbeq 360(%rdi), %rdx + movbeq 352(%rdi), %rax + movq %rdx, 144(%rsi) + movq %rax, 152(%rsi) + movbeq 344(%rdi), %rdx + movbeq 336(%rdi), %rax + movq %rdx, 160(%rsi) + movq %rax, 168(%rsi) + movbeq 328(%rdi), %rdx + movbeq 320(%rdi), %rax + movq %rdx, 176(%rsi) + movq %rax, 184(%rsi) + movbeq 312(%rdi), %rdx + movbeq 304(%rdi), %rax + movq %rdx, 192(%rsi) + movq %rax, 200(%rsi) + movbeq 296(%rdi), %rdx + movbeq 288(%rdi), %rax + movq %rdx, 208(%rsi) + movq %rax, 216(%rsi) + movbeq 280(%rdi), %rdx + movbeq 272(%rdi), %rax + movq %rdx, 224(%rsi) + movq %rax, 232(%rsi) + movbeq 264(%rdi), %rdx + movbeq 256(%rdi), %rax + movq %rdx, 240(%rsi) + movq %rax, 248(%rsi) + movbeq 248(%rdi), %rdx + movbeq 240(%rdi), %rax + movq %rdx, 256(%rsi) + movq %rax, 264(%rsi) + movbeq 232(%rdi), %rdx + movbeq 224(%rdi), %rax + movq %rdx, 272(%rsi) + movq %rax, 280(%rsi) + movbeq 216(%rdi), %rdx + movbeq 208(%rdi), %rax + movq %rdx, 288(%rsi) + movq %rax, 296(%rsi) + movbeq 200(%rdi), %rdx + movbeq 192(%rdi), %rax + movq %rdx, 304(%rsi) + movq %rax, 312(%rsi) + movbeq 184(%rdi), %rdx + movbeq 176(%rdi), %rax + movq %rdx, 320(%rsi) + movq %rax, 328(%rsi) + movbeq 168(%rdi), %rdx + movbeq 160(%rdi), %rax + movq %rdx, 336(%rsi) + movq %rax, 344(%rsi) + movbeq 152(%rdi), %rdx + movbeq 144(%rdi), %rax + movq %rdx, 352(%rsi) + movq %rax, 360(%rsi) + movbeq 136(%rdi), %rdx + movbeq 128(%rdi), %rax + movq %rdx, 368(%rsi) + movq %rax, 376(%rsi) + movbeq 120(%rdi), %rdx + movbeq 112(%rdi), %rax + movq %rdx, 384(%rsi) + movq %rax, 392(%rsi) + movbeq 104(%rdi), %rdx + movbeq 96(%rdi), %rax + movq %rdx, 400(%rsi) + movq %rax, 408(%rsi) + movbeq 88(%rdi), %rdx + movbeq 80(%rdi), %rax + movq %rdx, 416(%rsi) + movq %rax, 424(%rsi) + movbeq 72(%rdi), %rdx + movbeq 64(%rdi), %rax + movq %rdx, 432(%rsi) + movq %rax, 440(%rsi) + movbeq 56(%rdi), %rdx + movbeq 48(%rdi), %rax + movq %rdx, 448(%rsi) + movq %rax, 456(%rsi) + movbeq 40(%rdi), %rdx + movbeq 32(%rdi), %rax + movq %rdx, 464(%rsi) + movq %rax, 472(%rsi) + movbeq 24(%rdi), %rdx + movbeq 16(%rdi), %rax + movq %rdx, 480(%rsi) + movq %rax, 488(%rsi) + movbeq 8(%rdi), %rdx + movbeq (%rdi), %rax + movq %rdx, 496(%rsi) + movq %rax, 504(%rsi) + repz retq +#ifndef __APPLE__ +.size sp_4096_to_bin,.-sp_4096_to_bin +#endif /* __APPLE__ */ /* Sub b from a into a. (a -= b) * * a A single precision integer and result. @@ -24632,262 +26128,198 @@ sp_4096_sub_in_place_64: .p2align 4 _sp_4096_sub_in_place_64: #endif /* __APPLE__ */ - xorq %rax, %rax movq (%rdi), %rdx + xorq %rax, %rax + subq (%rsi), %rdx movq 8(%rdi), %rcx - movq (%rsi), %r8 - movq 8(%rsi), %r9 - subq %r8, %rdx - movq 16(%rsi), %r8 movq %rdx, (%rdi) + sbbq 8(%rsi), %rcx movq 16(%rdi), %rdx - sbbq %r9, %rcx - movq 24(%rsi), %r9 movq %rcx, 8(%rdi) + sbbq 16(%rsi), %rdx movq 24(%rdi), %rcx - sbbq %r8, %rdx - movq 32(%rsi), %r8 movq %rdx, 16(%rdi) + sbbq 24(%rsi), %rcx movq 32(%rdi), %rdx - sbbq %r9, %rcx - movq 40(%rsi), %r9 movq %rcx, 24(%rdi) + sbbq 32(%rsi), %rdx movq 40(%rdi), %rcx - sbbq %r8, %rdx - movq 48(%rsi), %r8 movq %rdx, 32(%rdi) + sbbq 40(%rsi), %rcx movq 48(%rdi), %rdx - sbbq %r9, %rcx - movq 56(%rsi), %r9 movq %rcx, 40(%rdi) + sbbq 48(%rsi), %rdx movq 56(%rdi), %rcx - sbbq %r8, %rdx - movq 64(%rsi), %r8 movq %rdx, 48(%rdi) + sbbq 56(%rsi), %rcx movq 64(%rdi), %rdx - sbbq %r9, %rcx - movq 72(%rsi), %r9 movq %rcx, 56(%rdi) + sbbq 64(%rsi), %rdx movq 72(%rdi), %rcx - sbbq %r8, %rdx - movq 80(%rsi), %r8 movq %rdx, 64(%rdi) + sbbq 72(%rsi), %rcx movq 80(%rdi), %rdx - sbbq %r9, %rcx - movq 88(%rsi), %r9 movq %rcx, 72(%rdi) + sbbq 80(%rsi), %rdx movq 88(%rdi), %rcx - sbbq %r8, %rdx - movq 96(%rsi), %r8 movq %rdx, 80(%rdi) + sbbq 88(%rsi), %rcx movq 96(%rdi), %rdx - sbbq %r9, %rcx - movq 104(%rsi), %r9 movq %rcx, 88(%rdi) + sbbq 96(%rsi), %rdx movq 104(%rdi), %rcx - sbbq %r8, %rdx - movq 112(%rsi), %r8 movq %rdx, 96(%rdi) + sbbq 104(%rsi), %rcx movq 112(%rdi), %rdx - sbbq %r9, %rcx - movq 120(%rsi), %r9 movq %rcx, 104(%rdi) + sbbq 112(%rsi), %rdx movq 120(%rdi), %rcx - sbbq %r8, %rdx - movq 128(%rsi), %r8 movq %rdx, 112(%rdi) + sbbq 120(%rsi), %rcx movq 128(%rdi), %rdx - sbbq %r9, %rcx - movq 136(%rsi), %r9 movq %rcx, 120(%rdi) + sbbq 128(%rsi), %rdx movq 136(%rdi), %rcx - sbbq %r8, %rdx - movq 144(%rsi), %r8 movq %rdx, 128(%rdi) + sbbq 136(%rsi), %rcx movq 144(%rdi), %rdx - sbbq %r9, %rcx - movq 152(%rsi), %r9 movq %rcx, 136(%rdi) + sbbq 144(%rsi), %rdx movq 152(%rdi), %rcx - sbbq %r8, %rdx - movq 160(%rsi), %r8 movq %rdx, 144(%rdi) + sbbq 152(%rsi), %rcx movq 160(%rdi), %rdx - sbbq %r9, %rcx - movq 168(%rsi), %r9 movq %rcx, 152(%rdi) + sbbq 160(%rsi), %rdx movq 168(%rdi), %rcx - sbbq %r8, %rdx - movq 176(%rsi), %r8 movq %rdx, 160(%rdi) + sbbq 168(%rsi), %rcx movq 176(%rdi), %rdx - sbbq %r9, %rcx - movq 184(%rsi), %r9 movq %rcx, 168(%rdi) + sbbq 176(%rsi), %rdx movq 184(%rdi), %rcx - sbbq %r8, %rdx - movq 192(%rsi), %r8 movq %rdx, 176(%rdi) + sbbq 184(%rsi), %rcx movq 192(%rdi), %rdx - sbbq %r9, %rcx - movq 200(%rsi), %r9 movq %rcx, 184(%rdi) + sbbq 192(%rsi), %rdx movq 200(%rdi), %rcx - sbbq %r8, %rdx - movq 208(%rsi), %r8 movq %rdx, 192(%rdi) + sbbq 200(%rsi), %rcx movq 208(%rdi), %rdx - sbbq %r9, %rcx - movq 216(%rsi), %r9 movq %rcx, 200(%rdi) + sbbq 208(%rsi), %rdx movq 216(%rdi), %rcx - sbbq %r8, %rdx - movq 224(%rsi), %r8 movq %rdx, 208(%rdi) + sbbq 216(%rsi), %rcx movq 224(%rdi), %rdx - sbbq %r9, %rcx - movq 232(%rsi), %r9 movq %rcx, 216(%rdi) + sbbq 224(%rsi), %rdx movq 232(%rdi), %rcx - sbbq %r8, %rdx - movq 240(%rsi), %r8 movq %rdx, 224(%rdi) + sbbq 232(%rsi), %rcx movq 240(%rdi), %rdx - sbbq %r9, %rcx - movq 248(%rsi), %r9 movq %rcx, 232(%rdi) + sbbq 240(%rsi), %rdx movq 248(%rdi), %rcx - sbbq %r8, %rdx - movq 256(%rsi), %r8 movq %rdx, 240(%rdi) + sbbq 248(%rsi), %rcx movq 256(%rdi), %rdx - sbbq %r9, %rcx - movq 264(%rsi), %r9 movq %rcx, 248(%rdi) + sbbq 256(%rsi), %rdx movq 264(%rdi), %rcx - sbbq %r8, %rdx - movq 272(%rsi), %r8 movq %rdx, 256(%rdi) + sbbq 264(%rsi), %rcx movq 272(%rdi), %rdx - sbbq %r9, %rcx - movq 280(%rsi), %r9 movq %rcx, 264(%rdi) + sbbq 272(%rsi), %rdx movq 280(%rdi), %rcx - sbbq %r8, %rdx - movq 288(%rsi), %r8 movq %rdx, 272(%rdi) + sbbq 280(%rsi), %rcx movq 288(%rdi), %rdx - sbbq %r9, %rcx - movq 296(%rsi), %r9 movq %rcx, 280(%rdi) + sbbq 288(%rsi), %rdx movq 296(%rdi), %rcx - sbbq %r8, %rdx - movq 304(%rsi), %r8 movq %rdx, 288(%rdi) + sbbq 296(%rsi), %rcx movq 304(%rdi), %rdx - sbbq %r9, %rcx - movq 312(%rsi), %r9 movq %rcx, 296(%rdi) + sbbq 304(%rsi), %rdx movq 312(%rdi), %rcx - sbbq %r8, %rdx - movq 320(%rsi), %r8 movq %rdx, 304(%rdi) + sbbq 312(%rsi), %rcx movq 320(%rdi), %rdx - sbbq %r9, %rcx - movq 328(%rsi), %r9 movq %rcx, 312(%rdi) + sbbq 320(%rsi), %rdx movq 328(%rdi), %rcx - sbbq %r8, %rdx - movq 336(%rsi), %r8 movq %rdx, 320(%rdi) + sbbq 328(%rsi), %rcx movq 336(%rdi), %rdx - sbbq %r9, %rcx - movq 344(%rsi), %r9 movq %rcx, 328(%rdi) + sbbq 336(%rsi), %rdx movq 344(%rdi), %rcx - sbbq %r8, %rdx - movq 352(%rsi), %r8 movq %rdx, 336(%rdi) + sbbq 344(%rsi), %rcx movq 352(%rdi), %rdx - sbbq %r9, %rcx - movq 360(%rsi), %r9 movq %rcx, 344(%rdi) + sbbq 352(%rsi), %rdx movq 360(%rdi), %rcx - sbbq %r8, %rdx - movq 368(%rsi), %r8 movq %rdx, 352(%rdi) + sbbq 360(%rsi), %rcx movq 368(%rdi), %rdx - sbbq %r9, %rcx - movq 376(%rsi), %r9 movq %rcx, 360(%rdi) + sbbq 368(%rsi), %rdx movq 376(%rdi), %rcx - sbbq %r8, %rdx - movq 384(%rsi), %r8 movq %rdx, 368(%rdi) + sbbq 376(%rsi), %rcx movq 384(%rdi), %rdx - sbbq %r9, %rcx - movq 392(%rsi), %r9 movq %rcx, 376(%rdi) + sbbq 384(%rsi), %rdx movq 392(%rdi), %rcx - sbbq %r8, %rdx - movq 400(%rsi), %r8 movq %rdx, 384(%rdi) + sbbq 392(%rsi), %rcx movq 400(%rdi), %rdx - sbbq %r9, %rcx - movq 408(%rsi), %r9 movq %rcx, 392(%rdi) + sbbq 400(%rsi), %rdx movq 408(%rdi), %rcx - sbbq %r8, %rdx - movq 416(%rsi), %r8 movq %rdx, 400(%rdi) + sbbq 408(%rsi), %rcx movq 416(%rdi), %rdx - sbbq %r9, %rcx - movq 424(%rsi), %r9 movq %rcx, 408(%rdi) + sbbq 416(%rsi), %rdx movq 424(%rdi), %rcx - sbbq %r8, %rdx - movq 432(%rsi), %r8 movq %rdx, 416(%rdi) + sbbq 424(%rsi), %rcx movq 432(%rdi), %rdx - sbbq %r9, %rcx - movq 440(%rsi), %r9 movq %rcx, 424(%rdi) + sbbq 432(%rsi), %rdx movq 440(%rdi), %rcx - sbbq %r8, %rdx - movq 448(%rsi), %r8 movq %rdx, 432(%rdi) + sbbq 440(%rsi), %rcx movq 448(%rdi), %rdx - sbbq %r9, %rcx - movq 456(%rsi), %r9 movq %rcx, 440(%rdi) + sbbq 448(%rsi), %rdx movq 456(%rdi), %rcx - sbbq %r8, %rdx - movq 464(%rsi), %r8 movq %rdx, 448(%rdi) + sbbq 456(%rsi), %rcx movq 464(%rdi), %rdx - sbbq %r9, %rcx - movq 472(%rsi), %r9 movq %rcx, 456(%rdi) + sbbq 464(%rsi), %rdx movq 472(%rdi), %rcx - sbbq %r8, %rdx - movq 480(%rsi), %r8 movq %rdx, 464(%rdi) + sbbq 472(%rsi), %rcx movq 480(%rdi), %rdx - sbbq %r9, %rcx - movq 488(%rsi), %r9 movq %rcx, 472(%rdi) + sbbq 480(%rsi), %rdx movq 488(%rdi), %rcx - sbbq %r8, %rdx - movq 496(%rsi), %r8 movq %rdx, 480(%rdi) + sbbq 488(%rsi), %rcx movq 496(%rdi), %rdx - sbbq %r9, %rcx - movq 504(%rsi), %r9 movq %rcx, 488(%rdi) + sbbq 496(%rsi), %rdx movq 504(%rdi), %rcx - sbbq %r8, %rdx movq %rdx, 496(%rdi) - sbbq %r9, %rcx + sbbq 504(%rsi), %rcx movq %rcx, 504(%rdi) sbbq $0, %rax repz retq @@ -24910,199 +26342,199 @@ sp_4096_add_64: .p2align 4 _sp_4096_add_64: #endif /* __APPLE__ */ - xorq %rax, %rax movq (%rsi), %rcx + xorq %rax, %rax addq (%rdx), %rcx + movq 8(%rsi), %r8 movq %rcx, (%rdi) - movq 8(%rsi), %rcx - adcq 8(%rdx), %rcx - movq %rcx, 8(%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) - movq 24(%rsi), %rcx - adcq 24(%rdx), %rcx - movq %rcx, 24(%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) - movq 40(%rsi), %rcx - adcq 40(%rdx), %rcx - movq %rcx, 40(%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) - movq 56(%rsi), %rcx - adcq 56(%rdx), %rcx - movq %rcx, 56(%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) - movq 72(%rsi), %rcx - adcq 72(%rdx), %rcx - movq %rcx, 72(%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) - movq 88(%rsi), %rcx - adcq 88(%rdx), %rcx - movq %rcx, 88(%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) - movq 104(%rsi), %rcx - adcq 104(%rdx), %rcx - movq %rcx, 104(%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) - movq 120(%rsi), %rcx - adcq 120(%rdx), %rcx - movq %rcx, 120(%rdi) + adcq 120(%rdx), %r8 movq 128(%rsi), %rcx + movq %r8, 120(%rdi) adcq 128(%rdx), %rcx + movq 136(%rsi), %r8 movq %rcx, 128(%rdi) - movq 136(%rsi), %rcx - adcq 136(%rdx), %rcx - movq %rcx, 136(%rdi) + adcq 136(%rdx), %r8 movq 144(%rsi), %rcx + movq %r8, 136(%rdi) adcq 144(%rdx), %rcx + movq 152(%rsi), %r8 movq %rcx, 144(%rdi) - movq 152(%rsi), %rcx - adcq 152(%rdx), %rcx - movq %rcx, 152(%rdi) + adcq 152(%rdx), %r8 movq 160(%rsi), %rcx + movq %r8, 152(%rdi) adcq 160(%rdx), %rcx + movq 168(%rsi), %r8 movq %rcx, 160(%rdi) - movq 168(%rsi), %rcx - adcq 168(%rdx), %rcx - movq %rcx, 168(%rdi) + adcq 168(%rdx), %r8 movq 176(%rsi), %rcx + movq %r8, 168(%rdi) adcq 176(%rdx), %rcx + movq 184(%rsi), %r8 movq %rcx, 176(%rdi) - movq 184(%rsi), %rcx - adcq 184(%rdx), %rcx - movq %rcx, 184(%rdi) + adcq 184(%rdx), %r8 movq 192(%rsi), %rcx + movq %r8, 184(%rdi) adcq 192(%rdx), %rcx + movq 200(%rsi), %r8 movq %rcx, 192(%rdi) - movq 200(%rsi), %rcx - adcq 200(%rdx), %rcx - movq %rcx, 200(%rdi) + adcq 200(%rdx), %r8 movq 208(%rsi), %rcx + movq %r8, 200(%rdi) adcq 208(%rdx), %rcx + movq 216(%rsi), %r8 movq %rcx, 208(%rdi) - movq 216(%rsi), %rcx - adcq 216(%rdx), %rcx - movq %rcx, 216(%rdi) + adcq 216(%rdx), %r8 movq 224(%rsi), %rcx + movq %r8, 216(%rdi) adcq 224(%rdx), %rcx + movq 232(%rsi), %r8 movq %rcx, 224(%rdi) - movq 232(%rsi), %rcx - adcq 232(%rdx), %rcx - movq %rcx, 232(%rdi) + adcq 232(%rdx), %r8 movq 240(%rsi), %rcx + movq %r8, 232(%rdi) adcq 240(%rdx), %rcx + movq 248(%rsi), %r8 movq %rcx, 240(%rdi) - movq 248(%rsi), %rcx - adcq 248(%rdx), %rcx - movq %rcx, 248(%rdi) + adcq 248(%rdx), %r8 movq 256(%rsi), %rcx + movq %r8, 248(%rdi) adcq 256(%rdx), %rcx + movq 264(%rsi), %r8 movq %rcx, 256(%rdi) - movq 264(%rsi), %rcx - adcq 264(%rdx), %rcx - movq %rcx, 264(%rdi) + adcq 264(%rdx), %r8 movq 272(%rsi), %rcx + movq %r8, 264(%rdi) adcq 272(%rdx), %rcx + movq 280(%rsi), %r8 movq %rcx, 272(%rdi) - movq 280(%rsi), %rcx - adcq 280(%rdx), %rcx - movq %rcx, 280(%rdi) + adcq 280(%rdx), %r8 movq 288(%rsi), %rcx + movq %r8, 280(%rdi) adcq 288(%rdx), %rcx + movq 296(%rsi), %r8 movq %rcx, 288(%rdi) - movq 296(%rsi), %rcx - adcq 296(%rdx), %rcx - movq %rcx, 296(%rdi) + adcq 296(%rdx), %r8 movq 304(%rsi), %rcx + movq %r8, 296(%rdi) adcq 304(%rdx), %rcx + movq 312(%rsi), %r8 movq %rcx, 304(%rdi) - movq 312(%rsi), %rcx - adcq 312(%rdx), %rcx - movq %rcx, 312(%rdi) + adcq 312(%rdx), %r8 movq 320(%rsi), %rcx + movq %r8, 312(%rdi) adcq 320(%rdx), %rcx + movq 328(%rsi), %r8 movq %rcx, 320(%rdi) - movq 328(%rsi), %rcx - adcq 328(%rdx), %rcx - movq %rcx, 328(%rdi) + adcq 328(%rdx), %r8 movq 336(%rsi), %rcx + movq %r8, 328(%rdi) adcq 336(%rdx), %rcx + movq 344(%rsi), %r8 movq %rcx, 336(%rdi) - movq 344(%rsi), %rcx - adcq 344(%rdx), %rcx - movq %rcx, 344(%rdi) + adcq 344(%rdx), %r8 movq 352(%rsi), %rcx + movq %r8, 344(%rdi) adcq 352(%rdx), %rcx + movq 360(%rsi), %r8 movq %rcx, 352(%rdi) - movq 360(%rsi), %rcx - adcq 360(%rdx), %rcx - movq %rcx, 360(%rdi) + adcq 360(%rdx), %r8 movq 368(%rsi), %rcx + movq %r8, 360(%rdi) adcq 368(%rdx), %rcx + movq 376(%rsi), %r8 movq %rcx, 368(%rdi) - movq 376(%rsi), %rcx - adcq 376(%rdx), %rcx - movq %rcx, 376(%rdi) + adcq 376(%rdx), %r8 movq 384(%rsi), %rcx + movq %r8, 376(%rdi) adcq 384(%rdx), %rcx + movq 392(%rsi), %r8 movq %rcx, 384(%rdi) - movq 392(%rsi), %rcx - adcq 392(%rdx), %rcx - movq %rcx, 392(%rdi) + adcq 392(%rdx), %r8 movq 400(%rsi), %rcx + movq %r8, 392(%rdi) adcq 400(%rdx), %rcx + movq 408(%rsi), %r8 movq %rcx, 400(%rdi) - movq 408(%rsi), %rcx - adcq 408(%rdx), %rcx - movq %rcx, 408(%rdi) + adcq 408(%rdx), %r8 movq 416(%rsi), %rcx + movq %r8, 408(%rdi) adcq 416(%rdx), %rcx + movq 424(%rsi), %r8 movq %rcx, 416(%rdi) - movq 424(%rsi), %rcx - adcq 424(%rdx), %rcx - movq %rcx, 424(%rdi) + adcq 424(%rdx), %r8 movq 432(%rsi), %rcx + movq %r8, 424(%rdi) adcq 432(%rdx), %rcx + movq 440(%rsi), %r8 movq %rcx, 432(%rdi) - movq 440(%rsi), %rcx - adcq 440(%rdx), %rcx - movq %rcx, 440(%rdi) + adcq 440(%rdx), %r8 movq 448(%rsi), %rcx + movq %r8, 440(%rdi) adcq 448(%rdx), %rcx + movq 456(%rsi), %r8 movq %rcx, 448(%rdi) - movq 456(%rsi), %rcx - adcq 456(%rdx), %rcx - movq %rcx, 456(%rdi) + adcq 456(%rdx), %r8 movq 464(%rsi), %rcx + movq %r8, 456(%rdi) adcq 464(%rdx), %rcx + movq 472(%rsi), %r8 movq %rcx, 464(%rdi) - movq 472(%rsi), %rcx - adcq 472(%rdx), %rcx - movq %rcx, 472(%rdi) + adcq 472(%rdx), %r8 movq 480(%rsi), %rcx + movq %r8, 472(%rdi) adcq 480(%rdx), %rcx + movq 488(%rsi), %r8 movq %rcx, 480(%rdi) - movq 488(%rsi), %rcx - adcq 488(%rdx), %rcx - movq %rcx, 488(%rdi) + adcq 488(%rdx), %r8 movq 496(%rsi), %rcx + movq %r8, 488(%rdi) adcq 496(%rdx), %rcx + movq 504(%rsi), %r8 movq %rcx, 496(%rdi) - movq 504(%rsi), %rcx - adcq 504(%rdx), %rcx - movq %rcx, 504(%rdi) + adcq 504(%rdx), %r8 + movq %r8, 504(%rdi) adcq $0, %rax repz retq #ifndef __APPLE__ @@ -26804,6 +28236,350 @@ L_mont_loop_64: #ifndef __APPLE__ .size sp_4096_mont_reduce_64,.-sp_4096_mont_reduce_64 #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__ +.globl sp_4096_cond_sub_avx2_64 +.type sp_4096_cond_sub_avx2_64,@function +.align 16 +sp_4096_cond_sub_avx2_64: +#else +.globl _sp_4096_cond_sub_avx2_64 +.p2align 4 +_sp_4096_cond_sub_avx2_64: +#endif /* __APPLE__ */ + movq $0, %rax + movq (%rsi), %r8 + movq (%rdx), %r10 + pextq %rcx, %r10, %r10 + subq %r10, %r8 + movq 8(%rsi), %r9 + movq 8(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, (%rdi) + sbbq %r10, %r9 + movq 16(%rsi), %r8 + movq 16(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 8(%rdi) + sbbq %r10, %r8 + movq 24(%rsi), %r9 + movq 24(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 16(%rdi) + sbbq %r10, %r9 + movq 32(%rsi), %r8 + movq 32(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 24(%rdi) + sbbq %r10, %r8 + movq 40(%rsi), %r9 + movq 40(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 32(%rdi) + sbbq %r10, %r9 + movq 48(%rsi), %r8 + movq 48(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 40(%rdi) + sbbq %r10, %r8 + movq 56(%rsi), %r9 + movq 56(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 48(%rdi) + sbbq %r10, %r9 + movq 64(%rsi), %r8 + movq 64(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 56(%rdi) + sbbq %r10, %r8 + movq 72(%rsi), %r9 + movq 72(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 64(%rdi) + sbbq %r10, %r9 + movq 80(%rsi), %r8 + movq 80(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 72(%rdi) + sbbq %r10, %r8 + movq 88(%rsi), %r9 + movq 88(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 80(%rdi) + sbbq %r10, %r9 + movq 96(%rsi), %r8 + movq 96(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 88(%rdi) + sbbq %r10, %r8 + movq 104(%rsi), %r9 + movq 104(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 96(%rdi) + sbbq %r10, %r9 + movq 112(%rsi), %r8 + movq 112(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 104(%rdi) + sbbq %r10, %r8 + movq 120(%rsi), %r9 + movq 120(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 112(%rdi) + sbbq %r10, %r9 + movq 128(%rsi), %r8 + movq 128(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 120(%rdi) + sbbq %r10, %r8 + movq 136(%rsi), %r9 + movq 136(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 128(%rdi) + sbbq %r10, %r9 + movq 144(%rsi), %r8 + movq 144(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 136(%rdi) + sbbq %r10, %r8 + movq 152(%rsi), %r9 + movq 152(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 144(%rdi) + sbbq %r10, %r9 + movq 160(%rsi), %r8 + movq 160(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 152(%rdi) + sbbq %r10, %r8 + movq 168(%rsi), %r9 + movq 168(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 160(%rdi) + sbbq %r10, %r9 + movq 176(%rsi), %r8 + movq 176(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 168(%rdi) + sbbq %r10, %r8 + movq 184(%rsi), %r9 + movq 184(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 176(%rdi) + sbbq %r10, %r9 + movq 192(%rsi), %r8 + movq 192(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 184(%rdi) + sbbq %r10, %r8 + movq 200(%rsi), %r9 + movq 200(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 192(%rdi) + sbbq %r10, %r9 + movq 208(%rsi), %r8 + movq 208(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 200(%rdi) + sbbq %r10, %r8 + movq 216(%rsi), %r9 + movq 216(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 208(%rdi) + sbbq %r10, %r9 + movq 224(%rsi), %r8 + movq 224(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 216(%rdi) + sbbq %r10, %r8 + movq 232(%rsi), %r9 + movq 232(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 224(%rdi) + sbbq %r10, %r9 + movq 240(%rsi), %r8 + movq 240(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 232(%rdi) + sbbq %r10, %r8 + movq 248(%rsi), %r9 + movq 248(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 240(%rdi) + sbbq %r10, %r9 + movq 256(%rsi), %r8 + movq 256(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 248(%rdi) + sbbq %r10, %r8 + movq 264(%rsi), %r9 + movq 264(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 256(%rdi) + sbbq %r10, %r9 + movq 272(%rsi), %r8 + movq 272(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 264(%rdi) + sbbq %r10, %r8 + movq 280(%rsi), %r9 + movq 280(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 272(%rdi) + sbbq %r10, %r9 + movq 288(%rsi), %r8 + movq 288(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 280(%rdi) + sbbq %r10, %r8 + movq 296(%rsi), %r9 + movq 296(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 288(%rdi) + sbbq %r10, %r9 + movq 304(%rsi), %r8 + movq 304(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 296(%rdi) + sbbq %r10, %r8 + movq 312(%rsi), %r9 + movq 312(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 304(%rdi) + sbbq %r10, %r9 + movq 320(%rsi), %r8 + movq 320(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 312(%rdi) + sbbq %r10, %r8 + movq 328(%rsi), %r9 + movq 328(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 320(%rdi) + sbbq %r10, %r9 + movq 336(%rsi), %r8 + movq 336(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 328(%rdi) + sbbq %r10, %r8 + movq 344(%rsi), %r9 + movq 344(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 336(%rdi) + sbbq %r10, %r9 + movq 352(%rsi), %r8 + movq 352(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 344(%rdi) + sbbq %r10, %r8 + movq 360(%rsi), %r9 + movq 360(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 352(%rdi) + sbbq %r10, %r9 + movq 368(%rsi), %r8 + movq 368(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 360(%rdi) + sbbq %r10, %r8 + movq 376(%rsi), %r9 + movq 376(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 368(%rdi) + sbbq %r10, %r9 + movq 384(%rsi), %r8 + movq 384(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 376(%rdi) + sbbq %r10, %r8 + movq 392(%rsi), %r9 + movq 392(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 384(%rdi) + sbbq %r10, %r9 + movq 400(%rsi), %r8 + movq 400(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 392(%rdi) + sbbq %r10, %r8 + movq 408(%rsi), %r9 + movq 408(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 400(%rdi) + sbbq %r10, %r9 + movq 416(%rsi), %r8 + movq 416(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 408(%rdi) + sbbq %r10, %r8 + movq 424(%rsi), %r9 + movq 424(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 416(%rdi) + sbbq %r10, %r9 + movq 432(%rsi), %r8 + movq 432(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 424(%rdi) + sbbq %r10, %r8 + movq 440(%rsi), %r9 + movq 440(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 432(%rdi) + sbbq %r10, %r9 + movq 448(%rsi), %r8 + movq 448(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 440(%rdi) + sbbq %r10, %r8 + movq 456(%rsi), %r9 + movq 456(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 448(%rdi) + sbbq %r10, %r9 + movq 464(%rsi), %r8 + movq 464(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 456(%rdi) + sbbq %r10, %r8 + movq 472(%rsi), %r9 + movq 472(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 464(%rdi) + sbbq %r10, %r9 + movq 480(%rsi), %r8 + movq 480(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 472(%rdi) + sbbq %r10, %r8 + movq 488(%rsi), %r9 + movq 488(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 480(%rdi) + sbbq %r10, %r9 + movq 496(%rsi), %r8 + movq 496(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 488(%rdi) + sbbq %r10, %r8 + movq 504(%rsi), %r9 + movq 504(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 496(%rdi) + sbbq %r10, %r9 + movq %r9, 504(%rdi) + sbbq $0, %rax + repz retq +#ifndef __APPLE__ +.size sp_4096_cond_sub_avx2_64,.-sp_4096_cond_sub_avx2_64 +#endif /* __APPLE__ */ #ifdef HAVE_INTEL_AVX2 /* Mul a by digit b into r. (r = a * b) * @@ -26821,392 +28597,390 @@ sp_4096_mul_d_avx2_64: .p2align 4 _sp_4096_mul_d_avx2_64: #endif /* __APPLE__ */ - movq %rdx, %rax # A[0] * B - movq %rax, %rdx - xorq %r11, %r11 - mulxq (%rsi), %r9, %r10 - movq %r9, (%rdi) + xorq %r10, %r10 + mulxq (%rsi), %r8, %r9 + movq %r8, (%rdi) # A[1] * B - mulxq 8(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 8(%rdi) - adoxq %r8, %r9 + mulxq 8(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 8(%rdi) + adoxq %rcx, %r8 # A[2] * B - mulxq 16(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 16(%rdi) - adoxq %r8, %r10 + mulxq 16(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 16(%rdi) + adoxq %rcx, %r9 # A[3] * B - mulxq 24(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 24(%rdi) - adoxq %r8, %r9 + mulxq 24(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 24(%rdi) + adoxq %rcx, %r8 # A[4] * B - mulxq 32(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 32(%rdi) - adoxq %r8, %r10 + mulxq 32(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 32(%rdi) + adoxq %rcx, %r9 # A[5] * B - mulxq 40(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 40(%rdi) - adoxq %r8, %r9 + mulxq 40(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 40(%rdi) + adoxq %rcx, %r8 # A[6] * B - mulxq 48(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 48(%rdi) - adoxq %r8, %r10 + mulxq 48(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 48(%rdi) + adoxq %rcx, %r9 # A[7] * B - mulxq 56(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 56(%rdi) - adoxq %r8, %r9 + mulxq 56(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 56(%rdi) + adoxq %rcx, %r8 # A[8] * B - mulxq 64(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 64(%rdi) - adoxq %r8, %r10 + mulxq 64(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 64(%rdi) + adoxq %rcx, %r9 # A[9] * B - mulxq 72(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 72(%rdi) - adoxq %r8, %r9 + mulxq 72(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 72(%rdi) + adoxq %rcx, %r8 # A[10] * B - mulxq 80(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 80(%rdi) - adoxq %r8, %r10 + mulxq 80(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 80(%rdi) + adoxq %rcx, %r9 # A[11] * B - mulxq 88(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 88(%rdi) - adoxq %r8, %r9 + mulxq 88(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 88(%rdi) + adoxq %rcx, %r8 # A[12] * B - mulxq 96(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 96(%rdi) - adoxq %r8, %r10 + mulxq 96(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 96(%rdi) + adoxq %rcx, %r9 # A[13] * B - mulxq 104(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 104(%rdi) - adoxq %r8, %r9 + mulxq 104(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 104(%rdi) + adoxq %rcx, %r8 # A[14] * B - mulxq 112(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 112(%rdi) - adoxq %r8, %r10 + mulxq 112(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 112(%rdi) + adoxq %rcx, %r9 # A[15] * B - mulxq 120(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 120(%rdi) - adoxq %r8, %r9 + mulxq 120(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 120(%rdi) + adoxq %rcx, %r8 # A[16] * B - mulxq 128(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 128(%rdi) - adoxq %r8, %r10 + mulxq 128(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 128(%rdi) + adoxq %rcx, %r9 # A[17] * B - mulxq 136(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 136(%rdi) - adoxq %r8, %r9 + mulxq 136(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 136(%rdi) + adoxq %rcx, %r8 # A[18] * B - mulxq 144(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 144(%rdi) - adoxq %r8, %r10 + mulxq 144(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 144(%rdi) + adoxq %rcx, %r9 # A[19] * B - mulxq 152(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 152(%rdi) - adoxq %r8, %r9 + mulxq 152(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 152(%rdi) + adoxq %rcx, %r8 # A[20] * B - mulxq 160(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 160(%rdi) - adoxq %r8, %r10 + mulxq 160(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 160(%rdi) + adoxq %rcx, %r9 # A[21] * B - mulxq 168(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 168(%rdi) - adoxq %r8, %r9 + mulxq 168(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 168(%rdi) + adoxq %rcx, %r8 # A[22] * B - mulxq 176(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 176(%rdi) - adoxq %r8, %r10 + mulxq 176(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 176(%rdi) + adoxq %rcx, %r9 # A[23] * B - mulxq 184(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 184(%rdi) - adoxq %r8, %r9 + mulxq 184(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 184(%rdi) + adoxq %rcx, %r8 # A[24] * B - mulxq 192(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 192(%rdi) - adoxq %r8, %r10 + mulxq 192(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 192(%rdi) + adoxq %rcx, %r9 # A[25] * B - mulxq 200(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 200(%rdi) - adoxq %r8, %r9 + mulxq 200(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 200(%rdi) + adoxq %rcx, %r8 # A[26] * B - mulxq 208(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 208(%rdi) - adoxq %r8, %r10 + mulxq 208(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 208(%rdi) + adoxq %rcx, %r9 # A[27] * B - mulxq 216(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 216(%rdi) - adoxq %r8, %r9 + mulxq 216(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 216(%rdi) + adoxq %rcx, %r8 # A[28] * B - mulxq 224(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 224(%rdi) - adoxq %r8, %r10 + mulxq 224(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 224(%rdi) + adoxq %rcx, %r9 # A[29] * B - mulxq 232(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 232(%rdi) - adoxq %r8, %r9 + mulxq 232(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 232(%rdi) + adoxq %rcx, %r8 # A[30] * B - mulxq 240(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 240(%rdi) - adoxq %r8, %r10 + mulxq 240(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 240(%rdi) + adoxq %rcx, %r9 # A[31] * B - mulxq 248(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 248(%rdi) - adoxq %r8, %r9 + mulxq 248(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 248(%rdi) + adoxq %rcx, %r8 # A[32] * B - mulxq 256(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 256(%rdi) - adoxq %r8, %r10 + mulxq 256(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 256(%rdi) + adoxq %rcx, %r9 # A[33] * B - mulxq 264(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 264(%rdi) - adoxq %r8, %r9 + mulxq 264(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 264(%rdi) + adoxq %rcx, %r8 # A[34] * B - mulxq 272(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 272(%rdi) - adoxq %r8, %r10 + mulxq 272(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 272(%rdi) + adoxq %rcx, %r9 # A[35] * B - mulxq 280(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 280(%rdi) - adoxq %r8, %r9 + mulxq 280(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 280(%rdi) + adoxq %rcx, %r8 # A[36] * B - mulxq 288(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 288(%rdi) - adoxq %r8, %r10 + mulxq 288(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 288(%rdi) + adoxq %rcx, %r9 # A[37] * B - mulxq 296(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 296(%rdi) - adoxq %r8, %r9 + mulxq 296(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 296(%rdi) + adoxq %rcx, %r8 # A[38] * B - mulxq 304(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 304(%rdi) - adoxq %r8, %r10 + mulxq 304(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 304(%rdi) + adoxq %rcx, %r9 # A[39] * B - mulxq 312(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 312(%rdi) - adoxq %r8, %r9 + mulxq 312(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 312(%rdi) + adoxq %rcx, %r8 # A[40] * B - mulxq 320(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 320(%rdi) - adoxq %r8, %r10 + mulxq 320(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 320(%rdi) + adoxq %rcx, %r9 # A[41] * B - mulxq 328(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 328(%rdi) - adoxq %r8, %r9 + mulxq 328(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 328(%rdi) + adoxq %rcx, %r8 # A[42] * B - mulxq 336(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 336(%rdi) - adoxq %r8, %r10 + mulxq 336(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 336(%rdi) + adoxq %rcx, %r9 # A[43] * B - mulxq 344(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 344(%rdi) - adoxq %r8, %r9 + mulxq 344(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 344(%rdi) + adoxq %rcx, %r8 # A[44] * B - mulxq 352(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 352(%rdi) - adoxq %r8, %r10 + mulxq 352(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 352(%rdi) + adoxq %rcx, %r9 # A[45] * B - mulxq 360(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 360(%rdi) - adoxq %r8, %r9 + mulxq 360(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 360(%rdi) + adoxq %rcx, %r8 # A[46] * B - mulxq 368(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 368(%rdi) - adoxq %r8, %r10 + mulxq 368(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 368(%rdi) + adoxq %rcx, %r9 # A[47] * B - mulxq 376(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 376(%rdi) - adoxq %r8, %r9 + mulxq 376(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 376(%rdi) + adoxq %rcx, %r8 # A[48] * B - mulxq 384(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 384(%rdi) - adoxq %r8, %r10 + mulxq 384(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 384(%rdi) + adoxq %rcx, %r9 # A[49] * B - mulxq 392(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 392(%rdi) - adoxq %r8, %r9 + mulxq 392(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 392(%rdi) + adoxq %rcx, %r8 # A[50] * B - mulxq 400(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 400(%rdi) - adoxq %r8, %r10 + mulxq 400(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 400(%rdi) + adoxq %rcx, %r9 # A[51] * B - mulxq 408(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 408(%rdi) - adoxq %r8, %r9 + mulxq 408(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 408(%rdi) + adoxq %rcx, %r8 # A[52] * B - mulxq 416(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 416(%rdi) - adoxq %r8, %r10 + mulxq 416(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 416(%rdi) + adoxq %rcx, %r9 # A[53] * B - mulxq 424(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 424(%rdi) - adoxq %r8, %r9 + mulxq 424(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 424(%rdi) + adoxq %rcx, %r8 # A[54] * B - mulxq 432(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 432(%rdi) - adoxq %r8, %r10 + mulxq 432(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 432(%rdi) + adoxq %rcx, %r9 # A[55] * B - mulxq 440(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 440(%rdi) - adoxq %r8, %r9 + mulxq 440(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 440(%rdi) + adoxq %rcx, %r8 # A[56] * B - mulxq 448(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 448(%rdi) - adoxq %r8, %r10 + mulxq 448(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 448(%rdi) + adoxq %rcx, %r9 # A[57] * B - mulxq 456(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 456(%rdi) - adoxq %r8, %r9 + mulxq 456(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 456(%rdi) + adoxq %rcx, %r8 # A[58] * B - mulxq 464(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 464(%rdi) - adoxq %r8, %r10 + mulxq 464(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 464(%rdi) + adoxq %rcx, %r9 # A[59] * B - mulxq 472(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 472(%rdi) - adoxq %r8, %r9 + mulxq 472(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 472(%rdi) + adoxq %rcx, %r8 # A[60] * B - mulxq 480(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 480(%rdi) - adoxq %r8, %r10 + mulxq 480(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 480(%rdi) + adoxq %rcx, %r9 # A[61] * B - mulxq 488(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 488(%rdi) - adoxq %r8, %r9 + mulxq 488(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 488(%rdi) + adoxq %rcx, %r8 # A[62] * B - mulxq 496(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 496(%rdi) - adoxq %r8, %r10 + mulxq 496(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 496(%rdi) + adoxq %rcx, %r9 # A[63] * B - mulxq 504(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - adoxq %r8, %r9 - adcxq %r11, %r9 - movq %r10, 504(%rdi) - movq %r9, 512(%rdi) + mulxq 504(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + adoxq %rcx, %r8 + adcxq %r10, %r8 + movq %r9, 504(%rdi) + movq %r8, 512(%rdi) repz retq #ifndef __APPLE__ .size sp_4096_mul_d_avx2_64,.-sp_4096_mul_d_avx2_64 @@ -27750,6 +29524,220 @@ _sp_4096_cmp_64: #ifndef __APPLE__ .size sp_4096_cmp_64,.-sp_4096_cmp_64 #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__ +.globl sp_4096_sub_64 +.type sp_4096_sub_64,@function +.align 16 +sp_4096_sub_64: +#else +.globl _sp_4096_sub_64 +.p2align 4 +_sp_4096_sub_64: +#endif /* __APPLE__ */ + movq (%rsi), %r8 + xorq %rax, %rax + subq (%rdx), %r8 + movq 8(%rsi), %r9 + movq %r8, (%rdi) + sbbq 8(%rdx), %r9 + movq 16(%rsi), %r8 + movq %r9, 8(%rdi) + sbbq 16(%rdx), %r8 + movq 24(%rsi), %r9 + movq %r8, 16(%rdi) + sbbq 24(%rdx), %r9 + movq 32(%rsi), %r8 + movq %r9, 24(%rdi) + sbbq 32(%rdx), %r8 + movq 40(%rsi), %r9 + movq %r8, 32(%rdi) + sbbq 40(%rdx), %r9 + movq 48(%rsi), %r8 + movq %r9, 40(%rdi) + sbbq 48(%rdx), %r8 + movq 56(%rsi), %r9 + movq %r8, 48(%rdi) + sbbq 56(%rdx), %r9 + movq 64(%rsi), %r8 + movq %r9, 56(%rdi) + sbbq 64(%rdx), %r8 + movq 72(%rsi), %r9 + movq %r8, 64(%rdi) + sbbq 72(%rdx), %r9 + movq 80(%rsi), %r8 + movq %r9, 72(%rdi) + sbbq 80(%rdx), %r8 + movq 88(%rsi), %r9 + movq %r8, 80(%rdi) + sbbq 88(%rdx), %r9 + movq 96(%rsi), %r8 + movq %r9, 88(%rdi) + sbbq 96(%rdx), %r8 + movq 104(%rsi), %r9 + movq %r8, 96(%rdi) + sbbq 104(%rdx), %r9 + movq 112(%rsi), %r8 + movq %r9, 104(%rdi) + sbbq 112(%rdx), %r8 + movq 120(%rsi), %r9 + movq %r8, 112(%rdi) + sbbq 120(%rdx), %r9 + movq 128(%rsi), %r8 + movq %r9, 120(%rdi) + sbbq 128(%rdx), %r8 + movq 136(%rsi), %r9 + movq %r8, 128(%rdi) + sbbq 136(%rdx), %r9 + movq 144(%rsi), %r8 + movq %r9, 136(%rdi) + sbbq 144(%rdx), %r8 + movq 152(%rsi), %r9 + movq %r8, 144(%rdi) + sbbq 152(%rdx), %r9 + movq 160(%rsi), %r8 + movq %r9, 152(%rdi) + sbbq 160(%rdx), %r8 + movq 168(%rsi), %r9 + movq %r8, 160(%rdi) + sbbq 168(%rdx), %r9 + movq 176(%rsi), %r8 + movq %r9, 168(%rdi) + sbbq 176(%rdx), %r8 + movq 184(%rsi), %r9 + movq %r8, 176(%rdi) + sbbq 184(%rdx), %r9 + movq 192(%rsi), %r8 + movq %r9, 184(%rdi) + sbbq 192(%rdx), %r8 + movq 200(%rsi), %r9 + movq %r8, 192(%rdi) + sbbq 200(%rdx), %r9 + movq 208(%rsi), %r8 + movq %r9, 200(%rdi) + sbbq 208(%rdx), %r8 + movq 216(%rsi), %r9 + movq %r8, 208(%rdi) + sbbq 216(%rdx), %r9 + movq 224(%rsi), %r8 + movq %r9, 216(%rdi) + sbbq 224(%rdx), %r8 + movq 232(%rsi), %r9 + movq %r8, 224(%rdi) + sbbq 232(%rdx), %r9 + movq 240(%rsi), %r8 + movq %r9, 232(%rdi) + sbbq 240(%rdx), %r8 + movq 248(%rsi), %r9 + movq %r8, 240(%rdi) + sbbq 248(%rdx), %r9 + movq 256(%rsi), %r8 + movq %r9, 248(%rdi) + sbbq 256(%rdx), %r8 + movq 264(%rsi), %r9 + movq %r8, 256(%rdi) + sbbq 264(%rdx), %r9 + movq 272(%rsi), %r8 + movq %r9, 264(%rdi) + sbbq 272(%rdx), %r8 + movq 280(%rsi), %r9 + movq %r8, 272(%rdi) + sbbq 280(%rdx), %r9 + movq 288(%rsi), %r8 + movq %r9, 280(%rdi) + sbbq 288(%rdx), %r8 + movq 296(%rsi), %r9 + movq %r8, 288(%rdi) + sbbq 296(%rdx), %r9 + movq 304(%rsi), %r8 + movq %r9, 296(%rdi) + sbbq 304(%rdx), %r8 + movq 312(%rsi), %r9 + movq %r8, 304(%rdi) + sbbq 312(%rdx), %r9 + movq 320(%rsi), %r8 + movq %r9, 312(%rdi) + sbbq 320(%rdx), %r8 + movq 328(%rsi), %r9 + movq %r8, 320(%rdi) + sbbq 328(%rdx), %r9 + movq 336(%rsi), %r8 + movq %r9, 328(%rdi) + sbbq 336(%rdx), %r8 + movq 344(%rsi), %r9 + movq %r8, 336(%rdi) + sbbq 344(%rdx), %r9 + movq 352(%rsi), %r8 + movq %r9, 344(%rdi) + sbbq 352(%rdx), %r8 + movq 360(%rsi), %r9 + movq %r8, 352(%rdi) + sbbq 360(%rdx), %r9 + movq 368(%rsi), %r8 + movq %r9, 360(%rdi) + sbbq 368(%rdx), %r8 + movq 376(%rsi), %r9 + movq %r8, 368(%rdi) + sbbq 376(%rdx), %r9 + movq 384(%rsi), %r8 + movq %r9, 376(%rdi) + sbbq 384(%rdx), %r8 + movq 392(%rsi), %r9 + movq %r8, 384(%rdi) + sbbq 392(%rdx), %r9 + movq 400(%rsi), %r8 + movq %r9, 392(%rdi) + sbbq 400(%rdx), %r8 + movq 408(%rsi), %r9 + movq %r8, 400(%rdi) + sbbq 408(%rdx), %r9 + movq 416(%rsi), %r8 + movq %r9, 408(%rdi) + sbbq 416(%rdx), %r8 + movq 424(%rsi), %r9 + movq %r8, 416(%rdi) + sbbq 424(%rdx), %r9 + movq 432(%rsi), %r8 + movq %r9, 424(%rdi) + sbbq 432(%rdx), %r8 + movq 440(%rsi), %r9 + movq %r8, 432(%rdi) + sbbq 440(%rdx), %r9 + movq 448(%rsi), %r8 + movq %r9, 440(%rdi) + sbbq 448(%rdx), %r8 + movq 456(%rsi), %r9 + movq %r8, 448(%rdi) + sbbq 456(%rdx), %r9 + movq 464(%rsi), %r8 + movq %r9, 456(%rdi) + sbbq 464(%rdx), %r8 + movq 472(%rsi), %r9 + movq %r8, 464(%rdi) + sbbq 472(%rdx), %r9 + movq 480(%rsi), %r8 + movq %r9, 472(%rdi) + sbbq 480(%rdx), %r8 + movq 488(%rsi), %r9 + movq %r8, 480(%rdi) + sbbq 488(%rdx), %r9 + movq 496(%rsi), %r8 + movq %r9, 488(%rdi) + sbbq 496(%rdx), %r8 + movq 504(%rsi), %r9 + movq %r8, 496(%rdi) + sbbq 504(%rdx), %r9 + movq %r9, 504(%rdi) + sbbq $0, %rax + repz retq +#ifndef __APPLE__ +.size sp_4096_sub_64,.-sp_4096_sub_64 +#endif /* __APPLE__ */ #ifdef HAVE_INTEL_AVX2 /* Reduce the number back to 4096 bits using Montgomery reduction. * @@ -28180,9 +30168,9 @@ L_mont_loop_avx2_64: movq %rdi, %rdi subq $512, %rdi #ifndef __APPLE__ - callq sp_4096_cond_sub_64@plt + callq sp_4096_cond_sub_avx2_64@plt #else - callq _sp_4096_cond_sub_64 + callq _sp_4096_cond_sub_avx2_64 #endif /* __APPLE__ */ pop %r14 pop %r13 @@ -29675,6 +31663,116 @@ _sp_256_add_one_4: #ifndef __APPLE__ .size sp_256_add_one_4,.-sp_256_add_one_4 #endif /* __APPLE__ */ +/* 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. + */ +#ifndef __APPLE__ +.globl sp_256_from_bin +.type sp_256_from_bin,@function +.align 16 +sp_256_from_bin: +#else +.globl _sp_256_from_bin +.p2align 4 +_sp_256_from_bin: +#endif /* __APPLE__ */ + movq %rdx, %r9 + movq %rdi, %r10 + addq %rcx, %r9 + addq $32, %r10 + xorq %r11, %r11 + jmp L_256_from_bin_64_end +L_256_from_bin_64_start: + subq $64, %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 $64, %rdi + subq $64, %rcx +L_256_from_bin_64_end: + cmpq $63, %rcx + jg L_256_from_bin_64_start + jmp L_256_from_bin_8_end +L_256_from_bin_8_start: + subq $8, %r9 + movbeq (%r9), %rax + movq %rax, (%rdi) + addq $8, %rdi + subq $8, %rcx +L_256_from_bin_8_end: + cmpq $7, %rcx + jg L_256_from_bin_8_start + cmpq %r11, %rcx + je L_256_from_bin_hi_end + movq %r11, %r8 + movq %r11, %rax +L_256_from_bin_hi_start: + movb (%rdx), %al + shlq $8, %r8 + incq %rdx + addq %rax, %r8 + decq %rcx + jg L_256_from_bin_hi_start + movq %r8, (%rdi) + addq $8, %rdi +L_256_from_bin_hi_end: + cmpq %r10, %rdi + je L_256_from_bin_zero_end +L_256_from_bin_zero_start: + movq %r11, (%rdi) + addq $8, %rdi + cmpq %r10, %rdi + jl L_256_from_bin_zero_start +L_256_from_bin_zero_end: + repz retq +#ifndef __APPLE__ +.size sp_256_from_bin,.-sp_256_from_bin +#endif /* __APPLE__ */ +/* Write r as big endian to byte array. + * Fixed length number of bytes written: 32 + * + * r A single precision integer. + * a Byte array. + */ +#ifndef __APPLE__ +.globl sp_256_to_bin +.type sp_256_to_bin,@function +.align 16 +sp_256_to_bin: +#else +.globl _sp_256_to_bin +.p2align 4 +_sp_256_to_bin: +#endif /* __APPLE__ */ + movbeq 24(%rdi), %rdx + movbeq 16(%rdi), %rax + movq %rdx, (%rsi) + movq %rax, 8(%rsi) + movbeq 8(%rdi), %rdx + movbeq (%rdi), %rax + movq %rdx, 16(%rsi) + movq %rax, 24(%rsi) + repz retq +#ifndef __APPLE__ +.size sp_256_to_bin,.-sp_256_to_bin +#endif /* __APPLE__ */ /* Add b to a into r. (r = a + b) * * r A single precision integer. @@ -29691,19 +31789,19 @@ sp_256_add_4: .p2align 4 _sp_256_add_4: #endif /* __APPLE__ */ - xorq %rax, %rax movq (%rsi), %rcx + xorq %rax, %rax addq (%rdx), %rcx + movq 8(%rsi), %r8 movq %rcx, (%rdi) - movq 8(%rsi), %rcx - adcq 8(%rdx), %rcx - movq %rcx, 8(%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) - movq 24(%rsi), %rcx - adcq 24(%rdx), %rcx - movq %rcx, 24(%rdi) + adcq 24(%rdx), %r8 + movq %r8, 24(%rdi) adcq $0, %rax repz retq #ifndef __APPLE__ @@ -29992,6 +32090,58 @@ _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__ +.globl sp_256_cond_sub_avx2_4 +.type sp_256_cond_sub_avx2_4,@function +.align 16 +sp_256_cond_sub_avx2_4: +#else +.globl _sp_256_cond_sub_avx2_4 +.p2align 4 +_sp_256_cond_sub_avx2_4: +#endif /* __APPLE__ */ + push %r12 + push %r13 + push %r14 + push %r15 + movq $0, %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 $0, %rax + pop %r15 + pop %r14 + pop %r13 + pop %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. @@ -30060,32 +32210,30 @@ sp_256_mul_d_avx2_4: .p2align 4 _sp_256_mul_d_avx2_4: #endif /* __APPLE__ */ - movq %rdx, %rax # A[0] * B - movq %rax, %rdx - xorq %r11, %r11 - mulxq (%rsi), %r9, %r10 - movq %r9, (%rdi) + xorq %r10, %r10 + mulxq (%rsi), %r8, %r9 + movq %r8, (%rdi) # A[1] * B - mulxq 8(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - movq %r10, 8(%rdi) - adoxq %r8, %r9 + mulxq 8(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 8(%rdi) + adoxq %rcx, %r8 # A[2] * B - mulxq 16(%rsi), %rcx, %r8 - movq %r11, %r10 - adcxq %rcx, %r9 - movq %r9, 16(%rdi) - adoxq %r8, %r10 + mulxq 16(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 16(%rdi) + adoxq %rcx, %r9 # A[3] * B - mulxq 24(%rsi), %rcx, %r8 - movq %r11, %r9 - adcxq %rcx, %r10 - adoxq %r8, %r9 - adcxq %r11, %r9 - movq %r10, 24(%rdi) - movq %r9, 32(%rdi) + mulxq 24(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + adoxq %rcx, %r8 + adcxq %r10, %r8 + movq %r9, 24(%rdi) + movq %r8, 32(%rdi) repz retq #ifndef __APPLE__ .size sp_256_mul_d_avx2_4,.-sp_256_mul_d_avx2_4 From 55ea2facdd1a187ce28869cb37994c25458878e1 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Wed, 15 Jan 2020 22:15:38 +1000 Subject: [PATCH 021/649] Changes to clear issues raised by cppcheck --- IDE/ECLIPSE/DEOS/tls_wolfssl.c | 4 - IDE/Espressif/ESP-IDF/test/test_wolfssl.c | 6 +- IDE/GCC-ARM/Source/armtarget.c | 28 +- IDE/HEXAGON/ecc-verify-benchmark.c | 1 - .../Projects/benchmark/current_time.c | 2 +- IDE/INTIME-RTOS/wolfExamples.c | 6 +- IDE/MDK-ARM/MDK-ARM/wolfSSL/shell.c | 2 +- IDE/MDK-ARM/MDK-ARM/wolfSSL/wolfssl_MDK_ARM.c | 2 +- IDE/MDK5-ARM/Projects/SimpleClient/main.c | 2 +- IDE/MDK5-ARM/Projects/wolfSSL-Full/shell.c | 2 +- IDE/OPENSTM32/Src/wolfssl_example.c | 2 +- IDE/RISCV/SIFIVE-HIFIVE1/main.c | 4 +- IDE/ROWLEY-CROSSWORKS-ARM/kinetis_hw.c | 8 +- IDE/zephyr/wolfssl_tls_sock/src/tls_sock.c | 19 +- examples/client/client.c | 35 ++- examples/echoclient/echoclient.c | 4 +- examples/echoserver/echoserver.c | 11 +- examples/server/server.c | 30 ++- mcapi/mcapi_test.c | 6 +- mqx/wolfssl_client/Sources/main.c | 2 +- src/bio.c | 4 +- src/crl.c | 14 +- src/internal.c | 22 +- src/ocsp.c | 2 +- src/ssl.c | 204 +++++++------- src/tls.c | 5 +- src/wolfio.c | 10 +- tests/api.c | 78 +++--- testsuite/testsuite.c | 60 ++--- wolfcrypt/benchmark/benchmark.c | 2 +- wolfcrypt/src/aes.c | 1 + wolfcrypt/src/asn.c | 60 +++-- wolfcrypt/src/blake2b.c | 3 +- wolfcrypt/src/blake2s.c | 3 +- wolfcrypt/src/dh.c | 12 +- wolfcrypt/src/ecc.c | 69 ++--- wolfcrypt/src/integer.c | 22 +- wolfcrypt/src/memory.c | 12 +- wolfcrypt/src/pkcs7.c | 32 +-- wolfcrypt/src/poly1305.c | 2 +- wolfcrypt/src/port/arm/armv8-sha256.c | 4 +- wolfcrypt/src/port/atmel/atmel.c | 3 + wolfcrypt/src/port/intel/quickassist_sync.c | 18 +- wolfcrypt/src/port/mynewt/mynewt_port.c | 1 - wolfcrypt/src/port/st/stm32.c | 3 +- wolfcrypt/src/random.c | 32 ++- wolfcrypt/src/rsa.c | 49 ++-- wolfcrypt/src/signature.c | 24 +- wolfcrypt/src/sp_arm32.c | 52 ++-- wolfcrypt/src/sp_arm64.c | 52 ++-- wolfcrypt/src/sp_armthumb.c | 52 ++-- wolfcrypt/src/sp_c32.c | 253 ++++++++---------- wolfcrypt/src/sp_c64.c | 243 +++++++---------- wolfcrypt/src/sp_cortexm.c | 52 ++-- wolfcrypt/src/sp_dsp32.c | 9 +- wolfcrypt/src/sp_x86_64.c | 52 ++-- wolfcrypt/src/tfm.c | 28 +- wolfcrypt/src/wc_encrypt.c | 10 +- wolfcrypt/src/wc_pkcs11.c | 8 +- wolfcrypt/src/wc_port.c | 5 +- wolfcrypt/test/test.c | 57 ++-- wolfcrypt/user-crypto/src/rsa.c | 5 +- wolfssl/test.h | 13 +- 63 files changed, 896 insertions(+), 922 deletions(-) diff --git a/IDE/ECLIPSE/DEOS/tls_wolfssl.c b/IDE/ECLIPSE/DEOS/tls_wolfssl.c index 5af4f0b5d..1abf5526d 100644 --- a/IDE/ECLIPSE/DEOS/tls_wolfssl.c +++ b/IDE/ECLIPSE/DEOS/tls_wolfssl.c @@ -380,10 +380,7 @@ void wolfssl_server_test(uintData_t statusPtr) int socketAddrLen=sizeof(sockaddr); char rx_buf[RX_BUF_SIZE]; char tx_buf[TX_BUF_SIZE]; - unsigned char attempt_conn; clientConnectionHandleType TCPserverHandle; - void * sendBuffer; - DWORD bufferSizeInBytes; WOLFSSL * ssl; WOLFSSL_CTX * ctx; @@ -572,7 +569,6 @@ int wolfsslRunTests (void) { thread_handle_t TCPhandle; threadStatus ts; - int ret; #if !defined(NO_CRYPT_TEST) wolfcrypt_test(NULL); diff --git a/IDE/Espressif/ESP-IDF/test/test_wolfssl.c b/IDE/Espressif/ESP-IDF/test/test_wolfssl.c index b0f817bab..b2ad2083e 100644 --- a/IDE/Espressif/ESP-IDF/test/test_wolfssl.c +++ b/IDE/Espressif/ESP-IDF/test/test_wolfssl.c @@ -280,13 +280,13 @@ int mp_performance_check(int mul, int mulmod, int exptmod) printf("(%d,%d) Xbits = %d, Ybits = %d Pbits = %d", i , j, Xbits, Ybits, Pbits); if(mul) { - printf(" mul = %llu (us)", elapsedTime1); + printf(" mul = %llu (us)", (unsigned long long)elapsedTime1); } if(mulmod) { - printf(" mulmod = %llu (us)\n", elapsedTime2); + printf(" mulmod = %llu (us)\n", (unsigned long long)elapsedTime2); } if(exptmod) { - printf(" exptmod = %llu (ms)\n", elapsedTime3); + printf(" exptmod = %llu (ms)\n", (unsigned long long)elapsedTime3); } } } diff --git a/IDE/GCC-ARM/Source/armtarget.c b/IDE/GCC-ARM/Source/armtarget.c index 0b9a01321..bee828faa 100644 --- a/IDE/GCC-ARM/Source/armtarget.c +++ b/IDE/GCC-ARM/Source/armtarget.c @@ -142,20 +142,20 @@ void HardFault_HandlerC( uint32_t *hardfault_args ) _BFAR = (*((volatile uint32_t *)(0xE000ED38))); printf ("\n\nHard fault handler (all numbers in hex):\n"); - printf ("R0 = %lx\n", stacked_r0); - printf ("R1 = %lx\n", stacked_r1); - printf ("R2 = %lx\n", stacked_r2); - printf ("R3 = %lx\n", stacked_r3); - printf ("R12 = %lx\n", stacked_r12); - printf ("LR [R14] = %lx subroutine call return address\n", stacked_lr); - printf ("PC [R15] = %lx program counter\n", stacked_pc); - printf ("PSR = %lx\n", stacked_psr); - printf ("CFSR = %lx\n", _CFSR); - printf ("HFSR = %lx\n", _HFSR); - printf ("DFSR = %lx\n", _DFSR); - printf ("AFSR = %lx\n", _AFSR); - printf ("MMAR = %lx\n", _MMAR); - printf ("BFAR = %lx\n", _BFAR); + printf ("R0 = %lx\n", (unsigned long)stacked_r0); + printf ("R1 = %lx\n", (unsigned long)stacked_r1); + printf ("R2 = %lx\n", (unsigned long)stacked_r2); + printf ("R3 = %lx\n", (unsigned long)stacked_r3); + printf ("R12 = %lx\n", (unsigned long)stacked_r12); + printf ("LR [R14] = %lx subroutine call return address\n", (unsigned long)stacked_lr); + printf ("PC [R15] = %lx program counter\n", (unsigned long)stacked_pc); + printf ("PSR = %lx\n", (unsigned long)stacked_psr); + printf ("CFSR = %lx\n", (unsigned long)_CFSR); + printf ("HFSR = %lx\n", (unsigned long)_HFSR); + printf ("DFSR = %lx\n", (unsigned long)_DFSR); + printf ("AFSR = %lx\n", (unsigned long)_AFSR); + printf ("MMAR = %lx\n", (unsigned long)_MMAR); + printf ("BFAR = %lx\n", (unsigned long)_BFAR); // Break into the debugger __asm("BKPT #0\n"); diff --git a/IDE/HEXAGON/ecc-verify-benchmark.c b/IDE/HEXAGON/ecc-verify-benchmark.c index 8eafa744d..a9e7ad8d6 100644 --- a/IDE/HEXAGON/ecc-verify-benchmark.c +++ b/IDE/HEXAGON/ecc-verify-benchmark.c @@ -78,7 +78,6 @@ static int hash_firmware_verify_default(int numThreads) int ret, i; word32 idx; double t; - char *sp_URI_value; pthread_t threads[numThreads]; ecc_key eccKey[numThreads]; diff --git a/IDE/IAR-EWARM/Projects/benchmark/current_time.c b/IDE/IAR-EWARM/Projects/benchmark/current_time.c index 4b7f6bd76..cbe6bae39 100644 --- a/IDE/IAR-EWARM/Projects/benchmark/current_time.c +++ b/IDE/IAR-EWARM/Projects/benchmark/current_time.c @@ -44,7 +44,7 @@ void InitTimer(void) { SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000); - printf("Clock=%dMHz\n", ui32SysClock/1000000) ; + printf("Clock=%dMHz\n", (int)(ui32SysClock/1000000)); ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0); ROM_TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC); ROM_TimerLoadSet(TIMER0_BASE, TIMER_A, -1); diff --git a/IDE/INTIME-RTOS/wolfExamples.c b/IDE/INTIME-RTOS/wolfExamples.c index 72520eedc..871220621 100644 --- a/IDE/INTIME-RTOS/wolfExamples.c +++ b/IDE/INTIME-RTOS/wolfExamples.c @@ -55,7 +55,7 @@ int wolfExample_TLSClient(const char* ip, int port) int ret = 0; WOLFSSL_CTX* ctx = NULL; WOLFSSL* ssl = NULL; /* create WOLFSSL object */ - int sockFd = -1; /* socket file descriptor */ + int sockFd; /* socket file descriptor */ struct sockaddr_in servAddr; /* struct for server address */ char sendBuff[TLS_MAXDATASIZE], rcvBuff[TLS_MAXDATASIZE]; @@ -144,13 +144,13 @@ int wolfExample_TLSServer(int port) int ret = 0; WOLFSSL_CTX* ctx = NULL; WOLFSSL* ssl = NULL; - int sockFd = -1, clientFd = -1; + int sockFd, clientFd = -1; struct sockaddr_in serverAddr = {0}, clientAddr = {0}; const char reply[] = "I hear ya fa shizzle!\n"; int addrSize = sizeof(clientAddr); char buff[256]; - sockFd = socket(AF_INET, SOCK_STREAM, 0); + sockFd = socket(AF_INET, SOCK_STREAM, 0); if (sockFd < 0) { printf("Failed to create socket. Error: %d\n", errno); return errno; diff --git a/IDE/MDK-ARM/MDK-ARM/wolfSSL/shell.c b/IDE/MDK-ARM/MDK-ARM/wolfSSL/shell.c index 518c8f5a2..fad4ec34b 100644 --- a/IDE/MDK-ARM/MDK-ARM/wolfSSL/shell.c +++ b/IDE/MDK-ARM/MDK-ARM/wolfSSL/shell.c @@ -436,7 +436,7 @@ static void for_command(void *args) { if( args == NULL || ((func_args *)args)->argc == 1) { printf("For %d times\n", for_iteration) ; - } else if( args == NULL || ((func_args *)args)->argc == 2) { + } else if(((func_args *)args)->argc == 2) { for_iteration = atoi(((func_args *)args)->argv[1]) ; } else printf("Invalid argument\n") ; } 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 c173e6a03..7158af50d 100644 --- a/IDE/MDK-ARM/MDK-ARM/wolfSSL/wolfssl_MDK_ARM.c +++ b/IDE/MDK-ARM/MDK-ARM/wolfSSL/wolfssl_MDK_ARM.c @@ -69,7 +69,7 @@ char *inet_ntoa(struct in_addr in) unsigned long inet_addr(const char *cp) { unsigned int a[4] ; unsigned long ret ; - sscanf(cp, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]) ; + sscanf(cp, "%u.%u.%u.%u", &a[0], &a[1], &a[2], &a[3]) ; ret = ((a[3]<<24) + (a[2]<<16) + (a[1]<<8) + a[0]) ; return(ret) ; } diff --git a/IDE/MDK5-ARM/Projects/SimpleClient/main.c b/IDE/MDK5-ARM/Projects/SimpleClient/main.c index 526ed955a..21f058eba 100644 --- a/IDE/MDK5-ARM/Projects/SimpleClient/main.c +++ b/IDE/MDK5-ARM/Projects/SimpleClient/main.c @@ -209,7 +209,7 @@ int main (void) { snprintf(ver, VERSIZE, "%d", TLS_VER); argv[6] = ver; - printf("SSL/TLS Client(%d)\n ", sizeof(argv)/sizeof(argv[0])) ; + printf("SSL/TLS Client(%d)\n ", (int)(sizeof(argv)/sizeof(argv[0]))) ; printf(" Remote IP: %s, Port: %s\n Version: %s\n", argv[2], argv[4], verStr[TLS_VER]) ; printf(" Other options: %s\n", OTHER_OPTIONS); setTime((time_t)((RTC_YEAR-1970)*365*24*60*60) + RTC_MONTH*30*24*60*60 + RTC_DAY*24*60*60); diff --git a/IDE/MDK5-ARM/Projects/wolfSSL-Full/shell.c b/IDE/MDK5-ARM/Projects/wolfSSL-Full/shell.c index 8245b1c57..a40cc2de5 100644 --- a/IDE/MDK5-ARM/Projects/wolfSSL-Full/shell.c +++ b/IDE/MDK5-ARM/Projects/wolfSSL-Full/shell.c @@ -477,7 +477,7 @@ static void for_command(void *args) { if( args == NULL || ((func_args *)args)->argc == 1) { printf("For %d times\n", for_iteration) ; - } else if( args == NULL || ((func_args *)args)->argc == 2) { + } else if(((func_args *)args)->argc == 2) { for_iteration = atoi(((func_args *)args)->argv[1]) ; } else printf("Invalid argument\n") ; } diff --git a/IDE/OPENSTM32/Src/wolfssl_example.c b/IDE/OPENSTM32/Src/wolfssl_example.c index d118c5723..72380803f 100644 --- a/IDE/OPENSTM32/Src/wolfssl_example.c +++ b/IDE/OPENSTM32/Src/wolfssl_example.c @@ -1122,7 +1122,7 @@ int bench_tls(void* args) { int ret = 0; info_t *info = NULL; - char *cipher, *next_cipher, *ciphers = NULL; + char *cipher, *next_cipher, *ciphers; /* Runtime variables */ int argRuntimeSec = BENCH_RUNTIME_SEC; diff --git a/IDE/RISCV/SIFIVE-HIFIVE1/main.c b/IDE/RISCV/SIFIVE-HIFIVE1/main.c index 4abbbb055..a3e4a19c0 100644 --- a/IDE/RISCV/SIFIVE-HIFIVE1/main.c +++ b/IDE/RISCV/SIFIVE-HIFIVE1/main.c @@ -143,12 +143,12 @@ int main(void) #ifdef USE_CLOCK_HZ /* Speed up clock */ printf("SiFive HiFive1 Demo\n"); - printf("Setting clock to %dMHz\n", USE_CLOCK_HZ/1000000); + printf("Setting clock to %dMHz\n", (int)(USE_CLOCK_HZ/1000000)); clk_Hz = metal_clock_set_rate_hz( &__METAL_DT_SIFIVE_FE310_G000_PLL_HANDLE->clock, USE_CLOCK_HZ ); #endif - printf("Actual Clock %dMHz\n", clk_Hz/1000000); + printf("Actual Clock %dMHz\n", (int)(clk_Hz/1000000)); /* Reconfigure the SPI Bus for dual mode */ #define QSPI0_CTRL 0x10014000UL diff --git a/IDE/ROWLEY-CROSSWORKS-ARM/kinetis_hw.c b/IDE/ROWLEY-CROSSWORKS-ARM/kinetis_hw.c index f4af87b16..8476b0f58 100644 --- a/IDE/ROWLEY-CROSSWORKS-ARM/kinetis_hw.c +++ b/IDE/ROWLEY-CROSSWORKS-ARM/kinetis_hw.c @@ -154,14 +154,14 @@ static void hw_gpio_init(void) static void hw_uart_init(void) { - register uint16_t sbr, brfa; - uint8_t temp; - #ifdef FREESCALE_KSDK_BM PORT_SetPinMux(UART_TX_PORT, UART_TX_PIN, UART_TX_MUX); CLOCK_SetLpuartClock(1); /* MCGPLLCLK */ DbgConsole_Init((uint32_t)UART_PORT, UART_BAUD, DEBUG_CONSOLE_DEVICE_TYPE_LPUART, SYS_CLK_HZ); #else + register uint16_t sbr, brfa; + uint8_t temp; + #ifdef WOLFSSL_FRDM_K64 /* Enable UART core clock ONLY for FRDM-K64F */ SIM->SCGC4 |= SIM_SCGC4_UART0_MASK; @@ -217,8 +217,6 @@ static void hw_rtc_init(void) /* Enable OSC */ if ((RTC->CR & RTC_CR_OSCE_MASK) == 0) { - int i; - /* Turn on */ RTC->CR |= RTC_CR_OSCE_MASK; diff --git a/IDE/zephyr/wolfssl_tls_sock/src/tls_sock.c b/IDE/zephyr/wolfssl_tls_sock/src/tls_sock.c index f8ebcfa1e..48c00a787 100644 --- a/IDE/zephyr/wolfssl_tls_sock/src/tls_sock.c +++ b/IDE/zephyr/wolfssl_tls_sock/src/tls_sock.c @@ -296,21 +296,20 @@ void join_thread(THREAD_TYPE thread) int wolfssl_server_accept_tcp(WOLFSSL* ssl, SOCKET_T* fd, SOCKET_T* acceptfd) { int ret = 0; - SOCKET_T sockfd = WOLFSSL_SOCKET_INVALID; + SOCKET_T sockfd; SOCKET_T clientfd = WOLFSSL_SOCKET_INVALID; SOCKADDR_IN_T client; socklen_t client_len = sizeof(client); word16 port = 443; struct sockaddr_in bind_addr; - if (ret == 0) { - sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - bind_addr.sin_family = AF_INET; - bind_addr.sin_addr.s_addr = htonl(INADDR_ANY); - bind_addr.sin_port = htons(port); - if (bind(sockfd, (struct sockaddr *)&bind_addr, sizeof(bind_addr)) != 0) - ret = -1; - } + sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + bind_addr.sin_family = AF_INET; + bind_addr.sin_addr.s_addr = htonl(INADDR_ANY); + bind_addr.sin_port = htons(port); + if (bind(sockfd, (struct sockaddr *)&bind_addr, sizeof(bind_addr)) != 0) + ret = -1; + if (ret == 0) { *fd = sockfd; printf("Server Listen\n"); @@ -507,6 +506,6 @@ int main() printf("Done\n"); - return (ret == 0) ? 0 : 1; + return 0; } diff --git a/examples/client/client.c b/examples/client/client.c index 85d082574..e29cad4ca 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -315,8 +315,8 @@ static void EarlyData(WOLFSSL_CTX* ctx, WOLFSSL* ssl, const char* msg, if (ret != msgSz) { printf("SSL_write_early_data msg error %d, %s\n", err, wolfSSL_ERR_error_string(err, buffer)); - wolfSSL_free(ssl); ssl = NULL; - wolfSSL_CTX_free(ctx); ctx = NULL; + wolfSSL_free(ssl); + wolfSSL_CTX_free(ctx); err_sys("SSL_write_early_data failed"); } } @@ -1392,9 +1392,9 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) unsigned char alpn_opt = 0; char* cipherList = NULL; int useDefCipherList = 0; - const char* verifyCert = caCertFile; - const char* ourCert = cliCertFile; - const char* ourKey = cliKeyFile; + const char* verifyCert; + const char* ourCert; + const char* ourKey; int doSTARTTLS = 0; char* starttlsProt = NULL; @@ -1479,17 +1479,26 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) ((func_args*)args)->return_code = -1; /* error state */ -#ifdef NO_RSA +#ifndef NO_RSA + verifyCert = caCertFile; + ourCert = cliCertFile; + ourKey = cliKeyFile; +#else #ifdef HAVE_ECC - verifyCert = (char*)caEccCertFile; - ourCert = (char*)cliEccCertFile; - ourKey = (char*)cliEccKeyFile; + verifyCert = caEccCertFile; + ourCert = cliEccCertFile; + ourKey = cliEccKeyFile; #elif defined(HAVE_ED25519) - verifyCert = (char*)caEdCertFile; - ourCert = (char*)cliEdCertFile; - ourKey = (char*)cliEdKeyFile; + verifyCert = caEdCertFile; + ourCert = cliEdCertFile; + ourKey = cliEdKeyFile; + #else + verifyCert = NULL; + ourCert = NULL; + ourKey = NULL; #endif #endif + (void)resumeSz; (void)session; (void)flatSession; @@ -1728,7 +1737,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) break; } } - if (throughput <= 0 || block <= 0) { + if (throughput == 0 || block <= 0) { Usage(); XEXIT_T(MY_EX_USAGE); } diff --git a/examples/echoclient/echoclient.c b/examples/echoclient/echoclient.c index 73dc2b017..13a0a381f 100644 --- a/examples/echoclient/echoclient.c +++ b/examples/echoclient/echoclient.c @@ -73,8 +73,10 @@ void echoclient_test(void* args) int doDTLS = 0; int doPSK = 0; int sendSz; +#ifndef WOLFSSL_MDK_SHELL int argc = 0; char** argv = 0; +#endif word16 port = yasslPort; char buffer[CYASSL_MAX_ERROR_SZ]; @@ -83,7 +85,6 @@ void echoclient_test(void* args) #ifndef WOLFSSL_MDK_SHELL argc = ((func_args*)args)->argc; argv = ((func_args*)args)->argv; -#endif if (argc >= 2) { fin = fopen(argv[1], "r"); @@ -93,6 +94,7 @@ void echoclient_test(void* args) fout = fopen(argv[2], "w"); outCreated = 1; } +#endif if (!fin) err_sys("can't open input file"); if (!fout) err_sys("can't open output file"); diff --git a/examples/echoserver/echoserver.c b/examples/echoserver/echoserver.c index 3d1bcd36c..a0cefb450 100644 --- a/examples/echoserver/echoserver.c +++ b/examples/echoserver/echoserver.c @@ -81,7 +81,7 @@ THREAD_RETURN CYASSL_THREAD echoserver_test(void* args) int ret = 0; int doDTLS = 0; - int doPSK = 0; + int doPSK; int outCreated = 0; int shutDown = 0; int useAnyAddr = 0; @@ -108,12 +108,11 @@ THREAD_RETURN CYASSL_THREAD echoserver_test(void* args) doDTLS = 1; #endif -#ifdef CYASSL_LEANPSK - doPSK = 1; -#endif - -#if defined(NO_RSA) && !defined(HAVE_ECC) && !defined(HAVE_ED25519) +#if (defined(NO_RSA) && !defined(HAVE_ECC) && !defined(HAVE_ED25519)) || \ + defined(CYASSL_LEANPSK) doPSK = 1; +#else + doPSK = 0; #endif #if defined(NO_MAIN_DRIVER) && !defined(CYASSL_SNIFFER) && \ diff --git a/examples/server/server.c b/examples/server/server.c index 3f1129184..afada953a 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -936,9 +936,9 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) char* cipherList = NULL; int useDefCipherList = 0; int overrideDateErrors = 0; - const char* verifyCert = cliCertFile; - const char* ourCert = svrCertFile; - const char* ourKey = svrKeyFile; + const char* verifyCert; + const char* ourCert; + const char* ourKey; const char* ourDhParam = dhParamFile; tcp_ready* readySignal = NULL; int argc = ((func_args*)args)->argc; @@ -1018,15 +1018,23 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) ((func_args*)args)->return_code = -1; /* error state */ -#ifdef NO_RSA +#ifndef NO_RSA + verifyCert = cliCertFile; + ourCert = svrCertFile; + ourKey = svrKeyFile; +#else #ifdef HAVE_ECC - verifyCert = (char*)cliEccCertFile; - ourCert = (char*)eccCertFile; - ourKey = (char*)eccKeyFile; + verifyCert = cliEccCertFile; + ourCert = eccCertFile; + ourKey = eccKeyFile; #elif defined(HAVE_ED25519) - verifyCert = (char*)cliEdCertFile; - ourCert = (char*)edCertFile; - ourKey = (char*)edKeyFile; + verifyCert = cliEdCertFile; + ourCert = edCertFile; + ourKey = edKeyFile; + #else + verifyCert = NULL; + ourCert = NULL; + ourKey = NULL; #endif #endif @@ -1314,7 +1322,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) break; } } - if (throughput <= 0 || block <= 0) { + if (throughput == 0 || block <= 0) { Usage(); XEXIT_T(MY_EX_USAGE); } diff --git a/mcapi/mcapi_test.c b/mcapi/mcapi_test.c index 50585ea49..cf0c31075 100644 --- a/mcapi/mcapi_test.c +++ b/mcapi/mcapi_test.c @@ -53,7 +53,7 @@ #include #include #include "PIC32MZ-serial.h" - #define SYSTEMConfigPerformance /* void out SYSTEMConfigPerformance(); */ + #define SYSTEMConfigPerformance(n) /* void out SYSTEMConfigPerformance(); */ #elif defined(MICROCHIP_PIC32) #define PIC32_STARTER_KIT #include @@ -1442,7 +1442,7 @@ static int check_ecc(void) return -1; } - if (usedA != usedB || usedA <= 0) { + if (usedA != usedB || usedA == 0) { printf("mcapi ecc make shared secret output size match failed\n"); return -1; } @@ -1461,7 +1461,7 @@ static int check_ecc(void) } sigSz = usedA; - if (sigSz <= 0) { + if (sigSz == 0) { printf("mcapi ecc sign hash bad sig size\n"); return -1; } diff --git a/mqx/wolfssl_client/Sources/main.c b/mqx/wolfssl_client/Sources/main.c index 51f5538e2..4b42b79ad 100644 --- a/mqx/wolfssl_client/Sources/main.c +++ b/mqx/wolfssl_client/Sources/main.c @@ -147,7 +147,7 @@ void setup_clock(void) for (i = 0; i < sntp_max_tries; i++) { - printf("Getting time from NTP server [ attempt %d of %d ]...\n", + printf("Getting time from NTP server [ attempt %u of %u ]...\n", i+1, sntp_max_tries); /* update time from NTP server */ diff --git a/src/bio.c b/src/bio.c index 2171f39ed..1f00af782 100644 --- a/src/bio.c +++ b/src/bio.c @@ -457,7 +457,7 @@ int wolfSSL_BIO_write(WOLFSSL_BIO* bio, const void* data, int len) } /* check for formatting */ - if (bio && bio->type == WOLFSSL_BIO_BASE64) { + if (bio->type == WOLFSSL_BIO_BASE64) { #if defined(WOLFSSL_BASE64_ENCODE) word32 sz = 0; @@ -527,7 +527,7 @@ int wolfSSL_BIO_write(WOLFSSL_BIO* bio, const void* data, int len) #ifndef WOLFCRYPT_ONLY if (bio && bio->type == WOLFSSL_BIO_SSL) { /* already got eof, again is error */ - if (bio && front->eof) { + if (front->eof) { ret = SSL_FATAL_ERROR; } else { diff --git a/src/crl.c b/src/crl.c index ade81a91a..a48cf9d83 100644 --- a/src/crl.c +++ b/src/crl.c @@ -201,8 +201,6 @@ static int CheckCertCRLList(WOLFSSL_CRL* crl, DecodedCert* cert, int *pFoundEntr while (crle) { if (XMEMCMP(crle->issuerHash, cert->issuerHash, CRL_DIGEST_SIZE) == 0) { - int doNextDate = 1; - WOLFSSL_MSG("Found CRL Entry on list"); if (crle->verified == 0) { @@ -211,7 +209,7 @@ static int CheckCertCRLList(WOLFSSL_CRL* crl, DecodedCert* cert, int *pFoundEntr byte extAuthKeyId[KEYID_SIZE]; #endif byte issuerHash[CRL_DIGEST_SIZE]; - byte* tbs = NULL; + byte* tbs; word32 tbsSz = crle->tbsSz; byte* sig = NULL; word32 sigSz = crle->signatureSz; @@ -297,12 +295,10 @@ static int CheckCertCRLList(WOLFSSL_CRL* crl, DecodedCert* cert, int *pFoundEntr WOLFSSL_MSG("Checking next date validity"); - #ifdef WOLFSSL_NO_CRL_NEXT_DATE - if (crle->nextDateFormat == ASN_OTHER_TYPE) - doNextDate = 0; /* skip */ - #endif - - if (doNextDate) { + #ifdef WOLFSSL_NO_CRL_NEXT_DATE + if (crle->nextDateFormat != ASN_OTHER_TYPE) + #endif + { #ifndef NO_ASN_TIME if (!XVALIDATE_DATE(crle->nextDate,crle->nextDateFormat, AFTER)) { WOLFSSL_MSG("CRL next date is no longer valid"); diff --git a/src/internal.c b/src/internal.c index 2097f3ff1..e88163632 100644 --- a/src/internal.c +++ b/src/internal.c @@ -259,7 +259,6 @@ static int QSH_FreeAll(WOLFSSL* ssl) /* free struct */ XFREE(preKey, ssl->heap, DYNAMIC_TYPE_QSH); } - key = NULL; /* free all of peers QSH keys */ @@ -1793,7 +1792,8 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap) /* In case contexts are held in array and don't want to free actual ctx */ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx) { -#if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) && !defined(NO_WOLFSSL_SERVER) +#if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) && \ + defined(HAVE_TLS_EXTENSIONS) && !defined(NO_WOLFSSL_SERVER) int i; #endif @@ -6372,7 +6372,7 @@ static WC_INLINE void WriteSEQ(WOLFSSL* ssl, int verifyOrder, byte* out) * extra space for the headers. */ DtlsMsg* DtlsMsgNew(word32 sz, void* heap) { - DtlsMsg* msg = NULL; + DtlsMsg* msg; (void)heap; msg = (DtlsMsg*)XMALLOC(sizeof(DtlsMsg), heap, DYNAMIC_TYPE_DTLS_MSG); @@ -9473,7 +9473,7 @@ int DoVerifyCallback(WOLFSSL_CERT_MANAGER* cm, WOLFSSL* ssl, int ret, #endif )) #ifndef NO_WOLFSSL_CM_VERIFY - || ((cm != NULL) && (cm->verifyCallback != NULL)) + || (cm->verifyCallback != NULL) #endif ) { int verifyFail = 0; @@ -15466,7 +15466,7 @@ int BuildMessage(WOLFSSL* ssl, byte* output, int outSz, const byte* input, if (ssl->truncated_hmac && ssl->specs.hash_size > args->digestSz) { #ifdef WOLFSSL_SMALL_STACK - byte* hmac = NULL; + byte* hmac; #else byte hmac[WC_MAX_DIGEST_SIZE]; #endif @@ -16458,7 +16458,7 @@ int SendCertificateStatus(WOLFSSL* ssl) buffer der; word32 idx = 0; #ifdef WOLFSSL_SMALL_STACK - DecodedCert* cert = NULL; + DecodedCert* cert; #else DecodedCert cert[1]; #endif @@ -20787,7 +20787,7 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, { if (IsAtLeastTLSv1_2(ssl)) { #ifdef WOLFSSL_SMALL_STACK - byte* encodedSig = NULL; + byte* encodedSig; #else byte encodedSig[MAX_ENCODED_SIG_SZ]; #endif @@ -22604,7 +22604,7 @@ int SendCertificateVerify(WOLFSSL* ssl) } } - if (args->length <= 0) { + if (args->length == 0) { ERROR_OUT(NO_PRIVATE_KEY, exit_scv); } @@ -23964,7 +23964,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #ifdef HAVE_PK_CALLBACKS if (wolfSSL_CTX_IsPrivatePkSet(ssl->ctx)) { args->tmpSigSz = GetPrivateKeySigSize(ssl); - if (args->tmpSigSz <= 0) { + if (args->tmpSigSz == 0) { ERROR_OUT(NO_PRIVATE_KEY, exit_sske); } } @@ -24250,7 +24250,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } } - if (keySz <= 0) { /* test if keySz has error */ + if (keySz == 0) { /* test if keySz has error */ ERROR_OUT(keySz, exit_sske); } @@ -26210,7 +26210,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #endif { #ifdef WOLFSSL_SMALL_STACK - byte* encodedSig = NULL; + byte* encodedSig; #else byte encodedSig[MAX_ENCODED_SIG_SZ]; #endif diff --git a/src/ocsp.c b/src/ocsp.c index a0376befa..b5a27197e 100644 --- a/src/ocsp.c +++ b/src/ocsp.c @@ -835,7 +835,7 @@ void wolfSSL_OCSP_REQUEST_free(OcspRequest* request) int wolfSSL_i2d_OCSP_REQUEST(OcspRequest* request, unsigned char** data) { - word32 size; + int size; size = EncodeOcspRequest(request, NULL, 0); if (size <= 0 || data == NULL) diff --git a/src/ssl.c b/src/ssl.c index 149594eb0..fd3ff9031 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -648,7 +648,7 @@ WOLFSSL* wolfSSL_write_dup(WOLFSSL* ssl) if ( (ret = InitSSL(dup, ssl->ctx, 1)) < 0) { FreeSSL(dup, ssl->ctx->heap); dup = NULL; - } else if ( (ret = DupSSL(dup, ssl) < 0)) { + } else if ( (ret = DupSSL(dup, ssl)) < 0) { FreeSSL(dup, ssl->ctx->heap); dup = NULL; } @@ -1342,55 +1342,55 @@ WC_RNG* wolfSSL_GetRNG(WOLFSSL* ssl) int wolfSSL_GetObjectSize(void) { #ifdef SHOW_SIZES - printf("sizeof suites = %lu\n", sizeof(Suites)); - printf("sizeof ciphers(2) = %lu\n", sizeof(Ciphers)); + printf("sizeof suites = %lu\n", (unsigned long)sizeof(Suites)); + printf("sizeof ciphers(2) = %lu\n", (unsigned long)sizeof(Ciphers)); #ifndef NO_RC4 - printf("\tsizeof arc4 = %lu\n", sizeof(Arc4)); + printf("\tsizeof arc4 = %lu\n", (unsigned long)sizeof(Arc4)); #endif - printf("\tsizeof aes = %lu\n", sizeof(Aes)); + printf("\tsizeof aes = %lu\n", (unsigned long)sizeof(Aes)); #ifndef NO_DES3 - printf("\tsizeof des3 = %lu\n", sizeof(Des3)); + printf("\tsizeof des3 = %lu\n", (unsigned long)sizeof(Des3)); #endif #ifndef NO_RABBIT - printf("\tsizeof rabbit = %lu\n", sizeof(Rabbit)); + printf("\tsizeof rabbit = %lu\n", (unsigned long)sizeof(Rabbit)); #endif #ifdef HAVE_CHACHA - printf("\tsizeof chacha = %lu\n", sizeof(ChaCha)); + printf("\tsizeof chacha = %lu\n", (unsigned long)sizeof(ChaCha)); #endif - printf("sizeof cipher specs = %lu\n", sizeof(CipherSpecs)); - printf("sizeof keys = %lu\n", sizeof(Keys)); - printf("sizeof Hashes(2) = %lu\n", sizeof(Hashes)); + printf("sizeof cipher specs = %lu\n", (unsigned long)sizeof(CipherSpecs)); + printf("sizeof keys = %lu\n", (unsigned long)sizeof(Keys)); + printf("sizeof Hashes(2) = %lu\n", (unsigned long)sizeof(Hashes)); #ifndef NO_MD5 - printf("\tsizeof MD5 = %lu\n", sizeof(wc_Md5)); + printf("\tsizeof MD5 = %lu\n", (unsigned long)sizeof(wc_Md5)); #endif #ifndef NO_SHA - printf("\tsizeof SHA = %lu\n", sizeof(wc_Sha)); + printf("\tsizeof SHA = %lu\n", (unsigned long)sizeof(wc_Sha)); #endif #ifdef WOLFSSL_SHA224 - printf("\tsizeof SHA224 = %lu\n", sizeof(wc_Sha224)); + printf("\tsizeof SHA224 = %lu\n", (unsigned long)sizeof(wc_Sha224)); #endif #ifndef NO_SHA256 - printf("\tsizeof SHA256 = %lu\n", sizeof(wc_Sha256)); + printf("\tsizeof SHA256 = %lu\n", (unsigned long)sizeof(wc_Sha256)); #endif #ifdef WOLFSSL_SHA384 - printf("\tsizeof SHA384 = %lu\n", sizeof(wc_Sha384)); + printf("\tsizeof SHA384 = %lu\n", (unsigned long)sizeof(wc_Sha384)); #endif #ifdef WOLFSSL_SHA384 - printf("\tsizeof SHA512 = %lu\n", sizeof(wc_Sha512)); + printf("\tsizeof SHA512 = %lu\n", (unsigned long)sizeof(wc_Sha512)); #endif - printf("sizeof Buffers = %lu\n", sizeof(Buffers)); - printf("sizeof Options = %lu\n", sizeof(Options)); - printf("sizeof Arrays = %lu\n", sizeof(Arrays)); + printf("sizeof Buffers = %lu\n", (unsigned long)sizeof(Buffers)); + printf("sizeof Options = %lu\n", (unsigned long)sizeof(Options)); + printf("sizeof Arrays = %lu\n", (unsigned long)sizeof(Arrays)); #ifndef NO_RSA - printf("sizeof RsaKey = %lu\n", sizeof(RsaKey)); + printf("sizeof RsaKey = %lu\n", (unsigned long)sizeof(RsaKey)); #endif #ifdef HAVE_ECC - printf("sizeof ecc_key = %lu\n", sizeof(ecc_key)); + printf("sizeof ecc_key = %lu\n", (unsigned long)sizeof(ecc_key)); #endif - printf("sizeof WOLFSSL_CIPHER = %lu\n", sizeof(WOLFSSL_CIPHER)); - printf("sizeof WOLFSSL_SESSION = %lu\n", sizeof(WOLFSSL_SESSION)); - printf("sizeof WOLFSSL = %lu\n", sizeof(WOLFSSL)); - printf("sizeof WOLFSSL_CTX = %lu\n", sizeof(WOLFSSL_CTX)); + printf("sizeof WOLFSSL_CIPHER = %lu\n", (unsigned long)sizeof(WOLFSSL_CIPHER)); + printf("sizeof WOLFSSL_SESSION = %lu\n", (unsigned long)sizeof(WOLFSSL_SESSION)); + printf("sizeof WOLFSSL = %lu\n", (unsigned long)sizeof(WOLFSSL)); + printf("sizeof WOLFSSL_CTX = %lu\n", (unsigned long)sizeof(WOLFSSL_CTX)); #endif return sizeof(WOLFSSL); @@ -1676,15 +1676,19 @@ int wolfSSL_SetTmpDH(WOLFSSL* ssl, const unsigned char* p, int pSz, ssl->options.haveDH = 1; if (ssl->options.side != WOLFSSL_NEITHER_END) { - word16 havePSK = 0; - word16 haveRSA = 1; + word16 havePSK; + word16 haveRSA; int keySz = 0; #ifndef NO_PSK havePSK = ssl->options.havePSK; + #else + havePSK = 0; #endif #ifdef NO_RSA haveRSA = 0; + #else + haveRSA = 1; #endif #ifndef NO_CERTS keySz = ssl->buffers.keySz; @@ -2450,7 +2454,7 @@ int wolfSSL_UseALPN(WOLFSSL* ssl, char *protocol_name_list, /* read all protocol name from the list */ token[idx] = XSTRTOK(list, ",", &ptr); - while (token[idx] != NULL && idx < WOLFSSL_MAX_ALPN_NUMBER) + while (idx < WOLFSSL_MAX_ALPN_NUMBER && token[idx] != NULL) token[++idx] = XSTRTOK(NULL, ",", &ptr); /* add protocol name list in the TLS extension in reverse order */ @@ -3425,7 +3429,7 @@ WOLFSSL_CERT_MANAGER* wolfSSL_CTX_GetCertManager(WOLFSSL_CTX* ctx) WOLFSSL_CERT_MANAGER* wolfSSL_CertManagerNew_ex(void* heap) { - WOLFSSL_CERT_MANAGER* cm = NULL; + WOLFSSL_CERT_MANAGER* cm; WOLFSSL_ENTER("wolfSSL_CertManagerNew"); @@ -4629,7 +4633,7 @@ int AddTrustedPeer(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int verify) { int ret, row; TrustedPeerCert* peerCert; - DecodedCert* cert = NULL; + DecodedCert* cert; DerBuffer* der = *pDer; byte* subjectHash = NULL; @@ -4925,10 +4929,10 @@ int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify) if ( ret == 0 && signer != NULL ) { signer->cm_idx = row; if (type == WOLFSSL_USER_CA && tsip_rootCAverified() == 0 ) { - if (ret = tsip_tls_RootCertVerify(cert->source, cert->maxIdx, - cert->sigCtx.pubkey_n_start, cert->sigCtx.pubkey_n_len - 1, - cert->sigCtx.pubkey_e_start, cert->sigCtx.pubkey_e_len - 1, - row/* cm index */) + if ((ret = tsip_tls_RootCertVerify(cert->source, cert->maxIdx, + cert->sigCtx.pubkey_n_start, cert->sigCtx.pubkey_n_len - 1, + cert->sigCtx.pubkey_e_start, cert->sigCtx.pubkey_e_len - 1, + row/* cm index */)) != 0) WOLFSSL_MSG("tsip_tls_RootCertVerify() failed"); else @@ -5240,15 +5244,15 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der (void)devId; if (ctx == NULL && ssl == NULL) - return BAD_FUNC_ARG; + ret = BAD_FUNC_ARG; if (!der || !keySz || !idx || !resetSuites || !keyFormat) - return BAD_FUNC_ARG; + ret = BAD_FUNC_ARG; #ifndef NO_RSA if (ret == 0 && (*keyFormat == 0 || *keyFormat == RSAk)) { /* make sure RSA key can be used */ #ifdef WOLFSSL_SMALL_STACK - RsaKey* key = NULL; + RsaKey* key; #else RsaKey key[1]; #endif @@ -5283,7 +5287,7 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der ssl->buffers.keyType = rsa_sa_algo; ssl->buffers.keySz = *keySz; } - else if(ctx) { + else { ctx->privateKeyType = rsa_sa_algo; ctx->privateKeySz = *keySz; } @@ -5308,7 +5312,7 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der if (ret == 0 && (*keyFormat == 0 || *keyFormat == ECDSAk)) { /* make sure ECC key can be used */ #ifdef WOLFSSL_SMALL_STACK - ecc_key* key = NULL; + ecc_key* key; #else ecc_key key[1]; #endif @@ -5338,7 +5342,7 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der ssl->buffers.keyType = ecc_dsa_sa_algo; ssl->buffers.keySz = *keySz; } - else if (ctx) { + else { ctx->haveStaticECC = 1; ctx->privateKeyType = ecc_dsa_sa_algo; ctx->privateKeySz = *keySz; @@ -5361,7 +5365,7 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der if (ret == 0 && (*keyFormat == 0 || *keyFormat == ED25519k)) { /* make sure Ed25519 key can be used */ #ifdef WOLFSSL_SMALL_STACK - ed25519_key* key = NULL; + ed25519_key* key; #else ed25519_key key[1]; #endif @@ -5698,7 +5702,7 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, } else if (type == CERT_TYPE) { #ifdef WOLFSSL_SMALL_STACK - DecodedCert* cert = NULL; + DecodedCert* cert; #else DecodedCert cert[1]; #endif @@ -6218,7 +6222,7 @@ int CM_VerifyBuffer_ex(WOLFSSL_CERT_MANAGER* cm, const byte* buff, int ret = 0; DerBuffer* der = NULL; #ifdef WOLFSSL_SMALL_STACK - DecodedCert* cert = NULL; + DecodedCert* cert; #else DecodedCert cert[1]; #endif @@ -6270,7 +6274,7 @@ int CM_VerifyBuffer_ex(WOLFSSL_CERT_MANAGER* cm, const byte* buff, if (cm->verifyCallback) { buffer certBuf; #ifdef WOLFSSL_SMALL_STACK - ProcPeerCertArgs* args = NULL; + ProcPeerCertArgs* args; args = (ProcPeerCertArgs*)XMALLOC( sizeof(ProcPeerCertArgs), cm->heap, DYNAMIC_TYPE_TMP_BUFFER); if (args == NULL) { @@ -6798,7 +6802,7 @@ int wolfSSL_CTX_load_verify_locations_ex(WOLFSSL_CTX* ctx, const char* file, #ifndef NO_WOLFSSL_DIR char* name = NULL; #ifdef WOLFSSL_SMALL_STACK - ReadDirCtx* readCtx = NULL; + ReadDirCtx* readCtx; readCtx = (ReadDirCtx*)XMALLOC(sizeof(ReadDirCtx), ctx->heap, DYNAMIC_TYPE_DIRCTX); if (readCtx == NULL) @@ -8640,8 +8644,7 @@ WOLFSSL_X509_EXTENSION* wolfSSL_X509_set_ext(WOLFSSL_X509* x509, int loc) /* Set object size and reallocate space in object buffer */ ext->obj->objSz = objSz; if(((ext->obj->dynamic & WOLFSSL_ASN1_DYNAMIC_DATA) != 0) || - (((ext->obj->dynamic & WOLFSSL_ASN1_DYNAMIC_DATA) == 0) && - (ext->obj->obj == NULL))) { + (ext->obj->obj == NULL)) { ext->obj->obj =(byte*)XREALLOC((byte*)ext->obj->obj, ext->obj->objSz, NULL,DYNAMIC_TYPE_ASN1); @@ -9308,7 +9311,7 @@ int wolfSSL_ASN1_BIT_STRING_get_bit(const WOLFSSL_ASN1_BIT_STRING* str, int i) return WOLFSSL_FAILURE; } - return str->data[i/8] & (1<<(7-(i%8))) ? 1 : 0; + return (str->data[i/8] & (1<<(7-(i%8)))) ? 1 : 0; } /* Looks for the extension matching the passed in nid @@ -11601,16 +11604,17 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, } WOLFSSL_METHOD* wolfSSLv23_method_ex(void* heap) { - WOLFSSL_METHOD* m = NULL; + WOLFSSL_METHOD* m; WOLFSSL_ENTER("SSLv23_method"); #if !defined(NO_WOLFSSL_CLIENT) m = wolfSSLv23_client_method_ex(heap); + m->side = WOLFSSL_NEITHER_END; #elif !defined(NO_WOLFSSL_SERVER) m = wolfSSLv23_server_method_ex(heap); + m->side = WOLFSSL_NEITHER_END; + #else + m = NULL; #endif - if (m != NULL) { - m->side = WOLFSSL_NEITHER_END; - } return m; } @@ -13053,7 +13057,7 @@ int AddSession(WOLFSSL* ssl) #ifdef SESSION_CERTS if (error == 0) { - if (!overwrite || (overwrite && ssl->session.chain.count > 0)) { + if (!overwrite || ssl->session.chain.count > 0) { /* * If we are overwriting and no certs present in ssl->session.chain * then keep the old chain. @@ -14231,7 +14235,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) (void)sz; WOLFSSL_MSG("session cache is set at compile time"); #ifndef NO_SESSION_CACHE - return SESSIONS_PER_ROW * SESSION_ROWS; + return (long)(SESSIONS_PER_ROW * SESSION_ROWS); #else return 0; #endif @@ -15254,7 +15258,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) int ret; int hashType = WC_HASH_TYPE_NONE; #ifdef WOLFSSL_SMALL_STACK - EncryptedInfo* info = NULL; + EncryptedInfo* info; #else EncryptedInfo info[1]; #endif @@ -15389,7 +15393,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) do { ret = wc_PeekErrorNode(0, &file, &reason, &line); if (ret >= 0) { - const char* r = wolfSSL_ERR_reason_error_string(ret - ret - ret); + const char* r = wolfSSL_ERR_reason_error_string(0 - ret); XSNPRINTF(buf, sizeof(buf), "error:%d:wolfSSL library:%s:%s:%d\n", ret, r, file, line); wolfSSL_BIO_write(bio, buf, (int)XSTRLEN(buf)); @@ -18156,7 +18160,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) { (void)ctx; #ifndef NO_SESSION_CACHE - return SESSIONS_PER_ROW * SESSION_ROWS; + return (long)(SESSIONS_PER_ROW * SESSION_ROWS); #else return 0; #endif @@ -18328,7 +18332,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) { int ret; #ifdef WOLFSSL_SMALL_STACK - DecodedCert* cert = NULL; + DecodedCert* cert; #else DecodedCert cert[1]; #endif @@ -18679,7 +18683,7 @@ WOLFSSL_X509* wolfSSL_X509_d2i(WOLFSSL_X509** x509, const byte* in, int len) if (in != NULL && len != 0) { #ifdef WOLFSSL_SMALL_STACK - DecodedCert* cert = NULL; + DecodedCert* cert; #else DecodedCert cert[1]; #endif @@ -19608,7 +19612,7 @@ WOLFSSL_STACK* wolfSSL_sk_get_node(WOLFSSL_STACK* sk, int idx) { int i; WOLFSSL_STACK* ret = NULL; - WOLFSSL_STACK* current = NULL; + WOLFSSL_STACK* current; current = sk; for (i = 0; i <= idx && current != NULL; i++) { @@ -20172,7 +20176,7 @@ WOLFSSL_X509* wolfSSL_X509_load_certificate_buffer( /* ready to be decoded. */ if (der != NULL && der->buffer != NULL) { #ifdef WOLFSSL_SMALL_STACK - DecodedCert* cert = NULL; + DecodedCert* cert; #else DecodedCert cert[1]; #endif @@ -20308,7 +20312,7 @@ WOLFSSL_ASN1_OBJECT* wolfSSL_ASN1_OBJECT_new(void) /* Creates and returns a new WOLFSSL_CIPHER stack. */ WOLFSSL_STACK* wolfSSL_sk_new_asn1_obj(void) { - WOLFSSL_STACK* sk = NULL; + WOLFSSL_STACK* sk; WOLFSSL_ENTER("wolfSSL_sk_new_asn1_obj"); sk = wolfSSL_sk_new_null(); @@ -21996,10 +22000,12 @@ int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b) return WOLFSSL_FAILURE; } { + #if (!defined(NO_RSA) && !defined(HAVE_USER_RSA)) || defined(HAVE_ECC) char tmp[100]; + #endif switch (x509->pubKeyOID) { - #ifndef NO_RSA + #ifndef NO_RSA case RSAk: if (wolfSSL_BIO_write(bio, " Public Key Algorithm: rsaEncryption\n", @@ -22139,9 +22145,9 @@ int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b) } #endif /* HAVE_USER_RSA */ break; - #endif /* NO_RSA */ + #endif /* NO_RSA */ - #ifdef HAVE_ECC + #ifdef HAVE_ECC case ECDSAk: { word32 i; @@ -22242,7 +22248,7 @@ int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b) wc_ecc_free(&ecc); } break; - #endif /* HAVE_ECC */ + #endif /* HAVE_ECC */ default: WOLFSSL_MSG("Unknown key type"); return WOLFSSL_FAILURE; @@ -24837,14 +24843,16 @@ int wolfSSL_X509_cmp_time(const WOLFSSL_ASN1_TIME* asnTime, time_t* cmpTime) int ret = WOLFSSL_FAILURE, i = 0; time_t tmpTime, *pTime = &tmpTime; byte data_ptr[MAX_TIME_STRING_SZ], inv = 0; - struct tm ts, *tmpTs = NULL, *ct; + struct tm ts, *tmpTs, *ct; #if defined(NEED_TMP_TIME) /* for use with gmtime_r */ struct tm tmpTimeStorage; + tmpTs = &tmpTimeStorage; #else - (void)tmpTs; + tmpTs = NULL; #endif + (void)tmpTs; if (asnTime == NULL) { return WOLFSSL_FAILURE; @@ -25196,16 +25204,17 @@ WOLFSSL_ASN1_TIME* wolfSSL_ASN1_TIME_adj(WOLFSSL_ASN1_TIME *s, time_t t, { const time_t sec_per_day = 24*60*60; struct tm* ts = NULL; - struct tm* tmpTime = NULL; + struct tm* tmpTime; time_t t_adj = 0; time_t offset_day_sec = 0; - #if defined(NEED_TMP_TIME) struct tm tmpTimeStorage; + tmpTime = &tmpTimeStorage; #else - (void)tmpTime; + tmpTime = NULL; #endif + (void)tmpTime; WOLFSSL_ENTER("wolfSSL_ASN1_TIME_adj"); @@ -28682,7 +28691,7 @@ int wolfSSL_cmp_peer_cert_to_file(WOLFSSL* ssl, const char *fname) #endif byte* myBuffer = staticBuffer; int dynamic = 0; - XFILE file = XBADFILE; + XFILE file; long sz = 0; WOLFSSL_CTX* ctx = ssl->ctx; WOLFSSL_X509* peer_cert = &ssl->peerCert; @@ -29096,7 +29105,7 @@ int wolfSSL_RAND_bytes(unsigned char* buf, int num) int initTmpRng = 0; WC_RNG* rng = NULL; #ifdef WOLFSSL_SMALL_STACK - WC_RNG* tmpRNG = NULL; + WC_RNG* tmpRNG; #else WC_RNG tmpRNG[1]; #endif @@ -29837,7 +29846,7 @@ int wolfSSL_DH_generate_key(WOLFSSL_DH* dh) int initTmpRng = 0; WC_RNG* rng = NULL; #ifdef WOLFSSL_SMALL_STACK - WC_RNG* tmpRNG = NULL; + WC_RNG* tmpRNG; #else WC_RNG tmpRNG[1]; #endif @@ -29848,7 +29857,6 @@ int wolfSSL_DH_generate_key(WOLFSSL_DH* dh) #ifdef WOLFSSL_SMALL_STACK tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG); - if (tmpRNG == NULL) { XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG); return ret; @@ -29930,10 +29938,10 @@ int wolfSSL_DH_compute_key(unsigned char* key, WOLFSSL_BIGNUM* otherPub, { int ret = WOLFSSL_FATAL_ERROR; word32 keySz = 0; - word32 pubSz = 1024; - word32 privSz = 1024; + int pubSz = 1024; + int privSz = 1024; #ifdef WOLFSSL_SMALL_STACK - unsigned char* pub = NULL; + unsigned char* pub; unsigned char* priv = NULL; #else unsigned char pub [1024]; @@ -30108,7 +30116,6 @@ void wolfSSL_DSA_free(WOLFSSL_DSA* dsa) InitwolfSSL_DSA(dsa); /* set back to NULLs for safety */ XFREE(dsa, NULL, DYNAMIC_TYPE_DSA); - dsa = NULL; } } @@ -30301,7 +30308,7 @@ int wolfSSL_RSA_generate_key_ex(WOLFSSL_RSA* rsa, int bits, WOLFSSL_BIGNUM* bn, #ifdef WOLFSSL_KEY_GEN { #ifdef WOLFSSL_SMALL_STACK - WC_RNG* rng = NULL; + WC_RNG* rng; #else WC_RNG rng[1]; #endif @@ -30365,7 +30372,7 @@ int wolfSSL_DSA_generate_key(WOLFSSL_DSA* dsa) int initTmpRng = 0; WC_RNG *rng = NULL; #ifdef WOLFSSL_SMALL_STACK - WC_RNG *tmpRNG = NULL; + WC_RNG *tmpRNG; #else WC_RNG tmpRNG[1]; #endif @@ -30466,7 +30473,7 @@ int wolfSSL_DSA_generate_parameters_ex(WOLFSSL_DSA* dsa, int bits, int initTmpRng = 0; WC_RNG *rng = NULL; #ifdef WOLFSSL_SMALL_STACK - WC_RNG *tmpRNG = NULL; + WC_RNG *tmpRNG; #else WC_RNG tmpRNG[1]; #endif @@ -30933,10 +30940,12 @@ int wolfSSL_HMAC_Init_ex(WOLFSSL_HMAC_CTX* ctx, const void* key, * returns WOLFSSL_SUCCESS on success */ int wolfSSL_HmacCopy(Hmac* des, Hmac* src) { - void* heap = NULL; + void* heap; #ifndef HAVE_FIPS heap = src->heap; +#else + heap = NULL; #endif if (wc_HmacInit(des, heap, 0) != 0) { return WOLFSSL_FAILURE; @@ -33237,7 +33246,6 @@ void wolfSSL_EC_KEY_free(WOLFSSL_EC_KEY *key) InitwolfSSL_ECKey(key); /* set back to NULLs for safety */ XFREE(key, NULL, DYNAMIC_TYPE_ECC); - key = NULL; } } #endif /* HAVE_ECC && (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) */ @@ -33522,7 +33530,6 @@ void wolfSSL_EC_GROUP_free(WOLFSSL_EC_GROUP *group) WOLFSSL_ENTER("wolfSSL_EC_GROUP_free"); XFREE(group, NULL, DYNAMIC_TYPE_ECC); - group = NULL; } #endif @@ -34039,7 +34046,6 @@ void wolfSSL_EC_POINT_free(WOLFSSL_EC_POINT *p) p->inSet = p->exSet = 0; XFREE(p, NULL, DYNAMIC_TYPE_ECC); - p = NULL; } } #endif @@ -35434,7 +35440,7 @@ WOLFSSL_DSA *wolfSSL_PEM_read_bio_DSA_PUBKEY(WOLFSSL_BIO* bio,WOLFSSL_DSA** dsa, WOLFSSL_EC_GROUP* wolfSSL_PEM_read_bio_ECPKParameters(WOLFSSL_BIO* bio, WOLFSSL_EC_GROUP** group, pem_password_cb* cb, void* pass) { - WOLFSSL_EVP_PKEY* pkey = NULL; + WOLFSSL_EVP_PKEY* pkey; WOLFSSL_EC_GROUP* ret = NULL; /* check on if bio is null is done in wolfSSL_PEM_read_bio_PrivateKey */ @@ -38317,7 +38323,7 @@ err: WOLFSSL_X509_NAME_ENTRY* wolfSSL_X509_NAME_ENTRY_new(void) { - WOLFSSL_X509_NAME_ENTRY* ne = NULL; + WOLFSSL_X509_NAME_ENTRY* ne; ne = (WOLFSSL_X509_NAME_ENTRY*)XMALLOC(sizeof(WOLFSSL_X509_NAME_ENTRY), NULL, DYNAMIC_TYPE_NAME_ENTRY); @@ -38334,7 +38340,7 @@ err: WOLFSSL_X509_NAME_ENTRY** out, int nid, int type, const unsigned char* data, int dataSz) { - WOLFSSL_X509_NAME_ENTRY* ne = NULL; + WOLFSSL_X509_NAME_ENTRY* ne; WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_create_by_NID()"); @@ -39068,8 +39074,7 @@ err: objSz += oidSz; obj->objSz = objSz; if(((obj->dynamic & WOLFSSL_ASN1_DYNAMIC_DATA) != 0) || - (((obj->dynamic & WOLFSSL_ASN1_DYNAMIC_DATA) == 0) && - (obj->obj == NULL))) { + (obj->obj == NULL)) { obj->obj = (byte*)XREALLOC((byte*)obj->obj, obj->objSz, NULL, DYNAMIC_TYPE_ASN1); if (obj->obj == NULL) { @@ -41680,7 +41685,7 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey_bio(WOLFSSL_BIO* bio, DYNAMIC_TYPE_TMP_BUFFER); } - if (out != NULL && key != NULL) { + if (out != NULL) { *out = key; } } @@ -43409,14 +43414,13 @@ int wolfSSL_AsyncPoll(WOLFSSL* ssl, WOLF_EVENT_FLAG flags) } ret = wolfAsync_EventQueuePoll(&ssl->ctx->event_queue, ssl, - events, sizeof(events)/sizeof(events), flags, &eventCount); + events, sizeof(events)/sizeof(*events), flags, &eventCount); if (ret == 0) { ret = eventCount; } return ret; } - #endif /* WOLFSSL_ASYNC_CRYPT */ #ifdef OPENSSL_EXTRA @@ -45956,7 +45960,7 @@ int wolfSSL_BN_hex2bn(WOLFSSL_BIGNUM** bn, const char* str) int ret = 0; word32 decSz = 1024; #ifdef WOLFSSL_SMALL_STACK - byte* decoded = NULL; + byte* decoded; #else byte decoded[1024]; #endif @@ -46536,7 +46540,7 @@ const char *wolfSSL_ASN1_tag2str(int tag) static int check_esc_char(char c, char *esc) { - char *ptr = NULL; + char *ptr; ptr = esc; while(*ptr != 0){ @@ -46631,7 +46635,7 @@ int wolfSSL_ASN1_STRING_print_ex(WOLFSSL_BIO *out, WOLFSSL_ASN1_STRING *str, if (flags & ASN1_STRFLGS_ESC_2253){ char esc_ch[] = "+;<>\\"; - char* esc_ptr = NULL; + char* esc_ptr; esc_ptr = str->data; while (*esc_ptr != 0){ @@ -47108,7 +47112,6 @@ void wolfSSL_BN_free(WOLFSSL_BIGNUM* bn) bn->internal = NULL; } XFREE(bn, NULL, DYNAMIC_TYPE_BIGINT); - bn = NULL; } } @@ -47182,7 +47185,6 @@ void wolfSSL_RSA_free(WOLFSSL_RSA* rsa) InitwolfSSL_Rsa(rsa); /* set back to NULLs for safety */ XFREE(rsa, NULL, DYNAMIC_TYPE_RSA); - rsa = NULL; } } @@ -47218,7 +47220,7 @@ WOLFSSL_RSA* wolfSSL_RSA_new(void) #if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && \ !defined(HAVE_FAST_RSA) && defined(WC_RSA_BLINDING) { - WC_RNG* rng = NULL; + WC_RNG* rng; rng = (WC_RNG*) XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG); if (rng != NULL && wc_InitRng(rng) != 0) { diff --git a/src/tls.c b/src/tls.c index 4e5bfdc14..dc5bdf5a6 100644 --- a/src/tls.c +++ b/src/tls.c @@ -4811,7 +4811,7 @@ static int TLSX_SecureRenegotiation_Parse(WOLFSSL* ssl, byte* input, int TLSX_UseSecureRenegotiation(TLSX** extensions, void* heap) { int ret = 0; - SecureRenegotiation* data = NULL; + SecureRenegotiation* data; data = (SecureRenegotiation*)XMALLOC(sizeof(SecureRenegotiation), heap, DYNAMIC_TYPE_TLSX); @@ -5566,7 +5566,7 @@ static int TLSX_HaveQSHScheme(word16 name) int TLSX_UseQSHScheme(TLSX** extensions, word16 name, byte* pKey, word16 pkeySz, void* heap) { - TLSX* extension = TLSX_Find(*extensions, TLSX_QUANTUM_SAFE_HYBRID); + TLSX* extension = NULL; QSHScheme* format = NULL; int ret = 0; @@ -5579,6 +5579,7 @@ int TLSX_UseQSHScheme(TLSX** extensions, word16 name, byte* pKey, word16 pkeySz, if ((ret = TLSX_QSH_Append(&format, name, pKey, pkeySz)) != 0) return ret; + extension = TLSX_Find(*extensions, TLSX_QUANTUM_SAFE_HYBRID); if (!extension) { if ((ret = TLSX_Push(extensions, TLSX_QUANTUM_SAFE_HYBRID, format, heap)) != 0) { diff --git a/src/wolfio.c b/src/wolfio.c index 1d2983146..e64d82284 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -1135,7 +1135,7 @@ int wolfIO_HttpProcessResponse(int sfd, const char** appStrList, int i; start += 13; - while (*start == ' ' && *start != '\0') start++; + while (*start == ' ') start++; /* try and match against appStrList */ i = 0; @@ -1154,13 +1154,13 @@ int wolfIO_HttpProcessResponse(int sfd, const char** appStrList, } else if (XSTRNCASECMP(start, "Content-Length:", 15) == 0) { start += 15; - while (*start == ' ' && *start != '\0') start++; + while (*start == ' ') start++; chunkSz = XATOI(start); state = (state == phr_http_start) ? phr_have_length : phr_wait_end; } else if (XSTRNCASECMP(start, "Transfer-Encoding:", 18) == 0) { start += 18; - while (*start == ' ' && *start != '\0') start++; + while (*start == ' ') start++; if (XSTRNCASECMP(start, "chunked", 7) == 0) { isChunked = 1; state = (state == phr_http_start) ? phr_have_length : phr_wait_end; @@ -2012,7 +2012,7 @@ void mynewt_ctx_clear(void *ctx) { /* return Mynewt_Ctx instance */ void* mynewt_ctx_new() { int rc = 0; - Mynewt_Ctx *mynewt_ctx = NULL; + Mynewt_Ctx *mynewt_ctx; int mem_buf_count = MYNEWT_VAL(WOLFSSL_MNSOCK_MEM_BUF_COUNT); int mem_buf_size = MYNEWT_VAL(WOLFSSL_MNSOCK_MEM_BUF_SIZE); int mempool_bytes = OS_MEMPOOL_BYTES(mem_buf_count, mem_buf_size); @@ -2149,7 +2149,7 @@ int Mynewt_Send(WOLFSSL* ssl, char *buf, int sz, void *ctx) { Mynewt_Ctx *mynewt_ctx = (Mynewt_Ctx*)ctx; int rc = 0; - struct os_mbuf *m = NULL; + struct os_mbuf *m; int write_sz = 0; m = os_msys_get_pkthdr(sz, 0); if (!m) { diff --git a/tests/api.c b/tests/api.c index 76d2f2310..0eb7228f2 100644 --- a/tests/api.c +++ b/tests/api.c @@ -1015,7 +1015,7 @@ static void test_wolfSSL_CTX_load_verify_locations(void) static int test_cm_load_ca_buffer(const byte* cert_buf, size_t cert_sz, int file_type) { int ret; - WOLFSSL_CERT_MANAGER* cm = NULL; + WOLFSSL_CERT_MANAGER* cm; cm = wolfSSL_CertManagerNew(); if (cm == NULL) { @@ -1150,7 +1150,7 @@ static int test_wolfSSL_CertManagerSetVerify(void) int ret = 0; #if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \ !defined(NO_WOLFSSL_CM_VERIFY) && !defined(NO_RSA) - WOLFSSL_CERT_MANAGER* cm = NULL; + WOLFSSL_CERT_MANAGER* cm; int tmp = myVerifyFail; const char* ca_cert = "./certs/ca-cert.pem"; const char* expiredCert = "./certs/test/expired/expired-cert.pem"; @@ -2037,7 +2037,7 @@ static void test_wolfSSL_EVP_CIPHER_CTX() #if !defined(NO_AES) && defined(HAVE_AES_CBC) && defined(WOLFSSL_AES_128) EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); const EVP_CIPHER *init = EVP_aes_128_cbc(); - const EVP_CIPHER *test = NULL; + const EVP_CIPHER *test; byte key[AES_BLOCK_SIZE] = {0}; byte iv[AES_BLOCK_SIZE] = {0}; @@ -2165,7 +2165,7 @@ static THREAD_RETURN WOLFSSL_THREAD test_server_nofail(void* args) SOCKET_T clientfd = 0; word16 port; - callback_functions* cbf = NULL; + callback_functions* cbf; WOLFSSL_CTX* ctx = 0; WOLFSSL* ssl = 0; @@ -2258,7 +2258,7 @@ static THREAD_RETURN WOLFSSL_THREAD test_server_nofail(void* args) #ifdef WOLFSSL_SESSION_EXPORT /* only add in more complex nonblocking case with session export tests */ - if (args && ((func_args*)args)->argc > 0) { + if (((func_args*)args)->argc > 0) { /* set as nonblock and time out for waiting on read/write */ tcp_set_nonblocking(&clientfd); wolfSSL_dtls_set_using_nonblock(ssl, 1); @@ -2296,7 +2296,7 @@ static THREAD_RETURN WOLFSSL_THREAD test_server_nofail(void* args) #ifdef WOLFSSL_SESSION_EXPORT /* only add in more complex nonblocking case with session export tests */ - if (args && ((func_args*)args)->argc > 0) { + if (((func_args*)args)->argc > 0) { ret = nonblocking_accept_read(args, ssl, &clientfd); if (ret >= 0) { ((func_args*)args)->return_code = TEST_SUCCESS; @@ -2385,7 +2385,7 @@ static THREAD_RETURN WOLFSSL_THREAD test_server_loop(void* args) SOCKET_T clientfd = 0; word16 port; - callback_functions* cbf = NULL; + callback_functions* cbf; WOLFSSL_CTX* ctx = 0; WOLFSSL* ssl = 0; @@ -2575,7 +2575,7 @@ typedef int (*cbType)(WOLFSSL_CTX *ctx, WOLFSSL *ssl); static void test_client_nofail(void* args, void *cb) { SOCKET_T sockfd = 0; - callback_functions* cbf = NULL; + callback_functions* cbf; WOLFSSL_CTX* ctx = 0; WOLFSSL* ssl = 0; @@ -2757,7 +2757,7 @@ done: static void test_client_reuse_WOLFSSLobj(void* args, void *cb, void* server_args) { SOCKET_T sockfd = 0; - callback_functions* cbf = NULL; + callback_functions* cbf; WOLFSSL_CTX* ctx = 0; WOLFSSL* ssl = 0; @@ -4391,11 +4391,13 @@ static void test_wolfSSL_X509_NAME_get_entry(void) { /* use openssl like name to test mapping */ - X509_NAME_ENTRY* ne = NULL; - X509_NAME* name = NULL; - char* subCN = NULL; + X509_NAME_ENTRY* ne; + X509_NAME* name; X509* x509; + #ifndef NO_FILESYSTEM ASN1_STRING* asn; + char* subCN = NULL; + #endif int idx; ASN1_OBJECT *object = NULL; #if defined(WOLFSSL_APACHE_HTTPD) || defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) @@ -4456,7 +4458,10 @@ static void test_wolfSSL_PKCS12(void) char file[] = "./certs/test-servercert.p12"; char order[] = "./certs/ecc-rsa-server.p12"; char pass[] = "a password"; +#ifdef HAVE_ECC WOLFSSL_X509_NAME* subject; + WOLFSSL_X509 *x509; +#endif XFILE f; int bytes, ret; WOLFSSL_BIO *bio; @@ -4464,7 +4469,6 @@ static void test_wolfSSL_PKCS12(void) WC_PKCS12 *pkcs12; WC_PKCS12 *pkcs12_2; WOLFSSL_X509 *cert; - WOLFSSL_X509 *x509; WOLFSSL_X509 *tmp; WOLF_STACK_OF(WOLFSSL_X509) *ca; #if defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO) || defined(WOLFSSL_HAPROXY) \ @@ -4710,8 +4714,6 @@ static void test_wolfSSL_PKCS12(void) PKCS12_free(pkcs12); BIO_free(bio); - (void)x509; - (void)subject; (void)order; printf(resultFmt, passed); @@ -5195,8 +5197,6 @@ static int test_wolfSSL_CTX_SetMinVersion(void) const int versions[0]; #endif - failFlag = WOLFSSL_SUCCESS; - ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()); printf(testingFmt, "wolfSSL_CTX_SetMinVersion()"); @@ -6913,6 +6913,8 @@ static int test_wc_InitSha3 (void) #if defined(WOLFSSL_SHA3) wc_Sha3 sha3; + (void)sha3; + #if !defined(WOLFSSL_NOSHA3_224) printf(testingFmt, "wc_InitSha3_224()"); @@ -10464,7 +10466,7 @@ static int test_wc_AesCbcEncryptDecrypt (void) } } /* If encrypt succeeds but cbc decrypt fails, we can still test. */ - if (ret == 0 || (ret != 0 && cbcE == 0)) { + if (ret == 0 || cbcE == 0) { ret = wc_AesCbcDecryptWithKey(dec2, enc, AES_BLOCK_SIZE, key32, sizeof(key32)/sizeof(byte), iv); if (ret == 0 || XMEMCMP(vector, dec2, AES_BLOCK_SIZE) == 0) { @@ -16573,9 +16575,7 @@ static int test_wc_ecc_mulmod (void) ret = wc_InitRng(&rng); if (ret == 0) { - if (ret == 0) { - ret = wc_ecc_init(&key1); - } + ret = wc_ecc_init(&key1); if (ret == 0) { ret = wc_ecc_init(&key2); } @@ -16585,6 +16585,7 @@ static int test_wc_ecc_mulmod (void) if (ret == 0) { ret = wc_ecc_make_key(&rng, KEY32, &key1); } + wc_FreeRng(&rng); } if (ret == 0) { ret = wc_ecc_import_raw_ex(&key2, key1.dp->Gx, key1.dp->Gy, key1.dp->Af, @@ -16626,9 +16627,6 @@ static int test_wc_ecc_mulmod (void) printf(resultFmt, ret == 0 ? passed : failed); - if (wc_FreeRng(&rng) && ret == 0) { - ret = WOLFSSL_FATAL_ERROR; - } wc_ecc_free(&key1); wc_ecc_free(&key2); wc_ecc_free(&key3); @@ -20540,7 +20538,7 @@ static void test_wolfSSL_CTX_add_extra_chain_cert(void) char caFile[] = "./certs/client-ca.pem"; char clientFile[] = "./certs/client-cert.pem"; SSL_CTX* ctx; - X509* x509 = NULL; + X509* x509; printf(testingFmt, "wolfSSL_CTX_add_extra_chain_cert()"); @@ -22864,6 +22862,14 @@ static void test_wolfSSL_PKCS8_d2i(void) #endif #endif +#ifndef NO_FILESYSTEM + (void)pkcs8_buffer; + (void)p; + (void)bytes; + (void)file; + (void)bio; +#endif + #ifndef NO_RSA /* Try to auto-detect normal RSA private key */ AssertNotNull(pkey = d2i_AutoPrivateKey(NULL, &rsa, rsaSz)); @@ -24367,8 +24373,8 @@ static void test_wolfSSL_RSA_get0_key(void) const BIGNUM* e = NULL; const BIGNUM* d = NULL; - const unsigned char* der = NULL; - int derSz = 0; + const unsigned char* der; + int derSz; #ifdef USE_CERT_BUFFERS_1024 der = client_key_der_1024; @@ -24376,6 +24382,9 @@ static void test_wolfSSL_RSA_get0_key(void) #elif defined(USE_CERT_BUFFERS_2048) der = client_key_der_2048; derSz = sizeof_client_key_der_2048; +#else + der = NULL; + derSz = 0; #endif printf(testingFmt, "test_wolfSSL_RSA_get0_key()"); @@ -25009,9 +25018,9 @@ static void test_wolfSSL_OpenSSL_add_all_algorithms(void){ static void test_wolfSSL_ASN1_STRING_print_ex(void){ #if defined(OPENSSL_EXTRA) && !defined(NO_ASN) - ASN1_STRING* asn_str = NULL; + ASN1_STRING* asn_str; const char data[] = "Hello wolfSSL!"; - ASN1_STRING* esc_str = NULL; + ASN1_STRING* esc_str; const char esc_data[] = "a+;<>"; BIO *bio; unsigned long flags; @@ -25119,7 +25128,6 @@ static void test_wolfSSL_ASN1_TIME_to_generalizedtime(void){ XMEMSET(t, 0, ASN_GENERALIZED_TIME_SIZE); XMEMSET(out, 0, ASN_GENERALIZED_TIME_SIZE); XMEMSET(data, 0, ASN_GENERALIZED_TIME_SIZE); - gtime = NULL; t->type = ASN_GENERALIZED_TIME; t->length = ASN_GENERALIZED_TIME_SIZE; XMEMCPY(t->data, "20050727123456Z", ASN_GENERALIZED_TIME_SIZE); @@ -26778,7 +26786,7 @@ static void test_wolfSSL_X509_EXTENSION_get_critical(void) WOLFSSL_X509* x509; WOLFSSL_X509_EXTENSION* ext; FILE* file; - int crit = -1; + int crit; printf(testingFmt, "wolfSSL_X509_EXTENSION_get_critical"); @@ -26994,7 +27002,7 @@ static void test_wolfSSL_OCSP_get0_info() ASN1_OBJECT* pmd = NULL; ASN1_STRING* keyHash = NULL; ASN1_INTEGER* serial = NULL; - ASN1_INTEGER* x509Int = NULL; + ASN1_INTEGER* x509Int; printf(testingFmt, "wolfSSL_OCSP_get0_info()"); @@ -29226,10 +29234,10 @@ static void test_wolfSSL_PEM_X509_INFO_read_bio(void) static void test_wolfSSL_X509_NAME_ENTRY_get_object() { #if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && !defined(NO_RSA) - X509 *x509 = NULL; - X509_NAME* name = NULL; + X509 *x509; + X509_NAME* name; int idx = 0; - X509_NAME_ENTRY *ne = NULL; + X509_NAME_ENTRY *ne; ASN1_OBJECT *object = NULL; printf(testingFmt, "wolfSSL_X509_NAME_ENTRY_get_object"); diff --git a/testsuite/testsuite.c b/testsuite/testsuite.c index cabfc8044..dd15cc743 100644 --- a/testsuite/testsuite.c +++ b/testsuite/testsuite.c @@ -136,13 +136,11 @@ int testsuite_test(int argc, char** argv) func_args echo_args; char* myArgv[NUMARGS]; - char argc0[32]; - char argc1[32]; - char argc2[32]; + char arg[3][32]; - myArgv[0] = argc0; - myArgv[1] = argc1; - myArgv[2] = argc2; + myArgv[0] = arg[0]; + myArgv[1] = arg[1]; + myArgv[2] = arg[2]; echo_args.argc = 3; echo_args.argv = myArgv; @@ -154,9 +152,9 @@ int testsuite_test(int argc, char** argv) return EXIT_FAILURE; } - strcpy(echo_args.argv[0], "echoclient"); - strcpy(echo_args.argv[1], "input"); - strcpy(echo_args.argv[2], outputName); + strcpy(arg[0], "echoclient"); + strcpy(arg[1], "input"); + strcpy(arg[2], outputName); /* Share the signal, it has the new port number in it. */ echo_args.signal = server_args.signal; @@ -229,36 +227,20 @@ void simple_test(func_args* args) { THREAD_TYPE serverThread; + int i; + func_args svrArgs; char *svrArgv[9]; - char argc0s[32]; - char argc1s[32]; - char argc2s[32]; - char argc3s[32]; - char argc4s[32]; - char argc5s[32]; - char argc6s[32]; - char argc7s[32]; - char argc8s[32]; + char argvs[9][32]; func_args cliArgs; char *cliArgv[NUMARGS]; - char argc0c[32]; - char argc1c[32]; - char argc2c[32]; + char argvc[3][32]; - svrArgv[0] = argc0s; - svrArgv[1] = argc1s; - svrArgv[2] = argc2s; - svrArgv[3] = argc3s; - svrArgv[4] = argc4s; - svrArgv[5] = argc5s; - svrArgv[6] = argc6s; - svrArgv[7] = argc7s; - svrArgv[8] = argc8s; - cliArgv[0] = argc0c; - cliArgv[1] = argc1c; - cliArgv[2] = argc2c; + for (i = 0; i < 9; i++) + svrArgv[i] = argvs[i]; + for (i = 0; i < 3; i++) + cliArgv[i] = argvc[i]; svrArgs.argc = 1; svrArgs.argv = svrArgv; @@ -267,11 +249,11 @@ void simple_test(func_args* args) cliArgs.argv = cliArgv; cliArgs.return_code = 0; - strcpy(svrArgs.argv[0], "SimpleServer"); + strcpy(argvs[0], "SimpleServer"); #if !defined(USE_WINDOWS_API) && !defined(WOLFSSL_SNIFFER) && \ !defined(WOLFSSL_TIRTOS) - strcpy(svrArgs.argv[svrArgs.argc++], "-p"); - strcpy(svrArgs.argv[svrArgs.argc++], "0"); + strcpy(argvs[svrArgs.argc++], "-p"); + strcpy(argvs[svrArgs.argc++], "0"); #endif /* Set the last arg later, when it is known. */ @@ -281,11 +263,11 @@ void simple_test(func_args* args) wait_tcp_ready(&svrArgs); /* Setting the actual port number. */ - strcpy(cliArgs.argv[0], "SimpleClient"); + strcpy(argvc[0], "SimpleClient"); #ifndef USE_WINDOWS_API cliArgs.argc = NUMARGS; - strcpy(cliArgs.argv[1], "-p"); - snprintf(cliArgs.argv[2], sizeof(argc2c), "%d", svrArgs.signal->port); + strcpy(argvc[1], "-p"); + snprintf(argvc[2], sizeof(argvc[2]), "%d", svrArgs.signal->port); #endif client_test(&cliArgs); diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index 7a905e59c..b296000b1 100755 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -4542,7 +4542,7 @@ void bench_rsa(int doAsync) int ret = 0, i; RsaKey rsaKey[BENCH_MAX_PENDING]; #if !defined(WOLFSSL_RSA_PUBLIC_ONLY) || defined(WOLFSSL_PUBLIC_MP) - int rsaKeySz = RSA_BUF_SIZE * 8; /* used in printf */ + int rsaKeySz; /* used in printf */ size_t bytes; const byte* tmp; word32 idx; diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 946fae4fe..6f81211bb 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -2152,6 +2152,7 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) #endif #ifdef NEED_AES_TABLES + (void)temp; switch (keylen) { #if defined(AES_MAX_KEY_SIZE) && AES_MAX_KEY_SIZE >= 128 && \ diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index e9971d958..f2bb932c5 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -2826,7 +2826,7 @@ int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der) /* test if RSA key */ if (der->keyOID == RSAk) { #ifdef WOLFSSL_SMALL_STACK - RsaKey* a = NULL; + RsaKey* a; RsaKey* b = NULL; #else RsaKey a[1], b[1]; @@ -2895,7 +2895,7 @@ int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der) #if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) && !defined(NO_ASN_CRYPT) if (der->keyOID == ECDSAk) { #ifdef WOLFSSL_SMALL_STACK - ecc_key* key_pair = NULL; + ecc_key* key_pair; byte* privDer; #else ecc_key key_pair[1]; @@ -2960,7 +2960,7 @@ int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der) #if defined(HAVE_ED25519) && !defined(NO_ASN_CRYPT) if (der->keyOID == ED25519k) { #ifdef WOLFSSL_SMALL_STACK - ed25519_key* key_pair = NULL; + ed25519_key* key_pair; #else ed25519_key key_pair[1]; #endif @@ -3284,7 +3284,7 @@ int UnTraditionalEnc(byte* key, word32 keySz, byte* out, word32* outSz, return ASN_VERSION_E; } - if (salt == NULL || saltSz <= 0) { + if (salt == NULL || saltSz == 0) { saltSz = 8; #ifdef WOLFSSL_SMALL_STACK saltTmp = (byte*)XMALLOC(saltSz, heap, DYNAMIC_TYPE_TMP_BUFFER); @@ -3356,7 +3356,7 @@ int UnTraditionalEnc(byte* key, word32 keySz, byte* out, word32* outSz, /* check if should return max size */ if (out == NULL) { /* account for salt size */ - if (salt == NULL || saltSz <= 0) { + if (salt == NULL || saltSz == 0) { tmpSz += MAX_SALT_SIZE; } else { @@ -3516,7 +3516,7 @@ int TraditionalEnc(byte* key, word32 keySz, byte* out, word32* outSz, ret = CheckAlgo(vPKCS, vAlgo, &id, &version, &blockSz); /* create random salt if one not provided */ - if (ret == 0 && (salt == NULL || saltSz <= 0)) { + if (ret == 0 && (salt == NULL || saltSz == 0)) { saltSz = 8; #ifdef WOLFSSL_SMALL_STACK saltTmp = (byte*)XMALLOC(saltSz, heap, DYNAMIC_TYPE_TMP_BUFFER); @@ -3914,7 +3914,7 @@ int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz, return ALGO_ID_E; } - if (saltSz <= 0) { + if (saltSz == 0) { sz += MAX_SALT_SIZE; } else { @@ -3944,7 +3944,7 @@ int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz, out[tmpIdx++] = ASN_OCTET_STRING; /* create random salt if one not provided */ - if (salt == NULL || saltSz <= 0) { + if (salt == NULL || saltSz == 0) { saltSz = 8; #ifdef WOLFSSL_SMALL_STACK saltTmp = (byte*)XMALLOC(saltSz, heap, DYNAMIC_TYPE_TMP_BUFFER); @@ -5129,7 +5129,7 @@ static int StoreRsaKey(DecodedCert* cert, word32 bitStringEnd) word32 oidSz = 0; ret = wc_ecc_get_oid(oid, NULL, &oidSz); - if (ret < 0 || oidSz <= 0) { + if (ret < 0 || oidSz == 0) { WOLFSSL_MSG("CheckCurve not found"); ret = ALGO_ID_E; } @@ -5490,7 +5490,7 @@ int wc_OBJ_sn2nid(const char *sn) /* Routine for calculating hashId */ int CalcHashId(const byte* data, word32 len, byte* hash) { - int ret = NOT_COMPILED_IN; + int ret; #ifdef WOLF_CRYPTO_CB /* try to use a registered crypto callback */ @@ -5504,6 +5504,8 @@ int CalcHashId(const byte* data, word32 len, byte* hash) ret = wc_Sha256Hash(data, len, hash); #elif !defined(NO_SHA) ret = wc_ShaHash(data, len, hash); +#else + ret = NOT_COMPILED_IN; #endif return ret; @@ -5860,7 +5862,7 @@ static int GetName(DecodedCert* cert, int nameType, int maxIdx) #endif /* OPENSSL_EXTRA */ #ifndef IGNORE_NAME_CONSTRAINTS { - DNS_entry* emailName = NULL; + DNS_entry* emailName; emailName = (DNS_entry*)XMALLOC(sizeof(DNS_entry), cert->heap, DYNAMIC_TYPE_ALTNAME); @@ -6330,7 +6332,7 @@ int ValidateDate(const byte* date, byte format, int dateType) time_t ltime; struct tm certTime; struct tm* localTime; - struct tm* tmpTime = NULL; + struct tm* tmpTime; int i = 0; int timeDiff = 0 ; int diffHH = 0 ; int diffMM = 0 ; @@ -6340,8 +6342,9 @@ int ValidateDate(const byte* date, byte format, int dateType) struct tm tmpTimeStorage; tmpTime = &tmpTimeStorage; #else - (void)tmpTime; + tmpTime = NULL; #endif + (void)tmpTime; ltime = XTIME(0); @@ -9326,7 +9329,7 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) type != TRUSTED_PEER_TYPE) { WOLFSSL_MSG("\tmaxPathLen status: OK"); } - } else if (decrementMaxPathLen && cert->ca->maxPathLen <= 0) { + } else if (decrementMaxPathLen && cert->ca->maxPathLen == 0) { cert->maxPathLen = 0; if (verify != NO_VERIFY && type != CA_TYPE && type != TRUSTED_PEER_TYPE) { @@ -9366,12 +9369,12 @@ int ParseCertRelative(DecodedCert* cert, int type, int verify, void* cm) /* prepare for TSIP TLS cert verification API use */ if (cert->keyOID == RSAk) { /* to call TSIP API, it needs keys position info in bytes */ - if (ret = RsaPublicKeyDecodeRawIndex(cert->publicKey, (word32*)&idx, + if ((ret = RsaPublicKeyDecodeRawIndex(cert->publicKey, (word32*)&idx, cert->pubKeySize, &cert->sigCtx.pubkey_n_start, &cert->sigCtx.pubkey_n_len, &cert->sigCtx.pubkey_e_start, - &cert->sigCtx.pubkey_e_len) != 0) { + &cert->sigCtx.pubkey_e_len)) != 0) { WOLFSSL_MSG("Decoding index from cert failed."); return ret; } @@ -10038,8 +10041,7 @@ int wc_EncryptedInfoParse(EncryptedInfo* info, char** pBuffer, size_t bufSz) newline = SkipEndOfLineChars(newline, bufferEnd); /* return new headerEnd */ - if (pBuffer) - *pBuffer = newline; + *pBuffer = newline; } return err; @@ -10844,7 +10846,7 @@ static int SetRsaPublicKey(byte* output, RsaKey* key, if (with_header) { int algoSz; #ifdef WOLFSSL_SMALL_STACK - byte* algo = NULL; + byte* algo; algo = (byte*)XMALLOC(MAX_ALGO_SZ, key->heap, DYNAMIC_TYPE_TMP_BUFFER); if (algo == NULL) { @@ -11289,7 +11291,7 @@ static int SetEccPublicKey(byte* output, ecc_key* key, int with_header) #ifdef WOLFSSL_SMALL_STACK byte* algo = NULL; byte* curve = NULL; - byte* pub = NULL; + byte* pub; #else byte algo[MAX_ALGO_SZ]; byte curve[MAX_ALGO_SZ]; @@ -11432,7 +11434,7 @@ int wc_EccPublicKeyToDer(ecc_key* key, byte* output, word32 inLen, return keySz + infoSz; } - if (output == NULL || inLen < keySz + infoSz) { + if (inLen < keySz + infoSz) { return BUFFER_E; } @@ -11459,7 +11461,7 @@ static int SetEd25519PublicKey(byte* output, ed25519_key* key, int with_header) word32 pubSz = ED25519_PUB_KEY_SIZE; #ifdef WOLFSSL_SMALL_STACK byte* algo = NULL; - byte* pub = NULL; + byte* pub; #else byte algo[MAX_ALGO_SZ]; byte pub[ED25519_PUB_KEY_SIZE]; @@ -11624,7 +11626,7 @@ static int SetValidity(byte* output, int daysValid) time_t now; time_t then; - struct tm* tmpTime = NULL; + struct tm* tmpTime; struct tm* expandedTime; struct tm localTime; @@ -11633,8 +11635,9 @@ static int SetValidity(byte* output, int daysValid) struct tm tmpTimeStorage; tmpTime = &tmpTimeStorage; #else - (void)tmpTime; + tmpTime = NULL; #endif + (void)tmpTime; now = XTIME(0); @@ -13501,11 +13504,14 @@ static int SignCert(int requestSz, int sType, byte* buffer, word32 buffSz, { int sigSz = 0; void* heap = NULL; - CertSignCtx* certSignCtx = NULL; + CertSignCtx* certSignCtx; #ifndef WOLFSSL_ASYNC_CRYPT CertSignCtx certSignCtx_lcl; + certSignCtx = &certSignCtx_lcl; XMEMSET(certSignCtx, 0, sizeof(CertSignCtx)); +#else + certSignCtx = NULL; #endif if (requestSz < 0) @@ -14882,7 +14888,7 @@ int wc_EccPrivateKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key, XMEMCPY(priv, &input[*inOutIdx], privSz); *inOutIdx += length; - if (ret == 0 && (*inOutIdx + 1) < inSz) { + if ((*inOutIdx + 1) < inSz) { /* prefix 0, may have */ b = input[*inOutIdx]; if (b == ECC_PREFIX_0) { @@ -16077,7 +16083,7 @@ static int DecodeBasicOcspResponse(byte* source, word32* ioIndex, else #endif /* WOLFSSL_NO_OCSP_OPTIONAL_CERTS */ { - Signer* ca = NULL; + Signer* ca; int sigValid = -1; #ifndef NO_SKID diff --git a/wolfcrypt/src/blake2b.c b/wolfcrypt/src/blake2b.c index 898dba6c3..1541947dd 100644 --- a/wolfcrypt/src/blake2b.c +++ b/wolfcrypt/src/blake2b.c @@ -317,8 +317,7 @@ int blake2b_update( blake2b_state *S, const byte *in, word64 inlen ) { XMEMCPY( S->buf + left, in, (wolfssl_word)inlen ); S->buflen += inlen; /* Be lazy, do not compress */ - in += inlen; - inlen -= inlen; + inlen = 0; } } diff --git a/wolfcrypt/src/blake2s.c b/wolfcrypt/src/blake2s.c index 9fef77f65..651a1d18d 100644 --- a/wolfcrypt/src/blake2s.c +++ b/wolfcrypt/src/blake2s.c @@ -311,8 +311,7 @@ int blake2s_update( blake2s_state *S, const byte *in, word32 inlen ) { XMEMCPY( S->buf + left, in, (wolfssl_word)inlen ); S->buflen += inlen; /* Be lazy, do not compress */ - in += inlen; - inlen -= inlen; + inlen = 0; } } diff --git a/wolfcrypt/src/dh.c b/wolfcrypt/src/dh.c index 65fd76973..1060b837a 100644 --- a/wolfcrypt/src/dh.c +++ b/wolfcrypt/src/dh.c @@ -1231,8 +1231,8 @@ static int GeneratePublicDh(DhKey* key, byte* priv, word32 privSz, int ret = 0; #ifndef WOLFSSL_SP_MATH #ifdef WOLFSSL_SMALL_STACK - mp_int* x = NULL; - mp_int* y = NULL; + mp_int* x; + mp_int* y; #else mp_int x[1]; mp_int y[1]; @@ -1499,7 +1499,7 @@ int wc_DhCheckPubKey_ex(DhKey* key, const byte* pub, word32 pubSz, /* SP 800-56Ar3, section 5.6.2.3.1, process step 2 */ #ifndef WOLFSSL_SP_MATH /* calculate (y^q) mod(p), store back into y */ - if (ret == 0 && mp_exptmod(y, q, p, y) != MP_OKAY) + if (mp_exptmod(y, q, p, y) != MP_OKAY) ret = MP_EXPTMOD_E; #else ret = WC_KEY_SIZE_E; @@ -1840,10 +1840,10 @@ static int wc_DhAgree_Sync(DhKey* key, byte* agree, word32* agreeSz, { int ret = 0; #ifdef WOLFSSL_SMALL_STACK - mp_int* y = NULL; + mp_int* y; #ifndef WOLFSSL_SP_MATH - mp_int* x = NULL; - mp_int* z = NULL; + mp_int* x; + mp_int* z; #endif #else mp_int y[1]; diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index b2249284c..eef68d398 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -3477,7 +3477,7 @@ int wc_ecc_shared_secret(ecc_key* private_key, ecc_key* public_key, byte* out, word32* outlen) { int err; -#if defined(WOLFSSL_CRYPTOCELL) +#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) CRYS_ECDH_TempData_t tempBuff; #endif if (private_key == NULL || public_key == NULL || out == NULL || @@ -4041,7 +4041,7 @@ int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id) DECLARE_CURVE_SPECS(curve, ECC_CURVE_FIELD_COUNT); #endif #endif /* !WOLFSSL_ATECC508A */ -#if defined(WOLFSSL_CRYPTOCELL) +#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) const CRYS_ECPKI_Domain_t* pDomain; CRYS_ECPKI_KG_TempData_t tempBuff; CRYS_ECPKI_KG_FipsContext_t fipsCtx; @@ -4462,14 +4462,14 @@ static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen, int err; #ifdef PLUTON_CRYPTO_ECC if (key->devId != INVALID_DEVID) /* use hardware */ -#endif -#if defined(WOLFSSL_CRYPTOCELL) - CRYS_ECDSA_SignUserContext_t sigCtxTemp; - word32 raw_sig_size = *outlen; - word32 msgLenInBytes = inlen; - CRYS_ECPKI_HASH_OpMode_t hash_mode; #endif { + #if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) + CRYS_ECDSA_SignUserContext_t sigCtxTemp; + word32 raw_sig_size = *outlen; + word32 msgLenInBytes = inlen; + CRYS_ECPKI_HASH_OpMode_t hash_mode; + #endif word32 keysize = (word32)key->dp->size; word32 orderBits = wc_ecc_get_curve_order_bit_count(key->dp); @@ -4478,11 +4478,6 @@ static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen, return ECC_BAD_ARG_E; } - /* if the input is larger than curve order, we must truncate */ - if ((inlen * WOLFSSL_BIT_SIZE) > orderBits) { - inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE; - } - #if defined(WOLFSSL_ATECC508A) key->slot = atmel_ecc_alloc(ATMEL_SLOT_DEVICE); if (key->slot == ATECC_INVALID_SLOT) { @@ -4496,6 +4491,11 @@ static int wc_ecc_sign_hash_hw(const byte* in, word32 inlen, } #elif defined(PLUTON_CRYPTO_ECC) { + /* if the input is larger than curve order, we must truncate */ + if ((inlen * WOLFSSL_BIT_SIZE) > orderBits) { + inlen = (orderBits + WOLFSSL_BIT_SIZE - 1) / WOLFSSL_BIT_SIZE; + } + /* perform ECC sign */ word32 raw_sig_size = *outlen; err = Crypto_EccSign(in, inlen, out, &raw_sig_size); @@ -4887,7 +4887,7 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, if (err == MP_OKAY) { int loop_check = 0; #ifdef WOLFSSL_SMALL_STACK - ecc_key* pubkey = NULL; + ecc_key* pubkey; #else ecc_key pubkey[1]; #endif @@ -5126,7 +5126,7 @@ int wc_ecc_sign_set_k(const byte* k, word32 klen, ecc_key* key) { int ret = 0; - if (k == NULL || klen <= 0 || key == NULL) { + if (k == NULL || klen == 0 || key == NULL) { ret = BAD_FUNC_ARG; } @@ -5363,7 +5363,7 @@ int ecc_mul2add(ecc_point* A, mp_int* kA, if (err == MP_OKAY) { #ifdef WOLFSSL_SMALL_STACK - mp_int* mu = NULL; + mp_int* mu; #else mp_int mu[1]; #endif @@ -5807,7 +5807,7 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, hash_mode = cc310_hashModeECC(msgLenInBytes); if (hash_mode == CRYS_ECPKI_HASH_OpModeLast) { - hash_mode = cc310_hashModeECC(keySz); + /* hash_mode = */ cc310_hashModeECC(keySz); hash_mode = CRYS_ECPKI_HASH_SHA256_mode; } /* truncate if hash is longer than key size */ @@ -6450,8 +6450,8 @@ int wc_ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime) #ifndef WOLFSSL_SP_MATH int err; #ifdef WOLFSSL_SMALL_STACK - mp_int* t1 = NULL; - mp_int* t2 = NULL; + mp_int* t1; + mp_int* t2; #else mp_int t1[1], t2[1]; #endif @@ -7114,7 +7114,7 @@ int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz, { int ret; word32 idx = 0; -#if defined(WOLFSSL_CRYPTOCELL) +#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) const CRYS_ECPKI_Domain_t* pDomain; CRYS_ECPKI_BUILD_TempData_t tempBuff; #endif @@ -7428,7 +7428,7 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx, const char* qy, const char* d, int curve_id, int encType) { int err = MP_OKAY; -#if defined(WOLFSSL_CRYPTOCELL) +#if defined(WOLFSSL_CRYPTOCELL) && !defined(WOLFSSL_ATECC508A) const CRYS_ECPKI_Domain_t* pDomain; CRYS_ECPKI_BUILD_TempData_t tempBuff; byte key_raw[ECC_MAX_CRYPTO_HW_SIZE*2 + 1]; @@ -7540,19 +7540,22 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx, else err = mp_read_unsigned_bin(&key->k, (const byte*)d, key->dp->size); + if (err == MP_OKAY) { + err = wc_export_int(&key->k, &key_raw[0], &keySz, keySz, + WC_TYPE_UNSIGNED_BIN); + } - err = wc_export_int(&key->k, &key_raw[0], &keySz, keySz, - WC_TYPE_UNSIGNED_BIN); + if (err == MP_OKAY) { + /* Create private key from external key buffer*/ + err = CRYS_ECPKI_BuildPrivKey(pDomain, + key_raw, + keySz, + &key->ctx.privKey); - /* Create private key from external key buffer*/ - err = CRYS_ECPKI_BuildPrivKey(pDomain, - key_raw, - keySz, - &key->ctx.privKey); - - if (err != SA_SILIB_RET_OK){ - WOLFSSL_MSG("CRYS_ECPKI_BuildPrivKey failed"); - return err; + if (err != SA_SILIB_RET_OK){ + WOLFSSL_MSG("CRYS_ECPKI_BuildPrivKey failed"); + return err; + } } #else @@ -9025,7 +9028,7 @@ int ecc_mul2add(ecc_point* A, mp_int* kA, ecc_point* B, mp_int* kB, ecc_point* C, mp_int* a, mp_int* modulus, void* heap) { - int idx1 = -1, idx2 = -1, err = MP_OKAY, mpInit = 0; + int idx1 = -1, idx2 = -1, err, mpInit = 0; mp_digit mp; mp_int mu; diff --git a/wolfcrypt/src/integer.c b/wolfcrypt/src/integer.c index 9e45ebdc2..21a87c3aa 100644 --- a/wolfcrypt/src/integer.c +++ b/wolfcrypt/src/integer.c @@ -287,7 +287,7 @@ int mp_leading_bit (mp_int * a) #ifndef MP_8BIT bit = (t.dp[0] & 0x80) != 0; #else - bit = (t.dp[0] | ((t.dp[1] & 0x01) << 7)) & 0x80 != 0; + bit = ((t.dp[0] | ((t.dp[1] & 0x01) << 7)) & 0x80) != 0; #endif if (mp_div_2d (&t, 8, &t, NULL) != MP_OKAY) break; @@ -918,6 +918,8 @@ int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) dr = 0; #endif + (void)dr; + #ifdef BN_MP_REDUCE_IS_2K_C /* if not, is it a unrestricted DR modulus? */ if (dr == 0) { @@ -1911,7 +1913,7 @@ int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, mp_digit buf, mp; int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; #ifdef WOLFSSL_SMALL_STACK - mp_int* M = NULL; + mp_int* M; #else mp_int M[TAB_SIZE]; #endif @@ -1919,7 +1921,7 @@ int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, * one of many reduction algorithms without modding the guts of * the code with if statements everywhere. */ - int (*redux)(mp_int*,mp_int*,mp_digit); + int (*redux)(mp_int*,mp_int*,mp_digit) = NULL; #ifdef WOLFSSL_SMALL_STACK M = (mp_int*) XMALLOC(sizeof(mp_int) * TAB_SIZE, NULL, @@ -2002,9 +2004,6 @@ int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, #ifdef BN_MP_MONTGOMERY_REDUCE_C /* use slower baseline Montgomery method */ redux = mp_montgomery_reduce; -#else - err = MP_VAL; - goto LBL_M; #endif } } else if (redmode == 1) { @@ -2012,9 +2011,6 @@ int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, /* setup DR reduction for moduli of the form B**k - b */ mp_dr_setup(P, &mp); redux = mp_dr_reduce; -#else - err = MP_VAL; - goto LBL_M; #endif } else { #if defined(BN_MP_REDUCE_2K_SETUP_C) && defined(BN_MP_REDUCE_2K_C) @@ -2023,10 +2019,12 @@ int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, goto LBL_M; } redux = mp_reduce_2k; -#else +#endif + } + + if (redux == NULL) { err = MP_VAL; goto LBL_M; -#endif } /* setup result */ @@ -3032,6 +3030,7 @@ int mp_mul (mp_int * a, mp_int * b, mp_int * c) neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG; { +#ifdef BN_FAST_S_MP_MUL_DIGS_C /* can we use the fast multiplier? * * The fast multiplier can be used if the output will @@ -3040,7 +3039,6 @@ int mp_mul (mp_int * a, mp_int * b, mp_int * c) */ int digs = a->used + b->used + 1; -#ifdef BN_FAST_S_MP_MUL_DIGS_C if ((digs < (int)MP_WARRAY) && MIN(a->used, b->used) <= (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) { diff --git a/wolfcrypt/src/memory.c b/wolfcrypt/src/memory.c index 03267dd2f..3bc8e21cf 100644 --- a/wolfcrypt/src/memory.c +++ b/wolfcrypt/src/memory.c @@ -1042,7 +1042,7 @@ void *xmalloc(size_t n, void* heap, int type, const char* func, p32[0] = (word32)n; p = (void*)(p32 + 4); - fprintf(stderr, "Alloc: %p -> %u (%d) at %s:%s:%d\n", p, (word32)n, type, + fprintf(stderr, "Alloc: %p -> %u (%d) at %s:%s:%u\n", p, (word32)n, type, func, file, line); (void)heap; @@ -1072,10 +1072,10 @@ void *xrealloc(void *p, size_t n, void* heap, int type, const char* func, p32[0] = (word32)n; newp = (void*)(p32 + 4); - fprintf(stderr, "Alloc: %p -> %u (%d) at %s:%s:%d\n", newp, (word32)n, + fprintf(stderr, "Alloc: %p -> %u (%d) at %s:%s:%u\n", newp, (word32)n, type, func, file, line); if (p != NULL) { - fprintf(stderr, "Free: %p -> %u (%d) at %s:%s:%d\n", p, oldLen, + fprintf(stderr, "Free: %p -> %u (%d) at %s:%s:%u\n", p, oldLen, type, func, file, line); } } @@ -1092,7 +1092,7 @@ void xfree(void *p, void* heap, int type, const char* func, const char* file, if (p != NULL) { p32 -= 4; - fprintf(stderr, "Free: %p -> %u (%d) at %s:%s:%d\n", p, p32[0], type, + fprintf(stderr, "Free: %p -> %u (%d) at %s:%s:%u\n", p, p32[0], type, func, file, line); if (free_function) @@ -1111,7 +1111,7 @@ void __attribute__((no_instrument_function)) __cyg_profile_func_enter(void *func, void *caller) { register void* sp asm("sp"); - fprintf(stderr, "ENTER: %016lx %p\n", (size_t)func, sp); + fprintf(stderr, "ENTER: %016lx %p\n", (unsigned long)(size_t)func, sp); (void)caller; } @@ -1119,7 +1119,7 @@ void __attribute__((no_instrument_function)) __cyg_profile_func_exit(void *func, void *caller) { register void* sp asm("sp"); - fprintf(stderr, "EXIT: %016lx %p\n", (size_t)func, sp); + fprintf(stderr, "EXIT: %016lx %p\n", (unsigned long)(size_t)func, sp); (void)caller; } #endif diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 3a79d8fc9..3231ce661 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -1605,8 +1605,9 @@ static int wc_PKCS7_RsaSign(PKCS7* pkcs7, byte* in, word32 inSz, ESD* esd) do { ret = wc_AsyncWait(ret, &privKey->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN); + if (ret >= 0) #endif - if (ret >= 0) { + { ret = wc_RsaSSL_Sign(in, inSz, esd->encContentDigest, sizeof(esd->encContentDigest), privKey, pkcs7->rng); @@ -1668,8 +1669,9 @@ static int wc_PKCS7_EcdsaSign(PKCS7* pkcs7, byte* in, word32 inSz, ESD* esd) do { ret = wc_AsyncWait(ret, &privKey->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN); + if (ret >= 0) #endif - if (ret >= 0) { + { ret = wc_ecc_sign_hash(in, inSz, esd->encContentDigest, &outSz, pkcs7->rng, privKey); } @@ -3982,11 +3984,10 @@ static int wc_PKCS7_ParseSignerInfo(PKCS7* pkcs7, byte* in, word32 inSz, tag == (ASN_CONSTRUCTED | ASN_CONTEXT_SPECIFIC | 0)) { idx++; - if (ret == 0 && GetLength(in, &idx, &length, inSz) <= 0) { + if (GetLength(in, &idx, &length, inSz) <= 0) ret = ASN_PARSE_E; - } - if (idx + 1 > inSz) + if (ret == 0 && idx + 1 > inSz) ret = BUFFER_E; if (ret == 0 && GetASNTag(in, &idx, &tag, inSz) < 0) @@ -4130,13 +4131,12 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, #ifndef NO_PKCS7_STREAM /* allow for 0 size inputs with stream mode */ - if (pkcs7 == NULL || (pkiMsg == NULL && pkiMsgSz > 0)) + if (pkiMsg == NULL && pkiMsgSz > 0) return BAD_FUNC_ARG; #else if (pkiMsg == NULL || pkiMsgSz == 0) return BAD_FUNC_ARG; - #endif if ((hashSz > 0 && hashBuf == NULL) || (pkiMsg2Sz > 0 && pkiMsg2 == NULL)) { @@ -4388,7 +4388,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, /* get length of content in case of single part */ if (ret == 0 && !multiPart) { - if (ret == 0 && tag != ASN_OCTET_STRING) + if (tag != ASN_OCTET_STRING) ret = ASN_PARSE_E; if (ret == 0 && GetLength_ex(pkiMsg, &localIdx, @@ -5646,7 +5646,7 @@ int wc_PKCS7_AddRecipient_KARI(PKCS7* pkcs7, const byte* cert, word32 certSz, int keyWrapOID, int keyAgreeOID, byte* ukm, word32 ukmSz, int options) { - Pkcs7EncodedRecip* recip = NULL; + Pkcs7EncodedRecip* recip; Pkcs7EncodedRecip* lastRecip = NULL; WC_PKCS7_KARI* kari = NULL; @@ -10123,7 +10123,7 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* in, #endif /* remove EncryptedContentInfo */ - if (ret == 0 && GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) { + if (GetSequence(pkiMsg, &idx, &length, pkiMsgSz) < 0) { ret = ASN_PARSE_E; } @@ -10211,13 +10211,13 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* in, explicitOctet = 0; localIdx = idx; - if (ret == 0 && GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) == 0 && + if (GetASNTag(pkiMsg, &localIdx, &tag, pkiMsgSz) == 0 && tag == (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)) { explicitOctet = 1; } /* read encryptedContent, cont[0] */ - if (ret == 0 && tag != (ASN_CONTEXT_SPECIFIC | 0) && + if (tag != (ASN_CONTEXT_SPECIFIC | 0) && tag != (ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 0)) { ret = ASN_PARSE_E; } @@ -10282,7 +10282,7 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* in, #endif encryptedContent = (byte*)XMALLOC(encryptedContentSz, pkcs7->heap, DYNAMIC_TYPE_PKCS7); - if (ret == 0 && encryptedContent == NULL) { + if (encryptedContent == NULL) { ret = MEMORY_E; break; } @@ -10457,7 +10457,7 @@ int wc_PKCS7_EncodeAuthEnvelopedData(PKCS7* pkcs7, byte* output, return blockKeySz; blockSz = wc_PKCS7_GetOIDBlockSize(pkcs7->encryptOID); - if (blockKeySz < 0 || blockSz < 0) + if (blockSz < 0) return blockSz; /* outer content type */ @@ -10585,7 +10585,7 @@ int wc_PKCS7_EncodeAuthEnvelopedData(PKCS7* pkcs7, byte* output, contentTypeAttrib.valueSz = ret; /* otherwise, try to set from custom content type */ - } else if (ret <= 0) { + } else { if (pkcs7->contentTypeSz == 0) { WOLFSSL_MSG("CMS pkcs7->contentType must be set if " "contentOID is not"); @@ -11188,7 +11188,7 @@ WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(PKCS7* pkcs7, byte* in, encodedAttribs = pkiMsg + idx; idx++; - if (ret == 0 && GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0) + if (GetLength(pkiMsg, &idx, &length, pkiMsgSz) < 0) ret = ASN_PARSE_E; #ifndef NO_PKCS7_STREAM pkcs7->stream->expected = length; diff --git a/wolfcrypt/src/poly1305.c b/wolfcrypt/src/poly1305.c index 174b912b6..651664884 100644 --- a/wolfcrypt/src/poly1305.c +++ b/wolfcrypt/src/poly1305.c @@ -392,7 +392,7 @@ void poly1305_block(Poly1305* ctx, const unsigned char *m) #if !defined(WOLFSSL_ARMASM) || !defined(__aarch64__) int wc_Poly1305SetKey(Poly1305* ctx, const byte* key, word32 keySz) { -#if defined(POLY130564) +#if defined(POLY130564) && !defined(USE_INTEL_SPEEDUP) word64 t0,t1; #endif diff --git a/wolfcrypt/src/port/arm/armv8-sha256.c b/wolfcrypt/src/port/arm/armv8-sha256.c index 42a64c36e..7f214d47c 100644 --- a/wolfcrypt/src/port/arm/armv8-sha256.c +++ b/wolfcrypt/src/port/arm/armv8-sha256.c @@ -1079,8 +1079,9 @@ static WC_INLINE int Sha256Final(wc_Sha256* sha256, byte* hash) sha256->loLen = sha256->loLen << 3; /* store lengths */ - word32* bufPt = sha256->buffer; #if defined(LITTLE_ENDIAN_ORDER) + { + word32* bufPt = sha256->buffer; __asm__ volatile ( "VLD1.32 {q0}, [%[in]] \n" "VREV32.8 q0, q0 \n" @@ -1098,6 +1099,7 @@ static WC_INLINE int Sha256Final(wc_Sha256* sha256, byte* hash) : [in] "0" (bufPt) : "cc", "memory", "q0", "q1", "q2", "q3" ); + } #endif /* ! length ordering dependent on digest endian type ! */ XMEMCPY(&local[WC_SHA256_PAD_SIZE], &sha256->hiLen, sizeof(word32)); diff --git a/wolfcrypt/src/port/atmel/atmel.c b/wolfcrypt/src/port/atmel/atmel.c index cfe0a93c7..04d2aeb3d 100644 --- a/wolfcrypt/src/port/atmel/atmel.c +++ b/wolfcrypt/src/port/atmel/atmel.c @@ -771,6 +771,9 @@ int atcatls_verify_signature_cb(WOLFSSL* ssl, const byte* sig, unsigned int sigS /* export public as unsigned bin for hardware */ ret = wc_ecc_export_public_raw(&tmpKey, qx, &qxLen, qy, &qyLen); wc_ecc_free(&tmpKey); + if (ret != 0) { + goto exit; + } /* decode the ECDSA signature */ ret = wc_ecc_sig_to_rs(sig, sigSz, diff --git a/wolfcrypt/src/port/intel/quickassist_sync.c b/wolfcrypt/src/port/intel/quickassist_sync.c index 4bb50085c..1b9b88303 100644 --- a/wolfcrypt/src/port/intel/quickassist_sync.c +++ b/wolfcrypt/src/port/intel/quickassist_sync.c @@ -511,7 +511,7 @@ int IntelQaHardwareStart(const char* process_name, int limitDevAccess) } } - QLOG("Inst %u, Node: %d, Affin: %u, Dev: %u, Accel %u, " + QLOG("Inst %d, Node: %d, Affin: %u, Dev: %u, Accel %u, " "EE %u, BDF %02X:%02X:%02X, isPolled %d\n", i, g_cyInstanceInfo[i].nodeAffinity, coreAffinity, g_cyInstanceInfo[i].physInstId.packageId, @@ -1532,7 +1532,7 @@ static void _qaeMemFree(void *ptr, void* heap, int type #ifdef WOLFSSL_DEBUG_MEMORY #ifdef WOLFSSL_DEBUG_MEMORY_PRINT - printf("Free: %p (%u) at %s:%d, heap %p, type %d, count %d\n", + printf("Free: %p (%u) at %s:%u, heap %p, type %d, count %d\n", origPtr, (unsigned int)size, func, line, heap, type, header->count); #else (void)func; @@ -1680,7 +1680,7 @@ static void* _qaeMemAlloc(size_t size, void* heap, int type #ifdef WOLFSSL_DEBUG_MEMORY #ifdef WOLFSSL_DEBUG_MEMORY_PRINT - printf("Alloc: %p (%u) at %s:%d, heap %p, type %d\n", + printf("Alloc: %p (%u) at %s:%u, heap %p, type %d\n", ptr, (unsigned int)size, func, line, heap, type); #else (void)func; @@ -1841,11 +1841,11 @@ void* wc_CryptoCb_IntelQaRealloc(void *ptr, size_t size, void* heap, int type #ifdef WOLFSSL_DEBUG_MEMORY #ifdef WOLFSSL_DEBUG_MEMORY_PRINT if (allocNew) { - printf("Realloc: New %p -> %p (%u) at %s:%d, heap %p, type %d\n", + printf("Realloc: New %p -> %p (%u) at %s:%u, heap %p, type %d\n", origPtr, newPtr, (unsigned int)size, func, line, heap, type); } else { - printf("Realloc: Reuse %p (%u) at %s:%d, heap %p, type %d, count %d\n", + printf("Realloc: Reuse %p (%u) at %s:%u, heap %p, type %d, count %d\n", origPtr, (unsigned int)size, func, line, header->heap, header->type, header->count); } #else @@ -1963,12 +1963,13 @@ static byte aesgcm_t[] = { /* simple example of using AES-GCM encrypt with Intel QA */ int main(int argc, char** argv) { +#if !defined(NO_AES) && defined(HAVE_AESGCM) int ret; IntelQaDev dev; byte out[256]; - word32 outLen = sizeof(out); byte tmp[256]; - word32 tmpLen = sizeof(tmp); + word32 tmpLen; +#endif #ifdef QAT_DEBUG wolfSSL_Debugging_ON(); @@ -1993,9 +1994,6 @@ int main(int argc, char** argv) #endif /* HAVE_AESGCM */ #endif /* NO_AES */ - (void)tmp; - (void)tmpLen; - IntelQaDeInit(0); return 0; diff --git a/wolfcrypt/src/port/mynewt/mynewt_port.c b/wolfcrypt/src/port/mynewt/mynewt_port.c index 0bd92e612..8a4e903fb 100644 --- a/wolfcrypt/src/port/mynewt/mynewt_port.c +++ b/wolfcrypt/src/port/mynewt/mynewt_port.c @@ -128,7 +128,6 @@ size_t mynewt_fread(void *restrict ptr, size_t size, size_t nitems, FILE *restri size_t mynewt_fwrite(const void *restrict ptr, size_t size, size_t nitems, FILE *restrict stream) { size_t to_write = size * nitems; - size_t write_size; int rc = fs_write(stream, ptr, to_write); if(rc != 0) { return 0; diff --git a/wolfcrypt/src/port/st/stm32.c b/wolfcrypt/src/port/st/stm32.c index 5e2ca9a39..b37dbd845 100644 --- a/wolfcrypt/src/port/st/stm32.c +++ b/wolfcrypt/src/port/st/stm32.c @@ -614,7 +614,7 @@ static int stm32_get_ecc_specs(const uint8_t **prime, const uint8_t **coef, #endif #ifdef ECC192 case 24: - (uint8_t)*prime = stm32_ecc192_prime; + *prime = stm32_ecc192_prime; *coef = stm32_ecc192_coef; *GenPointX = stm32_ecc192_pointX; *GenPointY = stm32_ecc192_pointY; @@ -804,7 +804,6 @@ int stm32_ecc_sign_hash_ex(const byte* hash, word32 hashlen, WC_RNG* rng, PKA_ECDSASignInTypeDef pka_ecc; PKA_ECDSASignOutTypeDef pka_ecc_out; int size; - int szrbin; int status; mp_int gen_k; mp_int order_mp; diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index a9dcac362..f81d8e037 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -613,7 +613,7 @@ static int Hash_DRBG_Instantiate(DRBG* drbg, const byte* seed, word32 seedSz, const byte* nonce, word32 nonceSz, void* heap, int devId) { - int ret = DRBG_FAILURE; + int ret; XMEMSET(drbg, 0, sizeof(DRBG)); #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLF_CRYPTO_CB) @@ -644,6 +644,9 @@ static int Hash_DRBG_Instantiate(DRBG* drbg, const byte* seed, word32 seedSz, drbg->matchCount = 0; ret = DRBG_SUCCESS; } + else { + ret = DRBG_FAILURE; + } return ret; } @@ -1650,10 +1653,11 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) RNGCONbits.PLEN = 0x40; RNGCONbits.PRNGEN = 1; for (i=0; i<5; i++) { /* wait for RNGNUMGEN ready */ - volatile int x; + volatile int x, y; x = RNGNUMGEN1; - x = RNGNUMGEN2; + y = RNGNUMGEN2; (void)x; + (void)y; } do { rnd32[0] = RNGNUMGEN1; @@ -2404,15 +2408,19 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) { int ret = 0; -#ifdef WOLF_CRYPTO_CB - if (os != NULL && os->devId != INVALID_DEVID) { - ret = wc_CryptoCb_RandomSeed(os, output, sz); - if (ret != CRYPTOCB_UNAVAILABLE) - return ret; - /* fall-through when unavailable */ - ret = 0; /* reset error code */ - } -#endif + if (os == NULL) { + return BAD_FUNC_ARG; + } + + #ifdef WOLF_CRYPTO_CB + if (os->devId != INVALID_DEVID) { + ret = wc_CryptoCb_RandomSeed(os, output, sz); + if (ret != CRYPTOCB_UNAVAILABLE) + return ret; + /* fall-through when unavailable */ + ret = 0; /* reset error code */ + } + #endif #ifdef HAVE_INTEL_RDSEED if (IS_INTEL_RDSEED(intel_flags)) { diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index 5ffb3b98c..74f558c33 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -684,10 +684,8 @@ int wc_CheckRsaKey(RsaKey* key) /* Check dP, dQ and u if they exist */ if (ret == 0 && !mp_iszero(&key->dP)) { - if (ret == 0) { - if (mp_sub_d(&key->p, 1, tmp) != MP_OKAY) { - ret = MP_EXPTMOD_E; - } + if (mp_sub_d(&key->p, 1, tmp) != MP_OKAY) { + ret = MP_EXPTMOD_E; } /* Check dP <= p-1. */ if (ret == 0) { @@ -2011,10 +2009,10 @@ static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out, { #ifndef WOLFSSL_SP_MATH #ifdef WOLFSSL_SMALL_STACK - mp_int* tmp = NULL; + mp_int* tmp; #ifdef WC_RSA_BLINDING - mp_int* rnd = NULL; - mp_int* rndi = NULL; + mp_int* rnd; + mp_int* rndi; #endif #else mp_int tmp[1]; @@ -2172,7 +2170,7 @@ static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out, #else if (ret == 0) { #ifdef WOLFSSL_SMALL_STACK - mp_int* tmpa = NULL; + mp_int* tmpa; mp_int* tmpb = NULL; #else mp_int tmpa[1], tmpb[1]; @@ -2258,8 +2256,8 @@ static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out, #else if (mp_exptmod(tmp, &key->e, &key->n, tmp) != MP_OKAY) ret = MP_EXPTMOD_E; - break; #endif + break; default: ret = RSA_WRONG_TYPE_E; break; @@ -2599,7 +2597,7 @@ int wc_RsaFunction(const byte* in, word32 inLen, byte* out, /* Check that 1 < in < n-1. (Requirement of 800-56B.) */ #ifdef WOLFSSL_SMALL_STACK - mp_int* c = NULL; + mp_int* c; #else mp_int c[1]; #endif @@ -3045,9 +3043,11 @@ int wc_RsaPublicEncrypt_ex(const byte* in, word32 inLen, byte* out, #ifndef WOLFSSL_RSA_PUBLIC_ONLY int wc_RsaPrivateDecryptInline(byte* in, word32 inLen, byte** out, RsaKey* key) { - WC_RNG* rng = NULL; + WC_RNG* rng; #ifdef WC_RSA_BLINDING rng = key->rng; +#else + rng = NULL; #endif return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key, RSA_PRIVATE_DECRYPT, RSA_BLOCK_TYPE_2, WC_RSA_PKCSV15_PAD, @@ -3060,9 +3060,11 @@ int wc_RsaPrivateDecryptInline_ex(byte* in, word32 inLen, byte** out, RsaKey* key, int type, enum wc_HashType hash, int mgf, byte* label, word32 labelSz) { - WC_RNG* rng = NULL; + WC_RNG* rng; #ifdef WC_RSA_BLINDING rng = key->rng; +#else + rng = NULL; #endif return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key, RSA_PRIVATE_DECRYPT, RSA_BLOCK_TYPE_2, type, hash, @@ -3074,9 +3076,11 @@ int wc_RsaPrivateDecryptInline_ex(byte* in, word32 inLen, byte** out, int wc_RsaPrivateDecrypt(const byte* in, word32 inLen, byte* out, word32 outLen, RsaKey* key) { - WC_RNG* rng = NULL; + WC_RNG* rng; #ifdef WC_RSA_BLINDING rng = key->rng; +#else + rng = NULL; #endif return RsaPrivateDecryptEx((byte*)in, inLen, out, outLen, NULL, key, RSA_PRIVATE_DECRYPT, RSA_BLOCK_TYPE_2, WC_RSA_PKCSV15_PAD, @@ -3089,9 +3093,11 @@ int wc_RsaPrivateDecrypt_ex(const byte* in, word32 inLen, byte* out, enum wc_HashType hash, int mgf, byte* label, word32 labelSz) { - WC_RNG* rng = NULL; + WC_RNG* rng; #ifdef WC_RSA_BLINDING rng = key->rng; +#else + rng = NULL; #endif return RsaPrivateDecryptEx((byte*)in, inLen, out, outLen, NULL, key, RSA_PRIVATE_DECRYPT, RSA_BLOCK_TYPE_2, type, hash, mgf, label, @@ -3103,9 +3109,11 @@ int wc_RsaPrivateDecrypt_ex(const byte* in, word32 inLen, byte* out, #if !defined(WOLFSSL_CRYPTOCELL) int wc_RsaSSL_VerifyInline(byte* in, word32 inLen, byte** out, RsaKey* key) { - WC_RNG* rng = NULL; + WC_RNG* rng; #ifdef WC_RSA_BLINDING rng = key->rng; +#else + rng = NULL; #endif return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key, RSA_PUBLIC_DECRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PKCSV15_PAD, @@ -3123,9 +3131,10 @@ int wc_RsaSSL_Verify(const byte* in, word32 inLen, byte* out, word32 outLen, return BAD_FUNC_ARG; } - rng = NULL; #ifdef WC_RSA_BLINDING rng = key->rng; +#else + rng = NULL; #endif return RsaPrivateDecryptEx((byte*)in, inLen, out, outLen, NULL, key, @@ -3177,9 +3186,11 @@ int wc_RsaPSS_VerifyInline_ex(byte* in, word32 inLen, byte** out, enum wc_HashType hash, int mgf, int saltLen, RsaKey* key) { - WC_RNG* rng = NULL; + WC_RNG* rng; #ifdef WC_RSA_BLINDING rng = key->rng; +#else + rng = NULL; #endif return RsaPrivateDecryptEx(in, inLen, in, inLen, out, key, RSA_PUBLIC_DECRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PSS_PAD, @@ -3226,9 +3237,11 @@ int wc_RsaPSS_Verify_ex(byte* in, word32 inLen, byte* out, word32 outLen, enum wc_HashType hash, int mgf, int saltLen, RsaKey* key) { - WC_RNG* rng = NULL; + WC_RNG* rng; #ifdef WC_RSA_BLINDING rng = key->rng; +#else + rng = NULL; #endif return RsaPrivateDecryptEx(in, inLen, out, outLen, NULL, key, RSA_PUBLIC_DECRYPT, RSA_BLOCK_TYPE_1, WC_RSA_PSS_PAD, diff --git a/wolfcrypt/src/signature.c b/wolfcrypt/src/signature.c index 07c9b409e..fcf4a28db 100644 --- a/wolfcrypt/src/signature.c +++ b/wolfcrypt/src/signature.c @@ -126,9 +126,9 @@ int wc_SignatureVerifyHash( int ret; /* Check arguments */ - if (hash_data == NULL || hash_len <= 0 || - sig == NULL || sig_len <= 0 || - key == NULL || key_len <= 0) { + if (hash_data == NULL || hash_len == 0 || + sig == NULL || sig_len == 0 || + key == NULL || key_len == 0) { return BAD_FUNC_ARG; } @@ -259,9 +259,9 @@ int wc_SignatureVerify( #endif /* Check arguments */ - if (data == NULL || data_len <= 0 || - sig == NULL || sig_len <= 0 || - key == NULL || key_len <= 0) { + if (data == NULL || data_len == 0 || + sig == NULL || sig_len == 0 || + key == NULL || key_len == 0) { return BAD_FUNC_ARG; } @@ -358,9 +358,9 @@ int wc_SignatureGenerateHash_ex( (void)rng; /* Check arguments */ - if (hash_data == NULL || hash_len <= 0 || - sig == NULL || sig_len == NULL || *sig_len <= 0 || - key == NULL || key_len <= 0) { + if (hash_data == NULL || hash_len == 0 || + sig == NULL || sig_len == NULL || *sig_len == 0 || + key == NULL || key_len == 0) { return BAD_FUNC_ARG; } @@ -469,9 +469,9 @@ int wc_SignatureGenerate_ex( #endif /* Check arguments */ - if (data == NULL || data_len <= 0 || - sig == NULL || sig_len == NULL || *sig_len <= 0 || - key == NULL || key_len <= 0) { + if (data == NULL || data_len == 0 || + sig == NULL || sig_len == NULL || *sig_len == 0 || + key == NULL || key_len == 0) { return BAD_FUNC_ARG; } diff --git a/wolfcrypt/src/sp_arm32.c b/wolfcrypt/src/sp_arm32.c index 3fad88e18..7821a2479 100644 --- a/wolfcrypt/src/sp_arm32.c +++ b/wolfcrypt/src/sp_arm32.c @@ -72321,16 +72321,18 @@ static const sp_digit p256_b[8] = { static int sp_ecc_point_new_ex(void* heap, sp_point* sp, sp_point** p) { int ret = MP_OKAY; - (void)heap; -#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - (void)sp; - *p = (sp_point*)XMALLOC(sizeof(sp_point), heap, DYNAMIC_TYPE_ECC); -#else - *p = sp; -#endif if (p == NULL) { ret = MEMORY_E; } + else { + #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + *p = (sp_point*)XMALLOC(sizeof(sp_point), heap, DYNAMIC_TYPE_ECC); + (void)sp; + #else + *p = sp; + (void)heap; + #endif + } return ret; } @@ -76111,11 +76113,12 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_point p; - sp_digit kd[8]; + sp_digit k[8]; +#else + sp_digit* k = NULL; #endif sp_point* point; - sp_digit* k = NULL; - int err = MP_OKAY; + int err; err = sp_ecc_point_new(heap, p, point); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) @@ -76125,8 +76128,6 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, if (k == NULL) err = MEMORY_E; } -#else - k = kd; #endif if (err == MP_OKAY) { sp_256_from_mp(k, 8, km); @@ -77559,11 +77560,12 @@ int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_point p; - sp_digit kd[8]; + sp_digit k[8]; +#else + sp_digit* k = NULL; #endif sp_point* point; - sp_digit* k = NULL; - int err = MP_OKAY; + int err; err = sp_ecc_point_new(heap, p, point); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) @@ -77574,8 +77576,6 @@ int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) err = MEMORY_E; } } -#else - k = kd; #endif if (err == MP_OKAY) { sp_256_from_mp(k, 8, km); @@ -77721,13 +77721,14 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_point p; - sp_digit kd[8]; + sp_digit k[8]; #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN sp_point inf; #endif +#else + sp_digit* k = NULL; #endif sp_point* point; - sp_digit* k = NULL; #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN sp_point* infinity; #endif @@ -77749,8 +77750,6 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) err = MEMORY_E; } } -#else - k = kd; #endif if (err == MP_OKAY) { @@ -77844,10 +77843,11 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_point p; - sp_digit kd[8]; + sp_digit k[8]; +#else + sp_digit* k = NULL; #endif sp_point* point = NULL; - sp_digit* k = NULL; int err = MP_OKAY; if (*outLen < 32U) { @@ -77864,8 +77864,6 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, if (k == NULL) err = MEMORY_E; } -#else - k = kd; #endif if (err == MP_OKAY) { @@ -79416,7 +79414,7 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_digit carry; sp_digit* s = NULL; sp_digit* kInv = NULL; - int err = MP_OKAY; + int err; int32_t c; int i; @@ -79724,7 +79722,7 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, static int sp_256_ecc_is_point_8(sp_point* point, void* heap) { #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - sp_digit* d = NULL; + sp_digit* d; #else sp_digit t1d[2*8]; sp_digit t2d[2*8]; diff --git a/wolfcrypt/src/sp_arm64.c b/wolfcrypt/src/sp_arm64.c index 0778575c9..be9fab2e2 100644 --- a/wolfcrypt/src/sp_arm64.c +++ b/wolfcrypt/src/sp_arm64.c @@ -30573,16 +30573,18 @@ static const sp_digit p256_b[4] = { static int sp_ecc_point_new_ex(void* heap, sp_point* sp, sp_point** p) { int ret = MP_OKAY; - (void)heap; -#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - (void)sp; - *p = (sp_point*)XMALLOC(sizeof(sp_point), heap, DYNAMIC_TYPE_ECC); -#else - *p = sp; -#endif if (p == NULL) { ret = MEMORY_E; } + else { + #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + *p = (sp_point*)XMALLOC(sizeof(sp_point), heap, DYNAMIC_TYPE_ECC); + (void)sp; + #else + *p = sp; + (void)heap; + #endif + } return ret; } @@ -32896,11 +32898,12 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_point p; - sp_digit kd[4]; + sp_digit k[4]; +#else + sp_digit* k = NULL; #endif sp_point* point; - sp_digit* k = NULL; - int err = MP_OKAY; + int err; err = sp_ecc_point_new(heap, p, point); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) @@ -32910,8 +32913,6 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, if (k == NULL) err = MEMORY_E; } -#else - k = kd; #endif if (err == MP_OKAY) { sp_256_from_mp(k, 4, km); @@ -46367,11 +46368,12 @@ int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_point p; - sp_digit kd[4]; + sp_digit k[4]; +#else + sp_digit* k = NULL; #endif sp_point* point; - sp_digit* k = NULL; - int err = MP_OKAY; + int err; err = sp_ecc_point_new(heap, p, point); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) @@ -46382,8 +46384,6 @@ int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) err = MEMORY_E; } } -#else - k = kd; #endif if (err == MP_OKAY) { sp_256_from_mp(k, 4, km); @@ -46513,13 +46513,14 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_point p; - sp_digit kd[4]; + sp_digit k[4]; #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN sp_point inf; #endif +#else + sp_digit* k = NULL; #endif sp_point* point; - sp_digit* k = NULL; #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN sp_point* infinity; #endif @@ -46541,8 +46542,6 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) err = MEMORY_E; } } -#else - k = kd; #endif if (err == MP_OKAY) { @@ -46636,10 +46635,11 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_point p; - sp_digit kd[4]; + sp_digit k[4]; +#else + sp_digit* k = NULL; #endif sp_point* point = NULL; - sp_digit* k = NULL; int err = MP_OKAY; if (*outLen < 32U) { @@ -46656,8 +46656,6 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, if (k == NULL) err = MEMORY_E; } -#else - k = kd; #endif if (err == MP_OKAY) { @@ -47474,7 +47472,7 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_digit carry; sp_digit* s = NULL; sp_digit* kInv = NULL; - int err = MP_OKAY; + int err; int64_t c; int i; @@ -47778,7 +47776,7 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, static int sp_256_ecc_is_point_4(sp_point* point, void* heap) { #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - sp_digit* d = NULL; + sp_digit* d; #else sp_digit t1d[2*4]; sp_digit t2d[2*4]; diff --git a/wolfcrypt/src/sp_armthumb.c b/wolfcrypt/src/sp_armthumb.c index 3aca80b66..06bb969b6 100644 --- a/wolfcrypt/src/sp_armthumb.c +++ b/wolfcrypt/src/sp_armthumb.c @@ -15715,16 +15715,18 @@ static const sp_digit p256_b[8] = { static int sp_ecc_point_new_ex(void* heap, sp_point* sp, sp_point** p) { int ret = MP_OKAY; - (void)heap; -#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - (void)sp; - *p = (sp_point*)XMALLOC(sizeof(sp_point), heap, DYNAMIC_TYPE_ECC); -#else - *p = sp; -#endif if (p == NULL) { ret = MEMORY_E; } + else { + #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + *p = (sp_point*)XMALLOC(sizeof(sp_point), heap, DYNAMIC_TYPE_ECC); + (void)sp; + #else + *p = sp; + (void)heap; + #endif + } return ret; } @@ -18522,11 +18524,12 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_point p; - sp_digit kd[8]; + sp_digit k[8]; +#else + sp_digit* k = NULL; #endif sp_point* point; - sp_digit* k = NULL; - int err = MP_OKAY; + int err; err = sp_ecc_point_new(heap, p, point); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) @@ -18536,8 +18539,6 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, if (k == NULL) err = MEMORY_E; } -#else - k = kd; #endif if (err == MP_OKAY) { sp_256_from_mp(k, 8, km); @@ -19970,11 +19971,12 @@ int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_point p; - sp_digit kd[8]; + sp_digit k[8]; +#else + sp_digit* k = NULL; #endif sp_point* point; - sp_digit* k = NULL; - int err = MP_OKAY; + int err; err = sp_ecc_point_new(heap, p, point); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) @@ -19985,8 +19987,6 @@ int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) err = MEMORY_E; } } -#else - k = kd; #endif if (err == MP_OKAY) { sp_256_from_mp(k, 8, km); @@ -20134,13 +20134,14 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_point p; - sp_digit kd[8]; + sp_digit k[8]; #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN sp_point inf; #endif +#else + sp_digit* k = NULL; #endif sp_point* point; - sp_digit* k = NULL; #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN sp_point* infinity; #endif @@ -20162,8 +20163,6 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) err = MEMORY_E; } } -#else - k = kd; #endif if (err == MP_OKAY) { @@ -20257,10 +20256,11 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_point p; - sp_digit kd[8]; + sp_digit k[8]; +#else + sp_digit* k = NULL; #endif sp_point* point = NULL; - sp_digit* k = NULL; int err = MP_OKAY; if (*outLen < 32U) { @@ -20277,8 +20277,6 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, if (k == NULL) err = MEMORY_E; } -#else - k = kd; #endif if (err == MP_OKAY) { @@ -20883,7 +20881,7 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_digit carry; sp_digit* s = NULL; sp_digit* kInv = NULL; - int err = MP_OKAY; + int err; int32_t c; int i; @@ -21191,7 +21189,7 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, static int sp_256_ecc_is_point_8(sp_point* point, void* heap) { #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - sp_digit* d = NULL; + sp_digit* d; #else sp_digit t1d[2*8]; sp_digit t2d[2*8]; diff --git a/wolfcrypt/src/sp_c32.c b/wolfcrypt/src/sp_c32.c index f3c872b5c..956ec5362 100644 --- a/wolfcrypt/src/sp_c32.c +++ b/wolfcrypt/src/sp_c32.c @@ -1896,7 +1896,7 @@ static int sp_2048_mod_exp_45(sp_digit* r, const sp_digit* a, const sp_digit* e, #ifdef WOLFSSL_SP_SMALL sp_digit* td; sp_digit* t[3]; - sp_digit* norm; + sp_digit* norm = NULL; sp_digit mp = 1; sp_digit n; int i; @@ -2828,7 +2828,7 @@ static int sp_2048_mod_exp_90(sp_digit* r, const sp_digit* a, const sp_digit* e, #ifdef WOLFSSL_SP_SMALL sp_digit* td; sp_digit* t[3]; - sp_digit* norm; + sp_digit* norm = NULL; sp_digit mp = 1; sp_digit n; int i; @@ -3226,7 +3226,7 @@ int sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm, #else e[0] = (sp_digit)em->dp[0]; if (em->used > 1) { - e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT; + e[0] |= ((sp_int_digit)em->dp[1]) << DIGIT_BIT; } #endif if (e[0] == 0) { @@ -3327,7 +3327,7 @@ int sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm, #else e[0] = (sp_digit)em->dp[0]; if (em->used > 1) { - e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT; + e[0] |= ((sp_int_digit)em->dp[1]) << DIGIT_BIT; } #endif if (e[0] == 0) { @@ -3799,13 +3799,13 @@ 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 b[180], e[90], m[90]; #else sp_digit* d = NULL; -#endif sp_digit* b; sp_digit* e; sp_digit* m; +#endif sp_digit* r; int err = MP_OKAY; int expBits = mp_count_bits(exp); @@ -3832,20 +3832,16 @@ int sp_ModExp_2048(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) if (d == NULL) err = MEMORY_E; } - - if (err == MP_OKAY) { - b = d; - e = b + 90 * 2; - m = e + 90; - r = b; - } -#else - r = b = bd; - e = ed; - m = md; #endif if (err == MP_OKAY) { +#ifdef WOLFSSL_SMALL_STACK + b = d; + e = b + 90 * 2; + m = e + 90; +#endif + r = b; + sp_2048_from_mp(b, 90, base); sp_2048_from_mp(e, 90, exp); sp_2048_from_mp(m, 90, mod); @@ -4081,13 +4077,13 @@ SP_NOINLINE static void sp_2048_lshift_90(sp_digit* r, sp_digit* a, byte n) static int sp_2048_mod_exp_2_90(sp_digit* r, const sp_digit* e, int bits, const sp_digit* m) { #ifndef WOLFSSL_SMALL_STACK - sp_digit nd[180]; - sp_digit td[91]; + sp_digit norm[180]; + sp_digit tmp[91]; #else sp_digit* td; -#endif sp_digit* norm; sp_digit* tmp; +#endif sp_digit mp = 1; sp_digit n, o; int i; @@ -4106,11 +4102,6 @@ static int sp_2048_mod_exp_2_90(sp_digit* r, const sp_digit* e, int bits, const #ifdef WOLFSSL_SMALL_STACK norm = td; tmp = td + 180; - XMEMSET(td, 0, sizeof(sp_digit) * 271); -#else - norm = nd; - tmp = td; - XMEMSET(td, 0, sizeof(td)); #endif sp_2048_mont_setup(m, &mp); @@ -4416,13 +4407,13 @@ 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 b[90], e[45], m[45]; #else sp_digit* d = NULL; -#endif sp_digit* b; sp_digit* e; sp_digit* m; +#endif sp_digit* r; int err = MP_OKAY; int expBits = mp_count_bits(exp); @@ -4449,20 +4440,16 @@ int sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) if (d == NULL) err = MEMORY_E; } - - if (err == MP_OKAY) { - b = d; - e = b + 45 * 2; - m = e + 45; - r = b; - } -#else - r = b = bd; - e = ed; - m = md; #endif if (err == MP_OKAY) { +#ifdef WOLFSSL_SMALL_STACK + b = d; + e = b + 45 * 2; + m = e + 45; +#endif + r = b; + sp_2048_from_mp(b, 45, base); sp_2048_from_mp(e, 45, exp); sp_2048_from_mp(m, 45, mod); @@ -5733,7 +5720,7 @@ static int sp_3072_mod_exp_67(sp_digit* r, const sp_digit* a, const sp_digit* e, #ifdef WOLFSSL_SP_SMALL sp_digit* td; sp_digit* t[3]; - sp_digit* norm; + sp_digit* norm = NULL; sp_digit mp = 1; sp_digit n; int i; @@ -6701,7 +6688,7 @@ static int sp_3072_mod_exp_134(sp_digit* r, const sp_digit* a, const sp_digit* e #ifdef WOLFSSL_SP_SMALL sp_digit* td; sp_digit* t[3]; - sp_digit* norm; + sp_digit* norm = NULL; sp_digit mp = 1; sp_digit n; int i; @@ -7097,7 +7084,7 @@ int sp_RsaPublic_3072(const byte* in, word32 inLen, mp_int* em, mp_int* mm, #else e[0] = (sp_digit)em->dp[0]; if (em->used > 1) { - e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT; + e[0] |= ((sp_int_digit)em->dp[1]) << DIGIT_BIT; } #endif if (e[0] == 0) { @@ -7198,7 +7185,7 @@ int sp_RsaPublic_3072(const byte* in, word32 inLen, mp_int* em, mp_int* mm, #else e[0] = (sp_digit)em->dp[0]; if (em->used > 1) { - e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT; + e[0] |= ((sp_int_digit)em->dp[1]) << DIGIT_BIT; } #endif if (e[0] == 0) { @@ -7670,13 +7657,13 @@ 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 b[268], e[134], m[134]; #else sp_digit* d = NULL; -#endif sp_digit* b; sp_digit* e; sp_digit* m; +#endif sp_digit* r; int err = MP_OKAY; int expBits = mp_count_bits(exp); @@ -7703,20 +7690,16 @@ int sp_ModExp_3072(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) if (d == NULL) err = MEMORY_E; } - - if (err == MP_OKAY) { - b = d; - e = b + 134 * 2; - m = e + 134; - r = b; - } -#else - r = b = bd; - e = ed; - m = md; #endif if (err == MP_OKAY) { +#ifdef WOLFSSL_SMALL_STACK + b = d; + e = b + 134 * 2; + m = e + 134; +#endif + r = b; + sp_3072_from_mp(b, 134, base); sp_3072_from_mp(e, 134, exp); sp_3072_from_mp(m, 134, mod); @@ -8040,13 +8023,13 @@ SP_NOINLINE static void sp_3072_lshift_134(sp_digit* r, sp_digit* a, byte n) static int sp_3072_mod_exp_2_134(sp_digit* r, const sp_digit* e, int bits, const sp_digit* m) { #ifndef WOLFSSL_SMALL_STACK - sp_digit nd[268]; - sp_digit td[135]; + sp_digit norm[268]; + sp_digit tmp[135]; #else sp_digit* td; -#endif sp_digit* norm; sp_digit* tmp; +#endif sp_digit mp = 1; sp_digit n, o; int i; @@ -8065,11 +8048,6 @@ static int sp_3072_mod_exp_2_134(sp_digit* r, const sp_digit* e, int bits, const #ifdef WOLFSSL_SMALL_STACK norm = td; tmp = td + 268; - XMEMSET(td, 0, sizeof(sp_digit) * 403); -#else - norm = nd; - tmp = td; - XMEMSET(td, 0, sizeof(td)); #endif sp_3072_mont_setup(m, &mp); @@ -8375,13 +8353,13 @@ 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 b[134], e[67], m[67]; #else sp_digit* d = NULL; -#endif sp_digit* b; sp_digit* e; sp_digit* m; +#endif sp_digit* r; int err = MP_OKAY; int expBits = mp_count_bits(exp); @@ -8408,20 +8386,16 @@ int sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) if (d == NULL) err = MEMORY_E; } - - if (err == MP_OKAY) { - b = d; - e = b + 67 * 2; - m = e + 67; - r = b; - } -#else - r = b = bd; - e = ed; - m = md; #endif if (err == MP_OKAY) { +#ifdef WOLFSSL_SMALL_STACK + b = d; + e = b + 67 * 2; + m = e + 67; +#endif + r = b; + sp_3072_from_mp(b, 67, base); sp_3072_from_mp(e, 67, exp); sp_3072_from_mp(m, 67, mod); @@ -9788,7 +9762,7 @@ static int sp_4096_mod_exp_98(sp_digit* r, const sp_digit* a, const sp_digit* e, #ifdef WOLFSSL_SP_SMALL sp_digit* td; sp_digit* t[3]; - sp_digit* norm; + sp_digit* norm = NULL; sp_digit mp = 1; sp_digit n; int i; @@ -10732,7 +10706,7 @@ static int sp_4096_mod_exp_196(sp_digit* r, const sp_digit* a, const sp_digit* e #ifdef WOLFSSL_SP_SMALL sp_digit* td; sp_digit* t[3]; - sp_digit* norm; + sp_digit* norm = NULL; sp_digit mp = 1; sp_digit n; int i; @@ -11127,7 +11101,7 @@ int sp_RsaPublic_4096(const byte* in, word32 inLen, mp_int* em, mp_int* mm, #else e[0] = (sp_digit)em->dp[0]; if (em->used > 1) { - e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT; + e[0] |= ((sp_int_digit)em->dp[1]) << DIGIT_BIT; } #endif if (e[0] == 0) { @@ -11228,7 +11202,7 @@ int sp_RsaPublic_4096(const byte* in, word32 inLen, mp_int* em, mp_int* mm, #else e[0] = (sp_digit)em->dp[0]; if (em->used > 1) { - e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT; + e[0] |= ((sp_int_digit)em->dp[1]) << DIGIT_BIT; } #endif if (e[0] == 0) { @@ -11700,13 +11674,13 @@ 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 b[392], e[196], m[196]; #else sp_digit* d = NULL; -#endif sp_digit* b; sp_digit* e; sp_digit* m; +#endif sp_digit* r; int err = MP_OKAY; int expBits = mp_count_bits(exp); @@ -11733,20 +11707,16 @@ int sp_ModExp_4096(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) if (d == NULL) err = MEMORY_E; } - - if (err == MP_OKAY) { - b = d; - e = b + 196 * 2; - m = e + 196; - r = b; - } -#else - r = b = bd; - e = ed; - m = md; #endif if (err == MP_OKAY) { +#ifdef WOLFSSL_SMALL_STACK + b = d; + e = b + 196 * 2; + m = e + 196; +#endif + r = b; + sp_4096_from_mp(b, 196, base); sp_4096_from_mp(e, 196, exp); sp_4096_from_mp(m, 196, mod); @@ -12194,13 +12164,13 @@ SP_NOINLINE static void sp_4096_lshift_196(sp_digit* r, sp_digit* a, byte n) static int sp_4096_mod_exp_2_196(sp_digit* r, const sp_digit* e, int bits, const sp_digit* m) { #ifndef WOLFSSL_SMALL_STACK - sp_digit nd[392]; - sp_digit td[197]; + sp_digit norm[392]; + sp_digit tmp[197]; #else sp_digit* td; -#endif sp_digit* norm; sp_digit* tmp; +#endif sp_digit mp = 1; sp_digit n, o; int i; @@ -12219,11 +12189,6 @@ static int sp_4096_mod_exp_2_196(sp_digit* r, const sp_digit* e, int bits, const #ifdef WOLFSSL_SMALL_STACK norm = td; tmp = td + 392; - XMEMSET(td, 0, sizeof(sp_digit) * 589); -#else - norm = nd; - tmp = td; - XMEMSET(td, 0, sizeof(td)); #endif sp_4096_mont_setup(m, &mp); @@ -12543,16 +12508,18 @@ static const sp_digit p256_b[10] = { static int sp_ecc_point_new_ex(void* heap, sp_point* sp, sp_point** p) { int ret = MP_OKAY; - (void)heap; -#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - (void)sp; - *p = (sp_point*)XMALLOC(sizeof(sp_point), heap, DYNAMIC_TYPE_ECC); -#else - *p = sp; -#endif if (p == NULL) { ret = MEMORY_E; } + else { + #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + *p = (sp_point*)XMALLOC(sizeof(sp_point), heap, DYNAMIC_TYPE_ECC); + (void)sp; + #else + *p = sp; + (void)heap; + #endif + } return ret; } @@ -12622,30 +12589,30 @@ static int sp_256_mod_mul_norm_10(sp_digit* r, const sp_digit* a, const sp_digit a32 = a32d; #endif - a32[0] = a[0]; - a32[0] |= a[1] << 26U; + a32[0] = (sp_int_digit)a[0]; + a32[0] |= (sp_int_digit)a[1] << 26U; a32[0] &= 0xffffffffL; a32[1] = (sp_digit)(a[1] >> 6); - a32[1] |= a[2] << 20U; + a32[1] |= (sp_int_digit)a[2] << 20U; a32[1] &= 0xffffffffL; a32[2] = (sp_digit)(a[2] >> 12); - a32[2] |= a[3] << 14U; + a32[2] |= (sp_int_digit)a[3] << 14U; a32[2] &= 0xffffffffL; a32[3] = (sp_digit)(a[3] >> 18); - a32[3] |= a[4] << 8U; + a32[3] |= (sp_int_digit)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] |= (sp_int_digit)a[5] << 2U; + a32[4] |= (sp_int_digit)a[6] << 28U; a32[4] &= 0xffffffffL; a32[5] = (sp_digit)(a[6] >> 4); - a32[5] |= a[7] << 22U; + a32[5] |= (sp_int_digit)a[7] << 22U; a32[5] &= 0xffffffffL; a32[6] = (sp_digit)(a[7] >> 10); - a32[6] |= a[8] << 16U; + a32[6] |= (sp_int_digit)a[8] << 16U; a32[6] &= 0xffffffffL; a32[7] = (sp_digit)(a[8] >> 16); - a32[7] |= a[9] << 10U; + a32[7] |= (sp_int_digit)a[9] << 10U; a32[7] &= 0xffffffffL; /* 1 1 0 -1 -1 -1 -1 0 */ @@ -12687,26 +12654,26 @@ static int sp_256_mod_mul_norm_10(sp_digit* r, const sp_digit* a, const sp_digit r[0] = (sp_digit)(t[0]) & 0x3ffffffL; r[1] = (sp_digit)(t[0] >> 26U); - r[1] |= t[1] << 6U; + r[1] |= (sp_int_digit)t[1] << 6U; r[1] &= 0x3ffffffL; r[2] = (sp_digit)(t[1] >> 20U); - r[2] |= t[2] << 12U; + r[2] |= (sp_int_digit)t[2] << 12U; r[2] &= 0x3ffffffL; r[3] = (sp_digit)(t[2] >> 14U); - r[3] |= t[3] << 18U; + r[3] |= (sp_int_digit)t[3] << 18U; r[3] &= 0x3ffffffL; r[4] = (sp_digit)(t[3] >> 8U); - r[4] |= t[4] << 24U; + r[4] |= (sp_int_digit)t[4] << 24U; r[4] &= 0x3ffffffL; r[5] = (sp_digit)(t[4] >> 2U) & 0x3ffffffL; r[6] = (sp_digit)(t[4] >> 28U); - r[6] |= t[5] << 4U; + r[6] |= (sp_int_digit)t[5] << 4U; r[6] &= 0x3ffffffL; r[7] = (sp_digit)(t[5] >> 22U); - r[7] |= t[6] << 10U; + r[7] |= (sp_int_digit)t[6] << 10U; r[7] &= 0x3ffffffL; r[8] = (sp_digit)(t[6] >> 16U); - r[8] |= t[7] << 16U; + r[8] |= (sp_int_digit)t[7] << 16U; r[8] &= 0x3ffffffL; r[9] = (sp_digit)(t[7] >> 10U); } @@ -14842,11 +14809,12 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_point p; - sp_digit kd[10]; + sp_digit k[10]; +#else + sp_digit* k = NULL; #endif sp_point* point; - sp_digit* k = NULL; - int err = MP_OKAY; + int err; err = sp_ecc_point_new(heap, p, point); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) @@ -14856,8 +14824,6 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, if (k == NULL) err = MEMORY_E; } -#else - k = kd; #endif if (err == MP_OKAY) { sp_256_from_mp(k, 10, km); @@ -16209,11 +16175,12 @@ int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_point p; - sp_digit kd[10]; + sp_digit k[10]; +#else + sp_digit* k = NULL; #endif sp_point* point; - sp_digit* k = NULL; - int err = MP_OKAY; + int err; err = sp_ecc_point_new(heap, p, point); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) @@ -16224,8 +16191,6 @@ int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) err = MEMORY_E; } } -#else - k = kd; #endif if (err == MP_OKAY) { sp_256_from_mp(k, 10, km); @@ -16346,13 +16311,14 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_point p; - sp_digit kd[10]; + sp_digit k[10]; #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN sp_point inf; #endif +#else + sp_digit* k = NULL; #endif sp_point* point; - sp_digit* k = NULL; #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN sp_point* infinity; #endif @@ -16374,8 +16340,6 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) err = MEMORY_E; } } -#else - k = kd; #endif if (err == MP_OKAY) { @@ -16473,10 +16437,11 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_point p; - sp_digit kd[10]; + sp_digit k[10]; +#else + sp_digit* k = NULL; #endif sp_point* point = NULL; - sp_digit* k = NULL; int err = MP_OKAY; if (*outLen < 32U) { @@ -16493,8 +16458,6 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, if (k == NULL) err = MEMORY_E; } -#else - k = kd; #endif if (err == MP_OKAY) { @@ -16930,7 +16893,7 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_digit carry; sp_digit* s = NULL; sp_digit* kInv = NULL; - int err = MP_OKAY; + int err; int32_t c; int i; @@ -17240,7 +17203,7 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, static int sp_256_ecc_is_point_10(sp_point* point, void* heap) { #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - sp_digit* d = NULL; + sp_digit* d; #else sp_digit t1d[2*10]; sp_digit t2d[2*10]; diff --git a/wolfcrypt/src/sp_c64.c b/wolfcrypt/src/sp_c64.c index a2d0274fb..eafa8e8cd 100644 --- a/wolfcrypt/src/sp_c64.c +++ b/wolfcrypt/src/sp_c64.c @@ -1544,7 +1544,7 @@ static int sp_2048_mod_exp_18(sp_digit* r, const sp_digit* a, const sp_digit* e, #ifdef WOLFSSL_SP_SMALL sp_digit* td; sp_digit* t[3]; - sp_digit* norm; + sp_digit* norm = NULL; sp_digit mp = 1; sp_digit n; int i; @@ -2468,7 +2468,7 @@ static int sp_2048_mod_exp_36(sp_digit* r, const sp_digit* a, const sp_digit* e, #ifdef WOLFSSL_SP_SMALL sp_digit* td; sp_digit* t[3]; - sp_digit* norm; + sp_digit* norm = NULL; sp_digit mp = 1; sp_digit n; int i; @@ -2863,7 +2863,7 @@ int sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm, #else e[0] = (sp_digit)em->dp[0]; if (em->used > 1) { - e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT; + e[0] |= ((sp_int_digit)em->dp[1]) << DIGIT_BIT; } #endif if (e[0] == 0) { @@ -2964,7 +2964,7 @@ int sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm, #else e[0] = (sp_digit)em->dp[0]; if (em->used > 1) { - e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT; + e[0] |= ((sp_int_digit)em->dp[1]) << DIGIT_BIT; } #endif if (e[0] == 0) { @@ -3436,13 +3436,13 @@ 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 b[72], e[36], m[36]; #else sp_digit* d = NULL; -#endif sp_digit* b; sp_digit* e; sp_digit* m; +#endif sp_digit* r; int err = MP_OKAY; int expBits = mp_count_bits(exp); @@ -3469,20 +3469,16 @@ int sp_ModExp_2048(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) if (d == NULL) err = MEMORY_E; } - - if (err == MP_OKAY) { - b = d; - e = b + 36 * 2; - m = e + 36; - r = b; - } -#else - r = b = bd; - e = ed; - m = md; #endif if (err == MP_OKAY) { +#ifdef WOLFSSL_SMALL_STACK + b = d; + e = b + 36 * 2; + m = e + 36; +#endif + r = b; + sp_2048_from_mp(b, 36, base); sp_2048_from_mp(e, 36, exp); sp_2048_from_mp(m, 36, mod); @@ -3610,13 +3606,13 @@ SP_NOINLINE static void sp_2048_lshift_36(sp_digit* r, sp_digit* a, byte n) static int sp_2048_mod_exp_2_36(sp_digit* r, const sp_digit* e, int bits, const sp_digit* m) { #ifndef WOLFSSL_SMALL_STACK - sp_digit nd[72]; - sp_digit td[37]; + sp_digit norm[72]; + sp_digit tmp[37]; #else sp_digit* td; -#endif sp_digit* norm; sp_digit* tmp; +#endif sp_digit mp = 1; sp_digit n, o; int i; @@ -3635,11 +3631,6 @@ static int sp_2048_mod_exp_2_36(sp_digit* r, const sp_digit* e, int bits, const #ifdef WOLFSSL_SMALL_STACK norm = td; tmp = td + 72; - XMEMSET(td, 0, sizeof(sp_digit) * 109); -#else - norm = nd; - tmp = td; - XMEMSET(td, 0, sizeof(td)); #endif sp_2048_mont_setup(m, &mp); @@ -3946,13 +3937,13 @@ 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 b[36], e[18], m[18]; #else sp_digit* d = NULL; -#endif sp_digit* b; sp_digit* e; sp_digit* m; +#endif sp_digit* r; int err = MP_OKAY; int expBits = mp_count_bits(exp); @@ -3979,20 +3970,16 @@ int sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) if (d == NULL) err = MEMORY_E; } - - if (err == MP_OKAY) { - b = d; - e = b + 18 * 2; - m = e + 18; - r = b; - } -#else - r = b = bd; - e = ed; - m = md; #endif if (err == MP_OKAY) { +#ifdef WOLFSSL_SMALL_STACK + b = d; + e = b + 18 * 2; + m = e + 18; +#endif + r = b; + sp_2048_from_mp(b, 18, base); sp_2048_from_mp(e, 18, exp); sp_2048_from_mp(m, 18, mod); @@ -5718,7 +5705,7 @@ static int sp_3072_mod_exp_27(sp_digit* r, const sp_digit* a, const sp_digit* e, #ifdef WOLFSSL_SP_SMALL sp_digit* td; sp_digit* t[3]; - sp_digit* norm; + sp_digit* norm = NULL; sp_digit mp = 1; sp_digit n; int i; @@ -6612,7 +6599,7 @@ static int sp_3072_mod_exp_54(sp_digit* r, const sp_digit* a, const sp_digit* e, #ifdef WOLFSSL_SP_SMALL sp_digit* td; sp_digit* t[3]; - sp_digit* norm; + sp_digit* norm = NULL; sp_digit mp = 1; sp_digit n; int i; @@ -7008,7 +6995,7 @@ int sp_RsaPublic_3072(const byte* in, word32 inLen, mp_int* em, mp_int* mm, #else e[0] = (sp_digit)em->dp[0]; if (em->used > 1) { - e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT; + e[0] |= ((sp_int_digit)em->dp[1]) << DIGIT_BIT; } #endif if (e[0] == 0) { @@ -7109,7 +7096,7 @@ int sp_RsaPublic_3072(const byte* in, word32 inLen, mp_int* em, mp_int* mm, #else e[0] = (sp_digit)em->dp[0]; if (em->used > 1) { - e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT; + e[0] |= ((sp_int_digit)em->dp[1]) << DIGIT_BIT; } #endif if (e[0] == 0) { @@ -7581,13 +7568,13 @@ 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 b[108], e[54], m[54]; #else sp_digit* d = NULL; -#endif sp_digit* b; sp_digit* e; sp_digit* m; +#endif sp_digit* r; int err = MP_OKAY; int expBits = mp_count_bits(exp); @@ -7614,20 +7601,16 @@ int sp_ModExp_3072(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) if (d == NULL) err = MEMORY_E; } - - if (err == MP_OKAY) { - b = d; - e = b + 54 * 2; - m = e + 54; - r = b; - } -#else - r = b = bd; - e = ed; - m = md; #endif if (err == MP_OKAY) { +#ifdef WOLFSSL_SMALL_STACK + b = d; + e = b + 54 * 2; + m = e + 54; +#endif + r = b; + sp_3072_from_mp(b, 54, base); sp_3072_from_mp(e, 54, exp); sp_3072_from_mp(m, 54, mod); @@ -7791,13 +7774,13 @@ SP_NOINLINE static void sp_3072_lshift_54(sp_digit* r, sp_digit* a, byte n) static int sp_3072_mod_exp_2_54(sp_digit* r, const sp_digit* e, int bits, const sp_digit* m) { #ifndef WOLFSSL_SMALL_STACK - sp_digit nd[108]; - sp_digit td[55]; + sp_digit norm[108]; + sp_digit tmp[55]; #else sp_digit* td; -#endif sp_digit* norm; sp_digit* tmp; +#endif sp_digit mp = 1; sp_digit n, o; int i; @@ -7816,11 +7799,6 @@ static int sp_3072_mod_exp_2_54(sp_digit* r, const sp_digit* e, int bits, const #ifdef WOLFSSL_SMALL_STACK norm = td; tmp = td + 108; - XMEMSET(td, 0, sizeof(sp_digit) * 163); -#else - norm = nd; - tmp = td; - XMEMSET(td, 0, sizeof(td)); #endif sp_3072_mont_setup(m, &mp); @@ -8127,13 +8105,13 @@ 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 b[54], e[27], m[27]; #else sp_digit* d = NULL; -#endif sp_digit* b; sp_digit* e; sp_digit* m; +#endif sp_digit* r; int err = MP_OKAY; int expBits = mp_count_bits(exp); @@ -8160,20 +8138,16 @@ int sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) if (d == NULL) err = MEMORY_E; } - - if (err == MP_OKAY) { - b = d; - e = b + 27 * 2; - m = e + 27; - r = b; - } -#else - r = b = bd; - e = ed; - m = md; #endif if (err == MP_OKAY) { +#ifdef WOLFSSL_SMALL_STACK + b = d; + e = b + 27 * 2; + m = e + 27; +#endif + r = b; + sp_3072_from_mp(b, 27, base); sp_3072_from_mp(e, 27, exp); sp_3072_from_mp(m, 27, mod); @@ -10006,7 +9980,7 @@ static int sp_4096_mod_exp_39(sp_digit* r, const sp_digit* a, const sp_digit* e, #ifdef WOLFSSL_SP_SMALL sp_digit* td; sp_digit* t[3]; - sp_digit* norm; + sp_digit* norm = NULL; sp_digit mp = 1; sp_digit n; int i; @@ -10998,7 +10972,7 @@ static int sp_4096_mod_exp_78(sp_digit* r, const sp_digit* a, const sp_digit* e, #ifdef WOLFSSL_SP_SMALL sp_digit* td; sp_digit* t[3]; - sp_digit* norm; + sp_digit* norm = NULL; sp_digit mp = 1; sp_digit n; int i; @@ -11398,7 +11372,7 @@ int sp_RsaPublic_4096(const byte* in, word32 inLen, mp_int* em, mp_int* mm, #else e[0] = (sp_digit)em->dp[0]; if (em->used > 1) { - e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT; + e[0] |= ((sp_int_digit)em->dp[1]) << DIGIT_BIT; } #endif if (e[0] == 0) { @@ -11499,7 +11473,7 @@ int sp_RsaPublic_4096(const byte* in, word32 inLen, mp_int* em, mp_int* mm, #else e[0] = (sp_digit)em->dp[0]; if (em->used > 1) { - e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT; + e[0] |= ((sp_int_digit)em->dp[1]) << DIGIT_BIT; } #endif if (e[0] == 0) { @@ -11971,13 +11945,13 @@ 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 b[156], e[78], m[78]; #else sp_digit* d = NULL; -#endif sp_digit* b; sp_digit* e; sp_digit* m; +#endif sp_digit* r; int err = MP_OKAY; int expBits = mp_count_bits(exp); @@ -12004,20 +11978,16 @@ int sp_ModExp_4096(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) if (d == NULL) err = MEMORY_E; } - - if (err == MP_OKAY) { - b = d; - e = b + 78 * 2; - m = e + 78; - r = b; - } -#else - r = b = bd; - e = ed; - m = md; #endif if (err == MP_OKAY) { +#ifdef WOLFSSL_SMALL_STACK + b = d; + e = b + 78 * 2; + m = e + 78; +#endif + r = b; + sp_4096_from_mp(b, 78, base); sp_4096_from_mp(e, 78, exp); sp_4096_from_mp(m, 78, mod); @@ -12229,13 +12199,13 @@ SP_NOINLINE static void sp_4096_lshift_78(sp_digit* r, sp_digit* a, byte n) static int sp_4096_mod_exp_2_78(sp_digit* r, const sp_digit* e, int bits, const sp_digit* m) { #ifndef WOLFSSL_SMALL_STACK - sp_digit nd[156]; - sp_digit td[79]; + sp_digit norm[156]; + sp_digit tmp[79]; #else sp_digit* td; -#endif sp_digit* norm; sp_digit* tmp; +#endif sp_digit mp = 1; sp_digit n, o; int i; @@ -12254,11 +12224,6 @@ static int sp_4096_mod_exp_2_78(sp_digit* r, const sp_digit* e, int bits, const #ifdef WOLFSSL_SMALL_STACK norm = td; tmp = td + 156; - XMEMSET(td, 0, sizeof(sp_digit) * 235); -#else - norm = nd; - tmp = td; - XMEMSET(td, 0, sizeof(td)); #endif sp_4096_mont_setup(m, &mp); @@ -12579,16 +12544,18 @@ static const sp_digit p256_b[5] = { static int sp_ecc_point_new_ex(void* heap, sp_point* sp, sp_point** p) { int ret = MP_OKAY; - (void)heap; -#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - (void)sp; - *p = (sp_point*)XMALLOC(sizeof(sp_point), heap, DYNAMIC_TYPE_ECC); -#else - *p = sp; -#endif if (p == NULL) { ret = MEMORY_E; } + else { + #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + *p = (sp_point*)XMALLOC(sizeof(sp_point), heap, DYNAMIC_TYPE_ECC); + (void)sp; + #else + *p = sp; + (void)heap; + #endif + } return ret; } @@ -12660,18 +12627,18 @@ static int sp_256_mod_mul_norm_5(sp_digit* r, const sp_digit* a, const sp_digit* a32[0] = (sp_digit)(a[0]) & 0xffffffffL; a32[1] = (sp_digit)(a[0] >> 32U); - a32[1] |= a[1] << 20U; + a32[1] |= (sp_int_digit)a[1] << 20U; a32[1] &= 0xffffffffL; a32[2] = (sp_digit)(a[1] >> 12U) & 0xffffffffL; a32[3] = (sp_digit)(a[1] >> 44U); - a32[3] |= a[2] << 8U; + a32[3] |= (sp_int_digit)a[2] << 8U; a32[3] &= 0xffffffffL; a32[4] = (sp_digit)(a[2] >> 24U); - a32[4] |= a[3] << 28U; + a32[4] |= (sp_int_digit)a[3] << 28U; a32[4] &= 0xffffffffL; a32[5] = (sp_digit)(a[3] >> 4U) & 0xffffffffL; a32[6] = (sp_digit)(a[3] >> 36U); - a32[6] |= a[4] << 16U; + a32[6] |= (sp_int_digit)a[4] << 16U; a32[6] &= 0xffffffffL; a32[7] = (sp_digit)(a[4] >> 16U) & 0xffffffffL; @@ -12712,22 +12679,22 @@ static int sp_256_mod_mul_norm_5(sp_digit* r, const sp_digit* a, const sp_digit* 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] = (sp_int_digit)t[0]; + r[0] |= (sp_int_digit)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] |= (sp_int_digit)t[2] << 12U; + r[1] |= (sp_int_digit)t[3] << 44U; r[1] &= 0xfffffffffffffLL; r[2] = (sp_digit)(t[3] >> 8); - r[2] |= t[4] << 24U; + r[2] |= (sp_int_digit)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] |= (sp_int_digit)t[5] << 4U; + r[3] |= (sp_int_digit)t[6] << 36U; r[3] &= 0xfffffffffffffLL; r[4] = (sp_digit)(t[6] >> 16); - r[4] |= t[7] << 16U; + r[4] |= (sp_int_digit)t[7] << 16U; } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) @@ -14664,11 +14631,12 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_point p; - sp_digit kd[5]; + sp_digit k[5]; +#else + sp_digit* k = NULL; #endif sp_point* point; - sp_digit* k = NULL; - int err = MP_OKAY; + int err; err = sp_ecc_point_new(heap, p, point); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) @@ -14678,8 +14646,6 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, if (k == NULL) err = MEMORY_E; } -#else - k = kd; #endif if (err == MP_OKAY) { sp_256_from_mp(k, 5, km); @@ -16031,11 +15997,12 @@ int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_point p; - sp_digit kd[5]; + sp_digit k[5]; +#else + sp_digit* k = NULL; #endif sp_point* point; - sp_digit* k = NULL; - int err = MP_OKAY; + int err; err = sp_ecc_point_new(heap, p, point); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) @@ -16046,8 +16013,6 @@ int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) err = MEMORY_E; } } -#else - k = kd; #endif if (err == MP_OKAY) { sp_256_from_mp(k, 5, km); @@ -16167,13 +16132,14 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_point p; - sp_digit kd[5]; + sp_digit k[5]; #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN sp_point inf; #endif +#else + sp_digit* k = NULL; #endif sp_point* point; - sp_digit* k = NULL; #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN sp_point* infinity; #endif @@ -16195,8 +16161,6 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) err = MEMORY_E; } } -#else - k = kd; #endif if (err == MP_OKAY) { @@ -16294,10 +16258,11 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_point p; - sp_digit kd[5]; + sp_digit k[5]; +#else + sp_digit* k = NULL; #endif sp_point* point = NULL; - sp_digit* k = NULL; int err = MP_OKAY; if (*outLen < 32U) { @@ -16314,8 +16279,6 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, if (k == NULL) err = MEMORY_E; } -#else - k = kd; #endif if (err == MP_OKAY) { @@ -16733,7 +16696,7 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_digit carry; sp_digit* s = NULL; sp_digit* kInv = NULL; - int err = MP_OKAY; + int err; int64_t c; int i; @@ -17038,7 +17001,7 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, static int sp_256_ecc_is_point_5(sp_point* point, void* heap) { #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - sp_digit* d = NULL; + sp_digit* d; #else sp_digit t1d[2*5]; sp_digit t2d[2*5]; diff --git a/wolfcrypt/src/sp_cortexm.c b/wolfcrypt/src/sp_cortexm.c index a8679d977..f6a928d54 100644 --- a/wolfcrypt/src/sp_cortexm.c +++ b/wolfcrypt/src/sp_cortexm.c @@ -13456,16 +13456,18 @@ static const sp_digit p256_b[8] = { static int sp_ecc_point_new_ex(void* heap, sp_point* sp, sp_point** p) { int ret = MP_OKAY; - (void)heap; -#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - (void)sp; - *p = (sp_point*)XMALLOC(sizeof(sp_point), heap, DYNAMIC_TYPE_ECC); -#else - *p = sp; -#endif if (p == NULL) { ret = MEMORY_E; } + else { + #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + *p = (sp_point*)XMALLOC(sizeof(sp_point), heap, DYNAMIC_TYPE_ECC); + (void)sp; + #else + *p = sp; + (void)heap; + #endif + } return ret; } @@ -16771,11 +16773,12 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_point p; - sp_digit kd[8]; + sp_digit k[8]; +#else + sp_digit* k = NULL; #endif sp_point* point; - sp_digit* k = NULL; - int err = MP_OKAY; + int err; err = sp_ecc_point_new(heap, p, point); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) @@ -16785,8 +16788,6 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, if (k == NULL) err = MEMORY_E; } -#else - k = kd; #endif if (err == MP_OKAY) { sp_256_from_mp(k, 8, km); @@ -18219,11 +18220,12 @@ int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_point p; - sp_digit kd[8]; + sp_digit k[8]; +#else + sp_digit* k = NULL; #endif sp_point* point; - sp_digit* k = NULL; - int err = MP_OKAY; + int err; err = sp_ecc_point_new(heap, p, point); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) @@ -18234,8 +18236,6 @@ int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) err = MEMORY_E; } } -#else - k = kd; #endif if (err == MP_OKAY) { sp_256_from_mp(k, 8, km); @@ -18383,13 +18383,14 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_point p; - sp_digit kd[8]; + sp_digit k[8]; #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN sp_point inf; #endif +#else + sp_digit* k = NULL; #endif sp_point* point; - sp_digit* k = NULL; #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN sp_point* infinity; #endif @@ -18411,8 +18412,6 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) err = MEMORY_E; } } -#else - k = kd; #endif if (err == MP_OKAY) { @@ -18506,10 +18505,11 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_point p; - sp_digit kd[8]; + sp_digit k[8]; +#else + sp_digit* k = NULL; #endif sp_point* point = NULL; - sp_digit* k = NULL; int err = MP_OKAY; if (*outLen < 32U) { @@ -18526,8 +18526,6 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, if (k == NULL) err = MEMORY_E; } -#else - k = kd; #endif if (err == MP_OKAY) { @@ -19000,7 +18998,7 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_digit carry; sp_digit* s = NULL; sp_digit* kInv = NULL; - int err = MP_OKAY; + int err; int32_t c; int i; @@ -19308,7 +19306,7 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, static int sp_256_ecc_is_point_8(sp_point* point, void* heap) { #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - sp_digit* d = NULL; + sp_digit* d; #else sp_digit t1d[2*8]; sp_digit t2d[2*8]; diff --git a/wolfcrypt/src/sp_dsp32.c b/wolfcrypt/src/sp_dsp32.c index a3df114b5..ef95c06fb 100644 --- a/wolfcrypt/src/sp_dsp32.c +++ b/wolfcrypt/src/sp_dsp32.c @@ -4441,6 +4441,9 @@ int wolfSSL_DSP_ECC_Verify_256(remote_handle64 h, int32 *u1, int hashLen, int32* int err; void* heap = NULL; + (void)h; + (void)hashLen; + err = sp_ecc_point_new(heap, p1d, p1); if (err == MP_OKAY) { err = sp_ecc_point_new(heap, p2d, p2); @@ -4450,10 +4453,6 @@ int wolfSSL_DSP_ECC_Verify_256(remote_handle64 h, int32 *u1, int hashLen, int32* u2 = u2d; tmp = tmpd; - if (hashLen > 32U) { - hashLen = 32U; - } - XMEMCPY(u2, r, 40); XMEMCPY(p2->x, x, 40); XMEMCPY(p2->y, y, 40); @@ -4533,7 +4532,7 @@ void wc_ecc_fp_free(void) AEEResult wolfSSL_open(const char *uri, remote_handle64 *handle) { - void *tptr = NULL; + void *tptr; /* can be any value or ignored, rpc layer doesn't care * also ok * *handle = 0; diff --git a/wolfcrypt/src/sp_x86_64.c b/wolfcrypt/src/sp_x86_64.c index 9a73e225f..0f9cef7d8 100644 --- a/wolfcrypt/src/sp_x86_64.c +++ b/wolfcrypt/src/sp_x86_64.c @@ -5880,16 +5880,18 @@ static const sp_digit p256_b[4] = { static int sp_ecc_point_new_ex(void* heap, sp_point* sp, sp_point** p) { int ret = MP_OKAY; - (void)heap; -#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - (void)sp; - *p = (sp_point*)XMALLOC(sizeof(sp_point), heap, DYNAMIC_TYPE_ECC); -#else - *p = sp; -#endif if (p == NULL) { ret = MEMORY_E; } + else { + #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + *p = (sp_point*)XMALLOC(sizeof(sp_point), heap, DYNAMIC_TYPE_ECC); + (void)sp; + #else + *p = sp; + (void)heap; + #endif + } return ret; } @@ -8340,11 +8342,12 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_point p; - sp_digit kd[4]; + sp_digit k[4]; +#else + sp_digit* k = NULL; #endif sp_point* point; - sp_digit* k = NULL; - int err = MP_OKAY; + int err; #ifdef HAVE_INTEL_AVX2 word32 cpuid_flags = cpuid_get_flags(); #endif @@ -8357,8 +8360,6 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, if (k == NULL) err = MEMORY_E; } -#else - k = kd; #endif if (err == MP_OKAY) { sp_256_from_mp(k, 4, km); @@ -21936,11 +21937,12 @@ int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_point p; - sp_digit kd[4]; + sp_digit k[4]; +#else + sp_digit* k = NULL; #endif sp_point* point; - sp_digit* k = NULL; - int err = MP_OKAY; + int err; #ifdef HAVE_INTEL_AVX2 word32 cpuid_flags = cpuid_get_flags(); #endif @@ -21954,8 +21956,6 @@ int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) err = MEMORY_E; } } -#else - k = kd; #endif if (err == MP_OKAY) { sp_256_from_mp(k, 4, km); @@ -22070,13 +22070,14 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_point p; - sp_digit kd[4]; + sp_digit k[4]; #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN sp_point inf; #endif +#else + sp_digit* k = NULL; #endif sp_point* point; - sp_digit* k = NULL; #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN sp_point* infinity; #endif @@ -22101,8 +22102,6 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) err = MEMORY_E; } } -#else - k = kd; #endif if (err == MP_OKAY) { @@ -22208,10 +22207,11 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_point p; - sp_digit kd[4]; + sp_digit k[4]; +#else + sp_digit* k = NULL; #endif sp_point* point = NULL; - sp_digit* k = NULL; int err = MP_OKAY; #ifdef HAVE_INTEL_AVX2 word32 cpuid_flags = cpuid_get_flags(); @@ -22231,8 +22231,6 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, if (k == NULL) err = MEMORY_E; } -#else - k = kd; #endif if (err == MP_OKAY) { @@ -22721,7 +22719,7 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_digit carry; sp_digit* s = NULL; sp_digit* kInv = NULL; - int err = MP_OKAY; + int err; int64_t c; int i; #ifdef HAVE_INTEL_AVX2 @@ -23099,7 +23097,7 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, static int sp_256_ecc_is_point_4(sp_point* point, void* heap) { #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - sp_digit* d = NULL; + sp_digit* d; #else sp_digit t1d[2*4]; sp_digit t2d[2*4]; diff --git a/wolfcrypt/src/tfm.c b/wolfcrypt/src/tfm.c index 8da0c7a57..2fd96bdb2 100644 --- a/wolfcrypt/src/tfm.c +++ b/wolfcrypt/src/tfm.c @@ -479,6 +479,9 @@ WC_INLINE static int fp_mul_comba_mulx(fp_int *A, fp_int *B, fp_int *C) #else fp_int *tmp; #endif + + /* Variables used but not seen by cppcheck. */ + (void)ix; (void)iy; (void)iz; #ifdef WOLFSSL_SMALL_STACK tmp = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT); @@ -526,6 +529,9 @@ int fp_mul_comba(fp_int *A, fp_int *B, fp_int *C) fp_int *tmp; #endif + /* Variables used but not seen by cppcheck. */ + (void)c0; (void)c1; (void)c2; + IF_HAVE_INTEL_MULX(ret = fp_mul_comba_mulx(A, B, C), return ret) ; #ifdef WOLFSSL_SMALL_STACK @@ -2503,6 +2509,12 @@ int fp_sqr_comba(fp_int *A, fp_int *B) fp_int *tmp; #endif + /* Variables used but not seen by cppcheck. */ + (void)c0; (void)c1; (void)c2; +#ifdef TFM_ISO + (void)tt; +#endif + #ifdef WOLFSSL_SMALL_STACK tmp = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_BIGINT); if (tmp == NULL) @@ -3362,22 +3374,26 @@ void fp_init(fp_int *a) void fp_zero(fp_int *a) { - int size = FP_SIZE; + int size; a->used = 0; a->sign = FP_ZPOS; #if defined(ALT_ECC_SIZE) || defined(HAVE_WOLF_BIGINT) size = a->size; +#else + size = FP_SIZE; #endif XMEMSET(a->dp, 0, size * sizeof(fp_digit)); } void fp_clear(fp_int *a) { - int size = FP_SIZE; + int size; a->used = 0; a->sign = FP_ZPOS; #if defined(ALT_ECC_SIZE) || defined(HAVE_WOLF_BIGINT) size = a->size; +#else + size = FP_SIZE; #endif XMEMSET(a->dp, 0, size * sizeof(fp_digit)); fp_free(a); @@ -3385,11 +3401,13 @@ void fp_clear(fp_int *a) void fp_forcezero (mp_int * a) { - int size = FP_SIZE; + int size; a->used = 0; a->sign = FP_ZPOS; #if defined(ALT_ECC_SIZE) || defined(HAVE_WOLF_BIGINT) size = a->size; +#else + size = FP_SIZE; #endif ForceZero(a->dp, size * sizeof(fp_digit)); #ifdef HAVE_WOLF_BIGINT @@ -4883,10 +4901,12 @@ int mp_toradix (mp_int *a, char *str, int radix) void mp_dump(const char* desc, mp_int* a, byte verbose) { char buffer[FP_SIZE * sizeof(fp_digit) * 2]; - int size = FP_SIZE; + int size; #if defined(ALT_ECC_SIZE) || defined(HAVE_WOLF_BIGINT) size = a->size; +#else + size = FP_SIZE; #endif printf("%s: ptr=%p, used=%d, sign=%d, size=%d, fpd=%d\n", diff --git a/wolfcrypt/src/wc_encrypt.c b/wolfcrypt/src/wc_encrypt.c index d7a3b8712..2d8364939 100644 --- a/wolfcrypt/src/wc_encrypt.c +++ b/wolfcrypt/src/wc_encrypt.c @@ -87,7 +87,7 @@ int wc_AesCbcEncryptWithKey(byte* out, const byte* in, word32 inSz, { int ret = 0; #ifdef WOLFSSL_SMALL_STACK - Aes* aes = NULL; + Aes* aes; #else Aes aes[1]; #endif @@ -122,7 +122,7 @@ int wc_Des_CbcEncryptWithKey(byte* out, const byte* in, word32 sz, { int ret = 0; #ifdef WOLFSSL_SMALL_STACK - Des* des = NULL; + Des* des; #else Des des[1]; #endif @@ -149,7 +149,7 @@ int wc_Des_CbcDecryptWithKey(byte* out, const byte* in, word32 sz, { int ret = 0; #ifdef WOLFSSL_SMALL_STACK - Des* des = NULL; + Des* des; #else Des des[1]; #endif @@ -177,7 +177,7 @@ int wc_Des3_CbcEncryptWithKey(byte* out, const byte* in, word32 sz, { int ret = 0; #ifdef WOLFSSL_SMALL_STACK - Des3* des3 = NULL; + Des3* des3; #else Des3 des3[1]; #endif @@ -209,7 +209,7 @@ int wc_Des3_CbcDecryptWithKey(byte* out, const byte* in, word32 sz, { int ret = 0; #ifdef WOLFSSL_SMALL_STACK - Des3* des3 = NULL; + Des3* des3; #else Des3 des3[1]; #endif diff --git a/wolfcrypt/src/wc_pkcs11.c b/wolfcrypt/src/wc_pkcs11.c index 90d24e2ba..cac0a0fcc 100644 --- a/wolfcrypt/src/wc_pkcs11.c +++ b/wolfcrypt/src/wc_pkcs11.c @@ -869,7 +869,7 @@ static int Pkcs11RsaPublic(Pkcs11Session* session, wc_CryptoInfo* info) WOLFSSL_MSG("PKCS#11: RSA Public Key Operation"); - if (ret == 0 && info->pk.rsa.outLen == NULL) { + if (info->pk.rsa.outLen == NULL) { ret = BAD_FUNC_ARG; } @@ -941,7 +941,7 @@ static int Pkcs11RsaPrivate(Pkcs11Session* session, wc_CryptoInfo* info) WOLFSSL_MSG("PKCS#11: RSA Private Key Operation"); - if (ret == 0 && info->pk.rsa.outLen == NULL) { + if (info->pk.rsa.outLen == NULL) { ret = BAD_FUNC_ARG; } @@ -1611,9 +1611,9 @@ static word32 Pkcs11ECDSASig_Encode(byte* sig, word32 sz) word32 i; /* Find first byte of data in r and s. */ - while (sig[rStart] == 0x00 && rStart < sz - 1) + while (rStart < sz - 1 && sig[rStart] == 0x00) rStart++; - while (sig[sz + sStart] == 0x00 && sStart < sz - 1) + while (sStart < sz - 1 && sig[sz + sStart] == 0x00) sStart++; /* Check if 0 needs to be prepended to make integer a positive number. */ rHigh = sig[rStart] >> 7; diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index a23d4449b..e57db5c5d 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -1335,7 +1335,7 @@ int wolfSSL_CryptHwMutexUnLock(void) { void *uITRON4_malloc(size_t sz) { ER ercd; - void *p; + void *p = NULL; ercd = get_mpl(ID_wolfssl_MPOOL, sz, (VP)&p); if (ercd == E_OK) { return p; @@ -1429,7 +1429,7 @@ int wolfSSL_CryptHwMutexUnLock(void) { void *uTKernel_malloc(unsigned int sz) { ER ercd; - void *p; + void *p = NULL; ercd = tk_get_mpl(ID_wolfssl_MPOOL, sz, (VP)&p, TMO_FEVR); if (ercd == E_OK) { return p; @@ -2206,7 +2206,6 @@ char* mystrnstr(const char* s1, const char* s2, unsigned int n) void* nucleus_realloc(void* ptr, unsigned long size, void* heap, int type) { - STATUS status; DM_HEADER* old_header; word32 old_size, copy_size; void* new_mem; diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 8f87f907b..c81894b49 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -2982,6 +2982,8 @@ int sha3_test(void) { int ret; + (void)ret; + #ifndef WOLFSSL_NOSHA3_224 if ((ret = sha3_224_test()) != 0) return ret; @@ -7576,7 +7578,7 @@ int aesgcm_test(void) int result; #ifdef WOLFSSL_AES_256 int alen; - #ifndef WOLFSSL_AFALG_XILINX_AES + #if !defined(WOLFSSL_AFALG_XILINX_AES) && !defined(WOLFSSL_XILINX_CRYPT) int plen; #endif #endif @@ -7594,6 +7596,8 @@ int aesgcm_test(void) XMEMSET(large_outdec, 0, sizeof(large_outdec)); #endif + (void)result; + XMEMSET(resultT, 0, sizeof(resultT)); XMEMSET(resultC, 0, sizeof(resultC)); XMEMSET(resultP, 0, sizeof(resultP)); @@ -7739,7 +7743,7 @@ int aesgcm_test(void) return -5715; #endif /* HAVE_AES_DECRYPT */ } -#else +#else /* BENCH_AESGCM_LARGE */ /* Variable plain text length test */ for (plen=1; plen<(int)sizeof(p); plen++) { /* AES-GCM encrypt and decrypt both use AES encrypt internally */ @@ -9074,7 +9078,7 @@ int random_test(void) static int simple_mem_test(int sz) { int ret = 0; - byte* b = NULL; + byte* b; int i; b = (byte*)XMALLOC(sz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); @@ -10979,7 +10983,7 @@ int rsa_no_pad_test(void) { WC_RNG rng; RsaKey key; - byte* tmp = NULL; + byte* tmp; size_t bytes; int ret; word32 inLen = 0; @@ -11193,7 +11197,7 @@ exit_rsa_nopadding: static int rsa_certgen_test(RsaKey* key, RsaKey* keypub, WC_RNG* rng, byte* tmp) { RsaKey caKey; - byte* der = NULL; + byte* der; byte* pem = NULL; int ret; Cert* myCert = NULL; @@ -11475,11 +11479,8 @@ exit_rsa: wc_FreeRsaKey(&caKey); XFREE(myCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - myCert = NULL; XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - pem = NULL; XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - der = NULL; return ret; } @@ -11492,7 +11493,7 @@ static int rsa_ecc_certgen_test(WC_RNG* rng, byte* tmp) RsaKey caKey; ecc_key caEccKey; ecc_key caEccKeyPub; - byte* der = NULL; + byte* der; byte* pem = NULL; Cert* myCert = NULL; int certSz; @@ -11698,7 +11699,7 @@ static int rsa_keygen_test(WC_RNG* rng) byte* pem = NULL; word32 idx = 0; int derSz = 0; -#ifndef WOLFSSL_SP_MATH +#if !defined(WOLFSSL_SP_MATH) && !defined(HAVE_FIPS) int keySz = 1024; #else int keySz = 2048; @@ -11706,10 +11707,6 @@ static int rsa_keygen_test(WC_RNG* rng) XMEMSET(&genKey, 0, sizeof(genKey)); - #ifdef HAVE_FIPS - keySz = 2048; - #endif /* HAVE_FIPS */ - ret = wc_InitRsaKey_ex(&genKey, HEAP_HINT, devId); if (ret != 0) { ERROR_OUT(-6962, exit_rsa); @@ -11786,7 +11783,7 @@ exit_rsa: int rsa_test(void) { int ret; - byte* tmp = NULL; + byte* tmp; byte* der = NULL; byte* pem = NULL; size_t bytes; @@ -15770,7 +15767,7 @@ int openssl_pkey1_test(void) EVP_PKEY_CTX* enc = NULL; EVP_PKEY* pubKey = NULL; EVP_PKEY* prvKey = NULL; - X509* x509 = NULL; + X509* x509; const unsigned char msg[] = "sugar slapped"; const unsigned char* clikey; @@ -17052,8 +17049,8 @@ done: static int ecc_test_make_pub(WC_RNG* rng) { ecc_key key; - unsigned char* exportBuf = NULL; - unsigned char* tmp = NULL; + unsigned char* exportBuf; + unsigned char* tmp; unsigned char msg[] = "test wolfSSL ECC public gen"; word32 x, tmpSz; int ret = 0; @@ -17170,6 +17167,9 @@ static int ecc_test_make_pub(WC_RNG* rng) #if defined(WOLFSSL_CRYPTOCELL) /* create a new key since building private key from public key is unsupported */ ret = wc_ecc_make_key(rng, 32, &key); + if (ret == 0) { + ERROR_OUT(-8323, done); + } #endif #ifdef HAVE_ECC_SIGN tmpSz = FOURK_BUF; @@ -18564,7 +18564,7 @@ static int ecc_test_cert_gen(WC_RNG* rng) #ifdef WOLFSSL_TEST_CERT DecodedCert decode; #endif - byte* der = NULL; + byte* der; byte* pem = NULL; ecc_key caEccKey; ecc_key certPubKey; @@ -19429,14 +19429,14 @@ static int curve25519_check_public_test(void) } /* Little-endian fail cases */ - for (i = 0; i < (int)(sizeof(fail_le) / sizeof(fail_le)); i++) { + for (i = 0; i < (int)(sizeof(fail_le) / sizeof(*fail_le)); i++) { if (wc_curve25519_check_public(fail_le[i], CURVE25519_KEYSIZE, EC25519_LITTLE_ENDIAN) == 0) { return -10390 - i; } } /* Big-endian fail cases */ - for (i = 0; i < (int)(sizeof(fail_be) / sizeof(fail_be)); i++) { + for (i = 0; i < (int)(sizeof(fail_be) / sizeof(*fail_be)); i++) { if (wc_curve25519_check_public(fail_be[i], CURVE25519_KEYSIZE, EC25519_BIG_ENDIAN) == 0) { return -10394 - i; @@ -19520,6 +19520,8 @@ int curve25519_test(void) }; #endif /* HAVE_CURVE25519_SHARED_SECRET */ + (void)x; + #ifndef HAVE_FIPS ret = wc_InitRng_ex(&rng, HEAP_HINT, devId); #else @@ -21049,8 +21051,8 @@ int compress_test(void) int ret = 0; word32 dSz = sizeof(sample_text); word32 cSz = (dSz + (word32)(dSz * 0.001) + 12); - byte *c = NULL; - byte *d = NULL; + byte *c; + byte *d; c = XMALLOC(cSz * sizeof(byte), HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); d = XMALLOC(dSz * sizeof(byte), HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); @@ -21074,7 +21076,6 @@ int compress_test(void) if (XMEMCMP(d, sample_text, dSz) != 0) { ERROR_OUT(-9203, exit); } - ret = 0; /* GZIP tests */ cSz = (dSz + (word32)(dSz * 0.001) + 12); /* reset cSz */ @@ -21170,6 +21171,9 @@ static int pkcs7_load_certs_keys( #ifndef NO_FILESYSTEM XFILE certFile; XFILE keyFile; + + (void)certFile; + (void)keyFile; #endif #ifndef NO_RSA @@ -25417,7 +25421,9 @@ int memcb_test(void) ret = -10006; #endif /* !WOLFSSL_NO_MALLOC */ +#ifndef WOLFSSL_NO_MALLOC exit_memcb: +#endif /* restore memory callbacks */ wolfSSL_SetAllocators(mc, fc, rc); @@ -25806,7 +25812,10 @@ static int myCryptoDevCb(int devIdArg, wc_CryptoInfo* info, void* ctx) /* reset devId */ info->hash.sha256->devId = devIdArg; } + else #endif + { + } } #endif /* !NO_SHA || !NO_SHA256 */ #ifndef NO_HMAC diff --git a/wolfcrypt/user-crypto/src/rsa.c b/wolfcrypt/user-crypto/src/rsa.c index ed47441c5..b88510167 100644 --- a/wolfcrypt/user-crypto/src/rsa.c +++ b/wolfcrypt/user-crypto/src/rsa.c @@ -693,7 +693,7 @@ static IppStatus init_mont(IppsMontState** mont, int* ctxSz, /* 2. Allocate working buffer using malloc */ *mont = (IppsMontState*)XMALLOC(*ctxSz, 0, DYNAMIC_TYPE_USER_CRYPTO); - if (mont == NULL) { + if (*mont == NULL) { XFREE(m, NULL, DYNAMIC_TYPE_USER_CRYPTO); return ippStsNoMemErr; } @@ -1620,7 +1620,6 @@ static void Free_BN(IppsBigNumState* bn) USER_DEBUG(("Issue with clearing a struct in RsaSSL_Sign free\n")); } XFREE(bn, NULL, DYNAMIC_TYPE_USER_CRYPTO); - bn = NULL; } } @@ -2552,7 +2551,7 @@ static int SetRsaPublicKey(byte* output, RsaKey* key, if (with_header) { int algoSz; #ifdef WOLFSSL_SMALL_STACK - byte* algo = NULL; + byte* algo; algo = (byte*)XMALLOC(MAX_ALGO_SZ, NULL, DYNAMIC_TYPE_USER_CRYPTO); if (algo == NULL) { diff --git a/wolfssl/test.h b/wolfssl/test.h index d48e30327..b669f4359 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -1164,6 +1164,8 @@ static WC_INLINE void udp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd, tcp_ready* ready = args->signal; ready->ready = 1; ready->port = port; +#else + (void)port; #endif *clientfd = *sockfd; @@ -1215,7 +1217,7 @@ static WC_INLINE void tcp_accept(SOCKET_T* sockfd, SOCKET_T* clientfd, ready = args->signal; if (ready) { - srf = fopen(ready->srfName, "w"); + srf = XFOPEN(ready->srfName, "w"); if (srf) { /* let's write port sever is listening on to ready file @@ -1495,7 +1497,7 @@ static WC_INLINE void OCSPRespFreeCb(void* ioCtx, unsigned char* response) *bufLen = 0; /* open file (read-only binary) */ - file = fopen(fname, "rb"); + file = XFOPEN(fname, "rb"); if (!file) { printf("Error loading %s\n", fname); return BAD_PATH_ERROR; @@ -1891,7 +1893,7 @@ static WC_INLINE void CaCb(unsigned char* der, int sz, int type) int depth, res; XFILE file; for(depth = 0; depth <= MAX_WOLF_ROOT_DEPTH; depth++) { - file = fopen(ntruKeyFile, "rb"); + file = XFOPEN(ntruKeyFile, "rb"); if (file != NULL) { fclose(file); return depth; @@ -2457,11 +2459,14 @@ static WC_INLINE int myEccKeyGen(WOLFSSL* ssl, ecc_key* key, word32 keySz, int ret; WC_RNG rng; PkCbInfo* cbInfo = (PkCbInfo*)ctx; - ecc_key* new_key = key; + ecc_key* new_key; #ifdef TEST_PK_PRIVKEY byte qx[MAX_ECC_BYTES], qy[MAX_ECC_BYTES]; word32 qxLen = sizeof(qx), qyLen = sizeof(qy); + new_key = &cbInfo->keyGen.ecc; +#else + new_key = key; #endif (void)ssl; From 9bfbdfe695c598611171c9a7012a406cb9b40262 Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 28 Jan 2020 15:43:03 -0800 Subject: [PATCH 022/649] Fix for `wc_EccPublicKeyDecode` to use the length from ASN sequence, not the provided `inSz`. Also checked the case where the sequence number is larger than supplied `inSz` and it will properly return ASN_PARSE_E. ZD 9791 --- wolfcrypt/src/asn.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index e9971d958..ea1b153bb 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -15028,7 +15028,7 @@ static int EccKeyParamCopy(char** dst, char* src) int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key, word32 inSz) { - int length; + int tot_len, length; int ret; int curve_id = ECC_CURVE_DEF; word32 oidSum, localIdx; @@ -15037,7 +15037,7 @@ int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx, if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) return BAD_FUNC_ARG; - if (GetSequence(input, inOutIdx, &length, inSz) < 0) + if (GetSequence(input, inOutIdx, &tot_len, inSz) < 0) return ASN_PARSE_E; if (GetSequence(input, inOutIdx, &length, inSz) < 0) @@ -15211,7 +15211,7 @@ int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx, return ret; /* This is the raw point data compressed or uncompressed. */ - if (wc_ecc_import_x963_ex(input + *inOutIdx, inSz - *inOutIdx, key, + if (wc_ecc_import_x963_ex(input + *inOutIdx, tot_len - *inOutIdx, key, curve_id) != 0) { return ASN_ECC_KEY_E; } From 32f478d3351df0da4fa584e581e09b16853cb8cd Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 30 Jan 2020 08:38:22 -0800 Subject: [PATCH 023/649] Better fix for using the ASN.1 provided length, not provided `inSz`. Confirmed `CheckBitString` will check case where `inSz < ASN.1 length`. --- wolfcrypt/src/asn.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index ea1b153bb..0d12753f6 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -15028,7 +15028,7 @@ static int EccKeyParamCopy(char** dst, char* src) int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx, ecc_key* key, word32 inSz) { - int tot_len, length; + int length; int ret; int curve_id = ECC_CURVE_DEF; word32 oidSum, localIdx; @@ -15037,7 +15037,7 @@ int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx, if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) return BAD_FUNC_ARG; - if (GetSequence(input, inOutIdx, &tot_len, inSz) < 0) + if (GetSequence(input, inOutIdx, &length, inSz) < 0) return ASN_PARSE_E; if (GetSequence(input, inOutIdx, &length, inSz) < 0) @@ -15211,7 +15211,7 @@ int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx, return ret; /* This is the raw point data compressed or uncompressed. */ - if (wc_ecc_import_x963_ex(input + *inOutIdx, tot_len - *inOutIdx, key, + if (wc_ecc_import_x963_ex(input + *inOutIdx, length, key, curve_id) != 0) { return ASN_ECC_KEY_E; } From 928f64106493fa3616b591bbe3d854da38045611 Mon Sep 17 00:00:00 2001 From: David Garske Date: Thu, 30 Jan 2020 13:53:06 -0800 Subject: [PATCH 024/649] Fixes for char strings not marked as const. The `const` is an optimization to allow use from flash, which saves RAM space on embedded devices. --- src/ssl.c | 4 ++-- wolfcrypt/src/asn.c | 32 ++++++++++++++++---------------- wolfssl/wolfcrypt/asn.h | 2 +- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 149594eb0..6204358d7 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -21836,8 +21836,8 @@ int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b) /* print signature algo */ { - int oid; - char* sig; + int oid; + const char* sig; if ((oid = wolfSSL_X509_get_signature_type(x509)) <= 0) { WOLFSSL_MSG("Error getting x509 signature type"); diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index e9971d958..7ff7ed46c 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -496,56 +496,56 @@ static int GetInteger7Bit(const byte* input, word32* inOutIdx, word32 maxIdx) #if !defined(NO_DSA) && !defined(NO_SHA) -static char sigSha1wDsaName[] = "SHAwDSA"; +static const char sigSha1wDsaName[] = "SHAwDSA"; #endif /* NO_DSA */ #ifndef NO_RSA #ifdef WOLFSSL_MD2 - static char sigMd2wRsaName[] = "md2WithRSAEncryption"; + static const char sigMd2wRsaName[] = "md2WithRSAEncryption"; #endif #ifndef NO_MD5 - static char sigMd5wRsaName[] = "md5WithRSAEncryption"; + static const char sigMd5wRsaName[] = "md5WithRSAEncryption"; #endif #ifndef NO_SHA - static char sigSha1wRsaName[] = "sha1WithRSAEncryption"; + static const char sigSha1wRsaName[] = "sha1WithRSAEncryption"; #endif #ifdef WOLFSSL_SHA224 - static char sigSha224wRsaName[] = "sha224WithRSAEncryption"; + static const char sigSha224wRsaName[] = "sha224WithRSAEncryption"; #endif #ifndef NO_SHA256 - static char sigSha256wRsaName[] = "sha256WithRSAEncryption"; + static const char sigSha256wRsaName[] = "sha256WithRSAEncryption"; #endif #ifdef WOLFSSL_SHA384 - static char sigSha384wRsaName[] = "sha384WithRSAEncryption"; + static const char sigSha384wRsaName[] = "sha384WithRSAEncryption"; #endif #ifdef WOLFSSL_SHA512 - static char sigSha512wRsaName[] = "sha512WithRSAEncryption"; + static const char sigSha512wRsaName[] = "sha512WithRSAEncryption"; #endif #endif /* NO_RSA */ #ifdef HAVE_ECC #ifndef NO_SHA - static char sigSha1wEcdsaName[] = "SHAwECDSA"; + static const char sigSha1wEcdsaName[] = "SHAwECDSA"; #endif #ifdef WOLFSSL_SHA224 - static char sigSha224wEcdsaName[] = "SHA224wECDSA"; + static const char sigSha224wEcdsaName[] = "SHA224wECDSA"; #endif #ifndef NO_SHA256 - static char sigSha256wEcdsaName[] = "SHA256wECDSA"; + static const char sigSha256wEcdsaName[] = "SHA256wECDSA"; #endif #ifdef WOLFSSL_SHA384 - static char sigSha384wEcdsaName[] = "SHA384wECDSA"; + static const char sigSha384wEcdsaName[] = "SHA384wECDSA"; #endif #ifdef WOLFSSL_SHA512 - static char sigSha512wEcdsaName[] = "SHA512wECDSA"; + static const char sigSha512wEcdsaName[] = "SHA512wECDSA"; #endif #endif /* HAVE_ECC */ -static char sigUnknownName[] = "Unknown"; +static const char sigUnknownName[] = "Unknown"; /* Get the human readable string for a signature type * * oid Oid value for signature */ -char* GetSigName(int oid) { +const char* GetSigName(int oid) { switch (oid) { #if !defined(NO_DSA) && !defined(NO_SHA) case CTC_SHAwDSA: @@ -15067,7 +15067,7 @@ int wc_EccPublicKeyDecode(const byte* input, word32* inOutIdx, ret = MEMORY_E; if (ret == 0) { - static char customName[] = "Custom"; + static const char customName[] = "Custom"; XMEMSET(curve, 0, sizeof(*curve)); #ifndef WOLFSSL_ECC_CURVE_STATIC curve->name = customName; diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 0ab501c8e..017a3652c 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -1103,7 +1103,7 @@ WOLFSSL_LOCAL int GetShortInt(const byte* input, word32* inOutIdx, int* number, WOLFSSL_LOCAL int SetShortInt(byte* input, word32* inOutIdx, word32 number, word32 maxIdx); -WOLFSSL_LOCAL char* GetSigName(int oid); +WOLFSSL_LOCAL const char* GetSigName(int oid); WOLFSSL_LOCAL int GetLength(const byte* input, word32* inOutIdx, int* len, word32 maxIdx); WOLFSSL_LOCAL int GetLength_ex(const byte* input, word32* inOutIdx, int* len, From 4bc0f79dd98065b943f1d6034547301bbd771ac9 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 30 Jan 2020 14:07:27 -0800 Subject: [PATCH 025/649] Fix ABI Someone removed some of the WOLFSSL_ABI tags from the ssl.h header file. It looks like it was a bad manual merge. --- wolfssl/ssl.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 356bf6185..75a3f5421 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1278,12 +1278,15 @@ WOLFSSL_API int wolfSSL_RSA_print(WOLFSSL_BIO* bio, WOLFSSL_RSA* rsa, int offset WOLFSSL_API int wolfSSL_X509_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509* x509, unsigned long nmflags, unsigned long cflag); WOLFSSL_API int wolfSSL_X509_print(WOLFSSL_BIO* bio, WOLFSSL_X509* x509); -WOLFSSL_API char* wolfSSL_X509_NAME_oneline(WOLFSSL_X509_NAME*, char*, int); +WOLFSSL_ABI WOLFSSL_API char* wolfSSL_X509_NAME_oneline(WOLFSSL_X509_NAME*, + char*, int); #if defined(OPENSSL_EXTRA) && defined(XSNPRINTF) WOLFSSL_API char* wolfSSL_X509_get_name_oneline(WOLFSSL_X509_NAME*, char*, int); #endif -WOLFSSL_API WOLFSSL_X509_NAME* wolfSSL_X509_get_issuer_name(WOLFSSL_X509*); -WOLFSSL_API WOLFSSL_X509_NAME* wolfSSL_X509_get_subject_name(WOLFSSL_X509*); +WOLFSSL_ABI WOLFSSL_API WOLFSSL_X509_NAME* wolfSSL_X509_get_issuer_name( + WOLFSSL_X509*); +WOLFSSL_ABI WOLFSSL_API WOLFSSL_X509_NAME* wolfSSL_X509_get_subject_name( + WOLFSSL_X509*); WOLFSSL_API int wolfSSL_X509_ext_isSet_by_NID(WOLFSSL_X509*, int); WOLFSSL_API int wolfSSL_X509_ext_get_critical_by_NID(WOLFSSL_X509*, int); WOLFSSL_API int wolfSSL_X509_get_isCA(WOLFSSL_X509*); From e13d9f7f1b5459adf8173de6fcb0a16c222c8e88 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 30 Jan 2020 20:38:31 +0100 Subject: [PATCH 026/649] Add SSL_CTX_set1_groups_list and SSL_set1_groups_list APIs --- src/ssl.c | 64 +++++++++++++++++------------------ src/tls13.c | 79 +++++++++++++++++++++++++++++++++++++++++++ tests/api.c | 41 ++++++++++++++++++++++ wolfssl/internal.h | 13 +++++++ wolfssl/openssl/ssl.h | 3 ++ wolfssl/ssl.h | 3 ++ 6 files changed, 171 insertions(+), 32 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 149594eb0..4f7bb7bd3 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -134,6 +134,34 @@ #endif /* !WOLFCRYPT_ONLY || OPENSSL_EXTRA */ #ifndef WOLFCRYPT_ONLY +#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) +const WOLF_EC_NIST_NAME kNistCurves[] = { + {STR_SIZEOF("P-192"), "P-192", NID_X9_62_prime192v1}, + {STR_SIZEOF("P-256"), "P-256", NID_X9_62_prime256v1}, + {STR_SIZEOF("P-112"), "P-112", NID_secp112r1}, + {STR_SIZEOF("P-112-2"), "P-112-2", NID_secp112r2}, + {STR_SIZEOF("P-128"), "P-128", NID_secp128r1}, + {STR_SIZEOF("P-128-2"), "P-128-2", NID_secp128r2}, + {STR_SIZEOF("P-160"), "P-160", NID_secp160r1}, + {STR_SIZEOF("P-160-2"), "P-160-2", NID_secp160r2}, + {STR_SIZEOF("P-224"), "P-224", NID_secp224r1}, + {STR_SIZEOF("P-384"), "P-384", NID_secp384r1}, + {STR_SIZEOF("P-521"), "P-521", NID_secp521r1}, + {STR_SIZEOF("K-160"), "K-160", NID_secp160k1}, + {STR_SIZEOF("K-192"), "K-192", NID_secp192k1}, + {STR_SIZEOF("K-224"), "K-224", NID_secp224k1}, + {STR_SIZEOF("K-256"), "K-256", NID_secp256k1}, + {STR_SIZEOF("B-160"), "B-160", NID_brainpoolP160r1}, + {STR_SIZEOF("B-192"), "B-192", NID_brainpoolP192r1}, + {STR_SIZEOF("B-224"), "B-224", NID_brainpoolP224r1}, + {STR_SIZEOF("B-256"), "B-256", NID_brainpoolP256r1}, + {STR_SIZEOF("B-320"), "B-320", NID_brainpoolP320r1}, + {STR_SIZEOF("B-384"), "B-384", NID_brainpoolP384r1}, + {STR_SIZEOF("B-512"), "B-512", NID_brainpoolP512r1}, + {0, NULL, 0}, +}; +#endif + #if defined(WOLFSSL_RENESAS_TSIP_TLS) /* for root ca verification */ int tsip_tls_RootCertVerify(const byte *cert, word32 cert_len, @@ -33095,40 +33123,12 @@ int wolfSSL_EVP_PKEY_set1_EC_KEY(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_EC_KEY *key) } #endif /* WOLFSSL_QT || OPENSSL_ALL */ -typedef struct { - const char *name; - int nid; -} WOLF_EC_NIST_NAME; -static const WOLF_EC_NIST_NAME kNistCurves[] = { - {"P-192", NID_X9_62_prime192v1}, - {"P-256", NID_X9_62_prime256v1}, - {"P-112", NID_secp112r1}, - {"P-112-2", NID_secp112r2}, - {"P-128", NID_secp128r1}, - {"P-128-2", NID_secp128r2}, - {"P-160", NID_secp160r1}, - {"P-160-2", NID_secp160r2}, - {"P-224", NID_secp224r1}, - {"P-384", NID_secp384r1}, - {"P-521", NID_secp521r1}, - {"K-160", NID_secp160k1}, - {"K-192", NID_secp192k1}, - {"K-224", NID_secp224k1}, - {"K-256", NID_secp256k1}, - {"B-160", NID_brainpoolP160r1}, - {"B-192", NID_brainpoolP192r1}, - {"B-224", NID_brainpoolP224r1}, - {"B-256", NID_brainpoolP256r1}, - {"B-320", NID_brainpoolP320r1}, - {"B-384", NID_brainpoolP384r1}, - {"B-512", NID_brainpoolP512r1}, -}; const char* wolfSSL_EC_curve_nid2nist(int nid) { - int i; - for (i = 0; i < (int)(sizeof(kNistCurves)/sizeof(WOLF_EC_NIST_NAME)); i++) { - if (kNistCurves[i].nid == nid) { - return kNistCurves[i].name; + const WOLF_EC_NIST_NAME* nist_name; + for (nist_name = kNistCurves; nist_name->name != NULL; nist_name++) { + if (nist_name->nid == nid) { + return kNistCurves->name; } } return NULL; diff --git a/src/tls13.c b/src/tls13.c index f9cbf86b8..909406098 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -8218,6 +8218,85 @@ int wolfSSL_request_certificate(WOLFSSL* ssl) } #endif /* !NO_CERTS && WOLFSSL_POST_HANDSHAKE_AUTH */ + +#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) +static int populate_groups(int* groups, int max_count, char *list) +{ + char *end; + size_t len; + int count = 0; + const WOLF_EC_NIST_NAME* nist_name; + + if (!groups || !list) { + return -1; + } + + for (end = list; ; list = ++end) { + if (count > max_count) { + WOLFSSL_MSG("Too many curves in list"); + return -1; + } + while (*end != ':' && *end != '\0') end++; + len = end - list; /* end points to char after end + * of curve name so no need for -1 */ + if ((len < kNistCurves_MIN_NAME_LEN) || + (len > kNistCurves_MAX_NAME_LEN)) { + WOLFSSL_MSG("Unrecognized curve name in list"); + return -1; + } + for (nist_name = kNistCurves; nist_name->name != NULL; nist_name++) { + if (XSTRNCMP(list, nist_name->name, nist_name->name_len) == 0) { + break; + } + } + if (!nist_name->name_len) { + WOLFSSL_MSG("Unrecognized curve name in list"); + return -1; + } + groups[count++] = nist_name->nid; + if (*end == '\0') break; + } + + return count; +} + +int wolfSSL_CTX_set1_groups_list(WOLFSSL_CTX *ctx, char *list) +{ + int groups[WOLFSSL_MAX_GROUP_COUNT]; + int count; + + if (!ctx || !list) { + return WOLFSSL_FAILURE; + } + + if ((count = populate_groups(groups, + WOLFSSL_MAX_GROUP_COUNT, list)) == -1) { + return WOLFSSL_FAILURE; + } + + return wolfSSL_CTX_set_groups(ctx, groups, count) == WOLFSSL_SUCCESS ? + WOLFSSL_SUCCESS : WOLFSSL_FAILURE; +} + +int wolfSSL_set1_groups_list(WOLFSSL *ssl, char *list) +{ + int groups[WOLFSSL_MAX_GROUP_COUNT]; + int count; + + if (!ssl || !list) { + return WOLFSSL_FAILURE; + } + + if ((count = populate_groups(groups, + WOLFSSL_MAX_GROUP_COUNT, list)) == -1) { + return WOLFSSL_FAILURE; + } + + return wolfSSL_set_groups(ssl, groups, count) == WOLFSSL_SUCCESS ? + WOLFSSL_SUCCESS : WOLFSSL_FAILURE; +} +#endif /* defined(OPENSSL_EXTRA) && defined(HAVE_ECC) */ + #if !defined(WOLFSSL_NO_SERVER_GROUPS_EXT) /* Get the preferred key exchange group. * diff --git a/tests/api.c b/tests/api.c index 76d2f2310..2a090e6f5 100644 --- a/tests/api.c +++ b/tests/api.c @@ -28248,6 +28248,9 @@ static int test_tls13_apis(void) #endif int groups[1] = { WOLFSSL_ECC_X25519 }; int numGroups = 1; +#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) + char groupList[] = "P-521:P-384:P-256"; +#endif /* defined(OPENSSL_EXTRA) && defined(HAVE_ECC) */ #ifndef WOLFSSL_NO_TLS12 #ifndef NO_WOLFSSL_CLIENT @@ -28491,6 +28494,44 @@ static int test_tls13_apis(void) WOLFSSL_SUCCESS); #endif +#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) + AssertIntEQ(wolfSSL_CTX_set1_groups_list(NULL, NULL), WOLFSSL_FAILURE); +#ifndef NO_WOLFSSL_CLIENT + AssertIntEQ(wolfSSL_CTX_set1_groups_list(clientCtx, NULL), WOLFSSL_FAILURE); +#endif + AssertIntEQ(wolfSSL_CTX_set1_groups_list(NULL, groupList), WOLFSSL_FAILURE); +#ifndef NO_WOLFSSL_CLIENT +#ifndef WOLFSSL_NO_TLS12 + AssertIntEQ(wolfSSL_CTX_set1_groups_list(clientTls12Ctx, groupList), + WOLFSSL_FAILURE); +#endif + AssertIntEQ(wolfSSL_CTX_set1_groups_list(clientCtx, groupList), + WOLFSSL_SUCCESS); +#endif +#ifndef NO_WOLFSSL_SERVER + AssertIntEQ(wolfSSL_CTX_set1_groups_list(serverCtx, groupList), + WOLFSSL_SUCCESS); +#endif + + AssertIntEQ(wolfSSL_set1_groups_list(NULL, NULL), WOLFSSL_FAILURE); +#ifndef NO_WOLFSSL_CLIENT + AssertIntEQ(wolfSSL_set1_groups_list(clientSsl, NULL), WOLFSSL_FAILURE); +#endif + AssertIntEQ(wolfSSL_set1_groups_list(NULL, groupList), WOLFSSL_FAILURE); +#ifndef NO_WOLFSSL_CLIENT +#ifndef WOLFSSL_NO_TLS12 + AssertIntEQ(wolfSSL_set1_groups_list(clientTls12Ssl, groupList), + WOLFSSL_FAILURE); +#endif + AssertIntEQ(wolfSSL_set1_groups_list(clientSsl, groupList), + WOLFSSL_SUCCESS); +#endif +#ifndef NO_WOLFSSL_SERVER + AssertIntEQ(wolfSSL_set1_groups_list(serverSsl, groupList), + WOLFSSL_SUCCESS); +#endif +#endif /* defined(OPENSSL_EXTRA) && defined(HAVE_ECC) */ + #ifdef WOLFSSL_EARLY_DATA AssertIntEQ(wolfSSL_CTX_set_max_early_data(NULL, 0), BAD_FUNC_ARG); #ifndef NO_WOLFSSL_CLIENT diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 15701bb4a..a586184d7 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -4235,6 +4235,19 @@ static const byte server[SIZEOF_SENDER] = { 0x53, 0x52, 0x56, 0x52 }; static const byte tls_client[FINISHED_LABEL_SZ + 1] = "client finished"; static const byte tls_server[FINISHED_LABEL_SZ + 1] = "server finished"; +#define STR_SIZEOF(x) (sizeof(x) - 1) /* -1 to not count the null char */ + +#ifdef OPENSSL_EXTRA +typedef struct { + int name_len; + const char *name; + int nid; +} WOLF_EC_NIST_NAME; +extern const WOLF_EC_NIST_NAME kNistCurves[]; +/* This is the longest and shortest curve name in the kNistCurves list */ +#define kNistCurves_MIN_NAME_LEN 5 +#define kNistCurves_MAX_NAME_LEN 7 +#endif /* internal functions */ WOLFSSL_LOCAL int SendChangeCipher(WOLFSSL*); diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index b5d016117..a1e01a126 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -293,6 +293,9 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; /* wolfSSL does not support expoting keying material */ #define SSL_export_keying_material(...) 0 +#define SSL_CTX_set1_groups_list wolfSSL_CTX_set1_groups_list +#define SSL_set1_groups_list wolfSSL_set1_groups_list + #define SSL_set_ex_data wolfSSL_set_ex_data #define SSL_get_shutdown wolfSSL_get_shutdown #define SSL_set_rfd wolfSSL_set_rfd diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 356bf6185..000e8b856 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -859,6 +859,9 @@ WOLFSSL_API int wolfSSL_CTX_allow_post_handshake_auth(WOLFSSL_CTX* ctx); WOLFSSL_API int wolfSSL_allow_post_handshake_auth(WOLFSSL* ssl); WOLFSSL_API int wolfSSL_request_certificate(WOLFSSL* ssl); +WOLFSSL_API int wolfSSL_CTX_set1_groups_list(WOLFSSL_CTX *ctx, char *list); +WOLFSSL_API int wolfSSL_set1_groups_list(WOLFSSL *ssl, char *list); + WOLFSSL_API int wolfSSL_preferred_group(WOLFSSL* ssl); WOLFSSL_API int wolfSSL_CTX_set_groups(WOLFSSL_CTX* ctx, int* groups, int count); From 6ec136208cdbd2d1abe4342a844e574dc426a03a Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Fri, 31 Jan 2020 14:26:04 -0800 Subject: [PATCH 027/649] add sha256 hardware acceleration --- wolfcrypt/src/sha256.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index de49e3283..31a56ed36 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -544,6 +544,42 @@ static int InitSha256(wc_Sha256* sha256) #elif defined(WOLFSSL_DEVCRYPTO_HASH) /* implemented in wolfcrypt/src/port/devcrypto/devcrypt_hash.c */ +#elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_HASH) + #include "hal_data.h" + + #ifndef WOLFSSL_SCE_SHA256_HANDLE + #define WOLFSSL_SCE_SHA256_HANDLE g_sce_hash_0 + #endif + + #define XTRANSFORM(S, D) wc_Sha256SCE_XTRANSFORM((S), (D)) + static int wc_Sha256SCE_XTRANSFORM(wc_Sha256* sha256, const byte* data) + { + if (WOLFSSL_SCE_SHA256_HANDLE.p_api->hashUpdate(WOLFSSL_SCE_SHA256_HANDLE.p_ctrl, + (word32*)data, 8, sha256->digest) != SSP_SUCCESS) { + WOLFSSL_MSG("Unexpected hardware return value"); + return WC_HW_E; + } + return 0; + } + + + int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId) + { + int ret = 0; + if (sha256 == NULL) + return BAD_FUNC_ARG; + + sha256->heap = heap; + + ret = InitSha256(sha256); + if (ret != 0) + return ret; + + (void)devId; + + return ret; + } + #elif defined(WOLFSSL_ESP32WROOM32_CRYPT) && \ !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH) From 420e597c1683919f0b8e733efd8d6900f53b0aa7 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Sat, 1 Feb 2020 10:06:53 +0100 Subject: [PATCH 028/649] Move functions to ssl.c --- src/ssl.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/tls13.c | 79 ----------------------------------------------------- 2 files changed, 78 insertions(+), 79 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 4f7bb7bd3..945ac32e5 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -33134,6 +33134,84 @@ const char* wolfSSL_EC_curve_nid2nist(int nid) return NULL; } +#ifdef WOLFSSL_TLS13 +static int populate_groups(int* groups, int max_count, char *list) +{ + char *end; + size_t len; + int count = 0; + const WOLF_EC_NIST_NAME* nist_name; + + if (!groups || !list) { + return -1; + } + + for (end = list; ; list = ++end) { + if (count > max_count) { + WOLFSSL_MSG("Too many curves in list"); + return -1; + } + while (*end != ':' && *end != '\0') end++; + len = end - list; /* end points to char after end + * of curve name so no need for -1 */ + if ((len < kNistCurves_MIN_NAME_LEN) || + (len > kNistCurves_MAX_NAME_LEN)) { + WOLFSSL_MSG("Unrecognized curve name in list"); + return -1; + } + for (nist_name = kNistCurves; nist_name->name != NULL; nist_name++) { + if (XSTRNCMP(list, nist_name->name, nist_name->name_len) == 0) { + break; + } + } + if (!nist_name->name) { + WOLFSSL_MSG("Unrecognized curve name in list"); + return -1; + } + groups[count++] = nist_name->nid; + if (*end == '\0') break; + } + + return count; +} + +int wolfSSL_CTX_set1_groups_list(WOLFSSL_CTX *ctx, char *list) +{ + int groups[WOLFSSL_MAX_GROUP_COUNT]; + int count; + + if (!ctx || !list) { + return WOLFSSL_FAILURE; + } + + if ((count = populate_groups(groups, + WOLFSSL_MAX_GROUP_COUNT, list)) == -1) { + return WOLFSSL_FAILURE; + } + + return wolfSSL_CTX_set_groups(ctx, groups, count) == WOLFSSL_SUCCESS ? + WOLFSSL_SUCCESS : WOLFSSL_FAILURE; +} + +int wolfSSL_set1_groups_list(WOLFSSL *ssl, char *list) +{ + int groups[WOLFSSL_MAX_GROUP_COUNT]; + int count; + + if (!ssl || !list) { + return WOLFSSL_FAILURE; + } + + if ((count = populate_groups(groups, + WOLFSSL_MAX_GROUP_COUNT, list)) == -1) { + return WOLFSSL_FAILURE; + } + + return wolfSSL_set_groups(ssl, groups, count) == WOLFSSL_SUCCESS ? + WOLFSSL_SUCCESS : WOLFSSL_FAILURE; +} +#endif /* WOLFSSL_TLS13 */ + #endif /* HAVE_ECC */ #endif /* OPENSSL_EXTRA */ diff --git a/src/tls13.c b/src/tls13.c index 909406098..f9cbf86b8 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -8218,85 +8218,6 @@ int wolfSSL_request_certificate(WOLFSSL* ssl) } #endif /* !NO_CERTS && WOLFSSL_POST_HANDSHAKE_AUTH */ - -#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) -static int populate_groups(int* groups, int max_count, char *list) -{ - char *end; - size_t len; - int count = 0; - const WOLF_EC_NIST_NAME* nist_name; - - if (!groups || !list) { - return -1; - } - - for (end = list; ; list = ++end) { - if (count > max_count) { - WOLFSSL_MSG("Too many curves in list"); - return -1; - } - while (*end != ':' && *end != '\0') end++; - len = end - list; /* end points to char after end - * of curve name so no need for -1 */ - if ((len < kNistCurves_MIN_NAME_LEN) || - (len > kNistCurves_MAX_NAME_LEN)) { - WOLFSSL_MSG("Unrecognized curve name in list"); - return -1; - } - for (nist_name = kNistCurves; nist_name->name != NULL; nist_name++) { - if (XSTRNCMP(list, nist_name->name, nist_name->name_len) == 0) { - break; - } - } - if (!nist_name->name_len) { - WOLFSSL_MSG("Unrecognized curve name in list"); - return -1; - } - groups[count++] = nist_name->nid; - if (*end == '\0') break; - } - - return count; -} - -int wolfSSL_CTX_set1_groups_list(WOLFSSL_CTX *ctx, char *list) -{ - int groups[WOLFSSL_MAX_GROUP_COUNT]; - int count; - - if (!ctx || !list) { - return WOLFSSL_FAILURE; - } - - if ((count = populate_groups(groups, - WOLFSSL_MAX_GROUP_COUNT, list)) == -1) { - return WOLFSSL_FAILURE; - } - - return wolfSSL_CTX_set_groups(ctx, groups, count) == WOLFSSL_SUCCESS ? - WOLFSSL_SUCCESS : WOLFSSL_FAILURE; -} - -int wolfSSL_set1_groups_list(WOLFSSL *ssl, char *list) -{ - int groups[WOLFSSL_MAX_GROUP_COUNT]; - int count; - - if (!ssl || !list) { - return WOLFSSL_FAILURE; - } - - if ((count = populate_groups(groups, - WOLFSSL_MAX_GROUP_COUNT, list)) == -1) { - return WOLFSSL_FAILURE; - } - - return wolfSSL_set_groups(ssl, groups, count) == WOLFSSL_SUCCESS ? - WOLFSSL_SUCCESS : WOLFSSL_FAILURE; -} -#endif /* defined(OPENSSL_EXTRA) && defined(HAVE_ECC) */ - #if !defined(WOLFSSL_NO_SERVER_GROUPS_EXT) /* Get the preferred key exchange group. * From cc2bf03e7378463d1ebf05a1ed73338f1f315c6c Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Fri, 24 Jan 2020 10:40:39 -0800 Subject: [PATCH 029/649] Client using common read and write func --- examples/client/client.c | 117 +++++---------------------------------- 1 file changed, 13 insertions(+), 104 deletions(-) diff --git a/examples/client/client.c b/examples/client/client.c index 85d082574..61335aba7 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -768,7 +768,7 @@ static int SMTP_Shutdown(WOLFSSL* ssl, int wc_shutdown) return WOLFSSL_SUCCESS; } -static void ClientWrite(WOLFSSL* ssl, char* msg, int msgSz) +static void ClientWrite(WOLFSSL* ssl, char* msg, int msgSz, const char* str) { int ret, err; char buffer[WOLFSSL_MAX_ERROR_SZ]; @@ -791,13 +791,14 @@ static void ClientWrite(WOLFSSL* ssl, char* msg, int msgSz) #endif ); if (ret != msgSz) { - printf("SSL_write msg error %d, %s\n", err, + printf("SSL_write%s msg error %d, %s\n", str, err, wolfSSL_ERR_error_string(err, buffer)); err_sys("SSL_write failed"); } } -static void ClientRead(WOLFSSL* ssl, char* reply, int replyLen, int mustRead) +static void ClientRead(WOLFSSL* ssl, char* reply, int replyLen, int mustRead, + const char* str) { int ret, err; char buffer[WOLFSSL_MAX_ERROR_SZ]; @@ -837,7 +838,7 @@ static void ClientRead(WOLFSSL* ssl, char* reply, int replyLen, int mustRead) ); if (ret > 0) { reply[ret] = 0; - printf("%s\n", reply); + printf("%s%s\n", str, reply); } } @@ -3000,16 +3001,16 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) wolfSSL_update_keys(ssl); #endif - ClientWrite(ssl, msg, msgSz); + ClientWrite(ssl, msg, msgSz, ""); - ClientRead(ssl, reply, sizeof(reply)-1, 1); + ClientRead(ssl, reply, sizeof(reply)-1, 1, ""); #if defined(WOLFSSL_TLS13) if (updateKeysIVs || postHandAuth) - ClientWrite(ssl, msg, msgSz); + ClientWrite(ssl, msg, msgSz, ""); #endif if (sendGET) { /* get html */ - ClientRead(ssl, reply, sizeof(reply)-1, 0); + ClientRead(ssl, reply, sizeof(reply)-1, 0, ""); } #ifndef NO_SESSION_CACHE @@ -3251,104 +3252,12 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) } #endif /* HAVE_SECURE_RENEGOTIATION */ - do { - err = 0; /* reset error */ - ret = wolfSSL_write(sslResume, resumeMsg, resumeSz); - if (ret <= 0) { - err = wolfSSL_get_error(sslResume, 0); - #ifdef WOLFSSL_ASYNC_CRYPT - if (err == WC_PENDING_E) { - ret = wolfSSL_AsyncPoll(sslResume, WOLF_POLL_FLAG_CHECK_HW); - if (ret < 0) break; - } - #endif - } - } while (err == WC_PENDING_E); - if (ret != resumeSz) { - printf("SSL_write resume error %d, %s\n", err, - wolfSSL_ERR_error_string(err, buffer)); - wolfSSL_free(sslResume); sslResume = NULL; - wolfSSL_CTX_free(ctx); ctx = NULL; - err_sys("SSL_write failed"); - } - - if (nonBlocking) { - /* give server a chance to bounce a message back to client */ - #ifdef USE_WINDOWS_API - Sleep(500); - #elif defined(WOLFSSL_TIRTOS) - Task_sleep(1); - #else - sleep(1); - #endif - } - - do { - err = 0; /* reset error */ - ret = wolfSSL_read(sslResume, reply, sizeof(reply)-1); - if (ret <= 0) { - err = wolfSSL_get_error(sslResume, 0); - #ifdef WOLFSSL_ASYNC_CRYPT - if (err == WC_PENDING_E) { - ret = wolfSSL_AsyncPoll(sslResume, WOLF_POLL_FLAG_CHECK_HW); - if (ret < 0) break; - } - #endif - } - } while (err == WC_PENDING_E); - if (ret > 0) { - reply[ret] = 0; - printf("Server resume response: %s\n", reply); - - if (sendGET) { /* get html */ - while (1) { - do { - err = 0; /* reset error */ - ret = wolfSSL_read(sslResume, reply, sizeof(reply)-1); - if (ret <= 0) { - err = wolfSSL_get_error(sslResume, 0); - #ifdef WOLFSSL_ASYNC_CRYPT - if (err == WC_PENDING_E) { - ret = wolfSSL_AsyncPoll(sslResume, - WOLF_POLL_FLAG_CHECK_HW); - if (ret < 0) break; - } - #endif - } - } while (err == WC_PENDING_E); - if (ret > 0) { - reply[ret] = 0; - printf("%s\n", reply); - } - else - break; - } - } - } - if (ret < 0) { - if (err != WOLFSSL_ERROR_WANT_READ) { - printf("SSL_read resume error %d, %s\n", err, - wolfSSL_ERR_error_string(err, buffer)); - wolfSSL_free(sslResume); sslResume = NULL; - wolfSSL_CTX_free(ctx); ctx = NULL; - err_sys("SSL_read failed"); - } - } + ClientWrite(sslResume, resumeMsg, resumeSz, " resume"); + ClientRead(sslResume, reply, sizeof(reply)-1, sendGET, + "Server resume: "); /* try to send session break */ - do { - err = 0; /* reset error */ - ret = wolfSSL_write(sslResume, msg, msgSz); - if (ret <= 0) { - err = wolfSSL_get_error(sslResume, 0); - #ifdef WOLFSSL_ASYNC_CRYPT - if (err == WC_PENDING_E) { - ret = wolfSSL_AsyncPoll(sslResume, WOLF_POLL_FLAG_CHECK_HW); - if (ret < 0) break; - } - #endif - } - } while (err == WC_PENDING_E); + ClientWrite(sslResume, msg, msgSz, " resume 2"); ret = wolfSSL_shutdown(sslResume); if (wc_shutdown && ret == WOLFSSL_SHUTDOWN_NOT_DONE) From 967235c1f313a578c7241a6fa18b059ed53bf4c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Otto=20Kek=C3=A4l=C3=A4inen?= Date: Mon, 3 Feb 2020 20:14:40 +0200 Subject: [PATCH 030/649] Wrap JavaScript source on multiple lines to make it readable Closes: wolfSSL/wolfssl#2783 --- doc/formats/html/html_changes/menu.js | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/doc/formats/html/html_changes/menu.js b/doc/formats/html/html_changes/menu.js index 9b399756a..670f059d4 100644 --- a/doc/formats/html/html_changes/menu.js +++ b/doc/formats/html/html_changes/menu.js @@ -5,9 +5,32 @@ function initMenu(relPath,searchEnabled,serverSide,searchPage,search) { result+='
    '; if (searchEnabled) { if (serverSide) { - result+=''; + result += ''; } else { - result+=''; + result += ''; } } for (var i in data.children) { From b67fd249e26cead2200b713eafa7e756b6c1a93c Mon Sep 17 00:00:00 2001 From: Tesfa Mael Date: Tue, 14 Jan 2020 12:02:49 -0800 Subject: [PATCH 031/649] Fix for cppcheck --- IDE/GCC-ARM/Source/armtarget.c | 28 +++++++------- .../Projects/benchmark/current_time.c | 6 +-- src/ssl.c | 11 +++++- src/tls.c | 8 ++-- tests/api.c | 9 +++++ wolfcrypt/src/asn.c | 1 + wolfcrypt/src/fe_operations.c | 38 +++++++++---------- 7 files changed, 61 insertions(+), 40 deletions(-) diff --git a/IDE/GCC-ARM/Source/armtarget.c b/IDE/GCC-ARM/Source/armtarget.c index bee828faa..8b276463f 100644 --- a/IDE/GCC-ARM/Source/armtarget.c +++ b/IDE/GCC-ARM/Source/armtarget.c @@ -142,20 +142,20 @@ void HardFault_HandlerC( uint32_t *hardfault_args ) _BFAR = (*((volatile uint32_t *)(0xE000ED38))); printf ("\n\nHard fault handler (all numbers in hex):\n"); - printf ("R0 = %lx\n", (unsigned long)stacked_r0); - printf ("R1 = %lx\n", (unsigned long)stacked_r1); - printf ("R2 = %lx\n", (unsigned long)stacked_r2); - printf ("R3 = %lx\n", (unsigned long)stacked_r3); - printf ("R12 = %lx\n", (unsigned long)stacked_r12); - printf ("LR [R14] = %lx subroutine call return address\n", (unsigned long)stacked_lr); - printf ("PC [R15] = %lx program counter\n", (unsigned long)stacked_pc); - printf ("PSR = %lx\n", (unsigned long)stacked_psr); - printf ("CFSR = %lx\n", (unsigned long)_CFSR); - printf ("HFSR = %lx\n", (unsigned long)_HFSR); - printf ("DFSR = %lx\n", (unsigned long)_DFSR); - printf ("AFSR = %lx\n", (unsigned long)_AFSR); - printf ("MMAR = %lx\n", (unsigned long)_MMAR); - printf ("BFAR = %lx\n", (unsigned long)_BFAR); + printf ("R0 = %ux\n", stacked_r0); + printf ("R1 = %ux\n", stacked_r1); + printf ("R2 = %ux\n", stacked_r2); + printf ("R3 = %ux\n", stacked_r3); + printf ("R12 = %ux\n", stacked_r12); + printf ("LR [R14] = %ux subroutine call return address\n", stacked_lr); + printf ("PC [R15] = %ux program counter\n", stacked_pc); + printf ("PSR = %ux\n", stacked_psr); + printf ("CFSR = %ux\n", _CFSR); + printf ("HFSR = %ux\n", _HFSR); + printf ("DFSR = %ux\n", _DFSR); + printf ("AFSR = %ux\n", _AFSR); + printf ("MMAR = %ux\n", _MMAR); + printf ("BFAR = %ux\n", _BFAR); // Break into the debugger __asm("BKPT #0\n"); diff --git a/IDE/IAR-EWARM/Projects/benchmark/current_time.c b/IDE/IAR-EWARM/Projects/benchmark/current_time.c index cbe6bae39..1e96a0bca 100644 --- a/IDE/IAR-EWARM/Projects/benchmark/current_time.c +++ b/IDE/IAR-EWARM/Projects/benchmark/current_time.c @@ -64,10 +64,10 @@ double current_time(int reset) /* dummy */ double current_time(int reset) { - static double t; + static double t; t += 1.0; /* for avoid infinite loop of waiting time */ if(reset)t = 0.0; - return t ; -} + return t ; +} #endif diff --git a/src/ssl.c b/src/ssl.c index 83526a074..7ff1b9c41 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -19379,7 +19379,8 @@ void wolfSSL_ACCESS_DESCRIPTION_free(WOLFSSL_ACCESS_DESCRIPTION* access) wolfSSL_ASN1_OBJECT_free(access->method); if (access->location) wolfSSL_GENERAL_NAME_free(access->location); - access = NULL; + + /* access = NULL, don't try to access or double free it */ } #endif @@ -30144,6 +30145,8 @@ void wolfSSL_DSA_free(WOLFSSL_DSA* dsa) InitwolfSSL_DSA(dsa); /* set back to NULLs for safety */ XFREE(dsa, NULL, DYNAMIC_TYPE_DSA); + + /* dsa = NULL, don't try to access or double free it */ } } @@ -33324,6 +33327,7 @@ void wolfSSL_EC_KEY_free(WOLFSSL_EC_KEY *key) InitwolfSSL_ECKey(key); /* set back to NULLs for safety */ XFREE(key, NULL, DYNAMIC_TYPE_ECC); + /* key = NULL, don't try to access or double free it */ } } #endif /* HAVE_ECC && (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) */ @@ -33608,6 +33612,7 @@ void wolfSSL_EC_GROUP_free(WOLFSSL_EC_GROUP *group) WOLFSSL_ENTER("wolfSSL_EC_GROUP_free"); XFREE(group, NULL, DYNAMIC_TYPE_ECC); + /* group = NULL, don't try to access or double free it */ } #endif @@ -34124,6 +34129,7 @@ void wolfSSL_EC_POINT_free(WOLFSSL_EC_POINT *p) p->inSet = p->exSet = 0; XFREE(p, NULL, DYNAMIC_TYPE_ECC); + /* p = NULL, don't try to access or double free it */ } } #endif @@ -47190,6 +47196,7 @@ void wolfSSL_BN_free(WOLFSSL_BIGNUM* bn) bn->internal = NULL; } XFREE(bn, NULL, DYNAMIC_TYPE_BIGINT); + /* bn = NULL, don't try to access or double free it */ } } @@ -47263,6 +47270,8 @@ void wolfSSL_RSA_free(WOLFSSL_RSA* rsa) InitwolfSSL_Rsa(rsa); /* set back to NULLs for safety */ XFREE(rsa, NULL, DYNAMIC_TYPE_RSA); + + /* rsa = NULL, don't try to access or double free it */ } } diff --git a/src/tls.c b/src/tls.c index dc5bdf5a6..531e0f15b 100644 --- a/src/tls.c +++ b/src/tls.c @@ -137,7 +137,7 @@ static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions); const byte *cr,const byte *sr, byte *ms/* out */); int tsip_generateSeesionKey(WOLFSSL *ssl); - int tsip_generateVerifyData(const byte *ms, const byte *side, + int tsip_generateVerifyData(const byte *ms, const byte *side, const byte *handshake_hash, byte *hashes /* out */); #endif @@ -1194,10 +1194,10 @@ int TLS_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz, int padSz, !defined(NO_WOLFSSL_RENESAS_TSIP_TLS_SESSION) if (tsip_useable(ssl)) { if (ssl->specs.hash_size == WC_SHA_DIGEST_SIZE) - ret = tsip_Sha1Hmac(ssl, myInner, WOLFSSL_TLS_HMAC_INNER_SZ, + ret = tsip_Sha1Hmac(ssl, myInner, WOLFSSL_TLS_HMAC_INNER_SZ, in, sz, digest, verify); else if (ssl->specs.hash_size == WC_SHA256_DIGEST_SIZE) - ret = tsip_Sha256Hmac(ssl, myInner, WOLFSSL_TLS_HMAC_INNER_SZ, + ret = tsip_Sha256Hmac(ssl, myInner, WOLFSSL_TLS_HMAC_INNER_SZ, in, sz, digest, verify); else ret = TSIP_MAC_DIGSZ_E; @@ -5574,6 +5574,8 @@ int TLSX_UseQSHScheme(TLSX** extensions, word16 name, byte* pKey, word16 pkeySz, if (extensions == NULL || (pKey == NULL && pkeySz != 0)) return BAD_FUNC_ARG; + extension = TLSX_Find(*extensions, TLSX_QUANTUM_SAFE_HYBRID); + /* if scheme is implemented than add */ if (TLSX_HaveQSHScheme(name)) { if ((ret = TLSX_QSH_Append(&format, name, pKey, pkeySz)) != 0) diff --git a/tests/api.c b/tests/api.c index 5533065a9..135d50e5e 100644 --- a/tests/api.c +++ b/tests/api.c @@ -2175,6 +2175,9 @@ static THREAD_RETURN WOLFSSL_THREAD test_server_nofail(void* args) int ret, err = 0; int sharedCtx = 0; + if (args) + return -1; + #ifdef WOLFSSL_TIRTOS fdOpenSession(Task_self()); #endif @@ -2397,6 +2400,9 @@ static THREAD_RETURN WOLFSSL_THREAD test_server_loop(void* args) int loop_count = ((func_args*)args)->argc; int count = 0; + if (args) + return -1; + #ifdef WOLFSSL_TIRTOS fdOpenSession(Task_self()); #endif @@ -2993,6 +2999,9 @@ static THREAD_RETURN WOLFSSL_THREAD run_wolfssl_server(void* args) int idx; int ret, err = 0; + if (args) + return -1; + #ifdef WOLFSSL_TIRTOS fdOpenSession(Task_self()); #endif diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 564190803..9cd7839b7 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -10041,6 +10041,7 @@ int wc_EncryptedInfoParse(EncryptedInfo* info, char** pBuffer, size_t bufSz) newline = SkipEndOfLineChars(newline, bufferEnd); /* return new headerEnd */ + *pBuffer = newline; } diff --git a/wolfcrypt/src/fe_operations.c b/wolfcrypt/src/fe_operations.c index c3baecefd..1e1c92bf2 100644 --- a/wolfcrypt/src/fe_operations.c +++ b/wolfcrypt/src/fe_operations.c @@ -134,16 +134,16 @@ int curve25519(byte* q, byte* n, byte* p) #if 0 unsigned char e[32]; #endif - fe x1; - fe x2; - fe z2; - fe x3; - fe z3; - fe tmp0; - fe tmp1; - int pos; - unsigned int swap; - unsigned int b; + fe x1 = {0}; + fe x2 = {0}; + fe z2 = {0}; + fe x3 = {0}; + fe z3 = {0}; + fe tmp0 = {0}; + fe tmp1 = {0}; + int pos = 0; + unsigned int swap = 0; + unsigned int b = 0; /* Clamp already done during key generation and import */ #if 0 @@ -645,11 +645,11 @@ void fe_frombytes(fe h,const unsigned char *s) void fe_invert(fe out,const fe z) { - fe t0; - fe t1; - fe t2; - fe t3; - int i; + fe t0 = {0}; + fe t1 = {0}; + fe t2 = {0}; + fe t3 = {0}; + int i = 0; /* pow225521 */ fe_sq(t0,z); for (i = 1;i < 1;++i) fe_sq(t0,t0); @@ -1263,10 +1263,10 @@ void fe_sq2(fe h,const fe f) void fe_pow22523(fe out,const fe z) { - fe t0; - fe t1; - fe t2; - int i; + fe t0 = {0}; + fe t1 = {0}; + fe t2 = {0}; + int i = 0; fe_sq(t0,z); for (i = 1;i < 1;++i) fe_sq(t0,t0); fe_sq(t1,t0); for (i = 1;i < 2;++i) fe_sq(t1,t1); From e664a4f2066ffea6adaf5ffdad479fad065c1fed Mon Sep 17 00:00:00 2001 From: Tesfa Mael Date: Fri, 24 Jan 2020 18:13:20 -0800 Subject: [PATCH 032/649] Review comments --- tests/api.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/tests/api.c b/tests/api.c index 135d50e5e..4fa095e18 100644 --- a/tests/api.c +++ b/tests/api.c @@ -2175,9 +2175,6 @@ static THREAD_RETURN WOLFSSL_THREAD test_server_nofail(void* args) int ret, err = 0; int sharedCtx = 0; - if (args) - return -1; - #ifdef WOLFSSL_TIRTOS fdOpenSession(Task_self()); #endif @@ -2261,7 +2258,7 @@ static THREAD_RETURN WOLFSSL_THREAD test_server_nofail(void* args) #ifdef WOLFSSL_SESSION_EXPORT /* only add in more complex nonblocking case with session export tests */ - if (((func_args*)args)->argc > 0) { + if (args && ((func_args*)args)->argc > 0) { /* set as nonblock and time out for waiting on read/write */ tcp_set_nonblocking(&clientfd); wolfSSL_dtls_set_using_nonblock(ssl, 1); @@ -2400,9 +2397,6 @@ static THREAD_RETURN WOLFSSL_THREAD test_server_loop(void* args) int loop_count = ((func_args*)args)->argc; int count = 0; - if (args) - return -1; - #ifdef WOLFSSL_TIRTOS fdOpenSession(Task_self()); #endif @@ -2999,9 +2993,6 @@ static THREAD_RETURN WOLFSSL_THREAD run_wolfssl_server(void* args) int idx; int ret, err = 0; - if (args) - return -1; - #ifdef WOLFSSL_TIRTOS fdOpenSession(Task_self()); #endif From b8b0b7da031b77ec44fa11c028bde0dc6e23e471 Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Tue, 4 Feb 2020 10:07:26 -0700 Subject: [PATCH 033/649] add Android debug for logcat --- wolfcrypt/src/logging.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/wolfcrypt/src/logging.c b/wolfcrypt/src/logging.c index e29460e1c..909062705 100644 --- a/wolfcrypt/src/logging.c +++ b/wolfcrypt/src/logging.c @@ -218,6 +218,8 @@ void WOLFSSL_TIME(int count) #elif defined(WOLFSSL_TELIT_M2MB) #include #include "m2m_log.h" +#elif defined(WOLFSSL_ANDROID_DEBUG) + #include #else #include /* for default printf stuff */ #endif @@ -260,6 +262,8 @@ static void wolfssl_log(const int logLevel, const char *const logMessage) printk("%s\n", logMessage); #elif defined(WOLFSSL_TELIT_M2MB) M2M_LOG_INFO("%s\n", logMessage); +#elif defined(WOLFSSL_ANDROID_DEBUG) + __android_log_print(ANDROID_LOG_VERBOSE, "[wolfSSL]", "%s", logMessage); #else fprintf(stderr, "%s\n", logMessage); #endif From b7d772700a416efa16b690b519387cbb86fef2c6 Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Tue, 4 Feb 2020 16:03:45 -0800 Subject: [PATCH 034/649] update sha256 support for endian --- wolfcrypt/src/sha256.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index 31a56ed36..cc2a1a280 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -551,14 +551,29 @@ static int InitSha256(wc_Sha256* sha256) #define WOLFSSL_SCE_SHA256_HANDLE g_sce_hash_0 #endif + #define WC_SHA256_DIGEST_WORD_SIZE 16 #define XTRANSFORM(S, D) wc_Sha256SCE_XTRANSFORM((S), (D)) static int wc_Sha256SCE_XTRANSFORM(wc_Sha256* sha256, const byte* data) { + if (g_sce.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_LITTLE) + { + ByteReverseWords((word32*)data, (word32*)data, WC_SHA256_BLOCK_SIZE); + ByteReverseWords(sha256->digest, sha256->digest, WC_SHA256_DIGEST_SIZE); + } + if (WOLFSSL_SCE_SHA256_HANDLE.p_api->hashUpdate(WOLFSSL_SCE_SHA256_HANDLE.p_ctrl, - (word32*)data, 8, sha256->digest) != SSP_SUCCESS) { + (word32*)data, WC_SHA256_DIGEST_WORD_SIZE, + sha256->digest) != SSP_SUCCESS) { WOLFSSL_MSG("Unexpected hardware return value"); return WC_HW_E; } + + if (g_sce.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_LITTLE) + { + ByteReverseWords((word32*)data, (word32*)data, WC_SHA256_BLOCK_SIZE); + ByteReverseWords(sha256->digest, sha256->digest, WC_SHA256_DIGEST_SIZE); + } + return 0; } From e75b1b5cb938e68dbce8f9104c50d485d7e70a1b Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Tue, 4 Feb 2020 16:10:20 -0800 Subject: [PATCH 035/649] add suport for AES acceleration --- IDE/Renesas/e2studio/DK-S7G2/README.md | 54 +++--- IDE/Renesas/e2studio/DK-S7G2/user_settings.h | 19 ++- wolfcrypt/src/aes.c | 165 ++++++++++++++++++- wolfcrypt/src/wc_port.c | 8 +- 4 files changed, 213 insertions(+), 33 deletions(-) diff --git a/IDE/Renesas/e2studio/DK-S7G2/README.md b/IDE/Renesas/e2studio/DK-S7G2/README.md index 4c999418e..211a054e0 100644 --- a/IDE/Renesas/e2studio/DK-S7G2/README.md +++ b/IDE/Renesas/e2studio/DK-S7G2/README.md @@ -1,27 +1,29 @@ - -## Building wolfSSL For DK-S7G2 - -- First physically toggle the ENET1 and JTAG switch to on with the DK-S7G2 board. -- Open e2studio and set the workspace to be wolfssl-X.X.X/IDE/Renesas/e2studio/DK-S7G2/ -- Create a Synergy library project named wolfssl "File->New->Synergy C/C++ Project", "Renesas Synergy C Library Project" then "Next", set wolfssl as the "Project Name" then "Next", set Board to "S7G2 DK" then "Next", finally select the BSP radius and click "Finish" -- Copy configuration.xml and .project from wolfssl-X.X.X/IDE/Renesas/e2studio/DK-S7G2/wolfssl-template-project/ into the wolfssl-X.X.X/IDE/Renesas/e2studio/DK-S7G2/wolfssl directory -- (optional but necessary for production) Add TRNG support by clicking on Threads tab and highlight HAL/Common click "New Stack > Driver > Crypto > TRNG Driver on r_sce_trng". Then uncomment WOLFSSL_SCE define in wolfssl project src/user_settings.h -- Generate the changes by clicking on "Generate Project Content" -- Exclude src/wolfcrypt/port and all src/wolfcrypt/*.S and src/wolfcrypt/*.asm files from the build -- Exclude src/wolfcrypt/evp.c, src/wolfcrypt/misc.c and src/wolfssl/bio.c -- Set the Preprocessor define in wolfssl proejct to have WOLFSSL_USER_SETTINGS. Right click on wolfssl project "Properties -> C/C++ Build -> GNU ARM Cross C Compiler -> Preprocessor" add WOLFSSL_USER_SETTINGS under "Defined symbols" -- Set include to wolfssl directory. Right click on project "Properties -> C/C++Build -> GNU ARM Cross Compiler -> Includes". Add "${ProjDirPath}/../../../../.." and "${ProjDirPath}/../" -- Build wolfssl by right clicking on wolfssl project and selecting "Build Project" - -## Example Projects and Building - -- Create a new Synergy project "Renesas Synergy C Project Using Synergy Library" -- Set it to use the wolfssl library -- Copy in the .cproject, .project and source file from the template desired i.e. wolfssl-X.X.X/IDE/Renesas/e2studio/DK-S7G2/wolfcrypttest-template/ -- Right click on the created project and select "Build Project" - -The example_server loops looking to accept connections and closes immediatly after a successful connection was made. - -The benchmark example tries to do a TCP connection to SERVER_IP on port 11112 and a TLS connection to SERVER_IP on port 11111 then does wolfCrypt benchmark collection. - + +## Building wolfSSL For DK-S7G2 + +- First physically toggle the ENET1 and JTAG switch to on with the DK-S7G2 board. +- Open e2studio and set the workspace to be wolfssl-X.X.X/IDE/Renesas/e2studio/DK-S7G2/ +- Create a Synergy library project named wolfssl "File->New->Synergy C/C++ Project", "Renesas Synergy C Library Project" then "Next", set wolfssl as the "Project Name" then "Next", set Board to "S7G2 DK" then "Next", finally select the BSP radius and click "Finish" +- Copy configuration.xml and .project from wolfssl-X.X.X/IDE/Renesas/e2studio/DK-S7G2/wolfssl-template-project/ into the wolfssl-X.X.X/IDE/Renesas/e2studio/DK-S7G2/wolfssl directory +- (optional but necessary for production) Add TRNG support by clicking on Threads tab and highlight HAL/Common click "New Stack > Driver > Crypto > TRNG Driver on r_sce_trng". Then comment out WOLFSSL_SCE_NO_TRNG define in wolfssl project src/user_settings.h +- (optional SHA acceleration) Add HASH support by clicking on Threads tab and highlight HAL/Common click "New Stack > Driver > Crypto > HASH Driver on r_sce_hash". Then uncomment WOLFSSL_SCE_NO_HASH define in wolfssl project src/user_settings.h +- (optional AES acceleration) Add the stacks for AES128, AES192, and AES256. Click on Threads tab and highlight HAL/Common click "New Stack > Driver > Crypto > AES Driver on r_sce_aes". Add three one for each key size and rename them to g_sce_aes_256, g_sce_aes_192, and g_sce_aes_128. Changing each to ECB chaining mode and the key length that matches the name. +- Generate the changes by clicking on "Generate Project Content" +- Exclude src/wolfcrypt/port and all src/wolfcrypt/*.S and src/wolfcrypt/*.asm files from the build +- Exclude src/wolfcrypt/evp.c, src/wolfcrypt/misc.c and src/wolfssl/bio.c +- Set the Preprocessor define in wolfssl proejct to have WOLFSSL_USER_SETTINGS. Right click on wolfssl project "Properties -> C/C++ Build -> GNU ARM Cross C Compiler -> Preprocessor" add WOLFSSL_USER_SETTINGS under "Defined symbols" +- Set include to wolfssl directory. Right click on project "Properties -> C/C++Build -> GNU ARM Cross Compiler -> Includes". Add "${ProjDirPath}/../../../../.." and "${ProjDirPath}/../" +- Build wolfssl by right clicking on wolfssl project and selecting "Build Project" + +## Example Projects and Building + +- Create a new Synergy project "Renesas Synergy C Project Using Synergy Library" +- Set it to use the wolfssl library +- Copy in the .cproject, .project and source file from the template desired i.e. wolfssl-X.X.X/IDE/Renesas/e2studio/DK-S7G2/wolfcrypttest-template/ +- Right click on the created project and select "Build Project" + +The example_server loops looking to accept connections and closes immediatly after a successful connection was made. + +The benchmark example tries to do a TCP connection to SERVER_IP on port 11112 and a TLS connection to SERVER_IP on port 11111 then does wolfCrypt benchmark collection. + The wolfcryptest runs through all of the unit tests from wolfcrypt/test/test.c \ No newline at end of file diff --git a/IDE/Renesas/e2studio/DK-S7G2/user_settings.h b/IDE/Renesas/e2studio/DK-S7G2/user_settings.h index ad58cd67f..cdebbd445 100644 --- a/IDE/Renesas/e2studio/DK-S7G2/user_settings.h +++ b/IDE/Renesas/e2studio/DK-S7G2/user_settings.h @@ -12,9 +12,19 @@ #define SYNERGY_CYCLE_COUNT #define BENCH_EMBEDDED -/* Use TRNG */ -//#define WOLFSSL_SCE -#ifndef WOLFSSL_SCE +/* Use turn on all SCE acceleration */ +#define WOLFSSL_SCE + +/* Used to turn off TRNG */ +#define WOLFSSL_SCE_NO_TRNG + +/* Used to turn off AES hardware acc. */ +#define WOLFSSL_SCE_NO_AES + +/* Used to turn off HASH hardware acc. */ +#define WOLFSSL_SCE_NO_HASH + +#if defined(WOLFSSL_SCE_NO_TRNG) /* use unsafe test seed if TRNG not used (not for production) */ #define WOLFSSL_GENSEED_FORTEST #endif @@ -27,6 +37,9 @@ #define HAVE_ONE_TIME_AUTH #define HAVE_AESGCM +#define HAVE_AES_ECB +#define WOLFSSL_AES_DIRECT + #define USE_FAST_MATH #define TFM_TIMING_RESISTANT diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 946fae4fe..10a46ce12 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -772,6 +772,132 @@ #elif defined(WOLFSSL_AFALG) #elif defined(WOLFSSL_DEVCRYPTO_AES) + +#elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES) + #include "hal_data.h" + + #ifndef WOLFSSL_SCE_AES256_HANDLE + #define WOLFSSL_SCE_AES256_HANDLE g_sce_aes_256 + #endif + + #ifndef WOLFSSL_SCE_AES192_HANDLE + #define WOLFSSL_SCE_AES192_HANDLE g_sce_aes_192 + #endif + + #ifndef WOLFSSL_SCE_AES128_HANDLE + #define WOLFSSL_SCE_AES128_HANDLE g_sce_aes_128 + #endif + + static int AES_ECB_encrypt(Aes* aes, const byte* inBlock, byte* outBlock, int sz) + { + uint32_t ret; + + if (g_sce.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_BIG) { + ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz); + } + + switch (aes->keylen) { + #ifdef WOLFSSL_AES_128 + case AES_128_KEY_SIZE: + ret = WOLFSSL_SCE_AES128_HANDLE.p_api->encrypt(WOLFSSL_SCE_AES128_HANDLE.p_ctrl, aes->key, + NULL, (sz / sizeof(word32)), + (word32*)inBlock, (word32*)outBlock); + break; + #endif + #ifdef WOLFSSL_AES_192 + case AES_192_KEY_SIZE: + ret = WOLFSSL_SCE_AES192_HANDLE.p_api->encrypt(WOLFSSL_SCE_AES192_HANDLE.p_ctrl, aes->key, + NULL, (sz / sizeof(word32)), + (word32*)inBlock, (word32*)outBlock); + break; + #endif + #ifdef WOLFSSL_AES_256 + case AES_256_KEY_SIZE: + ret = WOLFSSL_SCE_AES256_HANDLE.p_api->encrypt(WOLFSSL_SCE_AES256_HANDLE.p_ctrl, aes->key, + NULL, (sz / sizeof(word32)), + (word32*)inBlock, (word32*)outBlock); + break; + #endif + default: + WOLFSSL_MSG("Unknown key size"); + return BAD_FUNC_ARG; + } + + if (ret != SSP_SUCCESS) { + ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz); /* revert input*/ + return WC_HW_E; + } + + if (g_sce.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_BIG) { + ByteReverseWords((word32*)outBlock, (word32*)outBlock, sz); + if (inBlock != outBlock) { + ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz); /* revert input*/ + } + } + return 0; + } + + #if defined(HAVE_AES_DECRYPT) + static int AES_ECB_decrypt(Aes* aes, const byte* inBlock, byte* outBlock, int sz) + { + uint32_t ret; + + if (g_sce.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_BIG) { + ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz); + } + + switch (aes->keylen) { + #ifdef WOLFSSL_AES_128 + case AES_128_KEY_SIZE: + ret = WOLFSSL_SCE_AES128_HANDLE.p_api->decrypt(WOLFSSL_SCE_AES128_HANDLE.p_ctrl, aes->key, aes->reg, + (sz / sizeof(word32)), (word32*)inBlock, (word32*)outBlock); + break; + #endif + #ifdef WOLFSSL_AES_192 + case AES_192_KEY_SIZE: + ret = WOLFSSL_SCE_AES192_HANDLE.p_api->decrypt(WOLFSSL_SCE_AES192_HANDLE.p_ctrl, aes->key, aes->reg, + (sz / sizeof(word32)), (word32*)inBlock, (word32*)outBlock); + break; + #endif + #ifdef WOLFSSL_AES_256 + case AES_256_KEY_SIZE: + ret = WOLFSSL_SCE_AES256_HANDLE.p_api->decrypt(WOLFSSL_SCE_AES256_HANDLE.p_ctrl, aes->key, aes->reg, + (sz / sizeof(word32)), (word32*)inBlock, (word32*)outBlock); + break; + #endif + default: + WOLFSSL_MSG("Unknown key size"); + return BAD_FUNC_ARG; + } + if (ret != SSP_SUCCESS) { + return WC_HW_E; + } + + if (g_sce.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_BIG) { + ByteReverseWords((word32*)outBlock, (word32*)outBlock, sz); + if (inBlock != outBlock) { + ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz); /* revert input*/ + } + } + + return 0; + } + + #endif + + #if defined(HAVE_AESGCM) || defined(WOLFSSL_AES_DIRECT) + static int wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock) + { + return AES_ECB_encrypt(aes, inBlock, outBlock, AES_BLOCK_SIZE); + } + #endif + + #if defined(HAVE_AES_DECRYPT) && defined(WOLFSSL_AES_DIRECT) + static int wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) + { + return AES_ECB_decrypt(aes, inBlock, outBlock, AES_BLOCK_SIZE); + } + #endif #else /* using wolfCrypt software implementation */ @@ -1455,6 +1581,10 @@ static void wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock) #endif } #endif +#if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES) + AES_ECB_encrypt(aes, inBlock, outBlock, AES_BLOCK_SIZE); + return; +#endif /* * map byte array block to cipher state @@ -1653,6 +1783,9 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) #endif } #endif /* WOLFSSL_AESNI */ +#if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES) + return AES_ECB_decrypt(aes, inBlock, outBlock, AES_BLOCK_SIZE); +#endif /* * map byte array block to cipher state @@ -2280,6 +2413,13 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) #endif /* HAVE_AES_DECRYPT */ #endif /* NEED_AES_TABLES */ +#if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES) + XMEMCPY((byte*)aes->key, userKey, keylen); + if (g_sce.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_BIG) { + ByteReverseWords(aes->key, aes->key, 32); + } +#endif + return wc_AesSetIV(aes, iv); } @@ -5705,7 +5845,7 @@ int AES_GCM_encrypt_C(Aes* aes, byte* out, const byte* in, word32 sz, #if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT) /* some hardware acceleration can gain performance from doing AES encryption * of the whole buffer at once */ - if (c != p) { /* can not handle inline encryption */ + if (c != p && blocks > 0) { /* can not handle inline encryption */ while (blocks--) { IncrementGcmCounter(ctr); XMEMCPY(c, ctr, AES_BLOCK_SIZE); @@ -6157,7 +6297,7 @@ int AES_GCM_decrypt_C(Aes* aes, byte* out, const byte* in, word32 sz, #if defined(HAVE_AES_ECB) && !defined(WOLFSSL_PIC32MZ_CRYPT) /* some hardware acceleration can gain performance from doing AES encryption * of the whole buffer at once */ - if (c != p) { /* can not handle inline decryption */ + if (c != p && blocks > 0) { /* can not handle inline decryption */ while (blocks--) { IncrementGcmCounter(ctr); XMEMCPY(p, ctr, AES_BLOCK_SIZE); @@ -6166,6 +6306,7 @@ int AES_GCM_decrypt_C(Aes* aes, byte* out, const byte* in, word32 sz, /* reset number of blocks and then do encryption */ blocks = sz / AES_BLOCK_SIZE; + wc_AesEcbEncrypt(aes, out, out, AES_BLOCK_SIZE * blocks); xorbuf(out, c, AES_BLOCK_SIZE * blocks); c += AES_BLOCK_SIZE * blocks; @@ -7034,6 +7175,26 @@ int wc_AesGetKeySize(Aes* aes, word32* keySize) #elif defined(WOLFSSL_DEVCRYPTO_AES) /* implemented in wolfcrypt/src/port/devcrypt/devcrypto_aes.c */ +#elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES) + +/* Software AES - ECB */ +int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) +{ + if ((in == NULL) || (out == NULL) || (aes == NULL)) + return BAD_FUNC_ARG; + + return AES_ECB_encrypt(aes, in, out, sz); +} + + +int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) +{ + if ((in == NULL) || (out == NULL) || (aes == NULL)) + return BAD_FUNC_ARG; + + return AES_ECB_decrypt(aes, in, out, sz); +} + #else /* Software AES - ECB */ diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index 860422fcb..d8279886f 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -230,8 +230,12 @@ int wolfCrypt_Init(void) #ifdef WOLFSSL_SCE ret = (int)g_sce.p_api->open(g_sce.p_ctrl, g_sce.p_cfg); - if (ret != SSP_SUCCESS && ret != SSP_ERR_CRYPTO_ALREADY_OPEN) { - WOLFSSL_MSG("Error opening SCE\n"); + if (ret == SSP_ERR_CRYPTO_SCE_ALREADY_OPEN) { + WOLFSSL_MSG("SCE already open"); + ret = 0; + } + if (ret != SSP_SUCCESS) { + WOLFSSL_MSG("Error opening SCE"); return -1; /* FATAL_ERROR */ } #endif From bbfefd3cde5b69a460ae55cd101aceb710060c0c Mon Sep 17 00:00:00 2001 From: Stanislav Klima Date: Wed, 5 Feb 2020 16:59:20 +0100 Subject: [PATCH 036/649] Sanity check NULL dereference. --- wolfcrypt/src/integer.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/wolfcrypt/src/integer.c b/wolfcrypt/src/integer.c index 9e45ebdc2..8f955796e 100644 --- a/wolfcrypt/src/integer.c +++ b/wolfcrypt/src/integer.c @@ -2846,6 +2846,14 @@ int mp_set_bit (mp_int * a, int b) { int i = b / DIGIT_BIT, res; + /* + * Require: + * bit index b >= 0 + * a->alloc == a->used == 0 if a->dp == NULL + */ + if (b < 0 || (a->dp == NULL && (a->alloc != 0 || a->used != 0))) + return MP_VAL; + if (a->dp == NULL || a->used < (int)(i + 1)) { /* grow a to accommodate the single bit */ if ((res = mp_grow (a, i + 1)) != MP_OKAY) { From ba9dc11e625124d02ae9b137ae31cfe72ed8f7ab Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 5 Feb 2020 11:38:22 -0500 Subject: [PATCH 037/649] Adds options to disable the hash wrappers (`NO_HASH_WRAPPER`) and base64 decode (`NO_WOLFSSL_BASE64_DECODE`). --- wolfcrypt/src/coding.c | 3 +++ wolfcrypt/src/hash.c | 6 +++++- wolfssl/wolfcrypt/settings.h | 5 +++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/wolfcrypt/src/coding.c b/wolfcrypt/src/coding.c index 4ec742ec7..3aa59f0f3 100644 --- a/wolfcrypt/src/coding.c +++ b/wolfcrypt/src/coding.c @@ -42,6 +42,8 @@ enum { }; +#ifdef WOLFSSL_BASE64_DECODE + static const byte base64Decode[] = { 62, BAD, BAD, BAD, 63, /* + starts at 0x2B */ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, @@ -144,6 +146,7 @@ int Base64_Decode(const byte* in, word32 inLen, byte* out, word32* outLen) return 0; } +#endif /* WOLFSSL_BASE64_DECODE */ #if defined(WOLFSSL_BASE64_ENCODE) diff --git a/wolfcrypt/src/hash.c b/wolfcrypt/src/hash.c index 4286af08e..0dc0ba2c5 100644 --- a/wolfcrypt/src/hash.c +++ b/wolfcrypt/src/hash.c @@ -58,6 +58,7 @@ enum Hash_Sum { }; #endif /* !NO_ASN */ +#if !defined(NO_PWDBASED) || !defined(NO_ASN) /* function converts int hash type to enum */ enum wc_HashType wc_HashTypeConvert(int hashType) { @@ -126,6 +127,7 @@ enum wc_HashType wc_HashTypeConvert(int hashType) #endif return eHashType; } +#endif /* !NO_PWDBASED || !NO_ASN */ #if !defined(NO_ASN) || !defined(NO_DH) || defined(HAVE_ECC) @@ -264,7 +266,7 @@ enum wc_HashType wc_OidGetHash(int oid) } #endif /* !NO_ASN || !NO_DH || HAVE_ECC */ - +#ifndef NO_HASH_WRAPPER /* Get Hash digest size */ int wc_HashGetDigestSize(enum wc_HashType hash_type) @@ -1362,6 +1364,8 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) #endif /* !WOLFSSL_NOSHA3_512 */ #endif /* WOLFSSL_SHA3 */ +#endif /* !NO_HASH_WRAPPER */ + #ifdef WOLFSSL_HAVE_PRF #ifdef WOLFSSL_SHA384 diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 572b108b6..20823cea9 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -2101,6 +2101,11 @@ extern void uITRON4_free(void *p) ; #error TLS 1.3 requires the Signature Algorithms extension to be enabled #endif +#ifndef NO_WOLFSSL_BASE64_DECODE + #define WOLFSSL_BASE64_DECODE +#endif + + #ifdef __cplusplus } /* extern "C" */ #endif From 0964272dc62cbe7bf097420ba3bf0079846730bc Mon Sep 17 00:00:00 2001 From: Stanislav Klima Date: Wed, 5 Feb 2020 18:28:50 +0100 Subject: [PATCH 038/649] Resource leak fix. --- src/ssl.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ssl.c b/src/ssl.c index a67bbeafb..21dab1708 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -43820,8 +43820,10 @@ int wolfSSL_X509_check_host(X509 *x, const char *chk, size_t chklen, InitDecodedCert(&dCert, x->derCert->buffer, x->derCert->length, NULL); ret = ParseCertRelative(&dCert, CERT_TYPE, 0, NULL); - if (ret != 0) + if (ret != 0) { + FreeDecodedCert(&dCert); return WOLFSSL_FAILURE; + } ret = CheckHostName(&dCert, (char *)chk, chklen); FreeDecodedCert(&dCert); From da3df4f9c6282f7f82605477a923715cfbfef59f Mon Sep 17 00:00:00 2001 From: Stanislav Klima Date: Wed, 5 Feb 2020 19:36:37 +0100 Subject: [PATCH 039/649] Changing logic to remove dead code section. --- src/ssl.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 21dab1708..bd50fd777 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -42498,9 +42498,9 @@ int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name, return WOLFSSL_FAILURE; } +#if defined(WOLFSSL_APACHE_HTTPD) || defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) /* If XN_FLAG_DN_REV is present, print X509_NAME in reverse order */ if (flags == (XN_FLAG_RFC2253 & ~XN_FLAG_DN_REV)) { -#if defined(WOLFSSL_APACHE_HTTPD) || defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) fullName[0] = '\0'; count = wolfSSL_X509_NAME_entry_count(name); for (i = 0; i < count; i++) { @@ -42537,8 +42537,14 @@ int wolfSSL_X509_NAME_print_ex(WOLFSSL_BIO* bio, WOLFSSL_X509_NAME* name, if (wolfSSL_BIO_write(bio, fullName, totalSz) != totalSz) return WOLFSSL_FAILURE; return WOLFSSL_SUCCESS; -#endif /* WOLFSSL_APACHE_HTTPD || OPENSSL_ALL || WOLFSSL_NGINX */ } +#else + if (flags == XN_FLAG_RFC2253) { + if (wolfSSL_BIO_write(bio, name->name + 1, name->sz - 2) + != name->sz - 2) + return WOLFSSL_FAILURE; + } +#endif /* WOLFSSL_APACHE_HTTPD || OPENSSL_ALL || WOLFSSL_NGINX */ else if (wolfSSL_BIO_write(bio, name->name, name->sz - 1) != name->sz - 1) return WOLFSSL_FAILURE; From 61a5fe31088c80b39e925ad9e1c67b011a705759 Mon Sep 17 00:00:00 2001 From: JacobBarthelmeh Date: Thu, 6 Feb 2020 09:20:07 -0800 Subject: [PATCH 040/649] add macro for trng and gce driver names --- IDE/Renesas/e2studio/DK-S7G2/README.md | 80 ++++++++++++++++---------- wolfcrypt/src/aes.c | 10 ++-- wolfcrypt/src/random.c | 16 ++++-- wolfcrypt/src/sha256.c | 4 +- wolfcrypt/src/wc_port.c | 5 +- wolfssl/wolfcrypt/wc_port.h | 6 ++ 6 files changed, 78 insertions(+), 43 deletions(-) diff --git a/IDE/Renesas/e2studio/DK-S7G2/README.md b/IDE/Renesas/e2studio/DK-S7G2/README.md index 211a054e0..a95883c31 100644 --- a/IDE/Renesas/e2studio/DK-S7G2/README.md +++ b/IDE/Renesas/e2studio/DK-S7G2/README.md @@ -1,29 +1,51 @@ - -## Building wolfSSL For DK-S7G2 - -- First physically toggle the ENET1 and JTAG switch to on with the DK-S7G2 board. -- Open e2studio and set the workspace to be wolfssl-X.X.X/IDE/Renesas/e2studio/DK-S7G2/ -- Create a Synergy library project named wolfssl "File->New->Synergy C/C++ Project", "Renesas Synergy C Library Project" then "Next", set wolfssl as the "Project Name" then "Next", set Board to "S7G2 DK" then "Next", finally select the BSP radius and click "Finish" -- Copy configuration.xml and .project from wolfssl-X.X.X/IDE/Renesas/e2studio/DK-S7G2/wolfssl-template-project/ into the wolfssl-X.X.X/IDE/Renesas/e2studio/DK-S7G2/wolfssl directory -- (optional but necessary for production) Add TRNG support by clicking on Threads tab and highlight HAL/Common click "New Stack > Driver > Crypto > TRNG Driver on r_sce_trng". Then comment out WOLFSSL_SCE_NO_TRNG define in wolfssl project src/user_settings.h -- (optional SHA acceleration) Add HASH support by clicking on Threads tab and highlight HAL/Common click "New Stack > Driver > Crypto > HASH Driver on r_sce_hash". Then uncomment WOLFSSL_SCE_NO_HASH define in wolfssl project src/user_settings.h -- (optional AES acceleration) Add the stacks for AES128, AES192, and AES256. Click on Threads tab and highlight HAL/Common click "New Stack > Driver > Crypto > AES Driver on r_sce_aes". Add three one for each key size and rename them to g_sce_aes_256, g_sce_aes_192, and g_sce_aes_128. Changing each to ECB chaining mode and the key length that matches the name. -- Generate the changes by clicking on "Generate Project Content" -- Exclude src/wolfcrypt/port and all src/wolfcrypt/*.S and src/wolfcrypt/*.asm files from the build -- Exclude src/wolfcrypt/evp.c, src/wolfcrypt/misc.c and src/wolfssl/bio.c -- Set the Preprocessor define in wolfssl proejct to have WOLFSSL_USER_SETTINGS. Right click on wolfssl project "Properties -> C/C++ Build -> GNU ARM Cross C Compiler -> Preprocessor" add WOLFSSL_USER_SETTINGS under "Defined symbols" -- Set include to wolfssl directory. Right click on project "Properties -> C/C++Build -> GNU ARM Cross Compiler -> Includes". Add "${ProjDirPath}/../../../../.." and "${ProjDirPath}/../" -- Build wolfssl by right clicking on wolfssl project and selecting "Build Project" - -## Example Projects and Building - -- Create a new Synergy project "Renesas Synergy C Project Using Synergy Library" -- Set it to use the wolfssl library -- Copy in the .cproject, .project and source file from the template desired i.e. wolfssl-X.X.X/IDE/Renesas/e2studio/DK-S7G2/wolfcrypttest-template/ -- Right click on the created project and select "Build Project" - -The example_server loops looking to accept connections and closes immediatly after a successful connection was made. - -The benchmark example tries to do a TCP connection to SERVER_IP on port 11112 and a TLS connection to SERVER_IP on port 11111 then does wolfCrypt benchmark collection. - -The wolfcryptest runs through all of the unit tests from wolfcrypt/test/test.c \ No newline at end of file + +## Building wolfSSL For DK-S7G2 + +- First physically toggle the ENET1 and JTAG switch to on with the DK-S7G2 board. +- Open e2studio and set the workspace to be wolfssl-X.X.X/IDE/Renesas/e2studio/DK-S7G2/ +- Create a Synergy library project named wolfssl "File->New->Synergy C/C++ Project", "Renesas Synergy C Library Project" then "Next", set wolfssl as the "Project Name" then "Next", set Board to "S7G2 DK" then "Next", finally select the BSP radius and click "Finish" +- Copy configuration.xml and .project from wolfssl-X.X.X/IDE/Renesas/e2studio/DK-S7G2/wolfssl-template-project/ into the wolfssl-X.X.X/IDE/Renesas/e2studio/DK-S7G2/wolfssl directory +- (optional but necessary for production) Add TRNG support by clicking on Threads tab and highlight HAL/Common click "New Stack > Driver > Crypto > TRNG Driver on r_sce_trng". Then comment out WOLFSSL_SCE_NO_TRNG define in wolfssl project src/user_settings.h +- (optional SHA acceleration) Add HASH support by clicking on Threads tab and highlight HAL/Common click "New Stack > Driver > Crypto > HASH Driver on r_sce_hash". Then uncomment WOLFSSL_SCE_NO_HASH define in wolfssl project src/user_settings.h +- (optional AES acceleration) Add the stacks for AES128, AES192, and AES256. Click on Threads tab and highlight HAL/Common click "New Stack > Driver > Crypto > AES Driver on r_sce_aes". Add three one for each key size and rename them to g_sce_aes_256, g_sce_aes_192, and g_sce_aes_128. Changing each to ECB chaining mode and the key length that matches the name. +- Generate the changes by clicking on "Generate Project Content" +- Exclude src/wolfcrypt/port and all src/wolfcrypt/*.S and src/wolfcrypt/*.asm files from the build +- Exclude src/wolfcrypt/evp.c, src/wolfcrypt/misc.c and src/wolfssl/bio.c +- Set the Preprocessor define in wolfssl proejct to have WOLFSSL_USER_SETTINGS. Right click on wolfssl project "Properties -> C/C++ Build -> GNU ARM Cross C Compiler -> Preprocessor" add WOLFSSL_USER_SETTINGS under "Defined symbols" +- Set include to wolfssl directory. Right click on project "Properties -> C/C++Build -> GNU ARM Cross Compiler -> Includes". Add "${ProjDirPath}/../../../../.." and "${ProjDirPath}/../" +- Build wolfssl by right clicking on wolfssl project and selecting "Build Project" + +## Example Projects and Building + +- Create a new Synergy project "Renesas Synergy C Project Using Synergy Library" +- Set it to use the wolfssl library +- Copy in the .cproject, .project and source file from the template desired i.e. wolfssl-X.X.X/IDE/Renesas/e2studio/DK-S7G2/wolfcrypttest-template/ +- Right click on the created project and select "Build Project" + +The example_server loops looking to accept connections and closes immediatly after a successful connection was made. + +The benchmark example tries to do a TCP connection to SERVER_IP on port 11112 and a TLS connection to SERVER_IP on port 11111 then does wolfCrypt benchmark collection. + +The wolfcryptest runs through all of the unit tests from wolfcrypt/test/test.c + +## Advanced Overriding Driver Name +Defaults are set for when accessing the driver but the default names may not always work for an existing project. These are the macros and their defaults that could be mapped to other driver names: + +/* For main SCE open and close */ +WOLFSSL_SCE_GSCE_HANDLE g_sce + +/* For AES operations */ +WOLFSSL_SCE_AES256_HANDLE g_sce_aes_256 +WOLFSSL_SCE_AES192_HANDLE g_sce_aes_192 +WOLFSSL_SCE_AES128_HANDLE g_sce_aes_128 + +/* HASH operations */ +WOLFSSL_SCE_SHA256_HANDLE g_sce_hash_0 + +/* TRNG access */ +WOLFSSL_SCE_TRNG_HANDLE g_sce_trng + + + +An example of remapping a driver name would be the following added to a wolfSSL user_settings.h file: +#define WOFSSL_SCE_SHA256_HANDLE my_sce_hash_driver diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 10a46ce12..7017a0bb3 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -792,7 +792,7 @@ { uint32_t ret; - if (g_sce.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_BIG) { + if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_BIG) { ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz); } @@ -828,7 +828,7 @@ return WC_HW_E; } - if (g_sce.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_BIG) { + if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_BIG) { ByteReverseWords((word32*)outBlock, (word32*)outBlock, sz); if (inBlock != outBlock) { ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz); /* revert input*/ @@ -842,7 +842,7 @@ { uint32_t ret; - if (g_sce.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_BIG) { + if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_BIG) { ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz); } @@ -873,7 +873,7 @@ return WC_HW_E; } - if (g_sce.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_BIG) { + if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_BIG) { ByteReverseWords((word32*)outBlock, (word32*)outBlock, sz); if (inBlock != outBlock) { ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz); /* revert input*/ @@ -2415,7 +2415,7 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) #if defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_AES) XMEMCPY((byte*)aes->key, userKey, keylen); - if (g_sce.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_BIG) { + if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_BIG) { ByteReverseWords(aes->key, aes->key, 32); } #endif diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index 056baa536..3e014df76 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -2317,13 +2317,18 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) #elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_TRNG) #include "hal_data.h" + #ifndef WOLFSSL_SCE_TRNG_HANDLE + #define WOLFSSL_SCE_TRNG_HANDLE g_sce_trng + #endif + int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) { uint32_t ret; uint32_t blocks; word32 len = sz; - ret = g_sce_trng.p_api->open(g_sce_trng.p_ctrl, g_sce_trng.p_cfg); + ret = WOLFSSL_SCE_TRNG_HANDLE.p_api->open(WOLFSSL_SCE_TRNG_HANDLE.p_ctrl, + WOLFSSL_SCE_TRNG_HANDLE.p_cfg); if (ret != SSP_SUCCESS && ret != SSP_ERR_CRYPTO_ALREADY_OPEN) { /* error opening TRNG driver */ return -1; @@ -2331,8 +2336,8 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) blocks = sz / sizeof(uint32_t); if (blocks > 0) { - ret = g_sce_trng.p_api->read(g_sce_trng.p_ctrl, (uint32_t*)output, - blocks); + ret = WOLFSSL_SCE_TRNG_HANDLE.p_api->read(WOLFSSL_SCE_TRNG_HANDLE.p_ctrl, + (uint32_t*)output, blocks); if (ret != SSP_SUCCESS) { return -1; } @@ -2345,14 +2350,15 @@ int wc_GenerateSeed(OS_Seed* os, byte* output, word32 sz) if (len > sizeof(uint32_t)) { return -1; } - ret = g_sce_trng.p_api->read(g_sce_trng.p_ctrl, (uint32_t*)tmp, 1); + ret = WOLFSSL_SCE_TRNG_HANDLE.p_api->read(WOLFSSL_SCE_TRNG_HANDLE.p_ctrl, + (uint32_t*)tmp, 1); if (ret != SSP_SUCCESS) { return -1; } XMEMCPY(output + (blocks * sizeof(uint32_t)), (byte*)&tmp, len); } - ret = g_sce_trng.p_api->close(g_sce_trng.p_ctrl); + ret = WOLFSSL_SCE_TRNG_HANDLE.p_api->close(WOLFSSL_SCE_TRNG_HANDLE.p_ctrl); if (ret != SSP_SUCCESS) { /* error opening TRNG driver */ return -1; diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index cc2a1a280..7fe3b4f40 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -555,7 +555,7 @@ static int InitSha256(wc_Sha256* sha256) #define XTRANSFORM(S, D) wc_Sha256SCE_XTRANSFORM((S), (D)) static int wc_Sha256SCE_XTRANSFORM(wc_Sha256* sha256, const byte* data) { - if (g_sce.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_LITTLE) + if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_LITTLE) { ByteReverseWords((word32*)data, (word32*)data, WC_SHA256_BLOCK_SIZE); ByteReverseWords(sha256->digest, sha256->digest, WC_SHA256_DIGEST_SIZE); @@ -568,7 +568,7 @@ static int InitSha256(wc_Sha256* sha256) return WC_HW_E; } - if (g_sce.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_LITTLE) + if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_LITTLE) { ByteReverseWords((word32*)data, (word32*)data, WC_SHA256_BLOCK_SIZE); ByteReverseWords(sha256->digest, sha256->digest, WC_SHA256_DIGEST_SIZE); diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index d8279886f..f32ed9076 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -229,7 +229,8 @@ int wolfCrypt_Init(void) #endif #ifdef WOLFSSL_SCE - ret = (int)g_sce.p_api->open(g_sce.p_ctrl, g_sce.p_cfg); + ret = (int)WOLFSSL_SCE_GSCE_HANDLE.p_api->open(WOLFSSL_SCE_GSCE_HANDLE.p_ctrl, + WOLFSSL_SCE_GSCE_HANDLE.p_cfg); if (ret == SSP_ERR_CRYPTO_SCE_ALREADY_OPEN) { WOLFSSL_MSG("SCE already open"); ret = 0; @@ -293,7 +294,7 @@ int wolfCrypt_Cleanup(void) wolfAsync_HardwareStop(); #endif #ifdef WOLFSSL_SCE - g_sce.p_api->close(g_sce.p_ctrl); + WOLFSSL_SCE_GSCE_HANDLE.p_api->close(WOLFSSL_SCE_GSCE_HANDLE.p_ctrl); #endif #if defined(WOLFSSL_IMX6_CAAM) || defined(WOLFSSL_IMX6_CAAM_RNG) || \ defined(WOLFSSL_IMX6_CAAM_BLOB) diff --git a/wolfssl/wolfcrypt/wc_port.h b/wolfssl/wolfcrypt/wc_port.h index 2d3f8900b..f2dc702b2 100644 --- a/wolfssl/wolfcrypt/wc_port.h +++ b/wolfssl/wolfcrypt/wc_port.h @@ -767,6 +767,12 @@ WOLFSSL_API int wolfCrypt_Cleanup(void); WOLFSSL_LOCAL void wolfSSL_CleanupHandle(); #endif +#ifdef WOLFSSL_SCE + #ifndef WOLFSSL_SCE_GSCE_HANDLE + #define WOLFSSL_SCE_GSCE_HANDLE g_sce + #endif +#endif + #ifdef __cplusplus } /* extern "C" */ #endif From 17bedbac67adf42397d8d71a0123e9d845b2569f Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Thu, 6 Feb 2020 11:53:42 -0700 Subject: [PATCH 041/649] fix return with error on process peer cert --- src/internal.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/internal.c b/src/internal.c index e88163632..f638dbbf7 100644 --- a/src/internal.c +++ b/src/internal.c @@ -9979,16 +9979,16 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, /* Certificate Request Context */ if ((args->idx - args->begin) + OPAQUE8_LEN > totalSz) - return BUFFER_ERROR; + ERROR_OUT(BUFFER_ERROR, exit_ppc); ctxSz = *(input + args->idx); args->idx++; if ((args->idx - args->begin) + ctxSz > totalSz) - return BUFFER_ERROR; + ERROR_OUT(BUFFER_ERROR, exit_ppc); #ifndef NO_WOLFSSL_CLIENT /* Must be empty when received from server. */ if (ssl->options.side == WOLFSSL_CLIENT_END) { if (ctxSz != 0) { - return INVALID_CERT_CTX_E; + ERROR_OUT(INVALID_CERT_CTX_E, exit_ppc); } } #endif @@ -9997,7 +9997,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, if (ssl->options.side == WOLFSSL_SERVER_END) { if (ssl->options.handShakeState != HANDSHAKE_DONE && ctxSz != 0) { - return INVALID_CERT_CTX_E; + ERROR_OUT(INVALID_CERT_CTX_E, exit_ppc); } else if (ssl->options.handShakeState == HANDSHAKE_DONE) { #ifdef WOLFSSL_POST_HANDSHAKE_AUTH @@ -10020,7 +10020,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, } if (curr == NULL) #endif - return INVALID_CERT_CTX_E; + ERROR_OUT(INVALID_CERT_CTX_E, exit_ppc); } } #endif From 7648997e372efb1f920fa2ec6df3b8f49e851f9c Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 6 Feb 2020 13:33:38 -0800 Subject: [PATCH 042/649] ABI Additions Added the functions wolfSSL_GetRNG(), wolfSSL_CTX_GetDevId(), wc_ecc_import_x963(), and wc_RNG_GenerateBlock() to the ABI testing. --- src/ssl.c | 2 ++ wolfcrypt/src/ecc.c | 1 + wolfcrypt/src/random.c | 1 + wolfssl/ssl.h | 4 ++-- wolfssl/wolfcrypt/ecc.h | 2 +- wolfssl/wolfcrypt/random.h | 2 +- 6 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 7ff1b9c41..6b73d7ac8 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -1355,6 +1355,7 @@ int wolfSSL_negotiate(WOLFSSL* ssl) } +WOLFSSL_ABI WC_RNG* wolfSSL_GetRNG(WOLFSSL* ssl) { if (ssl) { @@ -2067,6 +2068,7 @@ int wolfSSL_CTX_SetDevId(WOLFSSL_CTX* ctx, int devId) } /* helpers to get device id and heap */ +WOLFSSL_ABI int wolfSSL_CTX_GetDevId(WOLFSSL_CTX* ctx, WOLFSSL* ssl) { int devId = INVALID_DEVID; diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index eef68d398..785378eeb 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -7002,6 +7002,7 @@ int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key, return err; } +WOLFSSL_ABI int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key) { return wc_ecc_import_x963_ex(in, inLen, key, ECC_CURVE_DEF); diff --git a/wolfcrypt/src/random.c b/wolfcrypt/src/random.c index f81d8e037..e4152cc75 100644 --- a/wolfcrypt/src/random.c +++ b/wolfcrypt/src/random.c @@ -891,6 +891,7 @@ int wc_InitRngNonce_ex(WC_RNG* rng, byte* nonce, word32 nonceSz, /* place a generated block in output */ +WOLFSSL_ABI int wc_RNG_GenerateBlock(WC_RNG* rng, byte* output, word32 sz) { int ret; diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 246734917..e52b395dc 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -2307,7 +2307,7 @@ enum { WOLFSSL_CHAIN_CA = 2 /* added to cache from trusted chain */ }; -WOLFSSL_API WC_RNG* wolfSSL_GetRNG(WOLFSSL*); +WOLFSSL_ABI WOLFSSL_API WC_RNG* wolfSSL_GetRNG(WOLFSSL*); WOLFSSL_ABI WOLFSSL_API int wolfSSL_CTX_SetMinVersion(WOLFSSL_CTX*, int); WOLFSSL_API int wolfSSL_SetMinVersion(WOLFSSL*, int); @@ -2713,7 +2713,7 @@ WOLFSSL_ABI WOLFSSL_API int wolfSSL_SetDevId(WOLFSSL*, int devId); WOLFSSL_ABI WOLFSSL_API int wolfSSL_CTX_SetDevId(WOLFSSL_CTX*, int devId); /* helpers to get device id and heap */ -WOLFSSL_API int wolfSSL_CTX_GetDevId(WOLFSSL_CTX* ctx, WOLFSSL* ssl); +WOLFSSL_ABI WOLFSSL_API int wolfSSL_CTX_GetDevId(WOLFSSL_CTX*, WOLFSSL*); WOLFSSL_API void* wolfSSL_CTX_GetHeap(WOLFSSL_CTX* ctx, WOLFSSL* ssl); /* TLS Extensions */ diff --git a/wolfssl/wolfcrypt/ecc.h b/wolfssl/wolfcrypt/ecc.h index 82ba00c10..ad3f407e9 100644 --- a/wolfssl/wolfcrypt/ecc.h +++ b/wolfssl/wolfcrypt/ecc.h @@ -585,7 +585,7 @@ int wc_ecc_export_x963_ex(ecc_key*, byte* out, word32* outLen, int compressed); #endif /* HAVE_ECC_KEY_EXPORT */ #ifdef HAVE_ECC_KEY_IMPORT -WOLFSSL_API +WOLFSSL_ABI WOLFSSL_API int wc_ecc_import_x963(const byte* in, word32 inLen, ecc_key* key); WOLFSSL_API int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key, diff --git a/wolfssl/wolfcrypt/random.h b/wolfssl/wolfcrypt/random.h index 13be76dd3..aaa21c48b 100644 --- a/wolfssl/wolfcrypt/random.h +++ b/wolfssl/wolfcrypt/random.h @@ -210,7 +210,7 @@ WOLFSSL_API int wc_InitRng_ex(WC_RNG* rng, void* heap, int devId); WOLFSSL_API int wc_InitRngNonce(WC_RNG* rng, byte* nonce, word32 nonceSz); WOLFSSL_API int wc_InitRngNonce_ex(WC_RNG* rng, byte* nonce, word32 nonceSz, void* heap, int devId); -WOLFSSL_API int wc_RNG_GenerateBlock(WC_RNG*, byte*, word32 sz); +WOLFSSL_ABI WOLFSSL_API int wc_RNG_GenerateBlock(WC_RNG*, byte*, word32 sz); WOLFSSL_API int wc_RNG_GenerateByte(WC_RNG*, byte*); WOLFSSL_API int wc_FreeRng(WC_RNG*); #else From 3c077a3cefb53022812cab52245c86b7680ba93f Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Fri, 7 Feb 2020 11:56:30 -0700 Subject: [PATCH 043/649] add NO_OLD_TIMEVAL_NAME macro for backwards compatibility --- examples/server/server.c | 6 +++++- wolfssl/callbacks.h | 4 +++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/examples/server/server.c b/examples/server/server.c index 08843c539..99a2d150e 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -81,7 +81,11 @@ int catastrophic = 0; /* Use with -x flag to still exit when an error is static int lng_index = 0; #ifdef WOLFSSL_CALLBACKS - WOLFSSL_TIMEVAL srvTo; + #if !defined(NO_OLD_TIMEVAL_NAME) + Timeval srvTo; + #else + WOLFSSL_TIMEVAL srvTo; + #endif static int srvHandShakeCB(HandShakeInfo* info) { (void)info; diff --git a/wolfssl/callbacks.h b/wolfssl/callbacks.h index 3d1702a01..eed27293c 100644 --- a/wolfssl/callbacks.h +++ b/wolfssl/callbacks.h @@ -61,7 +61,9 @@ typedef struct handShakeInfo_st { long tv_usec; /* Microseconds. */ } WOLFSSL_TIMEVAL; #endif /* HAVE_SYS_TIME_H */ - +#if !defined(NO_OLD_TIMEVAL_NAME) + #define Timeval WOLFSSL_TIMEVAL +#endif typedef struct packetInfo_st { char packetName[MAX_PACKETNAME_SZ + 1]; /* SSL packet name */ From f322b71526623a673e9c7985861801addde0756e Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 7 Feb 2020 13:04:45 -0800 Subject: [PATCH 044/649] wolfCrypt fixes for asynchronous (--enable-asynccrypt): * Fix for ECC and using NULL curve->order (wasn't loaded). * Fix for typo on heap. * Fix for QT case where GetInt failure retry did not "init" the mp_int. --- src/ssl.c | 3 ++- wolfcrypt/src/ecc.c | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 7ff1b9c41..4292afb9e 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -31765,7 +31765,7 @@ int wolfSSL_EVP_PKEY_set1_DH(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_DH *key) if (ret <= 0) { WOLFSSL_MSG("Failed to export DH Key"); - XFREE(derBuf, key->heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derBuf, pkey->heap, DYNAMIC_TYPE_TMP_BUFFER); return WOLFSSL_FAILURE; } @@ -45047,6 +45047,7 @@ WOLFSSL_BIGNUM *wolfSSL_ASN1_INTEGER_to_BN(const WOLFSSL_ASN1_INTEGER *ai, ret = GetInt(&mpi, ai->data, &idx, ai->dataMax); if (ret != 0) { #ifdef WOLFSSL_QT + mp_init(&mpi); /* must init mpi */ /* Serial number in QT starts at index 0 of data */ if (mp_read_unsigned_bin(&mpi, (byte*)ai->data, ai->length) != 0) { mp_clear(&mpi); diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index eef68d398..e9cdf1d60 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -4858,8 +4858,10 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, #else #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) && \ (defined(HAVE_CAVIUM_V) || defined(HAVE_INTEL_QA)) - if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) + if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) { ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT); + err = wc_ecc_curve_load(key->dp, &curve, ECC_CURVE_FIELD_ALL); + } else #endif { From 669d9b1ae419d2e9632bad537cf9701c620e38c4 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Mon, 10 Feb 2020 08:51:43 +1000 Subject: [PATCH 045/649] Fix for rsa key gen blinding - don't call lcm --- wolfcrypt/src/rsa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index 6fff86363..bdf8f698e 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -4038,7 +4038,7 @@ int wc_MakeRsaKey(RsaKey* key, int size, long e, WC_RNG* rng) err = mp_sub_d(&p, 1, &tmp1); if (err == MP_OKAY) /* tmp2 = q-1 */ err = mp_sub_d(&q, 1, &tmp2); -#ifndef WC_RSA_BLINDING +#ifdef WC_RSA_BLINDING if (err == MP_OKAY) /* tmp3 = order of n */ err = mp_mul(&tmp1, &tmp2, &tmp3); #else From 5b7fc7b13338108b9acf3be9899e16a1f4e663de Mon Sep 17 00:00:00 2001 From: kaleb-himes Date: Tue, 11 Feb 2020 14:39:30 -0700 Subject: [PATCH 046/649] Address failure when blinding disabled and key not initialized to zero --- src/ssl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ssl.c b/src/ssl.c index 6b73d7ac8..487e49014 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -47333,6 +47333,8 @@ WOLFSSL_RSA* wolfSSL_RSA_new(void) wc_RsaSetRNG(key, rng); } +#else + XMEMSET(key, 0, sizeof(RsaKey)); #endif /* WC_RSA_BLINDING */ external->internal = key; From 109173d7560b7b7b5c04836521f1b58455909b05 Mon Sep 17 00:00:00 2001 From: Stanislav Klima Date: Wed, 12 Feb 2020 12:57:40 +0100 Subject: [PATCH 047/649] Fix two resource leaks. --- src/ssl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ssl.c b/src/ssl.c index bd50fd777..96e3562b3 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -4639,6 +4639,7 @@ int AddTrustedPeer(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int verify) InitDecodedCert(cert, der->buffer, der->length, cm->heap); if ((ret = ParseCert(cert, TRUSTED_PEER_TYPE, verify, cm)) != 0) { + FreeDecodedCert(cert); XFREE(cert, NULL, DYNAMIC_TYPE_DCERT); return ret; } @@ -4673,6 +4674,7 @@ int AddTrustedPeer(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int verify) if (AlreadyTrustedPeer(cm, subjectHash)) { WOLFSSL_MSG("\tAlready have this CA, not adding again"); + FreeTrustedPeer(peerCert, cm->heap); (void)ret; } else { From 1a38c26097e0491ef831751a41d0877098dd4453 Mon Sep 17 00:00:00 2001 From: Stanislav Klima Date: Wed, 12 Feb 2020 13:29:33 +0100 Subject: [PATCH 048/649] Prevent infinite loop. --- wolfcrypt/src/rsa.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index 5ffb3b98c..af1fdff73 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -1624,6 +1624,9 @@ static int RsaUnPad(const byte *pkcsBlock, unsigned int pkcsBlockLen, word16 j; word16 pastSep = 0; + if (pkcsBlockLen > 0xFFFF) + return RSA_PAD_E; + /* Decrypted with private key - unpad must be constant time. */ for (i = 0, j = 2; j < pkcsBlockLen; j++) { /* Update i if not passed the separator and at separator. */ From 1b13178182cf1c25c0d01a537b6626824d41dabc Mon Sep 17 00:00:00 2001 From: Stanislav Klima Date: Wed, 12 Feb 2020 13:46:12 +0100 Subject: [PATCH 049/649] Fixes possible compile error if NO_PKCS7_STREAM is defined. --- wolfcrypt/src/pkcs7.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 3a79d8fc9..6b6c3ecaa 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -11419,7 +11419,9 @@ authenv_atrbend: XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7); decryptedKey = NULL; #ifdef WOLFSSL_SMALL_STACK + #ifndef NO_PKCS7_STREAM pkcs7->stream->key = NULL; + #endif #endif #endif ret = encryptedContentSz; From 0814f61b11f3e493df744b59e826d37e0c898359 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Wed, 12 Feb 2020 10:31:34 -0700 Subject: [PATCH 050/649] fix code formating and turn on HW acc. by default --- IDE/Renesas/e2studio/DK-S7G2/README.md | 3 +- .../benchmark-template/src/app_entry.c | 17 +++-- .../example_server-template/src/app_entry.c | 3 +- IDE/Renesas/e2studio/DK-S7G2/user_settings.h | 6 +- wolfcrypt/src/aes.c | 70 ++++++++++++------- wolfcrypt/src/sha256.c | 24 ++++--- wolfcrypt/src/wc_port.c | 4 +- 7 files changed, 79 insertions(+), 48 deletions(-) diff --git a/IDE/Renesas/e2studio/DK-S7G2/README.md b/IDE/Renesas/e2studio/DK-S7G2/README.md index a95883c31..1945d7b94 100644 --- a/IDE/Renesas/e2studio/DK-S7G2/README.md +++ b/IDE/Renesas/e2studio/DK-S7G2/README.md @@ -31,6 +31,7 @@ The wolfcryptest runs through all of the unit tests from wolfcrypt/test/test.c ## Advanced Overriding Driver Name Defaults are set for when accessing the driver but the default names may not always work for an existing project. These are the macros and their defaults that could be mapped to other driver names: +``` /* For main SCE open and close */ WOLFSSL_SCE_GSCE_HANDLE g_sce @@ -44,7 +45,7 @@ WOLFSSL_SCE_SHA256_HANDLE g_sce_hash_0 /* TRNG access */ WOLFSSL_SCE_TRNG_HANDLE g_sce_trng - +``` An example of remapping a driver name would be the following added to a wolfSSL user_settings.h file: 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 1bcbc55ee..23389a396 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 @@ -71,7 +71,7 @@ static void benchmark_TLS(int version, char* suites, int group) case 3: method = wolfTLSv1_3_client_method(); break; #endif default: - printf("Unknown TLS version (Check if wolfSSL was built with it supported)\n"); + printf("Unknown TLS version (Check if built with it supported)\n"); return; } @@ -136,13 +136,15 @@ static void benchmark_TLS(int version, char* suites, int group) } for (i = 0; i < CONNECTION_TIMES; i++) { - ret = (int)nx_tcp_client_socket_bind(&sockfd, NX_ANY_PORT, NX_WAIT_FOREVER); + ret = (int)nx_tcp_client_socket_bind(&sockfd, NX_ANY_PORT, + NX_WAIT_FOREVER); if (ret != NX_SUCCESS) { printf("failed to bind socket\n"); return; } - ret = (int)nx_tcp_client_socket_connect(&sockfd, TEST_IP, TEST_PORT, NX_WAIT_FOREVER); + ret = (int)nx_tcp_client_socket_connect(&sockfd, TEST_IP, TEST_PORT, + NX_WAIT_FOREVER); if (ret != NX_SUCCESS) { printf("failed to connect with error 0x%X\n", ret); return; @@ -208,7 +210,8 @@ static void benchmark_TCP() NX_PACKET* response; printf("Pinging server to see if up .. "); fflush(stdout); - ret = (int)nx_icmp_ping(&g_ip0, TEST_IP, "Hello", strlen("Hello"), &response, 2000); + ret = (int)nx_icmp_ping(&g_ip0, TEST_IP, "Hello", strlen("Hello"), + &response, 2000); if (ret != NX_SUCCESS) { printf("Unable to ping server, error = 0x%X\n", ret); return; @@ -228,13 +231,15 @@ static void benchmark_TCP() } for (i = 0; i < CONNECTION_TIMES; i++) { - ret = (int)nx_tcp_client_socket_bind(&sockfd, NX_ANY_PORT, NX_WAIT_FOREVER); + ret = (int)nx_tcp_client_socket_bind(&sockfd, NX_ANY_PORT, + NX_WAIT_FOREVER); if (ret != NX_SUCCESS) { printf("failed to bind socket\n"); return; } - ret = (int)nx_tcp_client_socket_connect(&sockfd, TEST_IP, TEST_PORT, NX_WAIT_FOREVER); + ret = (int)nx_tcp_client_socket_connect(&sockfd, TEST_IP, TEST_PORT, + NX_WAIT_FOREVER); if (ret != NX_SUCCESS) { printf("failed to connect with error 0x%X\n", ret); return; 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 92a32d8d7..a83322322 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 @@ -103,7 +103,8 @@ static void server() #endif printf("Waiting for connections on port %d\n", TEST_PORT); - ret = (int)nx_tcp_socket_create(&g_ip0, &sockfd, "TLS_SERVER", NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1500, NX_NULL, NX_NULL); + ret = (int)nx_tcp_socket_create(&g_ip0, &sockfd, "TLS_SERVER", NX_IP_NORMAL, + NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1500, NX_NULL, NX_NULL); if (ret != NX_SUCCESS) { printf("failed to create socket err = 0x%X\n", ret); } diff --git a/IDE/Renesas/e2studio/DK-S7G2/user_settings.h b/IDE/Renesas/e2studio/DK-S7G2/user_settings.h index cdebbd445..146f7020b 100644 --- a/IDE/Renesas/e2studio/DK-S7G2/user_settings.h +++ b/IDE/Renesas/e2studio/DK-S7G2/user_settings.h @@ -16,13 +16,13 @@ #define WOLFSSL_SCE /* Used to turn off TRNG */ -#define WOLFSSL_SCE_NO_TRNG +/* #define WOLFSSL_SCE_NO_TRNG */ /* Used to turn off AES hardware acc. */ -#define WOLFSSL_SCE_NO_AES +/* #define WOLFSSL_SCE_NO_AES */ /* Used to turn off HASH hardware acc. */ -#define WOLFSSL_SCE_NO_HASH +/* #define WOLFSSL_SCE_NO_HASH */ #if defined(WOLFSSL_SCE_NO_TRNG) /* use unsafe test seed if TRNG not used (not for production) */ diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 7017a0bb3..caeb2309f 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -788,34 +788,39 @@ #define WOLFSSL_SCE_AES128_HANDLE g_sce_aes_128 #endif - static int AES_ECB_encrypt(Aes* aes, const byte* inBlock, byte* outBlock, int sz) + static int AES_ECB_encrypt(Aes* aes, const byte* inBlock, byte* outBlock, + int sz) { uint32_t ret; - if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_BIG) { + if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag == + CRYPTO_WORD_ENDIAN_BIG) { ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz); } switch (aes->keylen) { #ifdef WOLFSSL_AES_128 case AES_128_KEY_SIZE: - ret = WOLFSSL_SCE_AES128_HANDLE.p_api->encrypt(WOLFSSL_SCE_AES128_HANDLE.p_ctrl, aes->key, - NULL, (sz / sizeof(word32)), - (word32*)inBlock, (word32*)outBlock); + ret = WOLFSSL_SCE_AES128_HANDLE.p_api->encrypt( + WOLFSSL_SCE_AES128_HANDLE.p_ctrl, aes->key, + NULL, (sz / sizeof(word32)), (word32*)inBlock, + (word32*)outBlock); break; #endif #ifdef WOLFSSL_AES_192 case AES_192_KEY_SIZE: - ret = WOLFSSL_SCE_AES192_HANDLE.p_api->encrypt(WOLFSSL_SCE_AES192_HANDLE.p_ctrl, aes->key, - NULL, (sz / sizeof(word32)), - (word32*)inBlock, (word32*)outBlock); + ret = WOLFSSL_SCE_AES192_HANDLE.p_api->encrypt( + WOLFSSL_SCE_AES192_HANDLE.p_ctrl, aes->key, + NULL, (sz / sizeof(word32)), (word32*)inBlock, + (word32*)outBlock); break; #endif #ifdef WOLFSSL_AES_256 case AES_256_KEY_SIZE: - ret = WOLFSSL_SCE_AES256_HANDLE.p_api->encrypt(WOLFSSL_SCE_AES256_HANDLE.p_ctrl, aes->key, - NULL, (sz / sizeof(word32)), - (word32*)inBlock, (word32*)outBlock); + ret = WOLFSSL_SCE_AES256_HANDLE.p_api->encrypt( + WOLFSSL_SCE_AES256_HANDLE.p_ctrl, aes->key, + NULL, (sz / sizeof(word32)), (word32*)inBlock, + (word32*)outBlock); break; #endif default: @@ -824,45 +829,56 @@ } if (ret != SSP_SUCCESS) { - ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz); /* revert input*/ + /* revert input */ + ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz); return WC_HW_E; } - if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_BIG) { + if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag == + CRYPTO_WORD_ENDIAN_BIG) { ByteReverseWords((word32*)outBlock, (word32*)outBlock, sz); if (inBlock != outBlock) { - ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz); /* revert input*/ + /* revert input */ + ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz); } } return 0; } #if defined(HAVE_AES_DECRYPT) - static int AES_ECB_decrypt(Aes* aes, const byte* inBlock, byte* outBlock, int sz) + static int AES_ECB_decrypt(Aes* aes, const byte* inBlock, byte* outBlock, + int sz) { uint32_t ret; - if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_BIG) { + if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag == + CRYPTO_WORD_ENDIAN_BIG) { ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz); } switch (aes->keylen) { #ifdef WOLFSSL_AES_128 case AES_128_KEY_SIZE: - ret = WOLFSSL_SCE_AES128_HANDLE.p_api->decrypt(WOLFSSL_SCE_AES128_HANDLE.p_ctrl, aes->key, aes->reg, - (sz / sizeof(word32)), (word32*)inBlock, (word32*)outBlock); + ret = WOLFSSL_SCE_AES128_HANDLE.p_api->decrypt( + WOLFSSL_SCE_AES128_HANDLE.p_ctrl, aes->key, aes->reg, + (sz / sizeof(word32)), (word32*)inBlock, + (word32*)outBlock); break; #endif #ifdef WOLFSSL_AES_192 case AES_192_KEY_SIZE: - ret = WOLFSSL_SCE_AES192_HANDLE.p_api->decrypt(WOLFSSL_SCE_AES192_HANDLE.p_ctrl, aes->key, aes->reg, - (sz / sizeof(word32)), (word32*)inBlock, (word32*)outBlock); + ret = WOLFSSL_SCE_AES192_HANDLE.p_api->decrypt( + WOLFSSL_SCE_AES192_HANDLE.p_ctrl, aes->key, aes->reg, + (sz / sizeof(word32)), (word32*)inBlock, + (word32*)outBlock); break; #endif #ifdef WOLFSSL_AES_256 case AES_256_KEY_SIZE: - ret = WOLFSSL_SCE_AES256_HANDLE.p_api->decrypt(WOLFSSL_SCE_AES256_HANDLE.p_ctrl, aes->key, aes->reg, - (sz / sizeof(word32)), (word32*)inBlock, (word32*)outBlock); + ret = WOLFSSL_SCE_AES256_HANDLE.p_api->decrypt( + WOLFSSL_SCE_AES256_HANDLE.p_ctrl, aes->key, aes->reg, + (sz / sizeof(word32)), (word32*)inBlock, + (word32*)outBlock); break; #endif default: @@ -873,10 +889,12 @@ return WC_HW_E; } - if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_BIG) { + if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag == + CRYPTO_WORD_ENDIAN_BIG) { ByteReverseWords((word32*)outBlock, (word32*)outBlock, sz); if (inBlock != outBlock) { - ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz); /* revert input*/ + /* revert input */ + ByteReverseWords((word32*)inBlock, (word32*)inBlock, sz); } } @@ -1559,8 +1577,8 @@ static void wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock) tmp_align = tmp + (AESNI_ALIGN - ((size_t)tmp % AESNI_ALIGN)); XMEMCPY(tmp_align, inBlock, AES_BLOCK_SIZE); - AES_ECB_encrypt(tmp_align, tmp_align, AES_BLOCK_SIZE, (byte*)aes->key, - aes->rounds); + AES_ECB_encrypt(tmp_align, tmp_align, AES_BLOCK_SIZE, + (byte*)aes->key, aes->rounds); XMEMCPY(outBlock, tmp_align, AES_BLOCK_SIZE); XFREE(tmp, aes->heap, DYNAMIC_TYPE_TMP_BUFFER); return; diff --git a/wolfcrypt/src/sha256.c b/wolfcrypt/src/sha256.c index 7fe3b4f40..eb0911b01 100644 --- a/wolfcrypt/src/sha256.c +++ b/wolfcrypt/src/sha256.c @@ -555,23 +555,29 @@ static int InitSha256(wc_Sha256* sha256) #define XTRANSFORM(S, D) wc_Sha256SCE_XTRANSFORM((S), (D)) static int wc_Sha256SCE_XTRANSFORM(wc_Sha256* sha256, const byte* data) { - if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_LITTLE) + if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag == + CRYPTO_WORD_ENDIAN_LITTLE) { - ByteReverseWords((word32*)data, (word32*)data, WC_SHA256_BLOCK_SIZE); - ByteReverseWords(sha256->digest, sha256->digest, WC_SHA256_DIGEST_SIZE); + ByteReverseWords((word32*)data, (word32*)data, + WC_SHA256_BLOCK_SIZE); + ByteReverseWords(sha256->digest, sha256->digest, + WC_SHA256_DIGEST_SIZE); } - if (WOLFSSL_SCE_SHA256_HANDLE.p_api->hashUpdate(WOLFSSL_SCE_SHA256_HANDLE.p_ctrl, - (word32*)data, WC_SHA256_DIGEST_WORD_SIZE, - sha256->digest) != SSP_SUCCESS) { + if (WOLFSSL_SCE_SHA256_HANDLE.p_api->hashUpdate( + WOLFSSL_SCE_SHA256_HANDLE.p_ctrl, (word32*)data, + WC_SHA256_DIGEST_WORD_SIZE, sha256->digest) != SSP_SUCCESS){ WOLFSSL_MSG("Unexpected hardware return value"); return WC_HW_E; } - if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag == CRYPTO_WORD_ENDIAN_LITTLE) + if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag == + CRYPTO_WORD_ENDIAN_LITTLE) { - ByteReverseWords((word32*)data, (word32*)data, WC_SHA256_BLOCK_SIZE); - ByteReverseWords(sha256->digest, sha256->digest, WC_SHA256_DIGEST_SIZE); + ByteReverseWords((word32*)data, (word32*)data, + WC_SHA256_BLOCK_SIZE); + ByteReverseWords(sha256->digest, sha256->digest, + WC_SHA256_DIGEST_SIZE); } return 0; diff --git a/wolfcrypt/src/wc_port.c b/wolfcrypt/src/wc_port.c index f32ed9076..d0d6bdf16 100644 --- a/wolfcrypt/src/wc_port.c +++ b/wolfcrypt/src/wc_port.c @@ -229,8 +229,8 @@ int wolfCrypt_Init(void) #endif #ifdef WOLFSSL_SCE - ret = (int)WOLFSSL_SCE_GSCE_HANDLE.p_api->open(WOLFSSL_SCE_GSCE_HANDLE.p_ctrl, - WOLFSSL_SCE_GSCE_HANDLE.p_cfg); + ret = (int)WOLFSSL_SCE_GSCE_HANDLE.p_api->open( + WOLFSSL_SCE_GSCE_HANDLE.p_ctrl, WOLFSSL_SCE_GSCE_HANDLE.p_cfg); if (ret == SSP_ERR_CRYPTO_SCE_ALREADY_OPEN) { WOLFSSL_MSG("SCE already open"); ret = 0; From 8e1adb125cf7b1661737ea38498415b143779b33 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Wed, 12 Feb 2020 15:45:44 -0700 Subject: [PATCH 051/649] free existing cert store when setting a new one --- src/ssl.c | 7 +++++++ tests/api.c | 23 ++++++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/ssl.c b/src/ssl.c index 6b73d7ac8..14e6545ae 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -14899,6 +14899,13 @@ int wolfSSL_set_compression(WOLFSSL* ssl) wolfSSL_CertManagerFree(ctx->cm); } ctx->cm = str->cm; + + /* free existing store if it exists */ + if (ctx->x509_store_pt != NULL) { + /* cert manager was free'd a little earlier in this function */ + ctx->x509_store_pt->cm = NULL; + } + wolfSSL_X509_STORE_free(ctx->x509_store_pt); ctx->x509_store.cache = str->cache; ctx->x509_store_pt = str; /* take ownership of store and free it with CTX free */ diff --git a/tests/api.c b/tests/api.c index 4fa095e18..5ca517543 100644 --- a/tests/api.c +++ b/tests/api.c @@ -21238,8 +21238,10 @@ static void test_wolfSSL_CTX_set_srp_password(void) static void test_wolfSSL_X509_STORE(void) { -#if defined(OPENSSL_EXTRA) && defined(HAVE_CRL) && !defined(NO_RSA) +#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) X509_STORE *store; + + #ifdef HAVE_CRL X509_CRL *crl; X509 *x509; const char crl_pem[] = "./certs/crl/crl.pem"; @@ -21260,6 +21262,25 @@ static void test_wolfSSL_X509_STORE(void) AssertIntEQ(X509_STORE_add_crl(store, crl), SSL_SUCCESS); X509_CRL_free(crl); X509_STORE_free(store); + #endif /* HAVE_CRL */ + + + + #ifndef WOLFCRYPT_ONLY + { + SSL_CTX* ctx; + #ifndef NO_WOLFSSL_SERVER + AssertNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method())); + #else + AssertNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method())); + #endif + AssertNotNull(store = (X509_STORE *)X509_STORE_new()); + SSL_CTX_set_cert_store(ctx, store); + AssertNotNull(store = (X509_STORE *)X509_STORE_new()); + SSL_CTX_set_cert_store(ctx, store); + SSL_CTX_free(ctx); + } + #endif printf(resultFmt, passed); #endif return; From bb7508f57091d19f1d9df87e8f902499bc5ed10f Mon Sep 17 00:00:00 2001 From: kaleb-himes Date: Wed, 12 Feb 2020 15:57:00 -0700 Subject: [PATCH 052/649] --disable-supportedcurves --enable-opensslextra - NIGHTLY DISABLE OPTIONS TEST --- src/ssl.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 6b73d7ac8..1747564af 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -2307,8 +2307,7 @@ int wolfSSL_CTX_UseOCSPStaplingV2(WOLFSSL_CTX* ctx, byte status_type, #endif /* HAVE_CERTIFICATE_STATUS_REQUEST_V2 */ /* Elliptic Curves */ -#ifdef HAVE_SUPPORTED_CURVES -#ifndef NO_WOLFSSL_CLIENT +#if defined(HAVE_SUPPORTED_CURVES) && !defined(NO_WOLFSSL_CLIENT) int wolfSSL_UseSupportedCurve(WOLFSSL* ssl, word16 name) { @@ -2386,8 +2385,7 @@ int wolfSSL_CTX_UseSupportedCurve(WOLFSSL_CTX* ctx, word16 name) return TLSX_UseSupportedCurve(&ctx->extensions, name, ctx->heap); } -#endif /* NO_WOLFSSL_CLIENT */ -#endif /* HAVE_SUPPORTED_CURVES */ +#endif /* HAVE_SUPPORTED_CURVES && !NO_WOLFSSL_CLIENT */ /* QSH quantum safe handshake */ #ifdef HAVE_QSH @@ -44552,7 +44550,7 @@ int wolfSSL_CTX_set1_curves_list(WOLFSSL_CTX* ctx, const char* names) return WOLFSSL_FAILURE; } - #ifndef NO_WOLFSSL_CLIENT + #if defined(HAVE_SUPPORTED_CURVES) && !defined(NO_WOLFSSL_CLIENT) /* set the supported curve so client TLS extension contains only the * desired curves */ if (wolfSSL_CTX_UseSupportedCurve(ctx, curve) != WOLFSSL_SUCCESS) { From 63a005d71b200fae5d66439277b904a80652b3c9 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 13 Feb 2020 09:08:54 -0800 Subject: [PATCH 053/649] VxWorks Strings When building for VxWorks, set HAVE_STRINGS_H as it uses strings.h, not string.h. --- wolfssl/wolfcrypt/settings.h | 1 + 1 file changed, 1 insertion(+) diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index b7beae382..07fd19479 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -458,6 +458,7 @@ #define NO_MAIN_DRIVER #define NO_DEV_RANDOM #define NO_WRITEV + #define HAVE_STRINGS_H #endif From 614e675a00a084434a03de510186d4dfa09f6462 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Wed, 12 Feb 2020 22:50:43 +1000 Subject: [PATCH 054/649] Call secret callback when TLS 1.3 secrets generated --- src/internal.c | 7 +++ src/tls13.c | 137 ++++++++++++++++++++++++++++++++++++-------- wolfssl/error-ssl.h | 1 + wolfssl/internal.h | 4 ++ wolfssl/ssl.h | 25 +++++++- 5 files changed, 148 insertions(+), 26 deletions(-) diff --git a/src/internal.c b/src/internal.c index e40a1220c..1750184ef 100644 --- a/src/internal.c +++ b/src/internal.c @@ -5501,6 +5501,10 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) #ifdef HAVE_SECRET_CALLBACK ssl->sessionSecretCb = NULL; ssl->sessionSecretCtx = NULL; +#ifdef WOLFSSL_TLS13 + ssl->tls13SecretCb = NULL; + ssl->tls13SecretCtx = NULL; +#endif #endif #ifdef HAVE_SESSION_TICKET @@ -17414,6 +17418,9 @@ const char* wolfSSL_ERR_reason_error_string(unsigned long e) case SSL_SHUTDOWN_ALREADY_DONE_E: return "Shutdown has already occurred"; + case TLS13_SECRET_CB_E: + return "TLS1.3 Secret Callback Error"; + default : return "unknown error number"; } diff --git a/src/tls13.c b/src/tls13.c index f9cbf86b8..097c74c50 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -440,7 +440,6 @@ static int DeriveKey(WOLFSSL* ssl, byte* output, int outputLen, hash, hashOutSz, digestAlg); } - #ifndef NO_PSK #ifdef WOLFSSL_TLS13_DRAFT_18 /* The length of the binder key label. */ @@ -521,10 +520,21 @@ static const byte earlyTrafficLabel[EARLY_TRAFFIC_LABEL_SZ + 1] = */ static int DeriveEarlyTrafficSecret(WOLFSSL* ssl, byte* key) { + int ret; WOLFSSL_MSG("Derive Early Traffic Secret"); - return DeriveKey(ssl, key, -1, ssl->arrays->secret, - earlyTrafficLabel, EARLY_TRAFFIC_LABEL_SZ, - ssl->specs.mac_algorithm, 1); + ret = DeriveKey(ssl, key, -1, ssl->arrays->secret, + earlyTrafficLabel, EARLY_TRAFFIC_LABEL_SZ, + ssl->specs.mac_algorithm, 1); +#ifdef HAVE_SECRET_CALLBACK + if (ret == 0 && ssl->tls13SecretCb != NULL) { + ret = ssl->tls13SecretCb(ssl, CLIENT_EARLY_TRAFFIC_SECRET, key, + ssl->specs.hash_size, ssl->tls13SecretCtx); + if (ret != 0) { + return TLS13_SECRET_CB_E; + } + } +#endif /* HAVE_SECRET_CALLBACK */ + return ret; } #ifdef TLS13_SUPPORTS_EXPORTERS @@ -549,10 +559,21 @@ static const byte earlyExporterLabel[EARLY_EXPORTER_LABEL_SZ + 1] = */ static int DeriveEarlyExporterSecret(WOLFSSL* ssl, byte* key) { + int ret; WOLFSSL_MSG("Derive Early Exporter Secret"); - return DeriveKey(ssl, key, -1, ssl->arrays->secret, - earlyExporterLabel, EARLY_EXPORTER_LABEL_SZ, - ssl->specs.mac_algorithm, 1); + ret = DeriveKey(ssl, key, -1, ssl->arrays->secret, + earlyExporterLabel, EARLY_EXPORTER_LABEL_SZ, + ssl->specs.mac_algorithm, 1); +#ifdef HAVE_SECRET_CALLBACK + if (ret == 0 && ssl->tls13SecretCb != NULL) { + ret = ssl->tls13SecretCb(ssl, EARLY_EXPORTER_SECRET, key + ssl->specs.hash_size, ssl->tls13SecretCtx); + if (ret != 0) { + return TLS13_SECRET_CB_E; + } + } +#endif /* HAVE_SECRET_CALLBACK */ + return ret; } #endif #endif @@ -578,10 +599,21 @@ static const byte clientHandshakeLabel[CLIENT_HANDSHAKE_LABEL_SZ + 1] = */ static int DeriveClientHandshakeSecret(WOLFSSL* ssl, byte* key) { + int ret; WOLFSSL_MSG("Derive Client Handshake Secret"); - return DeriveKey(ssl, key, -1, ssl->arrays->preMasterSecret, - clientHandshakeLabel, CLIENT_HANDSHAKE_LABEL_SZ, - ssl->specs.mac_algorithm, 1); + ret = DeriveKey(ssl, key, -1, ssl->arrays->preMasterSecret, + clientHandshakeLabel, CLIENT_HANDSHAKE_LABEL_SZ, + ssl->specs.mac_algorithm, 1); +#ifdef HAVE_SECRET_CALLBACK + if (ret == 0 && ssl->tls13SecretCb != NULL) { + ret = ssl->tls13SecretCb(ssl, CLIENT_HANDSHAKE_TRAFFIC_SECRET, key, + ssl->specs.hash_size, ssl->tls13SecretCtx); + if (ret != 0) { + return TLS13_SECRET_CB_E; + } + } +#endif /* HAVE_SECRET_CALLBACK */ + return ret; } #ifdef WOLFSSL_TLS13_DRAFT_18 @@ -605,10 +637,21 @@ static const byte serverHandshakeLabel[SERVER_HANDSHAKE_LABEL_SZ + 1] = */ static int DeriveServerHandshakeSecret(WOLFSSL* ssl, byte* key) { + int ret; WOLFSSL_MSG("Derive Server Handshake Secret"); - return DeriveKey(ssl, key, -1, ssl->arrays->preMasterSecret, - serverHandshakeLabel, SERVER_HANDSHAKE_LABEL_SZ, - ssl->specs.mac_algorithm, 1); + ret = DeriveKey(ssl, key, -1, ssl->arrays->preMasterSecret, + serverHandshakeLabel, SERVER_HANDSHAKE_LABEL_SZ, + ssl->specs.mac_algorithm, 1); +#ifdef HAVE_SECRET_CALLBACK + if (ret == 0 && ssl->tls13SecretCb != NULL) { + ret = ssl->tls13SecretCb(ssl, SERVER_HANDSHAKE_TRAFFIC_SECRET, key, + ssl->specs.hash_size, ssl->tls13SecretCtx); + if (ret != 0) { + return TLS13_SECRET_CB_E; + } + } +#endif /* HAVE_SECRET_CALLBACK */ + return ret; } #ifdef WOLFSSL_TLS13_DRAFT_18 @@ -632,10 +675,21 @@ static const byte clientAppLabel[CLIENT_APP_LABEL_SZ + 1] = */ static int DeriveClientTrafficSecret(WOLFSSL* ssl, byte* key) { + int ret; WOLFSSL_MSG("Derive Client Traffic Secret"); - return DeriveKey(ssl, key, -1, ssl->arrays->masterSecret, - clientAppLabel, CLIENT_APP_LABEL_SZ, - ssl->specs.mac_algorithm, 1); + ret = DeriveKey(ssl, key, -1, ssl->arrays->masterSecret, + clientAppLabel, CLIENT_APP_LABEL_SZ, + ssl->specs.mac_algorithm, 1); +#ifdef HAVE_SECRET_CALLBACK + if (ret == 0 && ssl->tls13SecretCb != NULL) { + ret = ssl->tls13SecretCb(ssl, CLIENT_TRAFFIC_SECRET, key, + ssl->specs.hash_size, ssl->tls13SecretCtx); + if (ret != 0) { + return TLS13_SECRET_CB_E; + } + } +#endif /* HAVE_SECRET_CALLBACK */ + return ret; } #ifdef WOLFSSL_TLS13_DRAFT_18 @@ -659,10 +713,21 @@ static const byte serverAppLabel[SERVER_APP_LABEL_SZ + 1] = */ static int DeriveServerTrafficSecret(WOLFSSL* ssl, byte* key) { + int ret; WOLFSSL_MSG("Derive Server Traffic Secret"); - return DeriveKey(ssl, key, -1, ssl->arrays->masterSecret, - serverAppLabel, SERVER_APP_LABEL_SZ, - ssl->specs.mac_algorithm, 1); + ret = DeriveKey(ssl, key, -1, ssl->arrays->masterSecret, + serverAppLabel, SERVER_APP_LABEL_SZ, + ssl->specs.mac_algorithm, 1); +#ifdef HAVE_SECRET_CALLBACK + if (ret == 0 && ssl->tls13SecretCb != NULL) { + ret = ssl->tls13SecretCb(ssl, SERVER_TRAFFIC_SECRET, key, + ssl->specs.hash_size, ssl->tls13SecretCtx); + if (ret != 0) { + return TLS13_SECRET_CB_E; + } + } +#endif /* HAVE_SECRET_CALLBACK */ + return ret; } #ifdef TLS13_SUPPORTS_EXPORTERS @@ -687,10 +752,21 @@ static const byte exporterMasterLabel[EXPORTER_MASTER_LABEL_SZ + 1] = */ static int DeriveExporterSecret(WOLFSSL* ssl, byte* key) { + int ret; WOLFSSL_MSG("Derive Exporter Secret"); - return DeriveKey(ssl, key, -1, ssl->arrays->masterSecret, - exporterMasterLabel, EXPORTER_MASTER_LABEL_SZ, - ssl->specs.mac_algorithm, 1); + ret = DeriveKey(ssl, key, -1, ssl->arrays->masterSecret, + exporterMasterLabel, EXPORTER_MASTER_LABEL_SZ, + ssl->specs.mac_algorithm, 1); +#ifdef HAVE_SECRET_CALLBACK + if (ret == 0 && ssl->tls13SecretCb != NULL) { + ret = ssl->tls13SecretCb(ssl, EXPORTER_SECRET, key, + ssl->specs.hash_size, ssl->tls13SecretCtx); + if (ret != 0) { + return TLS13_SECRET_CB_E; + } + } +#endif /* HAVE_SECRET_CALLBACK */ + return ret; } #endif @@ -3087,8 +3163,9 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, int secretSz = SECRET_LEN; ret = ssl->sessionSecretCb(ssl, ssl->session.masterSecret, &secretSz, ssl->sessionSecretCtx); - if (ret != 0 || secretSz != SECRET_LEN) + if (ret != 0 || secretSz != SECRET_LEN) { return SESSION_SECRET_CB_E; + } } #endif /* HAVE_SECRET_CALLBACK */ @@ -8844,6 +8921,20 @@ int wolfSSL_read_early_data(WOLFSSL* ssl, void* data, int sz, int* outSz) } #endif +#ifdef HAVE_SECRET_CALLBACK +int wolfSSL_set_tls13_secret_cb(WOLFSSL* ssl, Tls13SecretCb cb, void* ctx) +{ + WOLFSSL_ENTER("wolfSSL_set_tls13_secret_cb"); + if (ssl == NULL) + return WOLFSSL_FATAL_ERROR; + + ssl->tls13SecretCb = cb; + ssl->tls13SecretCtx = ctx; + + return WOLFSSL_SUCCESS; +} +#endif + #undef ERROR_OUT #endif /* !WOLFCRYPT_ONLY */ diff --git a/wolfssl/error-ssl.h b/wolfssl/error-ssl.h index 2327eab3d..9b44326e7 100644 --- a/wolfssl/error-ssl.h +++ b/wolfssl/error-ssl.h @@ -166,6 +166,7 @@ enum wolfSSL_ErrorCodes { TSIP_MAC_DIGSZ_E = -435, /* Invalid MAC size for TSIP */ CLIENT_CERT_CB_ERROR = -436, /* Client cert callback error */ SSL_SHUTDOWN_ALREADY_DONE_E = -437, /* Shutdown called redundantly */ + TLS13_SECRET_CB_E = -438, /* TLS1.3 secret Cb fcn failure */ /* add strings to wolfSSL_ERR_reason_error_string in internal.c !!!!! */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index a586184d7..5f47ff767 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -4107,6 +4107,10 @@ struct WOLFSSL { #ifdef HAVE_SECRET_CALLBACK SessionSecretCb sessionSecretCb; void* sessionSecretCtx; + #ifdef WOLFSSL_TLS13 + Tls13SecretCb tls13SecretCb; + void* tls13SecretCtx; + #endif #endif /* HAVE_SECRET_CALLBACK */ #ifdef WOLFSSL_JNI void* jObjectRef; /* reference to WolfSSLSession in JNI wrapper */ diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index e52b395dc..25b86ad5b 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -643,6 +643,19 @@ enum AlertLevel { /* Maximum number of groups that can be set */ #define WOLFSSL_MAX_GROUP_COUNT 10 +#if defined(HAVE_SECRET_CALLBACK) && defined(WOLFSSL_TLS13) +enum Tls13Secret { + CLIENT_EARLY_TRAFFIC_SECRET, + CLIENT_HANDSHAKE_TRAFFIC_SECRET, + SERVER_HANDSHAKE_TRAFFIC_SECRET, + CLIENT_TRAFFIC_SECRET, + SERVER_TRAFFIC_SECRET, + EARLY_EXPORTER_SECRET, + EXPORTER_SECRET +}; +#endif + + typedef WOLFSSL_METHOD* (*wolfSSL_method_func)(void* heap); /* CTX Method EX Constructor Functions */ @@ -957,9 +970,15 @@ WOLFSSL_ABI WOLFSSL_API long wolfSSL_CTX_set_session_cache_mode(WOLFSSL_CTX*, long); #ifdef HAVE_SECRET_CALLBACK -typedef int (*SessionSecretCb)(WOLFSSL* ssl, - void* secret, int* secretSz, void* ctx); -WOLFSSL_API int wolfSSL_set_session_secret_cb(WOLFSSL*, SessionSecretCb, void*); +typedef int (*SessionSecretCb)(WOLFSSL* ssl, void* secret, int* secretSz, + void* ctx); +WOLFSSL_API int wolfSSL_set_session_secret_cb(WOLFSSL*, SessionSecretCb, + void*); +#ifdef WOLFSSL_TLS13 +typedef int (*Tls13SecretCb)(WOLFSSL* ssl, int id, const unsigned char* secret, + int secretSz, void* ctx); +WOLFSSL_API int wolfSSL_set_tls13_secret_cb(WOLFSSL*, Tls13SecretCb, void*); +#endif #endif /* HAVE_SECRET_CALLBACK */ /* session cache persistence */ From aaaa191937fd84375b0df9597ee37e9841ec9c4c Mon Sep 17 00:00:00 2001 From: Tesfa Mael Date: Fri, 14 Feb 2020 12:54:35 -0800 Subject: [PATCH 055/649] Trim trailing padding byte --- wolfcrypt/src/asn.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 9cd7839b7..3f27159bf 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -10234,6 +10234,9 @@ int PemToDer(const unsigned char* buff, long longSz, int type, DerBuffer* der; #if defined(HAVE_PKCS8) || defined(WOLFSSL_ENCRYPTED_KEYS) word32 algId = 0; + #if defined(WOLFSSL_ENCRYPTED_KEYS) && !defined(NO_DES3) && !defined(NO_WOLFSSL_SKIP_TRAILING_PAD) + int padVal = 0; + #endif #endif WOLFSSL_ENTER("PemToDer"); @@ -10428,6 +10431,18 @@ int PemToDer(const unsigned char* buff, long longSz, int type, else { ret = wc_BufferKeyDecrypt(info, der->buffer, der->length, (byte*)password, passwordSz, WC_MD5); + +#ifndef NO_WOLFSSL_SKIP_TRAILING_PAD + #ifndef NO_DES3 + if (info->cipherType == WC_CIPHER_DES3) { + padVal = der->buffer[der->length-1]; + if (padVal <= DES_BLOCK_SIZE) { + der->length -= padVal; + } + } + #endif /* !NO_DES3 */ +#endif /* !NO_WOLFSSL_SKIP_TRAILING_PAD */ + } ForceZero(password, passwordSz); } From 8972bf62785b72ac853240d925582e148ae95a10 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Mon, 2 Dec 2019 10:04:58 +1000 Subject: [PATCH 056/649] Add support for P384 curve into SP --- configure.ac | 128 +- tests/api.c | 2 +- wolfcrypt/benchmark/benchmark.c | 45 +- wolfcrypt/src/ecc.c | 231 +- wolfcrypt/src/sp_arm32.c | 9054 ++++++++++++++++++++++++++++--- wolfcrypt/src/sp_arm64.c | 6831 +++++++++++++++++++++-- wolfcrypt/src/sp_armthumb.c | 6748 +++++++++++++++++++++-- wolfcrypt/src/sp_c32.c | 7358 +++++++++++++++++++++++-- wolfcrypt/src/sp_c64.c | 6833 +++++++++++++++++++++-- wolfcrypt/src/sp_cortexm.c | 6786 ++++++++++++++++++++--- wolfcrypt/src/sp_int.c | 54 +- wolfcrypt/src/sp_x86_64.c | 6712 +++++++++++++++++++++-- wolfcrypt/src/sp_x86_64_asm.S | 3639 ++++++++++--- wolfssl/wolfcrypt/sp.h | 22 + wolfssl/wolfcrypt/sp_int.h | 2 + 15 files changed, 49803 insertions(+), 4642 deletions(-) diff --git a/configure.ac b/configure.ac index f3f27dfcb..7ad86ed65 100644 --- a/configure.ac +++ b/configure.ac @@ -4124,92 +4124,128 @@ AC_ARG_ENABLE([sp], ENABLED_SP_RSA=no ENABLED_SP_DH=no +ENABLED_SP_FF_2048=no +ENABLED_SP_FF_3072=no +ENABLED_SP_FF_4096=no ENABLED_SP_ECC=no +ENABLED_SP_EC_256=no +ENABLED_SP_EC_384=no for v in `echo $ENABLED_SP | tr "," " "` do case $v in small) - AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_SMALL" ENABLED_SP_RSA=yes ENABLED_SP_DH=yes + ENABLED_SP_FF_2048=yes + ENABLED_SP_FF_3072=yes ENABLED_SP_ECC=yes + ENABLED_SP_SMALL=yes + ENABLED_SP_EC_256=yes + if test "$host_cpu" = "x86_64"; then + ENABLED_SP_FF_4096=yes + ENABLED_SP_EC_384=yes + fi ;; yes) ENABLED_SP_RSA=yes ENABLED_SP_DH=yes + ENABLED_SP_FF_2048=yes + ENABLED_SP_FF_3072=yes ENABLED_SP_ECC=yes + ENABLED_SP_EC_256=yes + if test "$host_cpu" = "x86_64"; then + ENABLED_SP_FF_4096=yes + ENABLED_SP_EC_384=yes + fi ;; no) ;; smallec256 | smallp256 | small256) ENABLED_SP_ECC=yes - AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_SMALL" - AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_SP_SMALL" + ENABLED_SP_SMALL=yes + ENABLED_SP_EC_256=yes ;; ec256 | p256 | 256) ENABLED_SP_ECC=yes + ENABLED_SP_EC_256=yes + ;; + smallec384 | smallp384 | small384) + ENABLED_SP_ECC=yes + ENABLED_SP_SMALL=yes + ENABLED_SP_EC_384=yes + ;; + ec384 | p384 | 384) + ENABLED_SP_ECC=yes + ENABLED_SP_EC_384=yes ;; small2048) - AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_SMALL" - AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_SP_SMALL" + ENABLED_SP_SMALL=yes ENABLED_SP_RSA=yes ENABLED_SP_DH=yes - AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_NO_3072" - AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_SP_NO_3072" + ENABLED_SP_FF_2048=yes ;; 2048) ENABLED_SP_RSA=yes ENABLED_SP_DH=yes - AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_NO_3072" - AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_SP_NO_3072" + ENABLED_SP_FF_2048=yes ;; smallrsa2048) - AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_SMALL" - AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_SP_SMALL" + ENABLED_SP_SMALL=yes ENABLED_SP_RSA=yes - AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_NO_3072" - AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_SP_NO_3072" + ENABLED_SP_FF_2048=yes ;; rsa2048) ENABLED_SP_RSA=yes - AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_NO_3072" - AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_SP_NO_3072" + ENABLED_SP_FF_2048=yes ;; small3072) - AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_SMALL" - AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_SP_SMALL" + ENABLED_SP_SMALL=yes ENABLED_SP_RSA=yes ENABLED_SP_DH=yes - AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_NO_2048" - AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_SP_NO_2048" + ENABLED_SP_FF_3072=yes ;; 3072) ENABLED_SP_RSA=yes ENABLED_SP_DH=yes - AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_NO_2048" - AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_SP_NO_2048" + ENABLED_SP_FF_3072=yes ;; smallrsa3072) - AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_SMALL" - AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_SP_SMALL" + ENABLED_SP_SMALL=yes ENABLED_SP_RSA=yes - AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_NO_2048" - AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_SP_NO_2048" + ENABLED_SP_FF_3072=yes ;; rsa3072) ENABLED_SP_RSA=yes - AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_NO_2048" - AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_SP_NO_2048" + ENABLED_SP_FF_3072=yes ;; - +4096) - AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_4096" - AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_SP_4096" + small4096) + ENABLED_SP_SMALL=yes + ENABLED_SP_RSA=yes + ENABLED_SP_DH=yes + ENABLED_SP_FF_4096=yes + ;; + + 4096 | +4096) + ENABLED_SP_RSA=yes + ENABLED_SP_DH=yes + ENABLED_SP_FF_4096=yes + ;; + + smallrsa4096) + ENABLED_SP_SMALL=yes + ENABLED_SP_RSA=yes + ENABLED_SP_FF_4096=yes + ;; + + rsa4096) + ENABLED_SP_RSA=yes + ENABLED_SP_FF_4096=yes ;; *) @@ -4229,10 +4265,36 @@ if test "$ENABLED_DH" = "yes" && test "$ENABLED_SP_DH" = "yes"; then AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_HAVE_SP_DH" AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_HAVE_SP_DH" fi +if test "$ENABLED_SP_RSA" = "yes" || test "$ENABLED_SP_DH" = "yes"; then + if test "$ENABLED_SP_FF_2048" = "no"; then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_NO_2048" + AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_SP_NO_2048" + fi + if test "$ENABLED_SP_FF_3072" = "no"; then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_NO_3072" + AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_SP_NO_3072" + fi + if test "$ENABLED_SP_FF_4096" = "yes"; then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_4096" + AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_SP_4096" + fi +fi if test "$ENABLED_ECC" = "yes" && test "$ENABLED_SP_ECC" = "yes"; then ENABLED_SP=yes AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_HAVE_SP_ECC" AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_HAVE_SP_ECC" + if test "$ENABLED_SP_EC_256" = "no"; then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_NO_256" + AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_SP_NO_256" + fi + if test "$ENABLED_SP_EC_384" = "yes"; then + AM_CFLAGS="$AM_CFLAGS -DHAVE_ECC384 -DWOLFSSL_SP_384" + AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_SP_384" + fi +fi +if test "$ENABLED_SP_SMALL" = "yes"; then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_SMALL" + AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_SP_SMALL" fi @@ -4264,7 +4326,7 @@ if test "$ENABLED_SP_ASM" = "yes"; then ENABLED_SP_ARM_THUMB_ASM=yes else if test $host_alias = "cortex"; then - AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_ARM_CORTEX_M_ASM -mcpu=cortex-m4" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_SP_ARM_CORTEX_M_ASM -mcpu=cortex-r5" AM_CCASFLAGS="$AM_CCASFLAGS -DWOLFSSL_SP_ARM_CORTEX_M_ASM" ENABLED_SP_ARM_CORTEX_ASM=yes else @@ -4307,10 +4369,10 @@ if test "$ENABLED_SP_MATH" = "yes"; then AC_MSG_ERROR([Cannot use single precision math and SRP]) fi if test "$ENABLED_SP_RSA" = "no" && test "$ENABLED_RSA" = "yes"; then - AC_MSG_ERROR([Cannot use P256 single precision only math and RSA]) + AC_MSG_ERROR([Cannot use RSA single precision only math and RSA]) fi if test "$ENABLED_SP_DH" = "no" && test "$ENABLED_DH" = "yes"; then - AC_MSG_ERROR([Cannot use P256 single precision only math and DH]) + AC_MSG_ERROR([Cannot use DH single precision only math and DH]) fi ENABLED_FASTMATH="no" diff --git a/tests/api.c b/tests/api.c index 4fa095e18..ab1ce665a 100644 --- a/tests/api.c +++ b/tests/api.c @@ -253,7 +253,7 @@ #endif #if defined(WOLFSSL_SHA3) || defined(HAVE_PKCS7) || (!defined(NO_RSA) && \ - !defined(WOLFSSL_RSA_PUBLIC_ONLY)) || !defined(NO_SIG_WRAPPER) + !defined(NO_SIG_WRAPPER)) static int devId = INVALID_DEVID; #endif #ifndef NO_DSA diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index 20ccbfcb4..d9c5cf81d 100755 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -508,7 +508,7 @@ static int lng_index = 0; #ifndef NO_MAIN_DRIVER #ifndef MAIN_NO_ARGS -static const char* bench_Usage_msg1[][14] = { +static const char* bench_Usage_msg1[][16] = { /* 0 English */ { "-? Help, print this usage\n 0: English, 1: Japanese\n", "-csv Print terminal output in csv format\n", @@ -519,6 +519,8 @@ static const char* bench_Usage_msg1[][14] = { " -rsa-sz\n Measure RSA performance.\n", "-ffhdhe2048 Measure DH using FFDHE 2048-bit parameters.\n", "-ffhdhe3072 Measure DH using FFDHE 3072-bit parameters.\n", + "-p256 Measure ECC using P-256 curve.\n", + "-p384 Measure ECC using P-384 curve.\n", "- Algorithm to benchmark. Available algorithms include:\n", "-lng Display benchmark result by specified language.\n 0: English, 1: Japanese\n", " Size of block in bytes\n", @@ -536,6 +538,8 @@ static const char* bench_Usage_msg1[][14] = { " -rsa-sz\n RSA の性能を測定します。\n", "-ffhdhe2048 Measure DH using FFDHE 2048-bit parameters.\n", "-ffhdhe3072 Measure DH using FFDHE 3072-bit parameters.\n", + "-p256 Measure ECC using P-256 curve.\n", + "-p384 Measure ECC using P-384 curve.\n", "- アルゴリズムのベンチマークを実施します。\n 利用可能なアルゴリズムは下記を含みます:\n", "-lng 指定された言語でベンチマーク結果を表示します。\n 0: 英語、 1: 日本語\n", " ブロックサイズをバイト単位で指定します。\n", @@ -5099,13 +5103,20 @@ void bench_ntruKeyGen(void) #ifdef HAVE_ECC #ifndef BENCH_ECC_SIZE - #define BENCH_ECC_SIZE 32 + #ifdef HAVE_ECC384 + #define BENCH_ECC_SIZE 48 + #else + #define BENCH_ECC_SIZE 32 + #endif #endif +/* Default to testing P-256 */ +static int bench_ecc_size = 32; + void bench_eccMakeKey(int doAsync) { int ret = 0, i, times, count, pending = 0; - const int keySize = BENCH_ECC_SIZE; + const int keySize = bench_ecc_size; ecc_key genKey[BENCH_MAX_PENDING]; double start; const char**desc = bench_desc_words[lng_index]; @@ -5150,7 +5161,7 @@ exit: void bench_ecc(int doAsync) { int ret = 0, i, times, count, pending = 0; - const int keySize = BENCH_ECC_SIZE; + const int keySize = bench_ecc_size; ecc_key genKey[BENCH_MAX_PENDING]; #ifdef HAVE_ECC_DHE ecc_key genKey2[BENCH_MAX_PENDING]; @@ -5321,7 +5332,7 @@ exit: void bench_eccEncrypt(void) { ecc_key userA, userB; - const int keySize = BENCH_ECC_SIZE; + const int keySize = bench_ecc_size; byte msg[48]; byte out[80]; word32 outSz = sizeof(out); @@ -5815,8 +5826,14 @@ static void Usage(void) #if !defined(NO_DH) && defined(HAVE_FFDHE_3072) printf("%s", bench_Usage_msg1[lng_index][8]); /* option -ffdhe3072 */ #endif +#if defined(HAVE_ECC) && !defined(NO_ECC256) + printf("%s", bench_Usage_msg1[lng_index][9]); /* option -p256 */ +#endif +#if defined(HAVE_ECC) && defined(HAVE_ECC384) + printf("%s", bench_Usage_msg1[lng_index][10]); /* option -p384 */ +#endif #ifndef WOLFSSL_BENCHMARK_ALL - printf("%s", bench_Usage_msg1[lng_index][9]); /* option - */ + printf("%s", bench_Usage_msg1[lng_index][11]); /* option - */ printf(" "); line = 13; for (i=0; bench_cipher_opt[i].str != NULL; i++) @@ -5839,12 +5856,12 @@ static void Usage(void) print_alg(bench_other_opt[i].str + 1, &line); printf("\n"); #endif - printf("%s", bench_Usage_msg1[lng_index][10]); /* option -lng */ - printf("%s", bench_Usage_msg1[lng_index][11]); /* option */ + printf("%s", bench_Usage_msg1[lng_index][12]); /* option -lng */ + printf("%s", bench_Usage_msg1[lng_index][13]); /* option */ #if defined(WOLFSSL_ASYNC_CRYPT) && !defined(WC_NO_ASYNC_THREADING) - printf("%s", bench_Usage_msg1[lng_index][12]); /* option -threads */ + printf("%s", bench_Usage_msg1[lng_index][14]); /* option -threads */ #endif - printf("%s", bench_Usage_msg1[lng_index][13]); /* option -print */ + printf("%s", bench_Usage_msg1[lng_index][15]); /* option -print */ } /* Match the command line argument with the string. @@ -5932,6 +5949,14 @@ int main(int argc, char** argv) else if (string_matches(argv[1], "-ffdhe3072")) use_ffdhe = 3072; #endif +#if defined(HAVE_ECC) && !defined(NO_ECC256) + else if (string_matches(argv[1], "-p256")) + bench_ecc_size = 32; +#endif +#if defined(HAVE_ECC) && defined(HAVE_ECC384) + else if (string_matches(argv[1], "-p384")) + bench_ecc_size = 48; +#endif #ifdef BENCH_ASYM else if (string_matches(argv[1], "-csv")) { csv_format = 1; diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 785378eeb..5e3bfaf64 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -1885,8 +1885,19 @@ done: (void)a; (void)mp; - return sp_ecc_proj_add_point_256(P->x, P->y, P->z, Q->x, Q->y, Q->z, - R->x, R->y, R->z); +#ifndef WOLFSSL_SP_NO_256 + if (mp_count_bits(modulus) == 256) { + return sp_ecc_proj_add_point_256(P->x, P->y, P->z, Q->x, Q->y, Q->z, + R->x, R->y, R->z); + } +#endif +#ifdef WOLFSSL_SP_384 + if (mp_count_bits(modulus) == 384) { + return sp_ecc_proj_add_point_384(P->x, P->y, P->z, Q->x, Q->y, Q->z, + R->x, R->y, R->z); + } +#endif + return ECC_BAD_ARG_E; #endif } @@ -2254,7 +2265,17 @@ int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a, (void)a; (void)mp; - return sp_ecc_proj_dbl_point_256(P->x, P->y, P->z, R->x, R->y, R->z); +#ifndef WOLFSSL_SP_NO_256 + if (mp_count_bits(modulus) == 256) { + return sp_ecc_proj_dbl_point_256(P->x, P->y, P->z, R->x, R->y, R->z); + } +#endif +#ifdef WOLFSSL_SP_384 + if (mp_count_bits(modulus) == 384) { + return sp_ecc_proj_dbl_point_384(P->x, P->y, P->z, R->x, R->y, R->z); + } +#endif + return ECC_BAD_ARG_E; #endif } @@ -2449,7 +2470,17 @@ done: (void)mp; - return sp_ecc_map_256(P->x, P->y, P->z); +#ifndef WOLFSSL_SP_NO_256 + if (mp_count_bits(modulus) == 256) { + return sp_ecc_map_256(P->x, P->y, P->z); + } +#endif +#ifdef WOLFSSL_SP_384 + if (mp_count_bits(modulus) == 384) { + return sp_ecc_map_384(P->x, P->y, P->z); + } +#endif + return ECC_BAD_ARG_E; #endif } @@ -2936,7 +2967,17 @@ exit: (void)a; - return sp_ecc_mulmod_256(k, G, R, map, heap); +#ifndef WOLFSSL_SP_NO_256 + if (mp_count_bits(modulus) == 256) { + return sp_ecc_mulmod_256(k, G, R, map, heap); + } +#endif +#ifdef WOLFSSL_SP_384 + if (mp_count_bits(modulus) == 384) { + return sp_ecc_mulmod_384(k, G, R, map, heap); + } +#endif + return ECC_BAD_ARG_E; #endif } @@ -3582,6 +3623,13 @@ static int wc_ecc_shared_secret_gen_sync(ecc_key* private_key, ecc_point* point, } else #endif +#ifdef WOLFSSL_SP_384 + if (private_key->idx != ECC_CUSTOM_IDX && + ecc_sets[private_key->idx].id == ECC_SECP384R1) { + err = sp_ecc_secret_gen_384(k, point, out, outlen, private_key->heap); + } + else +#endif #endif #ifdef WOLFSSL_SP_MATH { @@ -3948,6 +3996,13 @@ static int wc_ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curveIn, } else #endif +#ifdef WOLFSSL_SP_384 + if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) { + if (err == MP_OKAY) + err = sp_ecc_mulmod_base_384(&key->k, pub, 1, key->heap); + } + else +#endif #endif #ifdef WOLFSSL_SP_MATH err = WC_KEY_SIZE_E; @@ -4166,8 +4221,18 @@ int wc_ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key, int curve_id) #ifndef WOLFSSL_SP_NO_256 if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) { err = sp_ecc_make_key_256(rng, &key->k, &key->pubkey, key->heap); - if (err == MP_OKAY) + if (err == MP_OKAY) { key->type = ECC_PRIVATEKEY; + } + } + else +#endif +#ifdef WOLFSSL_SP_384 + if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) { + err = sp_ecc_make_key_384(rng, &key->k, &key->pubkey, key->heap); + if (err == MP_OKAY) { + key->type = ECC_PRIVATEKEY; + } } else #endif @@ -4780,6 +4845,7 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, } #ifdef WOLFSSL_SP_MATH +#ifndef WOLFSSL_SP_NO_256 if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) { #ifndef WOLFSSL_ECDSA_SET_K return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, NULL, key->heap); @@ -4788,17 +4854,27 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, key->heap); #endif } - else { - return WC_KEY_SIZE_E; +#endif +#ifdef WOLFSSL_SP_384 + if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) { + #ifndef WOLFSSL_ECDSA_SET_K + return sp_ecc_sign_384(in, inlen, rng, &key->k, r, s, NULL, key->heap); + #else + return sp_ecc_sign_384(in, inlen, rng, &key->k, r, s, key->sign_k, + key->heap); + #endif } +#endif + return WC_KEY_SIZE_E; #else #ifdef WOLFSSL_HAVE_SP_ECC #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) if (key->asyncDev.marker != WOLFSSL_ASYNC_MARKER_ECC) #endif { - #ifndef WOLFSSL_SP_NO_256 - if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) +#ifndef WOLFSSL_SP_NO_256 + if (key->idx != ECC_CUSTOM_IDX && + ecc_sets[key->idx].id == ECC_SECP256R1) { #ifndef WOLFSSL_ECDSA_SET_K return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, NULL, key->heap); @@ -4806,7 +4882,20 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng, return sp_ecc_sign_256(in, inlen, rng, &key->k, r, s, key->sign_k, key->heap); #endif - #endif + } +#endif +#ifdef WOLFSSL_SP_384 + if (key->idx != ECC_CUSTOM_IDX && + ecc_sets[key->idx].id == ECC_SECP384R1) { + #ifndef WOLFSSL_ECDSA_SET_K + return sp_ecc_sign_384(in, inlen, rng, &key->k, r, s, NULL, + key->heap); + #else + return sp_ecc_sign_384(in, inlen, rng, &key->k, r, s, key->sign_k, + key->heap); + #endif + } +#endif } #endif /* WOLFSSL_HAVE_SP_ECC */ @@ -5852,24 +5941,42 @@ int wc_ecc_verify_hash_ex(mp_int *r, mp_int *s, const byte* hash, } #endif #if defined(WOLFSSL_SP_MATH) && !defined(FREESCALE_LTC_ECC) +#ifndef WOLFSSL_SP_NO_256 if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) { return sp_ecc_verify_256(hash, hashlen, key->pubkey.x, key->pubkey.y, key->pubkey.z, r, s, res, key->heap); } - else - return WC_KEY_SIZE_E; +#endif +#ifdef WOLFSSL_SP_384 + if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) { + return sp_ecc_verify_384(hash, hashlen, key->pubkey.x, key->pubkey.y, + key->pubkey.z, r, s, res, key->heap); + } +#endif + return WC_KEY_SIZE_E; #else #if defined WOLFSSL_HAVE_SP_ECC && !defined(FREESCALE_LTC_ECC) -#ifndef WOLFSSL_SP_NO_256 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_ECC) if (key->asyncDev.marker != WOLFSSL_ASYNC_MARKER_ECC) #endif { - if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) - return sp_ecc_verify_256(hash, hashlen, key->pubkey.x, key->pubkey.y, - key->pubkey.z,r, s, res, key->heap); - } +#ifndef WOLFSSL_SP_NO_256 + if (key->idx != ECC_CUSTOM_IDX && + ecc_sets[key->idx].id == ECC_SECP256R1) { + return sp_ecc_verify_256(hash, hashlen, key->pubkey.x, + key->pubkey.y, key->pubkey.z,r, s, res, + key->heap); + } #endif /* WOLFSSL_SP_NO_256 */ +#ifdef WOLFSSL_SP_384 + if (key->idx != ECC_CUSTOM_IDX && + ecc_sets[key->idx].id == ECC_SECP384R1) { + return sp_ecc_verify_384(hash, hashlen, key->pubkey.x, + key->pubkey.y, key->pubkey.z,r, s, res, + key->heap); + } +#endif /* WOLFSSL_SP_384 */ + } #endif /* WOLFSSL_HAVE_SP_ECC */ ALLOC_CURVE_SPECS(ECC_CURVE_FIELD_COUNT); @@ -6257,7 +6364,23 @@ int wc_ecc_import_point_der(byte* in, word32 inLen, const int curve_idx, wc_ecc_curve_free(curve); FREE_CURVE_SPECS(); #else - sp_ecc_uncompress_256(point->x, pointType, point->y); + #ifndef WOLFSSL_SP_NO_256 + if (curve_idx != ECC_CUSTOM_IDX && + ecc_sets[curve_idx].id == ECC_SECP256R1) { + sp_ecc_uncompress_256(point->x, pointType, point->y); + } + else + #endif + #ifdef WOLFSSL_SP_384 + if (curve_idx != ECC_CUSTOM_IDX && + ecc_sets[curve_idx].id == ECC_SECP384R1) { + sp_ecc_uncompress_384(point->x, pointType, point->y); + } + else + #endif + { + err = WC_KEY_SIZE_E; + } #endif } #endif @@ -6551,9 +6674,18 @@ int wc_ecc_is_point(ecc_point* ecp, mp_int* a, mp_int* b, mp_int* prime) #else (void)a; (void)b; - (void)prime; - return sp_ecc_is_point_256(ecp->x, ecp->y); +#ifndef WOLFSSL_SP_NO_256 + if (mp_count_bits(prime) == 256) { + return sp_ecc_is_point_256(ecp->x, ecp->y); + } +#endif +#ifdef WOLFSSL_SP_384 + if (mp_count_bits(prime) == 384) { + return sp_ecc_is_point_384(ecp->x, ecp->y); + } +#endif + return WC_KEY_SIZE_E; #endif } @@ -6578,8 +6710,17 @@ static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime) #ifdef WOLFSSL_HAVE_SP_ECC #ifndef WOLFSSL_SP_NO_256 if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) { - if (err == MP_OKAY) + if (err == MP_OKAY) { err = sp_ecc_mulmod_base_256(&key->k, res, 1, key->heap); + } + } + else +#endif +#ifdef WOLFSSL_SP_384 + if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) { + if (err == MP_OKAY) { + err = sp_ecc_mulmod_base_384(&key->k, res, 1, key->heap); + } } else #endif @@ -6687,6 +6828,13 @@ static int ecc_check_pubkey_order(ecc_key* key, ecc_point* pubkey, mp_int* a, } else #endif +#ifdef WOLFSSL_SP_384 + if (key->idx != ECC_CUSTOM_IDX && + ecc_sets[key->idx].id == ECC_SECP384R1) { + err = sp_ecc_mulmod_384(order, pubkey, inf, 1, key->heap); + } + else +#endif #endif #ifndef WOLFSSL_SP_MATH err = wc_ecc_mulmod_ex(order, pubkey, inf, a, prime, 1, key->heap); @@ -6824,12 +6972,23 @@ int wc_ecc_check_key(ecc_key* key) return BAD_FUNC_ARG; /* pubkey point cannot be at infinity */ +#ifndef WOLFSSL_SP_NO_256 if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) { err = sp_ecc_check_key_256(key->pubkey.x, key->pubkey.y, &key->k, key->heap); } else +#endif +#ifdef WOLFSSL_SP_384 + if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) { + err = sp_ecc_check_key_384(key->pubkey.x, key->pubkey.y, &key->k, + key->heap); + } + else +#endif + { err = WC_KEY_SIZE_E; + } #endif return err; @@ -6977,7 +7136,21 @@ int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key, wc_ecc_curve_free(curve); FREE_CURVE_SPECS(); #else - sp_ecc_uncompress_256(key->pubkey.x, pointType, key->pubkey.y); + #ifndef WOLFSSL_SP_NO_256 + if (key->dp->id == ECC_SECP256R1) { + sp_ecc_uncompress_256(key->pubkey.x, pointType, key->pubkey.y); + } + else + #endif + #ifdef WOLFSSL_SP_384 + if (key->dp->id == ECC_SECP384R1) { + sp_ecc_uncompress_384(key->pubkey.x, pointType, key->pubkey.y); + } + else + #endif + { + err = WC_KEY_SIZE_E; + } #endif } #endif /* HAVE_COMP_KEY */ @@ -9234,7 +9407,17 @@ int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R, mp_int* a, return ECC_BAD_ARG_E; } - return sp_ecc_mulmod_256(k, G, R, map, heap); +#ifndef WOLFSSL_SP_NO_256 + if (mp_count_bits(modulus) == 256) { + return sp_ecc_mulmod_256(k, G, R, map, heap); + } +#endif +#ifdef WOLFSSL_SP_384 + if (mp_count_bits(modulus) == 384) { + return sp_ecc_mulmod_384(k, G, R, map, heap); + } +#endif + return WC_KEY_SIZE_E; #endif } diff --git a/wolfcrypt/src/sp_arm32.c b/wolfcrypt/src/sp_arm32.c index 7821a2479..8fd412d3b 100644 --- a/wolfcrypt/src/sp_arm32.c +++ b/wolfcrypt/src/sp_arm32.c @@ -72248,12 +72248,12 @@ int sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen, #ifndef WOLFSSL_SP_NO_256 /* Point structure to use. */ -typedef struct sp_point { +typedef struct sp_point_256 { sp_digit x[2 * 8]; sp_digit y[2 * 8]; sp_digit z[2 * 8]; int infinity; -} sp_point; +} sp_point_256; /* The modulus (prime) of the curve P256. */ static const sp_digit p256_mod[8] = { @@ -72292,21 +72292,24 @@ static const sp_digit p256_norm_order[8] = { static const sp_digit p256_mp_order = 0xee00bc4f; #endif /* The base point of curve P256. */ -static const sp_point p256_base = { +static const sp_point_256 p256_base = { /* X ordinate */ { 0xd898c296,0xf4a13945,0x2deb33a0,0x77037d81,0x63a440f2,0xf8bce6e5, - 0xe12c4247,0x6b17d1f2, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + 0xe12c4247,0x6b17d1f2, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L }, /* Y ordinate */ { 0x37bf51f5,0xcbb64068,0x6b315ece,0x2bce3357,0x7c0f9e16,0x8ee7eb4a, - 0xfe1a7f9b,0x4fe342e2, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + 0xfe1a7f9b,0x4fe342e2, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L }, /* Z ordinate */ { 0x00000001,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + 0x00000000,0x00000000, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L }, /* infinity */ 0 @@ -72318,34 +72321,32 @@ static const sp_digit p256_b[8] = { }; #endif -static int sp_ecc_point_new_ex(void* heap, sp_point* sp, sp_point** p) +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) + (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; } - else { - #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - *p = (sp_point*)XMALLOC(sizeof(sp_point), heap, DYNAMIC_TYPE_ECC); - (void)sp; - #else - *p = sp; - (void)heap; - #endif - } return ret; } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) /* Allocate memory for point and return error. */ -#define sp_ecc_point_new(heap, sp, p) sp_ecc_point_new_ex((heap), NULL, &(p)) +#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_ecc_point_new(heap, sp, p) sp_ecc_point_new_ex((heap), &(sp), &(p)) +#define sp_256_point_new_8(heap, sp, p) sp_256_point_new_ex_8((heap), &(sp), &(p)) #endif -static void sp_ecc_point_free(sp_point* p, int clear, void* heap) +static void sp_256_point_free_8(sp_point_256* p, int clear, void* heap) { #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) /* If valid pointer then clear point data if requested and free data. */ @@ -72681,12 +72682,12 @@ static void sp_256_from_mp(sp_digit* r, int size, const mp_int* a) #endif } -/* Convert a point of type ecc_point to type sp_point. +/* Convert a point of type ecc_point to type sp_point_256. * - * p Point of type sp_point (result). + * 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* 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)); @@ -72761,14 +72762,14 @@ static int sp_256_to_mp(const sp_digit* a, mp_int* r) return err; } -/* Convert a point of type sp_point to type ecc_point. +/* Convert a point of type sp_point_256 to type ecc_point. * - * p Point of type sp_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* p, ecc_point* pm) +static int sp_256_point_to_ecc_point_8(const sp_point_256* p, ecc_point* pm) { int err; @@ -72783,345 +72784,6 @@ static int sp_256_point_to_ecc_point_8(const sp_point* p, ecc_point* pm) 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 int32_t sp_256_cmp_8(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, #28\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], #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; -} - -/* Normalize the values in each word to 32. - * - * a Array of sp_digit to normalize. - */ -#define sp_256_norm_8(a) - -/* 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_256_cond_sub_8(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, #32\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" - "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; -} - -#define sp_256_mont_reduce_order_8 sp_256_mont_reduce_8 - -/* 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. - */ -SP_NOINLINE static void sp_256_mont_reduce_8(sp_digit* a, const sp_digit* m, - sp_digit mp) -{ - sp_digit ca = 0; - - __asm__ __volatile__ ( - "# 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 r7, [%[m], #0]\n\t" - "ldr r9, [%[a], #0]\n\t" - "umull r6, r7, r8, r7\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 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], #28]\n\t" - "ldr r9, [%[a], #32]\n\t" - "adcs r9, r9, r7\n\t" - "str r9, [%[a], #32]\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, #32\n\t" - "blt 1b\n\t" - "str r10, [%[a], #0]\n\t" - "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" - ); - - sp_256_cond_sub_8(a - 8, a, m, (sp_digit)0 - ca); -} - /* Multiply two Montogmery form numbers mod the modulus (prime). * (r = a * b mod m) * @@ -74318,7 +73980,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 */ #ifdef WOLFSSL_SP_SMALL /* Mod-2 for the P256 curve. */ -static const uint32_t p256_mod_2[8] = { +static const uint32_t p256_mod_minus_2[8] = { 0xfffffffdU,0xffffffffU,0xffffffffU,0x00000000U,0x00000000U,0x00000000U, 0x00000001U,0xffffffffU }; @@ -74340,71 +74002,405 @@ static void sp_256_mont_inv_8(sp_digit* r, const sp_digit* a, sp_digit* td) XMEMCPY(t, a, sizeof(sp_digit) * 8); for (i=254; i>=0; i--) { sp_256_mont_sqr_8(t, t, p256_mod, p256_mp_mod); - if (p256_mod_2[i / 32] & ((sp_digit)1 << (i % 32))) + if (p256_mod_minus_2[i / 32] & ((sp_digit)1 << (i % 32))) sp_256_mont_mul_8(t, t, a, p256_mod, p256_mp_mod); } XMEMCPY(r, t, sizeof(sp_digit) * 8); #else - sp_digit* t = td; + sp_digit* t1 = td; sp_digit* t2 = td + 2 * 8; sp_digit* t3 = td + 4 * 8; - - /* t = a^2 */ - sp_256_mont_sqr_8(t, a, p256_mod, p256_mp_mod); - /* t = a^3 = t * a */ - sp_256_mont_mul_8(t, t, a, p256_mod, p256_mp_mod); - /* t2= a^c = t ^ 2 ^ 2 */ - sp_256_mont_sqr_n_8(t2, t, 2, p256_mod, p256_mp_mod); - /* t3= a^d = t2 * a */ - sp_256_mont_mul_8(t3, t2, a, p256_mod, p256_mp_mod); - /* t = a^f = t2 * t */ - sp_256_mont_mul_8(t, t2, t, p256_mod, p256_mp_mod); - /* t2= a^f0 = t ^ 2 ^ 4 */ - sp_256_mont_sqr_n_8(t2, t, 4, p256_mod, p256_mp_mod); - /* t3= a^fd = t2 * t3 */ - sp_256_mont_mul_8(t3, t2, t3, p256_mod, p256_mp_mod); - /* t = a^ff = t2 * t */ - sp_256_mont_mul_8(t, t2, t, p256_mod, p256_mp_mod); - /* t2= a^ff00 = t ^ 2 ^ 8 */ - sp_256_mont_sqr_n_8(t2, t, 8, p256_mod, p256_mp_mod); - /* t3= a^fffd = t2 * t3 */ - sp_256_mont_mul_8(t3, t2, t3, p256_mod, p256_mp_mod); - /* t = a^ffff = t2 * t */ - sp_256_mont_mul_8(t, t2, t, p256_mod, p256_mp_mod); - /* t2= a^ffff0000 = t ^ 2 ^ 16 */ - sp_256_mont_sqr_n_8(t2, t, 16, p256_mod, p256_mp_mod); - /* t3= a^fffffffd = t2 * t3 */ - sp_256_mont_mul_8(t3, t2, t3, p256_mod, p256_mp_mod); - /* t = a^ffffffff = t2 * t */ - sp_256_mont_mul_8(t, t2, t, p256_mod, p256_mp_mod); - /* t = a^ffffffff00000000 = t ^ 2 ^ 32 */ - sp_256_mont_sqr_n_8(t2, t, 32, p256_mod, p256_mp_mod); - /* t2= a^ffffffffffffffff = t2 * t */ - sp_256_mont_mul_8(t, t2, t, p256_mod, p256_mp_mod); - /* t2= a^ffffffff00000001 = t2 * a */ - sp_256_mont_mul_8(t2, t2, a, p256_mod, p256_mp_mod); - /* t2= a^ffffffff000000010000000000000000000000000000000000000000 - * = t2 ^ 2 ^ 160 */ - sp_256_mont_sqr_n_8(t2, t2, 160, p256_mod, p256_mp_mod); - /* t2= a^ffffffff00000001000000000000000000000000ffffffffffffffff - * = t2 * t */ - sp_256_mont_mul_8(t2, t2, t, p256_mod, p256_mp_mod); - /* t2= a^ffffffff00000001000000000000000000000000ffffffffffffffff00000000 - * = t2 ^ 2 ^ 32 */ - sp_256_mont_sqr_n_8(t2, t2, 32, p256_mod, p256_mp_mod); - /* r = a^ffffffff00000001000000000000000000000000fffffffffffffffffffffffd - * = t2 * t3 */ - sp_256_mont_mul_8(r, t2, t3, p256_mod, p256_mp_mod); + /* 0x2 */ + sp_256_mont_sqr_8(t1, a, p256_mod, p256_mp_mod); + /* 0x3 */ + sp_256_mont_mul_8(t2, t1, a, p256_mod, p256_mp_mod); + /* 0xc */ + sp_256_mont_sqr_n_8(t1, t2, 2, p256_mod, p256_mp_mod); + /* 0xd */ + sp_256_mont_mul_8(t3, t1, a, p256_mod, p256_mp_mod); + /* 0xf */ + sp_256_mont_mul_8(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xf0 */ + sp_256_mont_sqr_n_8(t1, t2, 4, p256_mod, p256_mp_mod); + /* 0xfd */ + sp_256_mont_mul_8(t3, t3, t1, p256_mod, p256_mp_mod); + /* 0xff */ + sp_256_mont_mul_8(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xff00 */ + sp_256_mont_sqr_n_8(t1, t2, 8, p256_mod, p256_mp_mod); + /* 0xfffd */ + sp_256_mont_mul_8(t3, t3, t1, p256_mod, p256_mp_mod); + /* 0xffff */ + sp_256_mont_mul_8(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xffff0000 */ + sp_256_mont_sqr_n_8(t1, t2, 16, p256_mod, p256_mp_mod); + /* 0xfffffffd */ + sp_256_mont_mul_8(t3, t3, t1, p256_mod, p256_mp_mod); + /* 0xffffffff */ + sp_256_mont_mul_8(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xffffffff00000000 */ + sp_256_mont_sqr_n_8(t1, t2, 32, p256_mod, p256_mp_mod); + /* 0xffffffffffffffff */ + sp_256_mont_mul_8(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xffffffff00000001 */ + sp_256_mont_mul_8(r, t1, a, p256_mod, p256_mp_mod); + /* 0xffffffff000000010000000000000000000000000000000000000000 */ + sp_256_mont_sqr_n_8(r, r, 160, p256_mod, p256_mp_mod); + /* 0xffffffff00000001000000000000000000000000ffffffffffffffff */ + sp_256_mont_mul_8(r, r, t2, p256_mod, p256_mp_mod); + /* 0xffffffff00000001000000000000000000000000ffffffffffffffff00000000 */ + sp_256_mont_sqr_n_8(r, r, 32, p256_mod, p256_mp_mod); + /* 0xffffffff00000001000000000000000000000000fffffffffffffffffffffffd */ + sp_256_mont_mul_8(r, r, t3, p256_mod, p256_mp_mod); #endif /* WOLFSSL_SP_SMALL */ } +/* 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_256_cmp_8(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, #28\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], #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; +} + +/* Normalize the values in each word to 32. + * + * a Array of sp_digit to normalize. + */ +#define sp_256_norm_8(a) + +/* 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_256_cond_sub_8(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, #32\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" + "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; +} + +#define sp_256_mont_reduce_order_8 sp_256_mont_reduce_8 + +/* 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. + */ +SP_NOINLINE static void sp_256_mont_reduce_8(sp_digit* a, const sp_digit* m, + sp_digit mp) +{ + sp_digit ca = 0; + + __asm__ __volatile__ ( + "# 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 r7, [%[m], #0]\n\t" + "ldr r9, [%[a], #0]\n\t" + "umull r6, r7, r8, r7\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 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], #28]\n\t" + "ldr r9, [%[a], #32]\n\t" + "adcs r9, r9, r7\n\t" + "str r9, [%[a], #32]\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, #32\n\t" + "blt 1b\n\t" + "str r10, [%[a], #0]\n\t" + "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" + ); + + sp_256_cond_sub_8(a - 8, a, m, (sp_digit)0 - ca); +} + /* 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_8(sp_point* r, const sp_point* 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; @@ -74908,9 +74904,9 @@ static void sp_256_div2_8(sp_digit* r, const sp_digit* a, const sp_digit* m) * p Point to double. * t Temporary ordinate data. */ -static void sp_256_proj_point_dbl_8(sp_point* r, const sp_point* p, sp_digit* t) +static void sp_256_proj_point_dbl_8(sp_point_256* r, const sp_point_256* p, sp_digit* t) { - sp_point* rp[2]; + sp_point_256* rp[2]; sp_digit* t1 = t; sp_digit* t2 = t + 2*8; sp_digit* x; @@ -74922,8 +74918,8 @@ static void sp_256_proj_point_dbl_8(sp_point* r, const sp_point* p, sp_digit* t) rp[0] = r; /*lint allow cast to different type of pointer*/ - rp[1] = (sp_point*)t; /*lint !e9087 !e740*/ - XMEMSET(rp[1], 0, sizeof(sp_point)); + rp[1] = (sp_point_256*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_256)); x = rp[p->infinity]->x; y = rp[p->infinity]->y; z = rp[p->infinity]->z; @@ -75098,11 +75094,11 @@ static int sp_256_cmp_equal_8(const sp_digit* a, const sp_digit* b) * q Second point to add. * t Temporary ordinate data. */ -static void sp_256_proj_point_add_8(sp_point* r, const sp_point* p, const sp_point* q, +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* ap[2]; - sp_point* rp[2]; + const sp_point_256* ap[2]; + sp_point_256* rp[2]; sp_digit* t1 = t; sp_digit* t2 = t + 2*8; sp_digit* t3 = t + 4*8; @@ -75115,7 +75111,7 @@ static void sp_256_proj_point_add_8(sp_point* r, const sp_point* p, const sp_poi /* Ensure only the first point is the same as the result. */ if (q == r) { - const sp_point* a = p; + const sp_point_256* a = p; p = q; q = a; } @@ -75131,8 +75127,8 @@ static void sp_256_proj_point_add_8(sp_point* r, const sp_point* p, const sp_poi rp[0] = r; /*lint allow cast to different type of pointer*/ - rp[1] = (sp_point*)t; /*lint !e9087 !e740*/ - XMEMSET(rp[1], 0, sizeof(sp_point)); + rp[1] = (sp_point_256*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_256)); x = rp[p->infinity | q->infinity]->x; y = rp[p->infinity | q->infinity]->y; z = rp[p->infinity | q->infinity]->z; @@ -75195,16 +75191,16 @@ static void sp_256_proj_point_add_8(sp_point* r, const sp_point* p, const sp_poi * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_fast_8(sp_point* r, const sp_point* g, const sp_digit* k, +static int sp_256_ecc_mulmod_fast_8(sp_point_256* r, const sp_point_256* g, const sp_digit* k, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point td[16]; - sp_point rtd; + sp_point_256 td[16]; + sp_point_256 rtd; sp_digit tmpd[2 * 8 * 5]; #endif - sp_point* t; - sp_point* rt; + sp_point_256* t; + sp_point_256* rt; sp_digit* tmp; sp_digit n; int i; @@ -75213,9 +75209,9 @@ static int sp_256_ecc_mulmod_fast_8(sp_point* r, const sp_point* g, const sp_dig (void)heap; - err = sp_ecc_point_new(heap, rtd, rt); + err = sp_256_point_new_8(heap, rtd, rt); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - t = (sp_point*)XMALLOC(sizeof(sp_point) * 16, heap, DYNAMIC_TYPE_ECC); + t = (sp_point_256*)XMALLOC(sizeof(sp_point_256) * 16, heap, DYNAMIC_TYPE_ECC); if (t == NULL) err = MEMORY_E; tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 5, heap, @@ -75269,7 +75265,7 @@ static int sp_256_ecc_mulmod_fast_8(sp_point* r, const sp_point* g, const sp_dig n = k[i+1] << 0; c = 28; y = n >> 28; - XMEMCPY(rt, &t[y], sizeof(sp_point)); + XMEMCPY(rt, &t[y], sizeof(sp_point_256)); n <<= 4; for (; i>=0 || c>=4; ) { if (c < 4) { @@ -75292,7 +75288,7 @@ static int sp_256_ecc_mulmod_fast_8(sp_point* r, const sp_point* g, const sp_dig sp_256_map_8(r, rt, tmp); } else { - XMEMCPY(r, rt, sizeof(sp_point)); + XMEMCPY(r, rt, sizeof(sp_point_256)); } } @@ -75302,23 +75298,23 @@ static int sp_256_ecc_mulmod_fast_8(sp_point* r, const sp_point* g, const sp_dig XFREE(tmp, heap, DYNAMIC_TYPE_ECC); } if (t != NULL) { - XMEMSET(t, 0, sizeof(sp_point) * 16); + XMEMSET(t, 0, sizeof(sp_point_256) * 16); XFREE(t, heap, DYNAMIC_TYPE_ECC); } #else ForceZero(tmpd, sizeof(tmpd)); ForceZero(td, sizeof(td)); #endif - sp_ecc_point_free(rt, 1, heap); + sp_256_point_free_8(rt, 1, heap); return err; } /* A table entry for pre-computed points. */ -typedef struct sp_table_entry { +typedef struct sp_table_entry_256 { sp_digit x[8]; sp_digit y[8]; -} sp_table_entry; +} sp_table_entry_256; #ifdef FP_ECC /* Double the Montgomery form projective point p a number of times. @@ -75328,10 +75324,10 @@ typedef struct sp_table_entry { * n Number of times to double * t Temporary ordinate data. */ -static void sp_256_proj_point_dbl_n_8(sp_point* r, const sp_point* p, int n, +static void sp_256_proj_point_dbl_n_8(sp_point_256* r, const sp_point_256* p, int n, sp_digit* t) { - sp_point* rp[2]; + sp_point_256* rp[2]; sp_digit* w = t; sp_digit* a = t + 2*8; sp_digit* b = t + 4*8; @@ -75345,8 +75341,8 @@ static void sp_256_proj_point_dbl_n_8(sp_point* r, const sp_point* p, int n, rp[0] = r; /*lint allow cast to different type of pointer*/ - rp[1] = (sp_point*)t; /*lint !e9087 !e740*/ - XMEMSET(rp[1], 0, sizeof(sp_point)); + rp[1] = (sp_point_256*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_256)); x = rp[p->infinity]->x; y = rp[p->infinity]->y; z = rp[p->infinity]->z; @@ -75408,11 +75404,11 @@ static void sp_256_proj_point_dbl_n_8(sp_point* r, const sp_point* p, int n, * q Second point to add. * t Temporary ordinate data. */ -static void sp_256_proj_point_add_qz1_8(sp_point* r, const sp_point* p, - const sp_point* q, sp_digit* t) +static void sp_256_proj_point_add_qz1_8(sp_point_256* r, const sp_point_256* p, + const sp_point_256* q, sp_digit* t) { - const sp_point* ap[2]; - sp_point* rp[2]; + const sp_point_256* ap[2]; + sp_point_256* rp[2]; sp_digit* t1 = t; sp_digit* t2 = t + 2*8; sp_digit* t3 = t + 4*8; @@ -75434,8 +75430,8 @@ static void sp_256_proj_point_add_qz1_8(sp_point* r, const sp_point* p, rp[0] = r; /*lint allow cast to different type of pointer*/ - rp[1] = (sp_point*)t; /*lint !e9087 !e740*/ - XMEMSET(rp[1], 0, sizeof(sp_point)); + rp[1] = (sp_point_256*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_256)); x = rp[p->infinity | q->infinity]->x; y = rp[p->infinity | q->infinity]->y; z = rp[p->infinity | q->infinity]->z; @@ -75489,7 +75485,7 @@ static void sp_256_proj_point_add_qz1_8(sp_point* r, const sp_point* p, * a Point to convert. * t Temporary data. */ -static void sp_256_proj_to_affine_8(sp_point* a, sp_digit* t) +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; @@ -75512,26 +75508,26 @@ static void sp_256_proj_to_affine_8(sp_point* a, sp_digit* t) * tmp Temporary data. * heap Heap to use for allocation. */ -static int sp_256_gen_stripe_table_8(const sp_point* a, - sp_table_entry* table, sp_digit* tmp, void* heap) +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) - sp_point td, s1d, s2d; + sp_point_256 td, s1d, s2d; #endif - sp_point* t; - sp_point* s1 = NULL; - sp_point* s2 = NULL; + sp_point_256* t; + sp_point_256* s1 = NULL; + sp_point_256* s2 = NULL; int i, j; int err; (void)heap; - err = sp_ecc_point_new(heap, td, t); + err = sp_256_point_new_8(heap, td, t); if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, s1d, s1); + err = sp_256_point_new_8(heap, s1d, s1); } if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, s2d, s2); + err = sp_256_point_new_8(heap, s2d, s2); } if (err == MP_OKAY) { @@ -75553,7 +75549,7 @@ static int sp_256_gen_stripe_table_8(const sp_point* a, s2->infinity = 0; /* table[0] = {0, 0, infinity} */ - XMEMSET(&table[0], 0, sizeof(sp_table_entry)); + XMEMSET(&table[0], 0, sizeof(sp_table_entry_256)); /* 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)); @@ -75579,9 +75575,9 @@ static int sp_256_gen_stripe_table_8(const sp_point* a, } } - sp_ecc_point_free(s2, 0, heap); - sp_ecc_point_free(s1, 0, heap); - sp_ecc_point_free( t, 0, heap); + sp_256_point_free_8(s2, 0, heap); + sp_256_point_free_8(s1, 0, heap); + sp_256_point_free_8( t, 0, heap); return err; } @@ -75596,16 +75592,16 @@ static int sp_256_gen_stripe_table_8(const sp_point* a, * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_stripe_8(sp_point* r, const sp_point* g, - const sp_table_entry* table, const sp_digit* k, int map, void* heap) +static int sp_256_ecc_mulmod_stripe_8(sp_point_256* r, const sp_point_256* g, + const sp_table_entry_256* table, const sp_digit* k, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point rtd; - sp_point pd; + sp_point_256 rtd; + sp_point_256 pd; sp_digit td[2 * 8 * 5]; #endif - sp_point* rt; - sp_point* p = NULL; + sp_point_256* rt; + sp_point_256* p = NULL; sp_digit* t; int i, j; int y, x; @@ -75614,9 +75610,10 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point* r, const sp_point* g, (void)g; (void)heap; - err = sp_ecc_point_new(heap, rtd, rt); + + err = sp_256_point_new_8(heap, rtd, rt); if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, pd, p); + err = sp_256_point_new_8(heap, pd, p); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 5, heap, @@ -75656,7 +75653,7 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point* r, const sp_point* g, sp_256_map_8(r, rt, t); } else { - XMEMCPY(r, rt, sizeof(sp_point)); + XMEMCPY(r, rt, sizeof(sp_point_256)); } } @@ -75665,8 +75662,8 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point* r, const sp_point* g, XFREE(t, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(p, 0, heap); - sp_ecc_point_free(rt, 0, heap); + sp_256_point_free_8(p, 0, heap); + sp_256_point_free_8(rt, 0, heap); return err; } @@ -75676,43 +75673,43 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point* r, const sp_point* g, #define FP_ENTRIES 16 #endif -typedef struct sp_cache_t { +typedef struct sp_cache_256_t { sp_digit x[8]; sp_digit y[8]; - sp_table_entry table[16]; + sp_table_entry_256 table[16]; uint32_t cnt; int set; -} sp_cache_t; +} sp_cache_256_t; -static THREAD_LS_T sp_cache_t sp_cache[FP_ENTRIES]; -static THREAD_LS_T int sp_cache_last = -1; -static THREAD_LS_T int sp_cache_inited = 0; +static THREAD_LS_T sp_cache_256_t sp_cache_256[FP_ENTRIES]; +static THREAD_LS_T int sp_cache_256_last = -1; +static THREAD_LS_T int sp_cache_256_inited = 0; #ifndef HAVE_THREAD_LS - static volatile int initCacheMutex = 0; - static wolfSSL_Mutex sp_cache_lock; + static volatile int initCacheMutex_256 = 0; + static wolfSSL_Mutex sp_cache_256_lock; #endif -static void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache) +static void sp_ecc_get_cache_256(const sp_point_256* g, sp_cache_256_t** cache) { int i, j; uint32_t least; - if (sp_cache_inited == 0) { + if (sp_cache_256_inited == 0) { for (i=0; ix, sp_cache[i].x) & - sp_256_cmp_equal_8(g->y, sp_cache[i].y)) { - sp_cache[i].cnt++; + if (sp_256_cmp_equal_8(g->x, sp_cache_256[i].x) & + sp_256_cmp_equal_8(g->y, sp_cache_256[i].y)) { + sp_cache_256[i].cnt++; break; } } @@ -75720,32 +75717,32 @@ static void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache) /* No match. */ if (i == FP_ENTRIES) { /* Find empty entry. */ - i = (sp_cache_last + 1) % FP_ENTRIES; - for (; i != sp_cache_last; i=(i+1)%FP_ENTRIES) { - if (!sp_cache[i].set) { + i = (sp_cache_256_last + 1) % FP_ENTRIES; + for (; i != sp_cache_256_last; i=(i+1)%FP_ENTRIES) { + if (!sp_cache_256[i].set) { break; } } /* Evict least used. */ - if (i == sp_cache_last) { - least = sp_cache[0].cnt; + if (i == sp_cache_256_last) { + least = sp_cache_256[0].cnt; for (j=1; jx, sizeof(sp_cache[i].x)); - XMEMCPY(sp_cache[i].y, g->y, sizeof(sp_cache[i].y)); - sp_cache[i].set = 1; - sp_cache[i].cnt = 1; + XMEMCPY(sp_cache_256[i].x, g->x, sizeof(sp_cache_256[i].x)); + XMEMCPY(sp_cache_256[i].y, g->y, sizeof(sp_cache_256[i].y)); + sp_cache_256[i].set = 1; + sp_cache_256[i].cnt = 1; } - *cache = &sp_cache[i]; - sp_cache_last = i; + *cache = &sp_cache_256[i]; + sp_cache_256_last = i; } #endif /* FP_ECC */ @@ -75759,32 +75756,32 @@ static void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache) * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_8(sp_point* r, const sp_point* g, const sp_digit* k, +static int sp_256_ecc_mulmod_8(sp_point_256* r, const sp_point_256* g, const sp_digit* k, int map, void* heap) { #ifndef FP_ECC return sp_256_ecc_mulmod_fast_8(r, g, k, map, heap); #else sp_digit tmp[2 * 8 * 5]; - sp_cache_t* cache; + sp_cache_256_t* cache; int err = MP_OKAY; #ifndef HAVE_THREAD_LS - if (initCacheMutex == 0) { - wc_InitMutex(&sp_cache_lock); - initCacheMutex = 1; + if (initCacheMutex_256 == 0) { + wc_InitMutex(&sp_cache_256_lock); + initCacheMutex_256 = 1; } - if (wc_LockMutex(&sp_cache_lock) != 0) + if (wc_LockMutex(&sp_cache_256_lock) != 0) err = BAD_MUTEX_E; #endif /* HAVE_THREAD_LS */ if (err == MP_OKAY) { - sp_ecc_get_cache(g, &cache); + sp_ecc_get_cache_256(g, &cache); if (cache->cnt == 2) sp_256_gen_stripe_table_8(g, cache->table, tmp, heap); #ifndef HAVE_THREAD_LS - wc_UnLockMutex(&sp_cache_lock); + wc_UnLockMutex(&sp_cache_256_lock); #endif /* HAVE_THREAD_LS */ if (cache->cnt < 2) { @@ -75809,26 +75806,26 @@ static int sp_256_ecc_mulmod_8(sp_point* r, const sp_point* g, const sp_digit* k * tmp Temporary data. * heap Heap to use for allocation. */ -static int sp_256_gen_stripe_table_8(const sp_point* a, - sp_table_entry* table, sp_digit* tmp, void* heap) +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) - sp_point td, s1d, s2d; + sp_point_256 td, s1d, s2d; #endif - sp_point* t; - sp_point* s1 = NULL; - sp_point* s2 = NULL; + sp_point_256* t; + sp_point_256* s1 = NULL; + sp_point_256* s2 = NULL; int i, j; int err; (void)heap; - err = sp_ecc_point_new(heap, td, t); + err = sp_256_point_new_8(heap, td, t); if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, s1d, s1); + err = sp_256_point_new_8(heap, s1d, s1); } if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, s2d, s2); + err = sp_256_point_new_8(heap, s2d, s2); } if (err == MP_OKAY) { @@ -75850,7 +75847,7 @@ static int sp_256_gen_stripe_table_8(const sp_point* a, s2->infinity = 0; /* table[0] = {0, 0, infinity} */ - XMEMSET(&table[0], 0, sizeof(sp_table_entry)); + XMEMSET(&table[0], 0, sizeof(sp_table_entry_256)); /* 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)); @@ -75876,9 +75873,9 @@ static int sp_256_gen_stripe_table_8(const sp_point* a, } } - sp_ecc_point_free(s2, 0, heap); - sp_ecc_point_free(s1, 0, heap); - sp_ecc_point_free( t, 0, heap); + sp_256_point_free_8(s2, 0, heap); + sp_256_point_free_8(s1, 0, heap); + sp_256_point_free_8( t, 0, heap); return err; } @@ -75893,16 +75890,16 @@ static int sp_256_gen_stripe_table_8(const sp_point* a, * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_stripe_8(sp_point* r, const sp_point* g, - const sp_table_entry* table, const sp_digit* k, int map, void* heap) +static int sp_256_ecc_mulmod_stripe_8(sp_point_256* r, const sp_point_256* g, + const sp_table_entry_256* table, const sp_digit* k, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point rtd; - sp_point pd; + sp_point_256 rtd; + sp_point_256 pd; sp_digit td[2 * 8 * 5]; #endif - sp_point* rt; - sp_point* p = NULL; + sp_point_256* rt; + sp_point_256* p = NULL; sp_digit* t; int i, j; int y, x; @@ -75911,9 +75908,10 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point* r, const sp_point* g, (void)g; (void)heap; - err = sp_ecc_point_new(heap, rtd, rt); + + err = sp_256_point_new_8(heap, rtd, rt); if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, pd, p); + err = sp_256_point_new_8(heap, pd, p); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 5, heap, @@ -75953,7 +75951,7 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point* r, const sp_point* g, sp_256_map_8(r, rt, t); } else { - XMEMCPY(r, rt, sizeof(sp_point)); + XMEMCPY(r, rt, sizeof(sp_point_256)); } } @@ -75962,8 +75960,8 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point* r, const sp_point* g, XFREE(t, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(p, 0, heap); - sp_ecc_point_free(rt, 0, heap); + sp_256_point_free_8(p, 0, heap); + sp_256_point_free_8(rt, 0, heap); return err; } @@ -75973,43 +75971,43 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point* r, const sp_point* g, #define FP_ENTRIES 16 #endif -typedef struct sp_cache_t { +typedef struct sp_cache_256_t { sp_digit x[8]; sp_digit y[8]; - sp_table_entry table[256]; + sp_table_entry_256 table[256]; uint32_t cnt; int set; -} sp_cache_t; +} sp_cache_256_t; -static THREAD_LS_T sp_cache_t sp_cache[FP_ENTRIES]; -static THREAD_LS_T int sp_cache_last = -1; -static THREAD_LS_T int sp_cache_inited = 0; +static THREAD_LS_T sp_cache_256_t sp_cache_256[FP_ENTRIES]; +static THREAD_LS_T int sp_cache_256_last = -1; +static THREAD_LS_T int sp_cache_256_inited = 0; #ifndef HAVE_THREAD_LS - static volatile int initCacheMutex = 0; - static wolfSSL_Mutex sp_cache_lock; + static volatile int initCacheMutex_256 = 0; + static wolfSSL_Mutex sp_cache_256_lock; #endif -static void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache) +static void sp_ecc_get_cache_256(const sp_point_256* g, sp_cache_256_t** cache) { int i, j; uint32_t least; - if (sp_cache_inited == 0) { + if (sp_cache_256_inited == 0) { for (i=0; ix, sp_cache[i].x) & - sp_256_cmp_equal_8(g->y, sp_cache[i].y)) { - sp_cache[i].cnt++; + if (sp_256_cmp_equal_8(g->x, sp_cache_256[i].x) & + sp_256_cmp_equal_8(g->y, sp_cache_256[i].y)) { + sp_cache_256[i].cnt++; break; } } @@ -76017,32 +76015,32 @@ static void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache) /* No match. */ if (i == FP_ENTRIES) { /* Find empty entry. */ - i = (sp_cache_last + 1) % FP_ENTRIES; - for (; i != sp_cache_last; i=(i+1)%FP_ENTRIES) { - if (!sp_cache[i].set) { + i = (sp_cache_256_last + 1) % FP_ENTRIES; + for (; i != sp_cache_256_last; i=(i+1)%FP_ENTRIES) { + if (!sp_cache_256[i].set) { break; } } /* Evict least used. */ - if (i == sp_cache_last) { - least = sp_cache[0].cnt; + if (i == sp_cache_256_last) { + least = sp_cache_256[0].cnt; for (j=1; jx, sizeof(sp_cache[i].x)); - XMEMCPY(sp_cache[i].y, g->y, sizeof(sp_cache[i].y)); - sp_cache[i].set = 1; - sp_cache[i].cnt = 1; + XMEMCPY(sp_cache_256[i].x, g->x, sizeof(sp_cache_256[i].x)); + XMEMCPY(sp_cache_256[i].y, g->y, sizeof(sp_cache_256[i].y)); + sp_cache_256[i].set = 1; + sp_cache_256[i].cnt = 1; } - *cache = &sp_cache[i]; - sp_cache_last = i; + *cache = &sp_cache_256[i]; + sp_cache_256_last = i; } #endif /* FP_ECC */ @@ -76056,32 +76054,32 @@ static void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache) * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_8(sp_point* r, const sp_point* g, const sp_digit* k, +static int sp_256_ecc_mulmod_8(sp_point_256* r, const sp_point_256* g, const sp_digit* k, int map, void* heap) { #ifndef FP_ECC return sp_256_ecc_mulmod_fast_8(r, g, k, map, heap); #else sp_digit tmp[2 * 8 * 5]; - sp_cache_t* cache; + sp_cache_256_t* cache; int err = MP_OKAY; #ifndef HAVE_THREAD_LS - if (initCacheMutex == 0) { - wc_InitMutex(&sp_cache_lock); - initCacheMutex = 1; + if (initCacheMutex_256 == 0) { + wc_InitMutex(&sp_cache_256_lock); + initCacheMutex_256 = 1; } - if (wc_LockMutex(&sp_cache_lock) != 0) + if (wc_LockMutex(&sp_cache_256_lock) != 0) err = BAD_MUTEX_E; #endif /* HAVE_THREAD_LS */ if (err == MP_OKAY) { - sp_ecc_get_cache(g, &cache); + sp_ecc_get_cache_256(g, &cache); if (cache->cnt == 2) sp_256_gen_stripe_table_8(g, cache->table, tmp, heap); #ifndef HAVE_THREAD_LS - wc_UnLockMutex(&sp_cache_lock); + wc_UnLockMutex(&sp_cache_256_lock); #endif /* HAVE_THREAD_LS */ if (cache->cnt < 2) { @@ -76112,15 +76110,14 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point p; - sp_digit k[8]; -#else - sp_digit* k = NULL; + sp_point_256 p; + sp_digit kd[8]; #endif - sp_point* point; - int err; + sp_point_256* point; + sp_digit* k = NULL; + int err = MP_OKAY; - err = sp_ecc_point_new(heap, p, point); + err = sp_256_point_new_8(heap, p, point); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8, heap, @@ -76128,6 +76125,8 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, if (k == NULL) err = MEMORY_E; } +#else + k = kd; #endif if (err == MP_OKAY) { sp_256_from_mp(k, 8, km); @@ -76144,13 +76143,13 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, XFREE(k, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(point, 0, heap); + sp_256_point_free_8(point, 0, heap); return err; } #ifdef WOLFSSL_SP_SMALL -static const sp_table_entry p256_table[16] = { +static const sp_table_entry_256 p256_table[16] = { /* 0 */ { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, @@ -76240,7 +76239,7 @@ static const sp_table_entry p256_table[16] = { * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_base_8(sp_point* r, const sp_digit* k, +static int sp_256_ecc_mulmod_base_8(sp_point_256* r, const sp_digit* k, int map, void* heap) { return sp_256_ecc_mulmod_stripe_8(r, &p256_base, p256_table, @@ -76248,7 +76247,7 @@ static int sp_256_ecc_mulmod_base_8(sp_point* r, const sp_digit* k, } #else -static const sp_table_entry p256_table[256] = { +static const sp_table_entry_256 p256_table[256] = { /* 0 */ { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, @@ -77538,7 +77537,7 @@ static const sp_table_entry p256_table[256] = { * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_base_8(sp_point* r, const sp_digit* k, +static int sp_256_ecc_mulmod_base_8(sp_point_256* r, const sp_digit* k, int map, void* heap) { return sp_256_ecc_mulmod_stripe_8(r, &p256_base, p256_table, @@ -77559,15 +77558,14 @@ static int sp_256_ecc_mulmod_base_8(sp_point* r, const sp_digit* k, int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point p; - sp_digit k[8]; -#else - sp_digit* k = NULL; + sp_point_256 p; + sp_digit kd[8]; #endif - sp_point* point; - int err; + sp_point_256* point; + sp_digit* k = NULL; + int err = MP_OKAY; - err = sp_ecc_point_new(heap, p, point); + err = sp_256_point_new_8(heap, p, point); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8, heap, @@ -77576,6 +77574,8 @@ int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) err = MEMORY_E; } } +#else + k = kd; #endif if (err == MP_OKAY) { sp_256_from_mp(k, 8, km); @@ -77591,7 +77591,7 @@ int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) XFREE(k, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(point, 0, heap); + sp_256_point_free_8(point, 0, heap); return err; } @@ -77720,26 +77720,25 @@ static int sp_256_ecc_gen_k_8(WC_RNG* rng, sp_digit* k) int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point p; - sp_digit k[8]; + sp_point_256 p; + sp_digit kd[8]; #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN - sp_point inf; + sp_point_256 inf; #endif -#else +#endif + sp_point_256* point; sp_digit* k = NULL; -#endif - sp_point* point; #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN - sp_point* infinity; + sp_point_256* infinity; #endif int err; (void)heap; - err = sp_ecc_point_new(heap, p, point); + err = sp_256_point_new_8(heap, p, point); #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, inf, infinity); + err = sp_256_point_new_8(heap, inf, infinity); } #endif #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) @@ -77750,6 +77749,8 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) err = MEMORY_E; } } +#else + k = kd; #endif if (err == MP_OKAY) { @@ -77783,9 +77784,9 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) } #endif #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN - sp_ecc_point_free(infinity, 1, heap); + sp_256_point_free_8(infinity, 1, heap); #endif - sp_ecc_point_free(point, 1, heap); + sp_256_point_free_8(point, 1, heap); return err; } @@ -77842,12 +77843,11 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, word32* outLen, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point p; - sp_digit k[8]; -#else - sp_digit* k = NULL; + sp_point_256 p; + sp_digit kd[8]; #endif - sp_point* point = NULL; + sp_point_256* point = NULL; + sp_digit* k = NULL; int err = MP_OKAY; if (*outLen < 32U) { @@ -77855,7 +77855,7 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, } if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, p, point); + err = sp_256_point_new_8(heap, p, point); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { @@ -77864,6 +77864,8 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, if (k == NULL) err = MEMORY_E; } +#else + k = kd; #endif if (err == MP_OKAY) { @@ -77881,7 +77883,7 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, XFREE(k, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(point, 0, heap); + sp_256_point_free_8(point, 0, heap); return err; } @@ -79218,7 +79220,7 @@ static void sp_256_sqr_8(sp_digit* r, const sp_digit* a) #endif /* WOLFSSL_SP_SMALL */ #ifdef WOLFSSL_SP_SMALL /* Order-2 for the P256 curve. */ -static const uint32_t p256_order_2[8] = { +static const uint32_t p256_order_minus_2[8] = { 0xfc63254fU,0xf3b9cac2U,0xa7179e84U,0xbce6faadU,0xffffffffU,0xffffffffU, 0x00000000U,0xffffffffU }; @@ -79287,7 +79289,7 @@ static void sp_256_mont_inv_order_8(sp_digit* r, const sp_digit* a, XMEMCPY(t, a, sizeof(sp_digit) * 8); for (i=254; i>=0; i--) { sp_256_mont_sqr_order_8(t, t); - if ((p256_order_2[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { + if ((p256_order_minus_2[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { sp_256_mont_mul_order_8(t, t, a); } } @@ -79403,24 +79405,24 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_digit kd[2*8]; sp_digit rd[2*8]; sp_digit td[3 * 2*8]; - sp_point p; + sp_point_256 p; #endif sp_digit* e = NULL; sp_digit* x = NULL; sp_digit* k = NULL; sp_digit* r = NULL; sp_digit* tmp = NULL; - sp_point* point = NULL; + sp_point_256* point = NULL; sp_digit carry; sp_digit* s = NULL; sp_digit* kInv = NULL; - int err; + int err = MP_OKAY; int32_t c; int i; (void)heap; - err = sp_ecc_point_new(heap, p, point); + err = sp_256_point_new_8(heap, p, point); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7 * 2 * 8, heap, @@ -79536,7 +79538,7 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, XMEMSET(r, 0, sizeof(sp_digit) * 2U * 8U); XMEMSET(tmp, 0, sizeof(sp_digit) * 3U * 2U * 8U); #endif - sp_ecc_point_free(point, 1, heap); + sp_256_point_free_8(point, 1, heap); return err; } @@ -79573,22 +79575,22 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, sp_digit u2d[2*8]; sp_digit sd[2*8]; sp_digit tmpd[2*8 * 5]; - sp_point p1d; - sp_point p2d; + sp_point_256 p1d; + sp_point_256 p2d; #endif sp_digit* u1 = NULL; sp_digit* u2 = NULL; sp_digit* s = NULL; sp_digit* tmp = NULL; - sp_point* p1; - sp_point* p2 = NULL; + sp_point_256* p1; + sp_point_256* p2 = NULL; sp_digit carry; int32_t c; int err; - err = sp_ecc_point_new(heap, p1d, p1); + err = sp_256_point_new_8(heap, p1d, p1); if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, p2d, p2); + err = sp_256_point_new_8(heap, p2d, p2); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { @@ -79704,8 +79706,8 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, if (d != NULL) XFREE(d, heap, DYNAMIC_TYPE_ECC); #endif - sp_ecc_point_free(p1, 0, heap); - sp_ecc_point_free(p2, 0, heap); + sp_256_point_free_8(p1, 0, heap); + sp_256_point_free_8(p2, 0, heap); return err; } @@ -79719,10 +79721,10 @@ 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* point, void* heap) +static int sp_256_ecc_is_point_8(sp_point_256* point, void* heap) { #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - sp_digit* d; + sp_digit* d = NULL; #else sp_digit t1d[2*8]; sp_digit t2d[2*8]; @@ -79786,13 +79788,13 @@ static int sp_256_ecc_is_point_8(sp_point* point, void* heap) int sp_ecc_is_point_256(mp_int* pX, mp_int* pY) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point pubd; + sp_point_256 pubd; #endif - sp_point* pub; + sp_point_256* pub; byte one[1] = { 1 }; int err; - err = sp_ecc_point_new(NULL, pubd, pub); + err = sp_256_point_new_8(NULL, pubd, pub); if (err == MP_OKAY) { sp_256_from_mp(pub->x, 8, pX); sp_256_from_mp(pub->y, 8, pY); @@ -79801,7 +79803,7 @@ int sp_ecc_is_point_256(mp_int* pX, mp_int* pY) err = sp_256_ecc_is_point_8(pub, NULL); } - sp_ecc_point_free(pub, 0, NULL); + sp_256_point_free_8(pub, 0, NULL); return err; } @@ -79821,18 +79823,18 @@ int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_digit privd[8]; - sp_point pubd; - sp_point pd; + sp_point_256 pubd; + sp_point_256 pd; #endif sp_digit* priv = NULL; - sp_point* pub; - sp_point* p = NULL; + sp_point_256* pub; + sp_point_256* p = NULL; byte one[1] = { 1 }; int err; - err = sp_ecc_point_new(heap, pubd, pub); + err = sp_256_point_new_8(heap, pubd, pub); if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, pd, p); + err = sp_256_point_new_8(heap, pd, p); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { @@ -79903,8 +79905,8 @@ int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) XFREE(priv, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(p, 0, heap); - sp_ecc_point_free(pub, 0, heap); + sp_256_point_free_8(p, 0, heap); + sp_256_point_free_8(pub, 0, heap); return err; } @@ -79930,17 +79932,17 @@ int sp_ecc_proj_add_point_256(mp_int* pX, mp_int* pY, mp_int* pZ, { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_digit tmpd[2 * 8 * 5]; - sp_point pd; - sp_point qd; + sp_point_256 pd; + sp_point_256 qd; #endif sp_digit* tmp; - sp_point* p; - sp_point* q = NULL; + sp_point_256* p; + sp_point_256* q = NULL; int err; - err = sp_ecc_point_new(NULL, pd, p); + err = sp_256_point_new_8(NULL, pd, p); if (err == MP_OKAY) { - err = sp_ecc_point_new(NULL, qd, q); + err = sp_256_point_new_8(NULL, qd, q); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { @@ -79980,8 +79982,8 @@ int sp_ecc_proj_add_point_256(mp_int* pX, mp_int* pY, mp_int* pZ, XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(q, 0, NULL); - sp_ecc_point_free(p, 0, NULL); + sp_256_point_free_8(q, 0, NULL); + sp_256_point_free_8(p, 0, NULL); return err; } @@ -80002,13 +80004,13 @@ int sp_ecc_proj_dbl_point_256(mp_int* pX, mp_int* pY, mp_int* pZ, { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_digit tmpd[2 * 8 * 2]; - sp_point pd; + sp_point_256 pd; #endif sp_digit* tmp; - sp_point* p; + sp_point_256* p; int err; - err = sp_ecc_point_new(NULL, pd, p); + err = sp_256_point_new_8(NULL, pd, p); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 2, NULL, @@ -80044,7 +80046,7 @@ int sp_ecc_proj_dbl_point_256(mp_int* pX, mp_int* pY, mp_int* pZ, XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(p, 0, NULL); + sp_256_point_free_8(p, 0, NULL); return err; } @@ -80061,13 +80063,13 @@ int sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_digit tmpd[2 * 8 * 4]; - sp_point pd; + sp_point_256 pd; #endif sp_digit* tmp; - sp_point* p; + sp_point_256* p; int err; - err = sp_ecc_point_new(NULL, pd, p); + err = sp_256_point_new_8(NULL, pd, p); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 4, NULL, @@ -80102,7 +80104,7 @@ int sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ) XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(p, 0, NULL); + sp_256_point_free_8(p, 0, NULL); return err; } @@ -80183,6 +80185,7 @@ static int sp_256_mont_sqrt_8(sp_digit* y) return err; } + /* Uncompress the point given the X ordinate. * * xm X ordinate. @@ -80259,6 +80262,7749 @@ int sp_ecc_uncompress_256(mp_int* xm, int odd, mp_int* ym) } #endif #endif /* !WOLFSSL_SP_NO_256 */ +#ifdef WOLFSSL_SP_384 + +/* Point structure to use. */ +typedef struct sp_point_384 { + sp_digit x[2 * 12]; + sp_digit y[2 * 12]; + sp_digit z[2 * 12]; + int infinity; +} sp_point_384; + +/* The modulus (prime) of the curve P384. */ +static const sp_digit p384_mod[12] = { + 0xffffffff,0x00000000,0x00000000,0xffffffff,0xfffffffe,0xffffffff, + 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff +}; +/* The Montogmery normalizer for modulus of the curve P384. */ +static const sp_digit p384_norm_mod[12] = { + 0x00000001,0xffffffff,0xffffffff,0x00000000,0x00000001,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 +}; +/* The Montogmery multiplier for modulus of the curve P384. */ +static sp_digit p384_mp_mod = 0x00000001; +#if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \ + defined(HAVE_ECC_VERIFY) +/* The order of the curve P384. */ +static const sp_digit p384_order[12] = { + 0xccc52973,0xecec196a,0x48b0a77a,0x581a0db2,0xf4372ddf,0xc7634d81, + 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff +}; +#endif +/* The order of the curve P384 minus 2. */ +static const sp_digit p384_order2[12] = { + 0xccc52971,0xecec196a,0x48b0a77a,0x581a0db2,0xf4372ddf,0xc7634d81, + 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff +}; +#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[12] = { + 0x333ad68d,0x1313e695,0xb74f5885,0xa7e5f24d,0x0bc8d220,0x389cb27e, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 +}; +#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 = 0xe88fdc45; +#endif +/* The base point of curve P384. */ +static const sp_point_384 p384_base = { + /* X ordinate */ + { + 0x72760ab7,0x3a545e38,0xbf55296c,0x5502f25d,0x82542a38,0x59f741e0, + 0x8ba79b98,0x6e1d3b62,0xf320ad74,0x8eb1c71e,0xbe8b0537,0xaa87ca22, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + }, + /* Y ordinate */ + { + 0x90ea0e5f,0x7a431d7c,0x1d7e819d,0x0a60b1ce,0xb5f0b8c0,0xe9da3113, + 0x289a147c,0xf8f41dbd,0x9292dc29,0x5d9e98bf,0x96262c6f,0x3617de4a, + 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, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + }, + /* infinity */ + 0 +}; +#if defined(HAVE_ECC_CHECK_KEY) || defined(HAVE_COMP_KEY) +static const sp_digit p384_b[12] = { + 0xd3ec2aef,0x2a85c8ed,0x8a2ed19d,0xc656398d,0x5013875a,0x0314088f, + 0xfe814112,0x181d9c6e,0xe3f82d19,0x988e056b,0xe23ee7e4,0xb3312fa7 +}; +#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) + (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) +/* 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) +/* 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) + 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) + 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) + 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] |= a[i] << s; + r->dp[j] &= (1L << DIGIT_BIT) - 1; + s = DIGIT_BIT - s; + r->dp[++j] = 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] = 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) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +static void sp_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) +{ + __asm__ __volatile__ ( + "sub sp, sp, #96\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, #44\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, #48\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, #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), [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_384_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b) +{ + __asm__ __volatile__ ( + "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" + "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[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, 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" + "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" + "# A[8] * B[0]\n\t" + "ldr r8, [%[a], #32]\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, #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" + "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 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" + "# 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[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, 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" + "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[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[10] * B[0]\n\t" + "ldr r8, [%[a], #40]\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, #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" + "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 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" + "# 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[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, 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" + "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[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[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" + "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" + "adc r3, r10, 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 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, 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" + "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" + "str r4, [%[r], #52]\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, 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" + "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[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[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" + "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" + "adc r5, r10, 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 r8, [%[a], #28]\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[8] * B[7]\n\t" + "ldr r8, [%[a], #32]\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[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" + "str r3, [%[r], #60]\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, r10, 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[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[8] * B[8]\n\t" + "ldr r8, [%[a], #32]\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[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" + "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[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, r10, 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 r8, [%[a], #32]\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[9] * B[8]\n\t" + "ldr r8, [%[a], #36]\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[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" + "str r5, [%[r], #68]\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, r10, 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[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" + "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[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" + "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" + "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" + "str r4, [%[r], #76]\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" + "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" + "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" + : + : [r] "r" (r), [a] "r" (a), [b] "r" (b) + : "memory", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" + ); +} + +#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_12(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, #48\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" + "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; +} + +#define sp_384_mont_reduce_order_12 sp_384_mont_reduce_12 + +/* 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_12(sp_digit* a, const sp_digit* m, + sp_digit mp) +{ + sp_digit ca = 0; + + __asm__ __volatile__ ( + "# 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 r7, [%[m], #0]\n\t" + "ldr r9, [%[a], #0]\n\t" + "umull r6, r7, r8, r7\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 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], #44]\n\t" + "ldr r9, [%[a], #48]\n\t" + "adcs r9, r9, r7\n\t" + "str r9, [%[a], #48]\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, #48\n\t" + "blt 1b\n\t" + "str r10, [%[a], #0]\n\t" + "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" + ); + + sp_384_cond_sub_12(a - 12, 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_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. + * a Number to square in Montogmery form. + * 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) +{ + sp_384_sqr_12(r, a); + sp_384_mont_reduce_12(r, m, mp); +} + +#if !defined(WOLFSSL_SP_SMALL) || defined(HAVE_COMP_KEY) +/* Square the Montgomery form number a number of times. (r = a ^ n mod m) + * + * r Result of squaring. + * a Number to square in Montogmery form. + * n Number of times to square. + * m Modulus (prime). + * mp Montogmery mulitplier. + */ +static void sp_384_mont_sqr_n_12(sp_digit* r, const sp_digit* a, int n, + const sp_digit* m, sp_digit mp) +{ + sp_384_mont_sqr_12(r, a, m, mp); + for (; n > 1; n--) { + sp_384_mont_sqr_12(r, r, m, mp); + } +} + +#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] = { + 0xfffffffdU,0x00000000U,0x00000000U,0xffffffffU,0xfffffffeU,0xffffffffU, + 0xffffffffU,0xffffffffU,0xffffffffU,0xffffffffU,0xffffffffU,0xffffffffU +}; +#endif /* !WOLFSSL_SP_SMALL */ + +/* Invert the number, in Montgomery form, modulo the modulus (prime) of the + * P384 curve. (r = 1 / a mod m) + * + * r Inverse result. + * a Number to invert. + * td Temporary data. + */ +static void sp_384_mont_inv_12(sp_digit* r, const sp_digit* a, sp_digit* td) +{ +#ifdef WOLFSSL_SP_SMALL + sp_digit* t = td; + int i; + + XMEMCPY(t, a, sizeof(sp_digit) * 12); + for (i=382; i>=0; i--) { + sp_384_mont_sqr_12(t, t, p384_mod, p384_mp_mod); + if (p384_mod_minus_2[i / 32] & ((sp_digit)1 << (i % 32))) + sp_384_mont_mul_12(t, t, a, p384_mod, p384_mp_mod); + } + XMEMCPY(r, t, sizeof(sp_digit) * 12); +#else + sp_digit* t1 = td; + sp_digit* t2 = td + 2 * 12; + sp_digit* t3 = td + 4 * 12; + sp_digit* t4 = td + 6 * 12; + sp_digit* t5 = td + 8 * 12; + + /* 0x2 */ + sp_384_mont_sqr_12(t1, a, p384_mod, p384_mp_mod); + /* 0x3 */ + sp_384_mont_mul_12(t5, t1, a, p384_mod, p384_mp_mod); + /* 0xc */ + sp_384_mont_sqr_n_12(t1, t5, 2, p384_mod, p384_mp_mod); + /* 0xf */ + sp_384_mont_mul_12(t2, t5, t1, p384_mod, p384_mp_mod); + /* 0x1e */ + sp_384_mont_sqr_12(t1, t2, p384_mod, p384_mp_mod); + /* 0x1f */ + sp_384_mont_mul_12(t4, t1, a, p384_mod, p384_mp_mod); + /* 0x3e0 */ + sp_384_mont_sqr_n_12(t1, t4, 5, p384_mod, p384_mp_mod); + /* 0x3ff */ + sp_384_mont_mul_12(t2, t4, t1, p384_mod, p384_mp_mod); + /* 0x7fe0 */ + sp_384_mont_sqr_n_12(t1, t2, 5, p384_mod, p384_mp_mod); + /* 0x7fff */ + sp_384_mont_mul_12(t4, t4, t1, p384_mod, p384_mp_mod); + /* 0x3fff8000 */ + sp_384_mont_sqr_n_12(t1, t4, 15, p384_mod, p384_mp_mod); + /* 0x3fffffff */ + sp_384_mont_mul_12(t2, t4, t1, p384_mod, p384_mp_mod); + /* 0xfffffffc */ + sp_384_mont_sqr_n_12(t3, t2, 2, p384_mod, p384_mp_mod); + /* 0xfffffffd */ + sp_384_mont_mul_12(r, t3, a, p384_mod, p384_mp_mod); + /* 0xffffffff */ + sp_384_mont_mul_12(t3, t5, t3, p384_mod, p384_mp_mod); + /* 0xfffffffc0000000 */ + sp_384_mont_sqr_n_12(t1, t2, 30, p384_mod, p384_mp_mod); + /* 0xfffffffffffffff */ + sp_384_mont_mul_12(t2, t2, t1, p384_mod, p384_mp_mod); + /* 0xfffffffffffffff000000000000000 */ + sp_384_mont_sqr_n_12(t1, t2, 60, p384_mod, p384_mp_mod); + /* 0xffffffffffffffffffffffffffffff */ + sp_384_mont_mul_12(t2, t2, t1, p384_mod, p384_mp_mod); + /* 0xffffffffffffffffffffffffffffff000000000000000000000000000000 */ + sp_384_mont_sqr_n_12(t1, t2, 120, p384_mod, p384_mp_mod); + /* 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */ + sp_384_mont_mul_12(t2, t2, t1, p384_mod, p384_mp_mod); + /* 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000 */ + sp_384_mont_sqr_n_12(t1, t2, 15, p384_mod, p384_mp_mod); + /* 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */ + sp_384_mont_mul_12(t2, t4, t1, p384_mod, p384_mp_mod); + /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00000000 */ + sp_384_mont_sqr_n_12(t1, t2, 33, p384_mod, p384_mp_mod); + /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff */ + sp_384_mont_mul_12(t2, t3, t1, p384_mod, p384_mp_mod); + /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff000000000000000000000000 */ + sp_384_mont_sqr_n_12(t1, t2, 96, p384_mod, p384_mp_mod); + /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffd */ + sp_384_mont_mul_12(r, r, t1, p384_mod, p384_mp_mod); + +#endif /* WOLFSSL_SP_SMALL */ +} + +/* 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_384_cmp_12(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, #44\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], #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; +} + +/* Normalize the values in each word to 32. + * + * a Array of sp_digit to normalize. + */ +#define sp_384_norm_12(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_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; + int32_t n; + + sp_384_mont_inv_12(t1, p->z, t + 2*12); + + 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); + + /* x /= z^2 */ + sp_384_mont_mul_12(r->x, p->x, t2, p384_mod, p384_mp_mod); + XMEMSET(r->x + 12, 0, sizeof(r->x) / 2U); + sp_384_mont_reduce_12(r->x, p384_mod, p384_mp_mod); + /* Reduce x to less than modulus */ + n = sp_384_cmp_12(r->x, p384_mod); + sp_384_cond_sub_12(r->x, r->x, p384_mod, 0 - ((n >= 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_384_norm_12(r->x); + + /* y /= z^3 */ + sp_384_mont_mul_12(r->y, p->y, t1, p384_mod, p384_mp_mod); + XMEMSET(r->y + 12, 0, sizeof(r->y) / 2U); + sp_384_mont_reduce_12(r->y, p384_mod, p384_mp_mod); + /* Reduce y to less than modulus */ + n = sp_384_cmp_12(r->y, p384_mod); + sp_384_cond_sub_12(r->y, r->y, p384_mod, 0 - ((n >= 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_384_norm_12(r->y); + + XMEMSET(r->z, 0, sizeof(r->z)); + r->z[0] = 1; + +} + +#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. + * a First number to add in Montogmery form. + * b Second number to add in Montogmery form. + * m Modulus (prime). + */ +static void sp_384_mont_add_12(sp_digit* r, const sp_digit* a, const sp_digit* b, + const sp_digit* m) +{ + sp_digit o; + + o = sp_384_add_12(r, a, b); + sp_384_cond_sub_12(r, r, m, 0 - o); +} + +/* 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_384_mont_dbl_12(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + sp_digit o; + + o = sp_384_add_12(r, a, a); + sp_384_cond_sub_12(r, r, m, 0 - o); +} + +/* 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_384_mont_tpl_12(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + sp_digit o; + + o = sp_384_add_12(r, a, a); + sp_384_cond_sub_12(r, r, m, 0 - o); + o = sp_384_add_12(r, r, a); + 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. + * + * 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_384_cond_add_12(sp_digit* r, const sp_digit* a, const sp_digit* b, + sp_digit m) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "mov r8, #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" + "adc %[c], r8, r8\n\t" + : [c] "+r" (c) + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) + : "memory", "r4", "r6", "r5", "r7", "r8" + ); + + return c; +} + +/* 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_384_mont_sub_12(sp_digit* r, const sp_digit* a, const sp_digit* b, + const sp_digit* m) +{ + sp_digit o; + + o = sp_384_sub_12(r, a, b); + sp_384_cond_add_12(r, r, m, o); +} + +static void sp_384_rshift1_12(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" + "str r3, [%[r], #40]\n\t" + "str r4, [%[r], #44]\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_384_div2_12(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + sp_digit o; + + o = sp_384_cond_add_12(r, a, m, 0 - (a[0] & 1)); + sp_384_rshift1_12(r, r); + r[11] |= o << 31; +} + +/* Double the Montgomery form projective point p. + * + * r Result of doubling point. + * p Point to double. + * t Temporary ordinate data. + */ +static void sp_384_proj_point_dbl_12(sp_point_384* r, const sp_point_384* p, sp_digit* t) +{ + sp_point_384* rp[2]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*12; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + /* When infinity don't double point passed in - constant time. */ + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_384*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_384)); + x = rp[p->infinity]->x; + y = rp[p->infinity]->y; + z = rp[p->infinity]->z; + /* Put point to double into result - good for infinity. */ + if (r != p) { + for (i=0; i<12; i++) { + r->x[i] = p->x[i]; + } + for (i=0; i<12; i++) { + r->y[i] = p->y[i]; + } + for (i=0; i<12; i++) { + r->z[i] = p->z[i]; + } + r->infinity = p->infinity; + } + + /* T1 = Z * Z */ + sp_384_mont_sqr_12(t1, z, p384_mod, p384_mp_mod); + /* Z = Y * Z */ + sp_384_mont_mul_12(z, y, z, p384_mod, p384_mp_mod); + /* Z = 2Z */ + sp_384_mont_dbl_12(z, z, p384_mod); + /* T2 = X - T1 */ + sp_384_mont_sub_12(t2, x, t1, p384_mod); + /* T1 = X + T1 */ + sp_384_mont_add_12(t1, x, t1, p384_mod); + /* T2 = T1 * T2 */ + sp_384_mont_mul_12(t2, t1, t2, p384_mod, p384_mp_mod); + /* T1 = 3T2 */ + sp_384_mont_tpl_12(t1, t2, p384_mod); + /* Y = 2Y */ + sp_384_mont_dbl_12(y, y, p384_mod); + /* Y = Y * Y */ + sp_384_mont_sqr_12(y, y, p384_mod, p384_mp_mod); + /* T2 = Y * Y */ + sp_384_mont_sqr_12(t2, y, p384_mod, p384_mp_mod); + /* T2 = T2/2 */ + sp_384_div2_12(t2, t2, p384_mod); + /* Y = Y * X */ + sp_384_mont_mul_12(y, y, x, p384_mod, p384_mp_mod); + /* X = T1 * T1 */ + sp_384_mont_mul_12(x, t1, t1, p384_mod, p384_mp_mod); + /* X = X - Y */ + sp_384_mont_sub_12(x, x, y, p384_mod); + /* X = X - Y */ + sp_384_mont_sub_12(x, x, y, p384_mod); + /* Y = Y - X */ + sp_384_mont_sub_12(y, y, x, p384_mod); + /* Y = Y * T1 */ + sp_384_mont_mul_12(y, y, t1, p384_mod, p384_mp_mod); + /* Y = Y - T2 */ + sp_384_mont_sub_12(y, y, t2, p384_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_384_cmp_equal_12(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])) == 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. + */ +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]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*12; + sp_digit* t3 = t + 4*12; + sp_digit* t4 = t + 6*12; + sp_digit* t5 = t + 8*12; + 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_384* a = p; + p = q; + q = a; + } + + /* Check double */ + (void)sp_384_sub_12(t1, p384_mod, q->y); + sp_384_norm_12(t1); + if ((sp_384_cmp_equal_12(p->x, q->x) & sp_384_cmp_equal_12(p->z, q->z) & + (sp_384_cmp_equal_12(p->y, q->y) | sp_384_cmp_equal_12(p->y, t1))) != 0) { + sp_384_proj_point_dbl_12(r, p, t); + } + else { + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_384*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_384)); + 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<12; i++) { + r->x[i] = ap[p->infinity]->x[i]; + } + for (i=0; i<12; i++) { + r->y[i] = ap[p->infinity]->y[i]; + } + for (i=0; i<12; i++) { + r->z[i] = ap[p->infinity]->z[i]; + } + r->infinity = ap[p->infinity]->infinity; + + /* U1 = X1*Z2^2 */ + sp_384_mont_sqr_12(t1, q->z, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(t3, t1, q->z, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(t1, t1, x, p384_mod, p384_mp_mod); + /* U2 = X2*Z1^2 */ + sp_384_mont_sqr_12(t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(t4, t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(t2, t2, q->x, p384_mod, p384_mp_mod); + /* S1 = Y1*Z2^3 */ + sp_384_mont_mul_12(t3, t3, y, p384_mod, p384_mp_mod); + /* S2 = Y2*Z1^3 */ + sp_384_mont_mul_12(t4, t4, q->y, p384_mod, p384_mp_mod); + /* H = U2 - U1 */ + sp_384_mont_sub_12(t2, t2, t1, p384_mod); + /* R = S2 - S1 */ + sp_384_mont_sub_12(t4, t4, t3, p384_mod); + /* Z3 = H*Z1*Z2 */ + sp_384_mont_mul_12(z, z, q->z, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(z, z, t2, p384_mod, p384_mp_mod); + /* X3 = R^2 - H^3 - 2*U1*H^2 */ + sp_384_mont_sqr_12(x, t4, p384_mod, p384_mp_mod); + sp_384_mont_sqr_12(t5, t2, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(y, t1, t5, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(t5, t5, t2, p384_mod, p384_mp_mod); + sp_384_mont_sub_12(x, x, t5, p384_mod); + sp_384_mont_dbl_12(t1, y, p384_mod); + sp_384_mont_sub_12(x, x, t1, p384_mod); + /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */ + sp_384_mont_sub_12(y, y, x, p384_mod); + sp_384_mont_mul_12(y, y, t4, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(t5, t5, t3, p384_mod, p384_mp_mod); + sp_384_mont_sub_12(y, y, t5, p384_mod); + } +} + +/* Multiply the point 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. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_ecc_mulmod_fast_12(sp_point_384* r, const sp_point_384* g, const sp_digit* k, + int map, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 td[16]; + sp_point_384 rtd; + sp_digit tmpd[2 * 12 * 6]; +#endif + sp_point_384* t; + sp_point_384* rt; + sp_digit* tmp; + sp_digit n; + int i; + int c, y; + int err; + + (void)heap; + + err = sp_384_point_new_12(heap, rtd, rt); +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + t = (sp_point_384*)XMALLOC(sizeof(sp_point_384) * 16, heap, DYNAMIC_TYPE_ECC); + if (t == NULL) + err = MEMORY_E; + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 12 * 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 */ + (void)sp_384_mod_mul_norm_12(t[1].x, g->x, p384_mod); + (void)sp_384_mod_mul_norm_12(t[1].y, g->y, p384_mod); + (void)sp_384_mod_mul_norm_12(t[1].z, g->z, p384_mod); + t[1].infinity = 0; + sp_384_proj_point_dbl_12(&t[ 2], &t[ 1], tmp); + t[ 2].infinity = 0; + sp_384_proj_point_add_12(&t[ 3], &t[ 2], &t[ 1], tmp); + t[ 3].infinity = 0; + sp_384_proj_point_dbl_12(&t[ 4], &t[ 2], tmp); + t[ 4].infinity = 0; + sp_384_proj_point_add_12(&t[ 5], &t[ 3], &t[ 2], tmp); + t[ 5].infinity = 0; + sp_384_proj_point_dbl_12(&t[ 6], &t[ 3], tmp); + t[ 6].infinity = 0; + sp_384_proj_point_add_12(&t[ 7], &t[ 4], &t[ 3], tmp); + t[ 7].infinity = 0; + sp_384_proj_point_dbl_12(&t[ 8], &t[ 4], tmp); + t[ 8].infinity = 0; + sp_384_proj_point_add_12(&t[ 9], &t[ 5], &t[ 4], tmp); + t[ 9].infinity = 0; + sp_384_proj_point_dbl_12(&t[10], &t[ 5], tmp); + t[10].infinity = 0; + sp_384_proj_point_add_12(&t[11], &t[ 6], &t[ 5], tmp); + t[11].infinity = 0; + sp_384_proj_point_dbl_12(&t[12], &t[ 6], tmp); + t[12].infinity = 0; + sp_384_proj_point_add_12(&t[13], &t[ 7], &t[ 6], tmp); + t[13].infinity = 0; + sp_384_proj_point_dbl_12(&t[14], &t[ 7], tmp); + t[14].infinity = 0; + sp_384_proj_point_add_12(&t[15], &t[ 8], &t[ 7], tmp); + t[15].infinity = 0; + + i = 10; + n = k[i+1] << 0; + c = 28; + y = n >> 28; + XMEMCPY(rt, &t[y], sizeof(sp_point_384)); + n <<= 4; + for (; i>=0 || c>=4; ) { + if (c < 4) { + n |= k[i--] << (0 - c); + c += 32; + } + y = (n >> 28) & 0xf; + n <<= 4; + c -= 4; + + sp_384_proj_point_dbl_12(rt, rt, tmp); + sp_384_proj_point_dbl_12(rt, rt, tmp); + sp_384_proj_point_dbl_12(rt, rt, tmp); + sp_384_proj_point_dbl_12(rt, rt, tmp); + + sp_384_proj_point_add_12(rt, rt, &t[y], tmp); + } + + if (map != 0) { + sp_384_map_12(r, rt, tmp); + } + else { + XMEMCPY(r, rt, sizeof(sp_point_384)); + } + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (tmp != NULL) { + XMEMSET(tmp, 0, sizeof(sp_digit) * 2 * 12 * 6); + XFREE(tmp, heap, DYNAMIC_TYPE_ECC); + } + if (t != NULL) { + XMEMSET(t, 0, sizeof(sp_point_384) * 16); + XFREE(t, heap, DYNAMIC_TYPE_ECC); + } +#else + ForceZero(tmpd, sizeof(tmpd)); + ForceZero(td, sizeof(td)); +#endif + sp_384_point_free_12(rt, 1, heap); + + 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. + * + * r Result of repeated doubling of point. + * p Point to double. + * n Number of times to double + * t Temporary ordinate data. + */ +static void sp_384_proj_point_dbl_n_12(sp_point_384* r, const sp_point_384* p, int n, + sp_digit* t) +{ + sp_point_384* rp[2]; + sp_digit* w = t; + sp_digit* a = t + 2*12; + sp_digit* b = t + 4*12; + sp_digit* t1 = t + 6*12; + sp_digit* t2 = t + 8*12; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_384*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_384)); + x = rp[p->infinity]->x; + y = rp[p->infinity]->y; + z = rp[p->infinity]->z; + if (r != p) { + for (i=0; i<12; i++) { + r->x[i] = p->x[i]; + } + for (i=0; i<12; i++) { + r->y[i] = p->y[i]; + } + for (i=0; i<12; i++) { + r->z[i] = p->z[i]; + } + r->infinity = p->infinity; + } + + /* Y = 2*Y */ + sp_384_mont_dbl_12(y, y, p384_mod); + /* W = Z^4 */ + sp_384_mont_sqr_12(w, z, p384_mod, p384_mp_mod); + sp_384_mont_sqr_12(w, w, p384_mod, p384_mp_mod); + while (n-- > 0) { + /* A = 3*(X^2 - W) */ + sp_384_mont_sqr_12(t1, x, p384_mod, p384_mp_mod); + sp_384_mont_sub_12(t1, t1, w, p384_mod); + sp_384_mont_tpl_12(a, t1, p384_mod); + /* B = X*Y^2 */ + sp_384_mont_sqr_12(t2, y, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(b, t2, x, p384_mod, p384_mp_mod); + /* X = A^2 - 2B */ + sp_384_mont_sqr_12(x, a, p384_mod, p384_mp_mod); + sp_384_mont_dbl_12(t1, b, p384_mod); + sp_384_mont_sub_12(x, x, t1, p384_mod); + /* Z = Z*Y */ + sp_384_mont_mul_12(z, z, y, p384_mod, p384_mp_mod); + /* t2 = Y^4 */ + sp_384_mont_sqr_12(t2, t2, p384_mod, p384_mp_mod); + if (n != 0) { + /* W = W*Y^4 */ + sp_384_mont_mul_12(w, w, t2, p384_mod, p384_mp_mod); + } + /* y = 2*A*(B - X) - Y^4 */ + sp_384_mont_sub_12(y, b, x, p384_mod); + sp_384_mont_mul_12(y, y, a, p384_mod, p384_mp_mod); + sp_384_mont_dbl_12(y, y, p384_mod); + sp_384_mont_sub_12(y, y, t2, p384_mod); + } + /* Y = Y/2 */ + sp_384_div2_12(y, y, p384_mod); +} + +#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_384_proj_point_add_qz1_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]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*12; + sp_digit* t3 = t + 4*12; + sp_digit* t4 = t + 6*12; + sp_digit* t5 = t + 8*12; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + /* Check double */ + (void)sp_384_sub_12(t1, p384_mod, q->y); + sp_384_norm_12(t1); + if ((sp_384_cmp_equal_12(p->x, q->x) & sp_384_cmp_equal_12(p->z, q->z) & + (sp_384_cmp_equal_12(p->y, q->y) | sp_384_cmp_equal_12(p->y, t1))) != 0) { + sp_384_proj_point_dbl_12(r, p, t); + } + else { + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_384*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_384)); + 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<12; i++) { + r->x[i] = ap[p->infinity]->x[i]; + } + for (i=0; i<12; i++) { + r->y[i] = ap[p->infinity]->y[i]; + } + for (i=0; i<12; i++) { + r->z[i] = ap[p->infinity]->z[i]; + } + r->infinity = ap[p->infinity]->infinity; + + /* U2 = X2*Z1^2 */ + sp_384_mont_sqr_12(t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(t4, t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(t2, t2, q->x, p384_mod, p384_mp_mod); + /* S2 = Y2*Z1^3 */ + sp_384_mont_mul_12(t4, t4, q->y, p384_mod, p384_mp_mod); + /* H = U2 - X1 */ + sp_384_mont_sub_12(t2, t2, x, p384_mod); + /* R = S2 - Y1 */ + sp_384_mont_sub_12(t4, t4, y, p384_mod); + /* Z3 = H*Z1 */ + sp_384_mont_mul_12(z, z, t2, p384_mod, p384_mp_mod); + /* X3 = R^2 - H^3 - 2*X1*H^2 */ + sp_384_mont_sqr_12(t1, t4, p384_mod, p384_mp_mod); + sp_384_mont_sqr_12(t5, t2, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(t3, x, t5, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(t5, t5, t2, p384_mod, p384_mp_mod); + sp_384_mont_sub_12(x, t1, t5, p384_mod); + sp_384_mont_dbl_12(t1, t3, p384_mod); + sp_384_mont_sub_12(x, x, t1, p384_mod); + /* Y3 = R*(X1*H^2 - X3) - Y1*H^3 */ + sp_384_mont_sub_12(t3, t3, x, p384_mod); + sp_384_mont_mul_12(t3, t3, t4, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(t5, t5, y, p384_mod, p384_mp_mod); + sp_384_mont_sub_12(y, t3, t5, p384_mod); + } +} + +#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. + * + * 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_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) + sp_point_384 td, s1d, s2d; +#endif + sp_point_384* t; + sp_point_384* s1 = NULL; + sp_point_384* s2 = NULL; + int i, j; + int err; + + (void)heap; + + err = sp_384_point_new_12(heap, td, t); + if (err == MP_OKAY) { + err = sp_384_point_new_12(heap, s1d, s1); + } + if (err == MP_OKAY) { + err = sp_384_point_new_12(heap, s2d, s2); + } + + if (err == MP_OKAY) { + err = sp_384_mod_mul_norm_12(t->x, a->x, p384_mod); + } + if (err == MP_OKAY) { + err = sp_384_mod_mul_norm_12(t->y, a->y, p384_mod); + } + if (err == MP_OKAY) { + err = sp_384_mod_mul_norm_12(t->z, a->z, p384_mod); + } + if (err == MP_OKAY) { + t->infinity = 0; + sp_384_proj_to_affine_12(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<4; i++) { + sp_384_proj_point_dbl_n_12(t, t, 96, tmp); + sp_384_proj_to_affine_12(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_384_proj_point_add_qz1_12(t, s1, s2, tmp); + sp_384_proj_to_affine_12(t, tmp); + XMEMCPY(table[j].x, t->x, sizeof(table->x)); + XMEMCPY(table[j].y, t->y, sizeof(table->y)); + } + } + } + + sp_384_point_free_12(s2, 0, heap); + sp_384_point_free_12(s1, 0, heap); + sp_384_point_free_12( t, 0, heap); + + return err; +} + +#endif /* FP_ECC */ +/* Multiply the point 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_384_ecc_mulmod_stripe_12(sp_point_384* r, const sp_point_384* g, + const sp_table_entry_384* table, const sp_digit* k, int map, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 rtd; + sp_point_384 pd; + sp_digit td[2 * 12 * 6]; +#endif + sp_point_384* rt; + sp_point_384* p = NULL; + sp_digit* t; + int i, j; + int y, x; + int err; + + (void)g; + (void)heap; + + + err = sp_384_point_new_12(heap, rtd, rt); + if (err == MP_OKAY) { + err = sp_384_point_new_12(heap, pd, p); + } +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 12 * 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; + for (j=0,x=95; j<4; j++,x+=96) { + y |= ((k[x / 32] >> (x % 32)) & 1) << j; + } + 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=94; i>=0; i--) { + y = 0; + for (j=0,x=i; j<4; j++,x+=96) { + y |= ((k[x / 32] >> (x % 32)) & 1) << j; + } + + sp_384_proj_point_dbl_12(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_384_proj_point_add_qz1_12(rt, rt, p, t); + } + + if (map != 0) { + sp_384_map_12(r, rt, t); + } + else { + XMEMCPY(r, rt, sizeof(sp_point_384)); + } + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (t != NULL) { + XFREE(t, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_12(p, 0, heap); + sp_384_point_free_12(rt, 0, heap); + + return err; +} + +#ifdef FP_ECC +#ifndef FP_ENTRIES + #define FP_ENTRIES 16 +#endif + +typedef struct sp_cache_384_t { + sp_digit x[12]; + sp_digit y[12]; + sp_table_entry_384 table[16]; + uint32_t cnt; + int set; +} sp_cache_384_t; + +static THREAD_LS_T sp_cache_384_t sp_cache_384[FP_ENTRIES]; +static THREAD_LS_T int sp_cache_384_last = -1; +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 + +static void sp_ecc_get_cache_384(const sp_point_384* g, sp_cache_384_t** cache) +{ + int i, j; + uint32_t least; + + if (sp_cache_384_inited == 0) { + for (i=0; ix, sp_cache_384[i].x) & + sp_384_cmp_equal_12(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. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_ecc_mulmod_12(sp_point_384* r, const sp_point_384* g, const sp_digit* k, + int map, void* heap) +{ +#ifndef FP_ECC + return sp_384_ecc_mulmod_fast_12(r, g, k, map, heap); +#else + sp_digit tmp[2 * 12 * 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_12(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_fast_12(r, g, k, map, heap); + } + else { + err = sp_384_ecc_mulmod_stripe_12(r, g, cache->table, k, + map, heap); + } + } + + return err; +#endif +} + +#else +#ifdef FP_ECC +/* Generate the pre-computed table of points for the base point. + * + * 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_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) + sp_point_384 td, s1d, s2d; +#endif + sp_point_384* t; + sp_point_384* s1 = NULL; + sp_point_384* s2 = NULL; + int i, j; + int err; + + (void)heap; + + err = sp_384_point_new_12(heap, td, t); + if (err == MP_OKAY) { + err = sp_384_point_new_12(heap, s1d, s1); + } + if (err == MP_OKAY) { + err = sp_384_point_new_12(heap, s2d, s2); + } + + if (err == MP_OKAY) { + err = sp_384_mod_mul_norm_12(t->x, a->x, p384_mod); + } + if (err == MP_OKAY) { + err = sp_384_mod_mul_norm_12(t->y, a->y, p384_mod); + } + if (err == MP_OKAY) { + err = sp_384_mod_mul_norm_12(t->z, a->z, p384_mod); + } + if (err == MP_OKAY) { + t->infinity = 0; + sp_384_proj_to_affine_12(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_12(t, t, 48, tmp); + sp_384_proj_to_affine_12(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_12(t, s1, s2, tmp); + sp_384_proj_to_affine_12(t, tmp); + XMEMCPY(table[j].x, t->x, sizeof(table->x)); + XMEMCPY(table[j].y, t->y, sizeof(table->y)); + } + } + } + + sp_384_point_free_12(s2, 0, heap); + sp_384_point_free_12(s1, 0, heap); + sp_384_point_free_12( t, 0, heap); + + return err; +} + +#endif /* FP_ECC */ +/* Multiply the point 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_384_ecc_mulmod_stripe_12(sp_point_384* r, const sp_point_384* g, + const sp_table_entry_384* table, const sp_digit* k, int map, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 rtd; + sp_point_384 pd; + sp_digit td[2 * 12 * 6]; +#endif + sp_point_384* rt; + sp_point_384* p = NULL; + sp_digit* t; + int i, j; + int y, x; + int err; + + (void)g; + (void)heap; + + + err = sp_384_point_new_12(heap, rtd, rt); + if (err == MP_OKAY) { + err = sp_384_point_new_12(heap, pd, p); + } +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 12 * 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; + for (j=0,x=47; j<8; j++,x+=48) { + y |= ((k[x / 32] >> (x % 32)) & 1) << j; + } + 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; + for (j=0,x=i; j<8; j++,x+=48) { + y |= ((k[x / 32] >> (x % 32)) & 1) << j; + } + + sp_384_proj_point_dbl_12(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_384_proj_point_add_qz1_12(rt, rt, p, t); + } + + if (map != 0) { + sp_384_map_12(r, rt, t); + } + else { + XMEMCPY(r, rt, sizeof(sp_point_384)); + } + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (t != NULL) { + XFREE(t, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_12(p, 0, heap); + sp_384_point_free_12(rt, 0, heap); + + return err; +} + +#ifdef FP_ECC +#ifndef FP_ENTRIES + #define FP_ENTRIES 16 +#endif + +typedef struct sp_cache_384_t { + sp_digit x[12]; + sp_digit y[12]; + sp_table_entry_384 table[256]; + uint32_t cnt; + int set; +} sp_cache_384_t; + +static THREAD_LS_T sp_cache_384_t sp_cache_384[FP_ENTRIES]; +static THREAD_LS_T int sp_cache_384_last = -1; +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 + +static void sp_ecc_get_cache_384(const sp_point_384* g, sp_cache_384_t** cache) +{ + int i, j; + uint32_t least; + + if (sp_cache_384_inited == 0) { + for (i=0; ix, sp_cache_384[i].x) & + sp_384_cmp_equal_12(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. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_ecc_mulmod_12(sp_point_384* r, const sp_point_384* g, const sp_digit* k, + int map, void* heap) +{ +#ifndef FP_ECC + return sp_384_ecc_mulmod_fast_12(r, g, k, map, heap); +#else + sp_digit tmp[2 * 12 * 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_12(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_fast_12(r, g, k, map, heap); + } + else { + err = sp_384_ecc_mulmod_stripe_12(r, g, cache->table, k, + map, 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_384(mp_int* km, ecc_point* gm, ecc_point* r, int map, + void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 p; + sp_digit kd[12]; +#endif + sp_point_384* point; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_384_point_new_12(heap, p, point); +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 12, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) + err = MEMORY_E; + } +#else + k = kd; +#endif + if (err == MP_OKAY) { + sp_384_from_mp(k, 12, km); + sp_384_point_from_ecc_point_12(point, gm); + + err = sp_384_ecc_mulmod_12(point, point, k, map, heap); + } + if (err == MP_OKAY) { + err = sp_384_point_to_ecc_point_12(point, r); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_12(point, 0, heap); + + return err; +} + +#ifdef WOLFSSL_SP_SMALL +static const sp_table_entry_384 p384_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 } }, + /* 1 */ + { { 0x49c0b528,0x3dd07566,0xa0d6ce38,0x20e378e2,0x541b4d6e,0x879c3afc, + 0x59a30eff,0x64548684,0x614ede2b,0x812ff723,0x299e1513,0x4d3aadc2 }, + { 0x4b03a4fe,0x23043dad,0x7bb4a9ac,0xa1bfa8bf,0x2e83b050,0x8bade756, + 0x68f4ffd9,0xc6c35219,0x3969a840,0xdd800226,0x5a15c5e9,0x2b78abc2 } }, + /* 2 */ + { { 0xf26feef9,0x24480c57,0x3a0e1240,0xc31a2694,0x273e2bc7,0x735002c3, + 0x3ef1ed4c,0x8c42e9c5,0x7f4948e8,0x028babf6,0x8a978632,0x6a502f43 }, + { 0xb74536fe,0xf5f13a46,0xd8a9f0eb,0x1d218bab,0x37232768,0x30f36bcc, + 0x576e8c18,0xc5317b31,0x9bbcb766,0xef1d57a6,0xb3e3d4dc,0x917c4930 } }, + /* 3 */ + { { 0xe349ddd0,0x11426e2e,0x9b2fc250,0x9f117ef9,0xec0174a6,0xff36b480, + 0x18458466,0x4f4bde76,0x05806049,0x2f2edb6d,0x19dfca92,0x8adc75d1 }, + { 0xb7d5a7ce,0xa619d097,0xa34411e9,0x874275e5,0x0da4b4ef,0x5403e047, + 0x77901d8f,0x2ebaafd9,0xa747170f,0x5e63ebce,0x7f9d8036,0x12a36944 } }, + /* 4 */ + { { 0x2f9fbe67,0x378205de,0x7f728e44,0xc4afcb83,0x682e00f1,0xdbcec06c, + 0x114d5423,0xf2a145c3,0x7a52463e,0xa01d9874,0x7d717b0a,0xfc0935b1 }, + { 0xd4d01f95,0x9653bc4f,0x9560ad34,0x9aa83ea8,0xaf8e3f3f,0xf77943dc, + 0xe86fe16e,0x70774a10,0xbf9ffdcf,0x6b62e6f1,0x588745c9,0x8a72f39e } }, + /* 5 */ + { { 0x2341c342,0x73ade4da,0xea704422,0xdd326e54,0x3741cef3,0x336c7d98, + 0x59e61549,0x1eafa00d,0xbd9a3efd,0xcd3ed892,0xc5c6c7e4,0x03faf26c }, + { 0x3045f8ac,0x087e2fcf,0x174f1e73,0x14a65532,0xfe0af9a7,0x2cf84f28, + 0x2cdc935b,0xddfd7a84,0x6929c895,0x4c0f117b,0x4c8bcfcc,0x356572d6 } }, + /* 6 */ + { { 0x3f3b236f,0xfab08607,0x81e221da,0x19e9d41d,0x3927b428,0xf3f6571e, + 0x7550f1f6,0x4348a933,0xa85e62f0,0x7167b996,0x7f5452bf,0x62d43759 }, + { 0xf2955926,0xd85feb9e,0x6df78353,0x440a561f,0x9ca36b59,0x389668ec, + 0xa22da016,0x052bf1a1,0xf6093254,0xbdfbff72,0xe22209f3,0x94e50f28 } }, + /* 7 */ + { { 0x3062e8af,0x90b2e5b3,0xe8a3d369,0xa8572375,0x201db7b1,0x3fe1b00b, + 0xee651aa2,0xe926def0,0xb9b10ad7,0x6542c9be,0xa2fcbe74,0x098e309b }, + { 0xfff1d63f,0x779deeb3,0x20bfd374,0x23d0e80a,0x8768f797,0x8452bb3b, + 0x1f952856,0xcf75bb4d,0x29ea3faa,0x8fe6b400,0x81373a53,0x12bd3e40 } }, + /* 8 */ + { { 0x16973cf4,0x070d34e1,0x7e4f34f7,0x20aee08b,0x5eb8ad29,0x269af9b9, + 0xa6a45dda,0xdde0a036,0x63df41e0,0xa18b528e,0xa260df2a,0x03cc71b2 }, + { 0xa06b1dd7,0x24a6770a,0x9d2675d3,0x5bfa9c11,0x96844432,0x73c1e2a1, + 0x131a6cf0,0x3660558d,0x2ee79454,0xb0289c83,0xc6d8ddcd,0xa6aefb01 } }, + /* 9 */ + { { 0x01ab5245,0xba1464b4,0xc48d93ff,0x9b8d0b6d,0x93ad272c,0x939867dc, + 0xae9fdc77,0xbebe085e,0x894ea8bd,0x73ae5103,0x39ac22e1,0x740fc89a }, + { 0x28e23b23,0x5e28b0a3,0xe13104d0,0x2352722e,0xb0a2640d,0xf4667a18, + 0x49bb37c3,0xac74a72e,0xe81e183a,0x79f734f0,0x3fd9c0eb,0xbffe5b6c } }, + /* 10 */ + { { 0x00623f3b,0x03cf2922,0x5f29ebff,0x095c7111,0x80aa6823,0x42d72247, + 0x7458c0b0,0x044c7ba1,0x0959ec20,0xca62f7ef,0xf8ca929f,0x40ae2ab7 }, + { 0xa927b102,0xb8c5377a,0xdc031771,0x398a86a0,0xc216a406,0x04908f9d, + 0x918d3300,0xb423a73a,0xe0b94739,0x634b0ff1,0x2d69f697,0xe29de725 } }, + /* 11 */ + { { 0x8435af04,0x744d1400,0xfec192da,0x5f255b1d,0x336dc542,0x1f17dc12, + 0x636a68a8,0x5c90c2a7,0x7704ca1e,0x960c9eb7,0x6fb3d65a,0x9de8cf1e }, + { 0x511d3d06,0xc60fee0d,0xf9eb52c7,0x466e2313,0x206b0914,0x743c0f5f, + 0x2191aa4d,0x42f55bac,0xffebdbc2,0xcefc7c8f,0xe6e8ed1c,0xd4fa6081 } }, + /* 12 */ + { { 0x98683186,0x867db639,0xddcc4ea9,0xfb5cf424,0xd4f0e7bd,0xcc9a7ffe, + 0x7a779f7e,0x7c57f71c,0xd6b25ef2,0x90774079,0xb4081680,0x90eae903 }, + { 0x0ee1fceb,0xdf2aae5e,0xe86c1a1f,0x3ff1da24,0xca193edf,0x80f587d6, + 0xdc9b9d6a,0xa5695523,0x85920303,0x7b840900,0xba6dbdef,0x1efa4dfc } }, + /* 13 */ + { { 0xe0540015,0xfbd838f9,0xc39077dc,0x2c323946,0xad619124,0x8b1fb9e6, + 0x0ca62ea8,0x9612440c,0x2dbe00ff,0x9ad9b52c,0xae197643,0xf52abaa1 }, + { 0x2cac32ad,0xd0e89894,0x62a98f91,0xdfb79e42,0x276f55cb,0x65452ecf, + 0x7ad23e12,0xdb1ac0d2,0xde4986f0,0xf68c5f6a,0x82ce327d,0x389ac37b } }, + /* 14 */ + { { 0xb8a9e8c9,0xcd96866d,0x5bb8091e,0xa11963b8,0x045b3cd2,0xc7f90d53, + 0x80f36504,0x755a72b5,0x21d3751c,0x46f8b399,0x53c193de,0x4bffdc91 }, + { 0xb89554e7,0xcd15c049,0xf7a26be6,0x353c6754,0xbd41d970,0x79602370, + 0x12b176c0,0xde16470b,0x40c8809d,0x56ba1175,0xe435fb1e,0xe2db35c3 } }, + /* 15 */ + { { 0x6328e33f,0xd71e4aab,0xaf8136d1,0x5486782b,0x86d57231,0x07a4995f, + 0x1651a968,0xf1f0a5bd,0x76803b6d,0xa5dc5b24,0x42dda935,0x5c587cbc }, + { 0xbae8b4c0,0x2b6cdb32,0xb1331138,0x66d1598b,0x5d7e9614,0x4a23b2d2, + 0x74a8c05d,0x93e402a6,0xda7ce82e,0x45ac94e6,0xe463d465,0xeb9f8281 } }, +}; + +/* 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. + * 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_12(sp_point_384* r, const sp_digit* k, + int map, void* heap) +{ + return sp_384_ecc_mulmod_stripe_12(r, &p384_base, p384_table, + k, map, heap); +} + +#else +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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 */ + { { 0x49c0b528,0x3dd07566,0xa0d6ce38,0x20e378e2,0x541b4d6e,0x879c3afc, + 0x59a30eff,0x64548684,0x614ede2b,0x812ff723,0x299e1513,0x4d3aadc2 }, + { 0x4b03a4fe,0x23043dad,0x7bb4a9ac,0xa1bfa8bf,0x2e83b050,0x8bade756, + 0x68f4ffd9,0xc6c35219,0x3969a840,0xdd800226,0x5a15c5e9,0x2b78abc2 } }, + /* 2 */ + { { 0x2b0c535b,0x29864753,0x70506296,0x90dd6953,0x216ab9ac,0x038cd6b4, + 0xbe12d76a,0x3df9b7b7,0x5f347bdb,0x13f4d978,0x13e94489,0x222c5c9c }, + { 0x2680dc64,0x5f8e796f,0x58352417,0x120e7cb7,0xd10740b8,0x254b5d8a, + 0x5337dee6,0xc38b8efb,0x94f02247,0xf688c2e1,0x6c25bc4c,0x7b5c75f3 } }, + /* 3 */ + { { 0x9edffea5,0xe26a3cc3,0x37d7e9fc,0x35bbfd1c,0x9bde3ef6,0xf0e7700d, + 0x1a538f5a,0x0380eb47,0x05bf9eb3,0x2e9da8bb,0x1a460c3e,0xdbb93c73 }, + { 0xf526b605,0x37dba260,0xfd785537,0x95d4978e,0xed72a04a,0x24ed793a, + 0x76005b1a,0x26948377,0x9e681f82,0x99f557b9,0xd64954ef,0xae5f9557 } }, + /* 4 */ + { { 0xf26feef9,0x24480c57,0x3a0e1240,0xc31a2694,0x273e2bc7,0x735002c3, + 0x3ef1ed4c,0x8c42e9c5,0x7f4948e8,0x028babf6,0x8a978632,0x6a502f43 }, + { 0xb74536fe,0xf5f13a46,0xd8a9f0eb,0x1d218bab,0x37232768,0x30f36bcc, + 0x576e8c18,0xc5317b31,0x9bbcb766,0xef1d57a6,0xb3e3d4dc,0x917c4930 } }, + /* 5 */ + { { 0xe349ddd0,0x11426e2e,0x9b2fc250,0x9f117ef9,0xec0174a6,0xff36b480, + 0x18458466,0x4f4bde76,0x05806049,0x2f2edb6d,0x19dfca92,0x8adc75d1 }, + { 0xb7d5a7ce,0xa619d097,0xa34411e9,0x874275e5,0x0da4b4ef,0x5403e047, + 0x77901d8f,0x2ebaafd9,0xa747170f,0x5e63ebce,0x7f9d8036,0x12a36944 } }, + /* 6 */ + { { 0x4fc52870,0x28f9c07a,0x1a53a961,0xce0b3748,0x0e1828d9,0xd550fa18, + 0x6adb225a,0xa24abaf7,0x6e58a348,0xd11ed0a5,0x948acb62,0xf3d811e6 }, + { 0x4c61ed22,0x8618dd77,0x80b47c9d,0x0bb747f9,0xde6b8559,0x22bf796f, + 0x680a21e9,0xfdfd1c6d,0x2af2c9dd,0xc0db1577,0xc1e90f3d,0xa09379e6 } }, + /* 7 */ + { { 0xe085c629,0x386c66ef,0x095bc89a,0x5fc2a461,0x203f4b41,0x1353d631, + 0x7e4bd8f5,0x7ca1972b,0xa7df8ce9,0xb077380a,0xee7e4ea3,0xd8a90389 }, + { 0xe7b14461,0x1bc74dc7,0x0c9c4f78,0xdc2cb014,0x84ef0a10,0x52b4b3a6, + 0x20327fe2,0xbde6ea5d,0x660f9615,0xb71ec435,0xb8ad8173,0xeede5a04 } }, + /* 8 */ + { { 0x893b9a2d,0x5584cbb3,0x00850c5d,0x820c660b,0x7df2d43d,0x4126d826, + 0x0109e801,0xdd5bbbf0,0x38172f1c,0x85b92ee3,0xf31430d9,0x609d4f93 }, + { 0xeadaf9d6,0x1e059a07,0x0f125fb0,0x70e6536c,0x560f20e7,0xd6220751, + 0x7aaf3a9a,0xa59489ae,0x64bae14e,0x7b70e2f6,0x76d08249,0x0dd03701 } }, + /* 9 */ + { { 0x8510521f,0x4cc13be8,0xf724cc17,0x87315ba9,0x353dc263,0xb49d83bb, + 0x0c279257,0x8b677efe,0xc93c9537,0x510a1c1c,0xa4702c99,0x33e30cd8 }, + { 0x2208353f,0xf0ffc89d,0xced42b2b,0x0170fa8d,0x26e2a5f5,0x090851ed, + 0xecb52c96,0x81276455,0x7fe1adf4,0x0646c4e1,0xb0868eab,0x513f047e } }, + /* 10 */ + { { 0xdf5bdf53,0xc07611f4,0x58b11a6d,0x45d331a7,0x1c4ee394,0x58965daf, + 0x5a5878d1,0xba8bebe7,0x82dd3025,0xaecc0a18,0xa923eb8b,0xcf2a3899 }, + { 0xd24fd048,0xf98c9281,0x8bbb025d,0x841bfb59,0xc9ab9d53,0xb8ddf8ce, + 0x7fef044e,0x538a4cb6,0x23236662,0x092ac21f,0x0b66f065,0xa919d385 } }, + /* 11 */ + { { 0x85d480d8,0x3db03b40,0x1b287a7d,0x8cd9f479,0x4a8f3bae,0x8f24dc75, + 0x3db41892,0x482eb800,0x9c56e0f5,0x38bf9eb3,0x9a91dc6f,0x8b977320 }, + { 0x7209cfc2,0xa31b05b2,0x05b2db70,0x4c49bf85,0xd619527b,0x56462498, + 0x1fac51ba,0x3fe51039,0xab4b8342,0xfb04f55e,0x04c6eabf,0xc07c10dc } }, + /* 12 */ + { { 0xdb32f048,0xad22fe4c,0x475ed6df,0x5f23bf91,0xaa66b6cb,0xa50ce0c0, + 0xf03405c0,0xdf627a89,0xf95e2d6a,0x3674837d,0xba42e64e,0x081c95b6 }, + { 0xe71d6ceb,0xeba3e036,0x6c6b0271,0xb45bcccf,0x0684701d,0x67b47e63, + 0xe712523f,0x60f8f942,0x5cd47adc,0x82423472,0x87649cbb,0x83027d79 } }, + /* 13 */ + { { 0x3615b0b8,0xb3929ea6,0xa54dac41,0xb41441fd,0xb5b6a368,0x8995d556, + 0x167ef05e,0xa80d4529,0x6d25a27f,0xf6bcb4a1,0x7bd55b68,0x210d6a4c }, + { 0x25351130,0xf3804abb,0x903e37eb,0x1d2df699,0x084c25c8,0x5f201efc, + 0xa1c68e91,0x31a28c87,0x563f62a5,0x81dad253,0xd6c415d4,0x5dd6de70 } }, + /* 14 */ + { { 0x846612ce,0x29f470fd,0xda18d997,0x986f3eec,0x2f34af86,0x6b84c161, + 0x46ddaf8b,0x5ef0a408,0xe49e795f,0x14405a00,0xaa2f7a37,0x5f491b16 }, + { 0xdb41b38d,0xc7f07ae4,0x18fbfcaa,0xef7d119e,0x14443b19,0x3a18e076, + 0x79a19926,0x4356841a,0xe2226fbe,0x91f4a91c,0x3cc88721,0xdc77248c } }, + /* 15 */ + { { 0xe4b1ec9d,0xd570ff1a,0xe7eef706,0x21d23e0e,0xca19e086,0x3cde40f4, + 0xcd4bb270,0x7d6523c4,0xbf13aa6c,0x16c1f06c,0xd14c4b60,0x5aa7245a }, + { 0x44b74de8,0x37f81467,0x620a934e,0x839e7a17,0xde8b1aa1,0xf74d14e8, + 0xf30d75e2,0x8789fa51,0xc81c261e,0x09b24052,0x33c565ee,0x654e2678 } }, + /* 16 */ + { { 0x2f9fbe67,0x378205de,0x7f728e44,0xc4afcb83,0x682e00f1,0xdbcec06c, + 0x114d5423,0xf2a145c3,0x7a52463e,0xa01d9874,0x7d717b0a,0xfc0935b1 }, + { 0xd4d01f95,0x9653bc4f,0x9560ad34,0x9aa83ea8,0xaf8e3f3f,0xf77943dc, + 0xe86fe16e,0x70774a10,0xbf9ffdcf,0x6b62e6f1,0x588745c9,0x8a72f39e } }, + /* 17 */ + { { 0x2341c342,0x73ade4da,0xea704422,0xdd326e54,0x3741cef3,0x336c7d98, + 0x59e61549,0x1eafa00d,0xbd9a3efd,0xcd3ed892,0xc5c6c7e4,0x03faf26c }, + { 0x3045f8ac,0x087e2fcf,0x174f1e73,0x14a65532,0xfe0af9a7,0x2cf84f28, + 0x2cdc935b,0xddfd7a84,0x6929c895,0x4c0f117b,0x4c8bcfcc,0x356572d6 } }, + /* 18 */ + { { 0x7d8c1bba,0x7ecbac01,0x90b0f3d5,0x6058f9c3,0xf6197d0f,0xaee116e3, + 0x4033b128,0xc4dd7068,0xc209b983,0xf084dba6,0x831dbc4a,0x97c7c2cf }, + { 0xf96010e8,0x2f4e61dd,0x529faa17,0xd97e4e20,0x69d37f20,0x4ee66660, + 0x3d366d72,0xccc139ed,0x13488e0f,0x690b6ee2,0xf3a6d533,0x7cad1dc5 } }, + /* 19 */ + { { 0xda57a41f,0x660a9a81,0xec0039b6,0xe74a0412,0x5e1dad15,0x42343c6b, + 0x46681d4c,0x284f3ff5,0x63749e89,0xb51087f1,0x6f9f2f13,0x070f23cc }, + { 0x5d186e14,0x542211da,0xfddb0dff,0x84748f37,0xdb1f4180,0x41a3aab4, + 0xa6402d0e,0x25ed667b,0x02f58355,0x2f2924a9,0xfa44a689,0x5844ee7c } }, + /* 20 */ + { { 0x3f3b236f,0xfab08607,0x81e221da,0x19e9d41d,0x3927b428,0xf3f6571e, + 0x7550f1f6,0x4348a933,0xa85e62f0,0x7167b996,0x7f5452bf,0x62d43759 }, + { 0xf2955926,0xd85feb9e,0x6df78353,0x440a561f,0x9ca36b59,0x389668ec, + 0xa22da016,0x052bf1a1,0xf6093254,0xbdfbff72,0xe22209f3,0x94e50f28 } }, + /* 21 */ + { { 0x3062e8af,0x90b2e5b3,0xe8a3d369,0xa8572375,0x201db7b1,0x3fe1b00b, + 0xee651aa2,0xe926def0,0xb9b10ad7,0x6542c9be,0xa2fcbe74,0x098e309b }, + { 0xfff1d63f,0x779deeb3,0x20bfd374,0x23d0e80a,0x8768f797,0x8452bb3b, + 0x1f952856,0xcf75bb4d,0x29ea3faa,0x8fe6b400,0x81373a53,0x12bd3e40 } }, + /* 22 */ + { { 0x104cbba5,0xc023780d,0xfa35dd4c,0x6207e747,0x1ca9b6a3,0x35c23928, + 0x97987b10,0x4ff19be8,0x8022eee8,0xb8476bbf,0xd3bbe74d,0xaa0a4a14 }, + { 0x187d4543,0x20f94331,0x79f6e066,0x32153870,0xac7e82e1,0x83b0f74e, + 0x828f06ab,0xa7748ba2,0xc26ef35f,0xc5f0298a,0x8e9a7dbd,0x0f0c5070 } }, + /* 23 */ + { { 0xdef029dd,0x0c5c244c,0x850661b8,0x3dabc687,0xfe11d981,0x9992b865, + 0x6274dbad,0xe9801b8f,0x098da242,0xe54e6319,0x91a53d08,0x9929a91a }, + { 0x35285887,0x37bffd72,0xf1418102,0xbc759425,0xfd2e6e20,0x9280cc35, + 0xfbc42ee5,0x735c600c,0x8837619a,0xb7ad2864,0xa778c57b,0xa3627231 } }, + /* 24 */ + { { 0x91361ed8,0xae799b5c,0x6c63366c,0x47d71b75,0x1b265a6a,0x54cdd521, + 0x98d77b74,0xe0215a59,0xbab29db0,0x4424d9b7,0x7fd9e536,0x8b0ffacc }, + { 0x37b5d9ef,0x46d85d12,0xbfa91747,0x5b106d62,0x5f99ba2d,0xed0479f8, + 0x1d104de4,0x0e6f3923,0x25e8983f,0x83a84c84,0xf8105a70,0xa9507e0a } }, + /* 25 */ + { { 0x14cf381c,0xf6c68a6e,0xc22e31cc,0xaf9d27bd,0xaa8a5ccb,0x23568d4d, + 0xe338e4d2,0xe431eec0,0x8f52ad1f,0xf1a828fe,0xe86acd80,0xdb6a0579 }, + { 0x4507832a,0x2885672e,0x887e5289,0x73fc275f,0x05610d08,0x65f80278, + 0x075ff5b0,0x8d9b4554,0x09f712b5,0x3a8e8fb1,0x2ebe9cf2,0x39f0ac86 } }, + /* 26 */ + { { 0x4c52edf5,0xd8fabf78,0xa589ae53,0xdcd737e5,0xd791ab17,0x94918bf0, + 0xbcff06c9,0xb5fbd956,0xdca46d45,0xf6d3032e,0x41a3e486,0x2cdff7e1 }, + { 0x61f47ec8,0x6674b3ba,0xeef84608,0x8a882163,0x4c687f90,0xa257c705, + 0xf6cdf227,0xe30cb2ed,0x7f6ea846,0x2c4c64ca,0xcc6bcd3c,0x186fa17c } }, + /* 27 */ + { { 0x1dfcb91e,0x48a3f536,0x646d358a,0x83595e13,0x91128798,0xbd15827b, + 0x2187757a,0x3ce612b8,0x61bd7372,0x873150a1,0xb662f568,0xf4684530 }, + { 0x401896f6,0x8833950b,0x77f3e090,0xe11cb89a,0x48e7f4a5,0xb2f12cac, + 0xf606677e,0x313dd769,0x16579f93,0xfdcf08b3,0x46b8f22b,0x6429cec9 } }, + /* 28 */ + { { 0xbb75f9a4,0x4984dd54,0x29d3b570,0x4aef06b9,0x3d6e4c1e,0xb5f84ca2, + 0xb083ef35,0x24c61c11,0x392ca9ff,0xce4a7392,0x6730a800,0x865d6517 }, + { 0x722b4a2b,0xca3dfe76,0x7b083e0e,0x12c04bf9,0x1b86b8a5,0x803ce5b5, + 0x6a7e3e0c,0x3fc7632d,0xc81adbe4,0xc89970c2,0x120e16b1,0x3cbcd3ad } }, + /* 29 */ + { { 0xec30ce93,0xfbfb4cc7,0xb72720a2,0x10ed6c7d,0x47b55500,0xec675bf7, + 0x333ff7c3,0x90725903,0x5075bfc0,0xc7c3973e,0x07acf31b,0xb049ecb0 }, + { 0x4f58839c,0xb4076eaf,0xa2b05e4f,0x101896da,0xab40c66e,0x3f6033b0, + 0xc8d864ba,0x19ee9eeb,0x47bf6d2a,0xeb6cf155,0xf826477d,0x8e5a9663 } }, + /* 30 */ + { { 0xf7fbd5e1,0x69e62fdd,0x76912b1d,0x38ecfe54,0xd1da3bfb,0x845a3d56, + 0x1c86f0d4,0x0494950e,0x3bc36ce8,0x83cadbf9,0x4fccc8d1,0x41fce572 }, + { 0x8332c144,0x05f939c2,0x0871e46e,0xb17f248b,0x66e8aff6,0x3d8534e2, + 0x3b85c629,0x1d06f1dc,0xa3131b73,0xdb06a32e,0x8b3f64e5,0xf295184d } }, + /* 31 */ + { { 0x36ddc103,0xd9653ff7,0x95ef606f,0x25f43e37,0xfe06dce8,0x09e301fc, + 0x30b6eebf,0x85af2341,0x0ff56b20,0x79b12b53,0xfe9a3c6b,0x9b4fb499 }, + { 0x51d27ac2,0x0154f892,0x56ca5389,0xd33167e3,0xafc065a6,0x7828ec1f, + 0x7f746c9b,0x0959a258,0x0c44f837,0xb18f1be3,0xc4132fdb,0xa7946117 } }, + /* 32 */ + { { 0x5e3c647b,0xc0426b77,0x8cf05348,0xbfcbd939,0x172c0d3d,0x31d312e3, + 0xee754737,0x5f49fde6,0x6da7ee61,0x895530f0,0xe8b3a5fb,0xcf281b0a }, + { 0x41b8a543,0xfd149735,0x3080dd30,0x41a625a7,0x653908cf,0xe2baae07, + 0xba02a278,0xc3d01436,0x7b21b8f8,0xa0d0222e,0xd7ec1297,0xfdc270e9 } }, + /* 33 */ + { { 0xbc7f41d6,0x00873c0c,0x1b7ad641,0xd976113e,0x238443fb,0x2a536ff4, + 0x41e62e45,0x030d00e2,0x5f545fc6,0x532e9867,0x8e91208c,0xcd033108 }, + { 0x9797612c,0xd1a04c99,0xeea674e2,0xd4393e02,0xe19742a1,0xd56fa69e, + 0x85f0590e,0xdd2ab480,0x48a2243d,0xa5cefc52,0x54383f41,0x48cc67b6 } }, + /* 34 */ + { { 0xfc14ab48,0x4e50430e,0x26706a74,0x195b7f4f,0xcc881ff6,0x2fe8a228, + 0xd945013d,0xb1b968e2,0x4b92162b,0x936aa579,0x364e754a,0x4fb766b7 }, + { 0x31e1ff7f,0x13f93bca,0xce4f2691,0x696eb5ca,0xa2b09e02,0xff754bf8, + 0xe58e3ff8,0x58f13c9c,0x1678c0b0,0xb757346f,0xa86692b3,0xd54200db } }, + /* 35 */ + { { 0x6dda1265,0x9a030bbd,0xe89718dd,0xf7b4f3fc,0x936065b8,0xa6a4931f, + 0x5f72241c,0xbce72d87,0x65775857,0x6cbb51cb,0x4e993675,0xc7161815 }, + { 0x2ee32189,0xe81a0f79,0x277dc0b2,0xef2fab26,0xb71f469f,0x9e64f6fe, + 0xdfdaf859,0xb448ce33,0xbe6b5df1,0x3f5c1c4c,0x1de45f7b,0xfb8dfb00 } }, + /* 36 */ + { { 0x4d5bb921,0xc7345fa7,0x4d2b667e,0x5c7e04be,0x282d7a3e,0x47ed3a80, + 0x7e47b2a4,0x5c2777f8,0x08488e2e,0x89b3b100,0xb2eb5b45,0x9aad77c2 }, + { 0xdaac34ae,0xd681bca7,0x26afb326,0x2452e4e5,0x41a1ee14,0x0c887924, + 0xc2407ade,0x743b04d4,0xfc17a2ac,0xcb5e999b,0x4a701a06,0x4dca2f82 } }, + /* 37 */ + { { 0x1127bc1a,0x68e31ca6,0x17ead3be,0xa3edd59b,0xe25f5a15,0x67b6b645, + 0xa420e15e,0x76221794,0x4b1e872e,0x794fd83b,0xb2dece1b,0x7cab3f03 }, + { 0xca9b3586,0x7119bf15,0x4d250bd7,0xa5545924,0xcc6bcf24,0x173633ea, + 0xb1b6f884,0x9bd308c2,0x447d38c3,0x3bae06f5,0xf341fe1c,0x54dcc135 } }, + /* 38 */ + { { 0x943caf0d,0x56d3598d,0x225ff133,0xce044ea9,0x563fadea,0x9edf6a7c, + 0x73e8dc27,0x632eb944,0x3190dcab,0x814b467e,0x6dbb1e31,0x2d4f4f31 }, + { 0xa143b7ca,0x8d69811c,0xde7cf950,0x4ec1ac32,0x37b5fe82,0x223ab5fd, + 0x9390f1d9,0xe82616e4,0x75804610,0xabff4b20,0x875b08f0,0x11b9be15 } }, + /* 39 */ + { { 0x3bbe682c,0x4ae31a3d,0x74eef2dd,0xbc7c5d26,0x3c47dd40,0x92afd10a, + 0xc14ab9e1,0xec7e0a3b,0xb2e495e4,0x6a6c3dd1,0x309bcd85,0x085ee5e9 }, + { 0x8c2e67fd,0xf381a908,0xe261eaf2,0x32083a80,0x96deee15,0x0fcd6a49, + 0x5e524c79,0xe3b8fb03,0x1d5b08b9,0x8dc360d9,0x7f26719f,0x3a06e2c8 } }, + /* 40 */ + { { 0x7237cac0,0x5cd9f5a8,0x43586794,0x93f0b59d,0xe94f6c4e,0x4384a764, + 0xb62782d3,0x8304ed2b,0xcde06015,0x0b8db8b3,0x5dbe190f,0x4336dd53 }, + { 0x92ab473a,0x57443553,0xbe5ed046,0x031c7275,0x21909aa4,0x3e78678c, + 0x99202ddb,0x4ab7e04f,0x6977e635,0x2648d206,0x093198be,0xd427d184 } }, + /* 41 */ + { { 0x0f9b5a31,0x822848f5,0xbaadb62a,0xbb003468,0x3357559c,0x233a0472, + 0x79aee843,0x49ef6880,0xaeb9e1e3,0xa89867a0,0x1f6f9a55,0xc151931b }, + { 0xad74251e,0xd264eb0b,0x4abf295e,0x37b9b263,0x04960d10,0xb600921b, + 0x4da77dc0,0x0de53dbc,0xd2b18697,0x01d9bab3,0xf7156ddf,0xad54ec7a } }, + /* 42 */ + { { 0x79efdc58,0x8e74dc35,0x4ff68ddb,0x456bd369,0xd32096a5,0x724e74cc, + 0x386783d0,0xe41cff42,0x7c70d8a4,0xa04c7f21,0xe61a19a2,0x41199d2f }, + { 0x29c05dd2,0xd389a3e0,0xe7e3fda9,0x535f2a6b,0x7c2b4df8,0x26ecf72d, + 0xfe745294,0x678275f4,0x9d23f519,0x6319c9cc,0x88048fc4,0x1e05a02d } }, + /* 43 */ + { { 0xd4d5ffe8,0x75cc8e2e,0xdbea17f2,0xf8bb4896,0xcee3cb4a,0x35059790, + 0xa47c6165,0x4c06ee85,0x92935d2f,0xf98fff25,0x32ffd7c7,0x34c4a572 }, + { 0xea0376a2,0xc4b14806,0x4f115e02,0x2ea5e750,0x1e55d7c0,0x532d76e2, + 0xf31044da,0x68dc9411,0x71b77993,0x9272e465,0x93a8cfd5,0xadaa38bb } }, + /* 44 */ + { { 0x7d4ed72a,0x4bf0c712,0xba1f79a3,0xda0e9264,0xf4c39ea4,0x48c0258b, + 0x2a715138,0xa5394ed8,0xbf06c660,0x4af511ce,0xec5c37cd,0xfcebceef }, + { 0x779ae8c1,0xf23b75aa,0xad1e606e,0xdeff59cc,0x22755c82,0xf3f526fd, + 0xbb32cefd,0x64c5ab44,0x915bdefd,0xa96e11a2,0x1143813e,0xab19746a } }, + /* 45 */ + { { 0xec837d7d,0x43c78585,0xb8ee0ba4,0xca5b6fbc,0xd5dbb5ee,0x34e924d9, + 0xbb4f1ca5,0x3f4fa104,0x398640f7,0x15458b72,0xd7f407ea,0x4231faa9 }, + { 0xf96e6896,0x53e0661e,0xd03b0f9d,0x554e4c69,0x9c7858d1,0xd4fcb07b, + 0x52cb04fa,0x7e952793,0x8974e7f7,0x5f5f1574,0x6b6d57c8,0x2e3fa558 } }, + /* 46 */ + { { 0x6a9951a8,0x42cd4803,0x42792ad0,0xa8b15b88,0xabb29a73,0x18e8bcf9, + 0x409933e8,0xbfd9a092,0xefb88dc4,0x760a3594,0x40724458,0x14418863 }, + { 0x99caedc7,0x162a56ee,0x91d101c9,0x8fb12ecd,0x393202da,0xea671967, + 0xa4ccd796,0x1aac8c4a,0x1cf185a8,0x7db05036,0x8cfd095a,0x0c9f86cd } }, + /* 47 */ + { { 0x10b2a556,0x9a728147,0x327b70b2,0x767ca964,0x5e3799b7,0x04ed9e12, + 0x22a3eb2a,0x6781d2dc,0x0d9450ac,0x5bd116eb,0xa7ebe08a,0xeccac1fc }, + { 0xdc2d6e94,0xde68444f,0x35ecf21b,0x3621f429,0x29e03a2c,0x14e2d543, + 0x7d3e7f0a,0x53e42cd5,0x73ed00b9,0xbba26c09,0xc57d2272,0x00297c39 } }, + /* 48 */ + { { 0xb8243a7d,0x3aaaab10,0x8fa58c5b,0x6eeef93e,0x9ae7f764,0xf866fca3, + 0x61ab04d3,0x64105a26,0x03945d66,0xa3578d8a,0x791b848c,0xb08cd3e4 }, + { 0x756d2411,0x45edc5f8,0xa755128c,0xd4a790d9,0x49e5f6a0,0xc2cf0963, + 0xf649beaa,0xc66d267d,0x8467039e,0x3ce6d968,0x42f7816f,0x50046c6b } }, + /* 49 */ + { { 0x66425043,0x92ae1602,0xf08db890,0x1ff66afd,0x8f162ce5,0x386f5a7f, + 0xfcf5598f,0x18d2dea0,0x1a8ca18e,0x78372b3a,0x8cd0e6f7,0xdf0d20eb }, + { 0x75bb4045,0x7edd5e1d,0xb96d94b7,0x252a47ce,0x2c626776,0xbdb29358, + 0x40dd1031,0x853c3943,0x7d5f47fd,0x9dc9becf,0xbae4044a,0x27c2302f } }, + /* 50 */ + { { 0x8f2d49ce,0x2d1d208a,0x162df0a2,0x0d91aa02,0x09a07f65,0x9c5cce87, + 0x84339012,0xdf07238b,0x419442cd,0x5028e2c8,0x72062aba,0x2dcbd358 }, + { 0xe4680967,0xb5fbc3cb,0x9f92d72c,0x2a7bc645,0x116c369d,0x806c76e1, + 0x3177e8d8,0x5c50677a,0x4569df57,0x753739eb,0x36c3f40b,0x2d481ef6 } }, + /* 51 */ + { { 0xfea1103e,0x1a2d39fd,0x95f81b17,0xeaae5592,0xf59b264a,0xdbd0aa18, + 0xcb592ee0,0x90c39c1a,0x9750cca3,0xdf62f80d,0xdf97cc6c,0xda4d8283 }, + { 0x1e201067,0x0a6dd346,0x69fb1f6b,0x1531f859,0x1d60121f,0x4895e552, + 0x4c041c91,0x0b21aab0,0xbcc1ccf8,0x9d896c46,0x3141bde7,0xd24da3b3 } }, + /* 52 */ + { { 0x53b0a354,0x575a0537,0x0c6ddcd8,0x392ff2f4,0x56157b94,0x0b8e8cff, + 0x3b1b80d1,0x073e57bd,0x3fedee15,0x2a75e0f0,0xaa8e6f19,0x752380e4 }, + { 0x6558ffe9,0x1f4e227c,0x19ec5415,0x3a348618,0xf7997085,0xab382d5e, + 0xddc46ac2,0x5e6deaff,0xfc8d094c,0xe5144078,0xf60e37c6,0xf674fe51 } }, + /* 53 */ + { { 0xaf63408f,0x6fb87ae5,0xcd75a737,0xa39c36a9,0xcf4c618d,0x7833313f, + 0xf034c88d,0xfbcd4482,0x39b35288,0x4469a761,0x66b5d9c9,0x77a711c5 }, + { 0x944f8d65,0x4a695dc7,0x161aaba8,0xe6da5f65,0x24601669,0x8654e9c3, + 0x28ae7491,0xbc8b93f5,0x8f5580d8,0x5f1d1e83,0xcea32cc8,0x8ccf9a1a } }, + /* 54 */ + { { 0x7196fee2,0x28ab110c,0x874c8945,0x75799d63,0x29aedadd,0xa2629348, + 0x2be88ff4,0x9714cc7b,0xd58d60d6,0xf71293cf,0x32a564e9,0xda6b6cb3 }, + { 0x3dd821c2,0xf43fddb1,0x90dd323d,0xf2f2785f,0x048489f8,0x91246419, + 0xd24c6749,0x61660f26,0xc803c15c,0x961d9e8c,0xfaadc4c9,0x631c6158 } }, + /* 55 */ + { { 0xfd752366,0xacf2ebe0,0x139be88b,0xb93c340e,0x0f20179e,0x98f66485, + 0xff1da785,0x14820254,0x4f85c16e,0x5278e276,0x7aab1913,0xa246ee45 }, + { 0x53763b33,0x43861eb4,0x45c0bc0d,0xc49f03fc,0xad6b1ea1,0xafff16bc, + 0x6fd49c99,0xce33908b,0xf7fde8c3,0x5c51e9bf,0xff142c5e,0x076a7a39 } }, + /* 56 */ + { { 0x9e338d10,0x04639dfe,0xf42b411b,0x8ee6996f,0xa875cef2,0x960461d1, + 0x95b4d0ba,0x1057b6d6,0xa906e0bc,0x27639252,0xe1c20f8a,0x2c19f09a }, + { 0xeef4c43d,0x5b8fc3f0,0x07a84aa9,0xe2e1b1a8,0x835d2bdb,0x5f455528, + 0x207132dd,0x0f4aee4d,0x3907f675,0xe9f8338c,0x0e0531f0,0x7a874dc9 } }, + /* 57 */ + { { 0x97c27050,0x84b22d45,0x59e70bf8,0xbd0b8df7,0x79738b9b,0xb4d67405, + 0xcd917c4f,0x47f4d5f5,0x13ce6e33,0x9099c4ce,0x521d0f8b,0x942bfd39 }, + { 0xa43b566d,0x5028f0f6,0x21bff7de,0xaf6e8669,0xc44232cd,0x83f6f856, + 0xf915069a,0x65680579,0xecfecb85,0xd12095a2,0xdb01ba16,0xcf7f06ae } }, + /* 58 */ + { { 0x8ef96c80,0x0f56e3c4,0x3ddb609c,0xd521f2b3,0x7dc1450d,0x2be94102, + 0x02a91fe2,0x2d21a071,0x1efa37de,0x2e6f74fa,0x156c28a1,0x9a9a90b8 }, + { 0x9dc7dfcb,0xc54ea9ea,0x2c2c1d62,0xc74e66fc,0x49d3e067,0x9f23f967, + 0x54dd38ad,0x1c7c3a46,0x5946cee3,0xc7005884,0x45cc045d,0x89856368 } }, + /* 59 */ + { { 0xfce73946,0x29da7cd4,0x23168563,0x8f697db5,0xcba92ec6,0x8e235e9c, + 0x9f91d3ea,0x55d4655f,0xaa50a6cd,0xf3689f23,0x21e6a1a0,0xdcf21c26 }, + { 0x61b818bf,0xcffbc82e,0xda47a243,0xc74a2f96,0x8bc1a0cf,0x234e980a, + 0x7929cb6d,0xf35fd6b5,0xefe17d6c,0x81468e12,0x58b2dafb,0xddea6ae5 } }, + /* 60 */ + { { 0x7e787b2e,0x294de887,0x39a9310d,0x258acc1f,0xac14265d,0x92d9714a, + 0x708b48a0,0x18b5591c,0xe1abbf71,0x27cc6bb0,0x568307b9,0xc0581fa3 }, + { 0xf24d4d58,0x9e0f58a3,0xe0ce2327,0xfebe9bb8,0x9d1be702,0x91fd6a41, + 0xfacac993,0x9a7d8a45,0x9e50d66d,0xabc0a08c,0x06498201,0x02c342f7 } }, + /* 61 */ + { { 0x157bdbc2,0xccd71407,0xad0e1605,0x72fa89c6,0xb92a015f,0xb1d3da2b, + 0xa0a3fe56,0x8ad9e7cd,0x24f06737,0x160edcbd,0x61275be6,0x79d4db33 }, + { 0x5f3497c4,0xd3d31fd9,0x04192fb0,0x8cafeaee,0x13a50af3,0xe13ca745, + 0x8c85aae5,0x18826167,0x9eb556ff,0xce06cea8,0xbdb549f3,0x2eef1995 } }, + /* 62 */ + { { 0x50596edc,0x8ed7d3eb,0x905243a2,0xaa359362,0xa4b6d02b,0xa212c2c2, + 0xc4fbec68,0x611fd727,0xb84f733d,0x8a0b8ff7,0x5f0daf0e,0xd85a6b90 }, + { 0xd4091cf7,0x60e899f5,0x2eff2768,0x4fef2b67,0x10c33964,0xc1f195cb, + 0x93626a8f,0x8275d369,0x0d6c840a,0xc77904f4,0x7a868acd,0x88d8b7fd } }, + /* 63 */ + { { 0x7bd98425,0x85f23723,0xc70b154e,0xd4463992,0x96687a2e,0xcbb00ee2, + 0xc83214fd,0x905fdbf7,0x13593684,0x2019d293,0xef51218e,0x0428c393 }, + { 0x981e909a,0x40c7623f,0x7be192da,0x92513385,0x4010907e,0x48fe480f, + 0x3120b459,0xdd7a187c,0xa1fd8f3c,0xc9d7702d,0xe358efc5,0x66e4753b } }, + /* 64 */ + { { 0x16973cf4,0x070d34e1,0x7e4f34f7,0x20aee08b,0x5eb8ad29,0x269af9b9, + 0xa6a45dda,0xdde0a036,0x63df41e0,0xa18b528e,0xa260df2a,0x03cc71b2 }, + { 0xa06b1dd7,0x24a6770a,0x9d2675d3,0x5bfa9c11,0x96844432,0x73c1e2a1, + 0x131a6cf0,0x3660558d,0x2ee79454,0xb0289c83,0xc6d8ddcd,0xa6aefb01 } }, + /* 65 */ + { { 0x01ab5245,0xba1464b4,0xc48d93ff,0x9b8d0b6d,0x93ad272c,0x939867dc, + 0xae9fdc77,0xbebe085e,0x894ea8bd,0x73ae5103,0x39ac22e1,0x740fc89a }, + { 0x28e23b23,0x5e28b0a3,0xe13104d0,0x2352722e,0xb0a2640d,0xf4667a18, + 0x49bb37c3,0xac74a72e,0xe81e183a,0x79f734f0,0x3fd9c0eb,0xbffe5b6c } }, + /* 66 */ + { { 0xc6a2123f,0xb1a358f5,0xfe28df6d,0x927b2d95,0xf199d2f9,0x89702753, + 0x1a3f82dc,0x0a73754c,0x777affe1,0x063d029d,0xdae6d34d,0x5439817e }, + { 0x6b8b83c4,0xf7979eef,0x9d945682,0x615cb214,0xc5e57eae,0x8f0e4fac, + 0x113047dd,0x042b89b8,0x93f36508,0x888356dc,0x5fd1f32f,0xbf008d18 } }, + /* 67 */ + { { 0x4e8068db,0x8012aa24,0xa5729a47,0xc72cc641,0x43f0691d,0x3c33df2c, + 0x1d92145f,0xfa057347,0xb97f7946,0xaefc0f2f,0x2f8121bf,0x813d75cb }, + { 0x4383bba6,0x05613c72,0xa4224b3f,0xa924ce70,0x5f2179a6,0xe59cecbe, + 0x79f62b61,0x78e2e8aa,0x53ad8079,0x3ac2cc3b,0xd8f4fa96,0x55518d71 } }, + /* 68 */ + { { 0x00623f3b,0x03cf2922,0x5f29ebff,0x095c7111,0x80aa6823,0x42d72247, + 0x7458c0b0,0x044c7ba1,0x0959ec20,0xca62f7ef,0xf8ca929f,0x40ae2ab7 }, + { 0xa927b102,0xb8c5377a,0xdc031771,0x398a86a0,0xc216a406,0x04908f9d, + 0x918d3300,0xb423a73a,0xe0b94739,0x634b0ff1,0x2d69f697,0xe29de725 } }, + /* 69 */ + { { 0x8435af04,0x744d1400,0xfec192da,0x5f255b1d,0x336dc542,0x1f17dc12, + 0x636a68a8,0x5c90c2a7,0x7704ca1e,0x960c9eb7,0x6fb3d65a,0x9de8cf1e }, + { 0x511d3d06,0xc60fee0d,0xf9eb52c7,0x466e2313,0x206b0914,0x743c0f5f, + 0x2191aa4d,0x42f55bac,0xffebdbc2,0xcefc7c8f,0xe6e8ed1c,0xd4fa6081 } }, + /* 70 */ + { { 0xb0ab9645,0xb5e405d3,0xd5f1f711,0xaeec7f98,0x585c2a6e,0x8ad42311, + 0x512c6944,0x045acb9e,0xa90db1c6,0xae106c4e,0x898e6563,0xb89f33d5 }, + { 0x7fed2ce4,0x43b07cd9,0xdd815b20,0xf9934e17,0x0a81a349,0x6778d4d5, + 0x52918061,0x9e616ade,0xd7e67112,0xfa06db06,0x88488091,0x1da23cf1 } }, + /* 71 */ + { { 0x42f2c4b5,0x821c46b3,0x66059e47,0x931513ef,0x66f50cd1,0x7030ae43, + 0x43e7b127,0x43b536c9,0x5fca5360,0x006258cf,0x6b557abf,0xe4e3ee79 }, + { 0x24c8b22f,0xbb6b3900,0xfcbf1054,0x2eb5e2c1,0x567492af,0x937b18c9, + 0xacf53957,0xf09432e4,0x1dbf3a56,0x585f5a9d,0xbe0887cf,0xf86751fd } }, + /* 72 */ + { { 0x9d10e0b2,0x157399cb,0x60dc51b7,0x1c0d5956,0x1f583090,0x1d496b8a, + 0x88590484,0x6658bc26,0x03213f28,0x88c08ab7,0x7ae58de4,0x8d2e0f73 }, + { 0x486cfee6,0x9b79bc95,0xe9e5bc57,0x036a26c7,0xcd8ae97a,0x1ad03601, + 0xff3a0494,0x06907f87,0x2c7eb584,0x078f4bbf,0x7e8d0a5a,0xe3731bf5 } }, + /* 73 */ + { { 0xe1cd0abe,0x72f2282b,0x87efefa2,0xd4f9015e,0x6c3834bd,0x9d189806, + 0xb8a29ced,0x9c8cdcc1,0xfee82ebc,0x0601b9f4,0x7206a756,0x371052bc }, + { 0x46f32562,0x76fa1092,0x17351bb4,0xdaad534c,0xb3636bb5,0xc3d64c37, + 0x45d54e00,0x038a8c51,0x32c09e7c,0x301e6180,0x95735151,0x9764eae7 } }, + /* 74 */ + { { 0xcbd5256a,0x8791b19f,0x6ca13a3b,0x4007e0f2,0x4cf06904,0x03b79460, + 0xb6c17589,0xb18a9c22,0x81d45908,0xa1cb7d7d,0x21bb68f1,0x6e13fa9d }, + { 0xa71e6e16,0x47183c62,0xe18749ed,0x5cf0ef8e,0x2e5ed409,0x2c9c7f9b, + 0xe6e117e1,0x042eeacc,0x13fb5a7f,0xb86d4816,0xc9e5feb1,0xea1cf0ed } }, + /* 75 */ + { { 0xcea4cc9b,0x6e6573c9,0xafcec8f3,0x5417961d,0xa438b6f6,0x804bf02a, + 0xdcd4ea88,0xb894b03c,0x3799571f,0xd0f807e9,0x862156e8,0x3466a7f5 }, + { 0x56515664,0x51e59acd,0xa3c5eb0b,0x55b0f93c,0x6a4279db,0x84a06b02, + 0xc5fae08e,0x5c850579,0xa663a1a2,0xcf07b8db,0xf46ffc8d,0x49a36bbc } }, + /* 76 */ + { { 0x46d93106,0xe47f5acc,0xaa897c9c,0x65b7ade0,0x12d7e4be,0x37cf4c94, + 0xd4b2caa9,0xa2ae9b80,0xe60357a3,0x5e7ce09c,0xc8ecd5f9,0x29f77667 }, + { 0xa8a0b1c5,0xdf6868f5,0x62978ad8,0x240858cf,0xdc0002a1,0x0f7ac101, + 0xffe9aa05,0x1d28a9d7,0x5b962c97,0x744984d6,0x3d28c8b2,0xa8a7c00b } }, + /* 77 */ + { { 0xae11a338,0x7c58a852,0xd1af96e7,0xa78613f1,0x5355cc73,0x7e9767d2, + 0x792a2de6,0x6ba37009,0x124386b2,0x7d60f618,0x11157674,0xab09b531 }, + { 0x98eb9dd0,0x95a04841,0x15070328,0xe6c17acc,0x489c6e49,0xafc6da45, + 0xbb211530,0xab45a60a,0x7d7ea933,0xc58d6592,0x095642c6,0xa3ef3c65 } }, + /* 78 */ + { { 0xdf010879,0x89d420e9,0x39576179,0x9d25255d,0xe39513b6,0x9cdefd50, + 0xd5d1c313,0xe4efe45b,0x3f7af771,0xc0149de7,0x340ab06b,0x55a6b4f4 }, + { 0xebeaf771,0xf1325251,0x878d4288,0x2ab44128,0x18e05afe,0xfcd5832e, + 0xcc1fb62b,0xef52a348,0xc1c4792a,0x2bd08274,0x877c6dc7,0x345c5846 } }, + /* 79 */ + { { 0xbea65e90,0xde15ceb0,0x2416d99c,0x0987f72b,0xfd863dec,0x44db578d, + 0xac6a3578,0xf617b74b,0xdb48e999,0x9e62bd7a,0xeab1a1be,0x877cae61 }, + { 0x3a358610,0x23adddaa,0x325e2b07,0x2fc4d6d1,0x1585754e,0x897198f5, + 0xb392b584,0xf741852c,0xb55f7de1,0x9927804c,0x1aa8efae,0xe9e6c4ed } }, + /* 80 */ + { { 0x98683186,0x867db639,0xddcc4ea9,0xfb5cf424,0xd4f0e7bd,0xcc9a7ffe, + 0x7a779f7e,0x7c57f71c,0xd6b25ef2,0x90774079,0xb4081680,0x90eae903 }, + { 0x0ee1fceb,0xdf2aae5e,0xe86c1a1f,0x3ff1da24,0xca193edf,0x80f587d6, + 0xdc9b9d6a,0xa5695523,0x85920303,0x7b840900,0xba6dbdef,0x1efa4dfc } }, + /* 81 */ + { { 0xe0540015,0xfbd838f9,0xc39077dc,0x2c323946,0xad619124,0x8b1fb9e6, + 0x0ca62ea8,0x9612440c,0x2dbe00ff,0x9ad9b52c,0xae197643,0xf52abaa1 }, + { 0x2cac32ad,0xd0e89894,0x62a98f91,0xdfb79e42,0x276f55cb,0x65452ecf, + 0x7ad23e12,0xdb1ac0d2,0xde4986f0,0xf68c5f6a,0x82ce327d,0x389ac37b } }, + /* 82 */ + { { 0xf8e60f5b,0x511188b4,0x48aa2ada,0x7fe67015,0x381abca2,0xdb333cb8, + 0xdaf3fc97,0xb15e6d9d,0x36aabc03,0x4b24f6eb,0x72a748b4,0xc59789df }, + { 0x29cf5279,0x26fcb8a5,0x01ad9a6c,0x7a3c6bfc,0x4b8bac9b,0x866cf88d, + 0x9c80d041,0xf4c89989,0x70add148,0xf0a04241,0x45d81a41,0x5a02f479 } }, + /* 83 */ + { { 0xc1c90202,0xfa5c877c,0xf8ac7570,0xd099d440,0xd17881f7,0x428a5b1b, + 0x5b2501d7,0x61e267db,0xf2e4465b,0xf889bf04,0x76aa4cb8,0x4da3ae08 }, + { 0xe3e66861,0x3ef0fe26,0x3318b86d,0x5e772953,0x747396df,0xc3c35fbc, + 0x439ffd37,0x5115a29c,0xb2d70374,0xbfc4bd97,0x56246b9d,0x088630ea } }, + /* 84 */ + { { 0xb8a9e8c9,0xcd96866d,0x5bb8091e,0xa11963b8,0x045b3cd2,0xc7f90d53, + 0x80f36504,0x755a72b5,0x21d3751c,0x46f8b399,0x53c193de,0x4bffdc91 }, + { 0xb89554e7,0xcd15c049,0xf7a26be6,0x353c6754,0xbd41d970,0x79602370, + 0x12b176c0,0xde16470b,0x40c8809d,0x56ba1175,0xe435fb1e,0xe2db35c3 } }, + /* 85 */ + { { 0x6328e33f,0xd71e4aab,0xaf8136d1,0x5486782b,0x86d57231,0x07a4995f, + 0x1651a968,0xf1f0a5bd,0x76803b6d,0xa5dc5b24,0x42dda935,0x5c587cbc }, + { 0xbae8b4c0,0x2b6cdb32,0xb1331138,0x66d1598b,0x5d7e9614,0x4a23b2d2, + 0x74a8c05d,0x93e402a6,0xda7ce82e,0x45ac94e6,0xe463d465,0xeb9f8281 } }, + /* 86 */ + { { 0xfecf5b9b,0x34e0f9d1,0xf206966a,0xa115b12b,0x1eaa0534,0x5591cf3b, + 0xfb1558f9,0x5f0293cb,0x1bc703a5,0x1c8507a4,0x862c1f81,0x92e6b81c }, + { 0xcdaf24e3,0xcc9ebc66,0x72fcfc70,0x68917ecd,0x8157ba48,0x6dc9a930, + 0xb06ab2b2,0x5d425c08,0x36e929c4,0x362f8ce7,0x62e89324,0x09f6f57c } }, + /* 87 */ + { { 0xd29375fb,0x1c7d6b78,0xe35d1157,0xfabd851e,0x4243ea47,0xf6f62dcd, + 0x8fe30b0f,0x1dd92460,0xffc6e709,0x08166dfa,0x0881e6a7,0xc6c4c693 }, + { 0xd6a53fb0,0x20368f87,0x9eb4d1f9,0x38718e9f,0xafd7e790,0x03f08acd, + 0x72fe2a1c,0x0835eb44,0x88076e5d,0x7e050903,0xa638e731,0x538f765e } }, + /* 88 */ + { { 0xc2663b4b,0x0e0249d9,0x47cd38dd,0xe700ab5b,0x2c46559f,0xb192559d, + 0x4bcde66d,0x8f9f74a8,0x3e2aced5,0xad161523,0x3dd03a5b,0xc155c047 }, + { 0x3be454eb,0x346a8799,0x83b7dccd,0x66ee94db,0xab9d2abe,0x1f6d8378, + 0x7733f355,0x4a396dd2,0xf53553c2,0x419bd40a,0x731dd943,0xd0ead98d } }, + /* 89 */ + { { 0xec142408,0x908e0b0e,0x4114b310,0x98943cb9,0x1742b1d7,0x03dbf7d8, + 0x693412f4,0xd270df6b,0x8f69e20c,0xc5065494,0x697e43a1,0xa76a90c3 }, + { 0x4624825a,0xe0fa3384,0x8acc34c2,0x82e48c0b,0xe9a14f2b,0x7b24bd14, + 0x4db30803,0x4f5dd5e2,0x932da0a3,0x0c77a9e7,0x74c653dc,0x20db90f2 } }, + /* 90 */ + { { 0x0e6c5fd9,0x261179b7,0x6c982eea,0xf8bec123,0xd4957b7e,0x47683338, + 0x0a72f66a,0xcc47e664,0x1bad9350,0xbd54bf6a,0xf454e95a,0xdfbf4c6a }, + { 0x6907f4fa,0x3f7a7afa,0x865ca735,0x7311fae0,0x2a496ada,0x24737ab8, + 0x15feb79b,0x13e425f1,0xa1b93c21,0xe9e97c50,0x4ddd3eb5,0xb26b6eac } }, + /* 91 */ + { { 0x2a2e5f2b,0x81cab9f5,0xbf385ac4,0xf93caf29,0xc909963a,0xf4bf35c3, + 0x74c9143c,0x081e7300,0xc281b4c5,0x3ea57fa8,0x9b340741,0xe497905c }, + { 0x55ab3cfb,0xf556dd8a,0x518db6ad,0xd444b96b,0x5ef4b955,0x34f5425a, + 0xecd26aa3,0xdda7a3ac,0xda655e97,0xb57da11b,0xc2024c70,0x02da3eff } }, + /* 92 */ + { { 0x6481d0d9,0xe24b0036,0x818fdfe2,0x3740dbe5,0x190fda00,0xc1fc1f45, + 0x3cf27fde,0x329c9280,0x6934f43e,0x7435cb53,0x7884e8fe,0x2b505a5d }, + { 0x711adcc9,0x6cfcc6a6,0x531e21e1,0xf034325c,0x9b2a8a99,0xa2f4a967, + 0x3c21bdff,0x9d5f3842,0x31b57d66,0xb25c7811,0x0b8093b9,0xdb5344d8 } }, + /* 93 */ + { { 0xae50a2f5,0x0d72e667,0xe4a861d1,0x9b7f8d8a,0x330df1cb,0xa129f70f, + 0xe04fefc3,0xe90aa5d7,0xe72c3ae1,0xff561ecb,0xcdb955fa,0x0d8fb428 }, + { 0xd7663784,0xd2235f73,0x7e2c456a,0xc05baec6,0x2adbfccc,0xe5c292e4, + 0xefb110d5,0x4fd17988,0xd19d49f3,0x27e57734,0x84f679fe,0x188ac4ce } }, + /* 94 */ + { { 0xa796c53e,0x7ee344cf,0x0868009b,0xbbf6074d,0x474a1295,0x1f1594f7, + 0xac11632d,0x66776edc,0x04e2fa5a,0x1862278b,0xc854a89a,0x52665cf2 }, + { 0x8104ab58,0x7e376464,0x7204fd6d,0x16775913,0x44ea1199,0x86ca06a5, + 0x1c9240dd,0xaa3f765b,0x24746149,0x5f8501a9,0xdcd251d7,0x7b982e30 } }, + /* 95 */ + { { 0xc15f3060,0xe44e9efc,0xa87ebbe6,0x5ad62f2e,0xc79500d4,0x36499d41, + 0x336fa9d1,0xa66d6dc0,0x5afd3b1f,0xf8afc495,0xe5c9822b,0x1d8ccb24 }, + { 0x79d7584b,0x4031422b,0xea3f20dd,0xc54a0580,0x958468c5,0x3f837c8f, + 0xfbea7735,0x3d82f110,0x7dffe2fc,0x679a8778,0x20704803,0x48eba63b } }, + /* 96 */ + { { 0xdf46e2f6,0x89b10d41,0x19514367,0x13ab57f8,0x1d469c87,0x067372b9, + 0x4f6c5798,0x0c195afa,0x272c9acf,0xea43a12a,0x678abdac,0x9dadd8cb }, + { 0xe182579a,0xcce56c6b,0x2d26c2d8,0x86febadb,0x2a44745c,0x1c668ee1, + 0x98dc047a,0x580acd86,0x51b9ec2d,0x5a2b79cc,0x4054f6a0,0x007da608 } }, + /* 97 */ + { { 0x17b00dd0,0x9e3ca352,0x0e81a7a6,0x046779cb,0xd482d871,0xb999fef3, + 0xd9233fbc,0xe6f38134,0xf48cd0e0,0x112c3001,0x3c6c66ae,0x934e7576 }, + { 0xd73234dc,0xb44d4fc3,0x864eafc1,0xfcae2062,0x26bef21a,0x843afe25, + 0xf3b75fdf,0x61355107,0x794c2e6b,0x8367a5aa,0x8548a372,0x3d2629b1 } }, + /* 98 */ + { { 0x437cfaf8,0x6230618f,0x2032c299,0x5b8742cb,0x2293643a,0x949f7247, + 0x09464f79,0xb8040f1a,0x4f254143,0x049462d2,0x366c7e76,0xabd6b522 }, + { 0xd5338f55,0x119b392b,0x01495a0c,0x1a80a9ce,0xf8d7537e,0xf3118ca7, + 0x6bf4b762,0xb715adc2,0xa8482b6c,0x24506165,0x96a7c84d,0xd958d7c6 } }, + /* 99 */ + { { 0xbdc21f31,0x9ad8aa87,0x8063e58c,0xadb3cab4,0xb07dd7b8,0xefd86283, + 0x1be7c6b4,0xc7b9b762,0x015582de,0x2ef58741,0x299addf3,0xc970c52e }, + { 0x22f24d66,0x78f02e2a,0x74cc100a,0xefec1d10,0x09316e1a,0xaf2a6a39, + 0x5849dd49,0xce7c2205,0x96bffc4c,0x9c1fe75c,0x7ba06ec0,0xcad98fd2 } }, + /* 100 */ + { { 0xb648b73e,0xed76e2d0,0x1cfd285e,0xa9f92ce5,0x2ed13de1,0xa8c86c06, + 0xa5191a93,0x1d3a574e,0x1ad1b8bf,0x385cdf8b,0x47d2cfe3,0xbbecc28a }, + { 0x69cec548,0x98d326c0,0xf240a0b2,0x4f5bc1dd,0x29057236,0x241a7062, + 0xc68294a4,0x0fc6e9c5,0xa319f17a,0x4d04838b,0x9ffc1c6f,0x8b612cf1 } }, + /* 101 */ + { { 0x4c3830eb,0x9bb0b501,0x8ee0d0c5,0x3d08f83c,0x79ba9389,0xa4a62642, + 0x9cbc2914,0x5d5d4044,0x074c46f0,0xae9eb83e,0x74ead7d6,0x63bb758f }, + { 0xc6bb29e0,0x1c40d2ea,0x4b02f41e,0x95aa2d87,0x53cb199a,0x92989175, + 0x51584f6d,0xdd91bafe,0x31a1aaec,0x3715efb9,0x46780f9e,0xc1b6ae5b } }, + /* 102 */ + { { 0x42772f41,0xcded3e4b,0x3bcb79d1,0x3a700d5d,0x80feee60,0x4430d50e, + 0xf5e5d4bb,0x444ef1fc,0xe6e358ff,0xc660194f,0x6a91b43c,0xe68a2f32 }, + { 0x977fe4d2,0x5842775c,0x7e2a41eb,0x78fdef5c,0xff8df00e,0x5f3bec02, + 0x5852525d,0xf4b840cd,0x4e6988bd,0x0870483a,0xcc64b837,0x39499e39 } }, + /* 103 */ + { { 0xb08df5fe,0xfc05de80,0x63ba0362,0x0c12957c,0xd5cf1428,0xea379414, + 0x54ef6216,0xc559132a,0xb9e65cf8,0x33d5f12f,0x1695d663,0x09c60278 }, + { 0x61f7a2fb,0x3ac1ced4,0xd4f5eeb8,0xdd838444,0x8318fcad,0x82a38c6c, + 0xe9f1a864,0x315be2e5,0x442daf47,0x317b5771,0x95aa5f9e,0x81b5904a } }, + /* 104 */ + { { 0x8b21d232,0x6b6b1c50,0x8c2cba75,0x87f3dbc0,0xae9f0faf,0xa7e74b46, + 0xbb7b8079,0x036a0985,0x8d974a25,0x4f185b90,0xd9af5ec9,0x5aa7cef0 }, + { 0x57dcfffc,0xe0566a70,0xb8453225,0x6ea311da,0x23368aa9,0x72ea1a8d, + 0x48cd552d,0xed9b2083,0xc80ea435,0xb987967c,0x6c104173,0xad735c75 } }, + /* 105 */ + { { 0xcee76ef4,0xaea85ab3,0xaf1d2b93,0x44997444,0xeacb923f,0x0851929b, + 0x51e3bc0c,0xb080b590,0x59be68a2,0xc4ee1d86,0x64b26cda,0xf00de219 }, + { 0xf2e90d4d,0x8d7fb5c0,0x77d9ec64,0x00e219a7,0x5d1c491c,0xc4e6febd, + 0x1a8f4585,0x080e3754,0x48d2af9c,0x4a9b86c8,0xb6679851,0x2ed70db6 } }, + /* 106 */ + { { 0x586f25cb,0xaee44116,0xa0fcf70f,0xf7b6861f,0x18a350e8,0x55d2cd20, + 0x92dc286f,0x861bf3e5,0x6226aba7,0x9ab18ffa,0xa9857b03,0xd15827be }, + { 0x92e6acef,0x26c1f547,0xac1fbac3,0x422c63c8,0xfcbfd71d,0xa2d8760d, + 0xb2511224,0x35f6a539,0x048d1a21,0xbaa88fa1,0xebf999db,0x49f1abe9 } }, + /* 107 */ + { { 0xf7492b73,0x16f9f4f4,0xcb392b1a,0xcf28ec1e,0x69ca6ffc,0x45b130d4, + 0xb72efa58,0x28ba8d40,0x5ca066f5,0xace987c7,0x4ad022eb,0x3e399246 }, + { 0x752555bb,0x63a2d84e,0x9c2ae394,0xaaa93b4a,0xc89539ca,0xcd80424e, + 0xaa119a99,0x6d6b5a6d,0x379f2629,0xbd50334c,0xef3cc7d3,0x899e925e } }, + /* 108 */ + { { 0xbf825dc4,0xb7ff3651,0x40b9c462,0x0f741cc4,0x5cc4fb5b,0x771ff5a9, + 0x47fd56fe,0xcb9e9c9b,0x5626c0d3,0xbdf053db,0xf7e14098,0xa97ce675 }, + { 0x6c934f5e,0x68afe5a3,0xccefc46f,0x6cd5e148,0xd7a88586,0xc7758570, + 0xdd558d40,0x49978f5e,0x64ae00c1,0xa1d5088a,0xf1d65bb2,0x58f2a720 } }, + /* 109 */ + { { 0x3e4daedb,0x66fdda4a,0x65d1b052,0x38318c12,0x4c4bbf5c,0x28d910a2, + 0x78a9cd14,0x762fe5c4,0xd2cc0aee,0x08e5ebaa,0xca0c654c,0xd2cdf257 }, + { 0x08b717d2,0x48f7c58b,0x386cd07a,0x3807184a,0xae7d0112,0x3240f626, + 0xc43917b0,0x03e9361b,0x20aea018,0xf261a876,0x7e1e6372,0x53f556a4 } }, + /* 110 */ + { { 0x2f512a90,0xc84cee56,0x1b0ea9f1,0x24b3c004,0xe26cc1ea,0x0ee15d2d, + 0xf0c9ef7d,0xd848762c,0xd5341435,0x1026e9c5,0xfdb16b31,0x8f5b73dc }, + { 0xd2c75d95,0x1f69bef2,0xbe064dda,0x8d33d581,0x57ed35e6,0x8c024c12, + 0xc309c281,0xf8d435f9,0xd6960193,0xfd295061,0xe9e49541,0x66618d78 } }, + /* 111 */ + { { 0x8ce382de,0x571cfd45,0xde900dde,0x175806ee,0x34aba3b5,0x61849965, + 0xde7aec95,0xe899778a,0xff4aa97f,0xe8f00f6e,0x010b0c6d,0xae971cb5 }, + { 0x3af788f1,0x1827eebc,0xe413fe2d,0xd46229ff,0x4741c9b4,0x8a15455b, + 0xf8e424eb,0x5f02e690,0xdae87712,0x40a1202e,0x64944f6d,0x49b3bda2 } }, + /* 112 */ + { { 0x035b2d69,0xd63c6067,0x6bed91b0,0xb507150d,0x7afb39b2,0x1f35f82f, + 0x16012b66,0xb9bd9c01,0xed0a5f50,0x00d97960,0x2716f7c9,0xed705451 }, + { 0x127abdb4,0x1576eff4,0xf01e701c,0x6850d698,0x3fc87e2f,0x9fa7d749, + 0xb0ce3e48,0x0b6bcc6f,0xf7d8c1c0,0xf4fbe1f5,0x02719cc6,0xcf75230e } }, + /* 113 */ + { { 0x722d94ed,0x6761d6c2,0x3718820e,0xd1ec3f21,0x25d0e7c6,0x65a40b70, + 0xbaf3cf31,0xd67f830e,0xb93ea430,0x633b3807,0x0bc96c69,0x17faa0ea }, + { 0xdf866b98,0xe6bf3482,0xa9db52d4,0x205c1ee9,0xff9ab869,0x51ef9bbd, + 0x75eeb985,0x3863dad1,0xd3cf442a,0xef216c3b,0xf9c8e321,0x3fb228e3 } }, + /* 114 */ + { { 0x0760ac07,0x94f9b70c,0x9d79bf4d,0xf3c9ccae,0xc5ffc83d,0x73cea084, + 0xdc49c38e,0xef50f943,0xbc9e7330,0xf467a2ae,0x44ea7fba,0x5ee534b6 }, + { 0x03609e7f,0x20cb6272,0x62fdc9f0,0x09844355,0x0f1457f7,0xaf5c8e58, + 0xb4b25941,0xd1f50a6c,0x2ec82395,0x77cb247c,0xda3dca33,0xa5f3e1e5 } }, + /* 115 */ + { { 0x7d85fa94,0x023489d6,0x2db9ce47,0x0ba40537,0xaed7aad1,0x0fdf7a1f, + 0x9a4ccb40,0xa57b0d73,0x5b18967c,0x48fcec99,0xb7274d24,0xf30b5b6e }, + { 0xc81c5338,0x7ccb4773,0xa3ed6bd0,0xb85639e6,0x1d56eada,0x7d9df95f, + 0x0a1607ad,0xe256d57f,0x957574d6,0x6da7ffdc,0x01c7a8c4,0x65f84046 } }, + /* 116 */ + { { 0xcba1e7f1,0x8d45d0cb,0x02b55f64,0xef0a08c0,0x17e19892,0x771ca31b, + 0x4885907e,0xe1843ecb,0x364ce16a,0x67797ebc,0x8df4b338,0x816d2b2d }, + { 0x39aa8671,0xe870b0e5,0xc102b5f5,0x9f0db3e4,0x1720c697,0x34296659, + 0x613c0d2a,0x0ad4c89e,0x418ddd61,0x1af900b2,0xd336e20e,0xe087ca72 } }, + /* 117 */ + { { 0xaba10079,0x222831ff,0x6d64fff2,0x0dc5f87b,0x3e8cb330,0x44547907, + 0x702a33fb,0xe815aaa2,0x5fba3215,0x338d6b2e,0x79f549c8,0x0f7535cb }, + { 0x2ee95923,0x471ecd97,0xc6d1c09f,0x1e868b37,0xc666ef4e,0x2bc7b8ec, + 0x808a4bfc,0xf5416589,0x3fbc4d2e,0xf23e9ee2,0x2d75125b,0x4357236c } }, + /* 118 */ + { { 0xba9cdb1b,0xfe176d95,0x2f82791e,0x45a1ca01,0x4de4cca2,0x97654af2, + 0x5cc4bcb9,0xbdbf9d0e,0xad97ac0a,0xf6a7df50,0x61359fd6,0xc52112b0 }, + { 0x4f05eae3,0x696d9ce3,0xe943ac2b,0x903adc02,0x0848be17,0xa9075347, + 0x2a3973e5,0x1e20f170,0x6feb67e9,0xe1aacc1c,0xe16bc6b9,0x2ca0ac32 } }, + /* 119 */ + { { 0xef871eb5,0xffea12e4,0xa8bf0a7a,0x94c2f25d,0x78134eaa,0x4d1e4c2a, + 0x0360fb10,0x11ed16fb,0x85fc11be,0x4029b6db,0xf4d390fa,0x5e9f7ab7 }, + { 0x30646612,0x5076d72f,0xdda1d0d8,0xa0afed1d,0x85a1d103,0x29022257, + 0x4e276bcd,0xcb499e17,0x51246c3d,0x16d1da71,0x589a0443,0xc72d56d3 } }, + /* 120 */ + { { 0xdae5bb45,0xdf5ffc74,0x261bd6dc,0x99068c4a,0xaa98ec7b,0xdc0afa7a, + 0xf121e96d,0xedd2ee00,0x1414045c,0x163cc7be,0x335af50e,0xb0b1bbce }, + { 0x01a06293,0xd440d785,0x6552e644,0xcdebab7c,0x8c757e46,0x48cb8dbc, + 0x3cabe3cb,0x81f9cf78,0xb123f59a,0xddd02611,0xeeb3784d,0x3dc7b88e } }, + /* 121 */ + { { 0xc4741456,0xe1b8d398,0x6032a121,0xa9dfa902,0x1263245b,0x1cbfc86d, + 0x5244718c,0xf411c762,0x05b0fc54,0x96521d54,0xdbaa4985,0x1afab46e }, + { 0x8674b4ad,0xa75902ba,0x5ad87d12,0x486b43ad,0x36e0d099,0x72b1c736, + 0xbb6cd6d6,0x39890e07,0x59bace4e,0x8128999c,0x7b535e33,0xd8da430b } }, + /* 122 */ + { { 0xc6b75791,0x39f65642,0x21806bfb,0x050947a6,0x1362ef84,0x0ca3e370, + 0x8c3d2391,0x9bc60aed,0x732e1ddc,0x9b488671,0xa98ee077,0x12d10d9e }, + { 0x3651b7dc,0xb6f2822d,0x80abd138,0x6345a5ba,0x472d3c84,0x62033262, + 0xacc57527,0xd54a1d40,0x424447cb,0x6ea46b3a,0x2fb1a496,0x5bc41057 } }, + /* 123 */ + { { 0xa751cd0e,0xe70c57a3,0xeba3c7d6,0x190d8419,0x9d47d55a,0xb1c3bee7, + 0xf912c6d8,0xda941266,0x407a6ad6,0x12e9aacc,0x6e838911,0xd6ce5f11 }, + { 0x70e1f2ce,0x063ca97b,0x8213d434,0xa3e47c72,0x84df810a,0xa016e241, + 0xdfd881a4,0x688ad7b0,0xa89bf0ad,0xa37d99fc,0xa23c2d23,0xd8e3f339 } }, + /* 124 */ + { { 0x750bed6f,0xbdf53163,0x83e68b0a,0x808abc32,0x5bb08a33,0x85a36627, + 0x6b0e4abe,0xf72a3a0f,0xfaf0c6ad,0xf7716d19,0x5379b25f,0x22dcc020 }, + { 0xf9a56e11,0x7400bf8d,0x56a47f21,0x6cb8bad7,0x7a6eb644,0x7c97176f, + 0xd1f5b646,0xe8fd84f7,0x44ddb054,0x98320a94,0x1dde86f5,0x07071ba3 } }, + /* 125 */ + { { 0x98f8fcb9,0x6fdfa0e5,0x94d0d70c,0x89cec8e0,0x106d20a8,0xa0899397, + 0xba8acc9c,0x915bfb9a,0x5507e01c,0x1370c94b,0x8a821ffb,0x83246a60 }, + { 0xbe3c378f,0xa8273a9f,0x35a25be9,0x7e544789,0x4dd929d7,0x6cfa4972, + 0x365bd878,0x987fed9d,0x5c29a7ae,0x4982ac94,0x5ddd7ec5,0x4589a5d7 } }, + /* 126 */ + { { 0xa95540a9,0x9fabb174,0x0162c5b0,0x7cfb886f,0xea3dee18,0x17be766b, + 0xe88e624c,0xff7da41f,0x8b919c38,0xad0b71eb,0xf31ff9a9,0x86a522e0 }, + { 0x868bc259,0xbc8e6f72,0x3ccef9e4,0x6130c638,0x9a466555,0x09f1f454, + 0x19b2bfb4,0x8e6c0f09,0x0ca7bb22,0x945c46c9,0x4dafb67b,0xacd87168 } }, + /* 127 */ + { { 0x10c53841,0x090c72ca,0x55a4fced,0xc20ae01b,0xe10234ad,0x03f7ebd5, + 0x85892064,0xb3f42a6a,0xb4a14722,0xbdbc30c0,0x8ca124cc,0x971bc437 }, + { 0x517ff2ff,0x6f79f46d,0xecba947b,0x6a9c96e2,0x62925122,0x5e79f2f4, + 0x6a4e91f1,0x30a96bb1,0x2d4c72da,0x1147c923,0x5811e4df,0x65bc311f } }, + /* 128 */ + { { 0x139b3239,0x87c7dd7d,0x4d833bae,0x8b57824e,0x9fff0015,0xbcbc4878, + 0x909eaf1a,0x8ffcef8b,0xf1443a78,0x9905f4ee,0xe15cbfed,0x020dd4a2 }, + { 0xa306d695,0xca2969ec,0xb93caf60,0xdf940cad,0x87ea6e39,0x67f7fab7, + 0xf98c4fe5,0x0d0ee10f,0xc19cb91e,0xc646879a,0x7d1d7ab4,0x4b4ea50c } }, + /* 129 */ + { { 0x7a0db57e,0x19e40945,0x9a8c9702,0xe6017cad,0x1be5cff9,0xdbf739e5, + 0xa7a938a2,0x3646b3cd,0x68350dfc,0x04511085,0x56e098b5,0xad3bd6f3 }, + { 0xee2e3e3e,0x935ebabf,0x473926cb,0xfbd01702,0x9e9fb5aa,0x7c735b02, + 0x2e3feff0,0xc52a1b85,0x046b405a,0x9199abd3,0x39039971,0xe306fcec } }, + /* 130 */ + { { 0x23e4712c,0xd6d9aec8,0xc3c198ee,0x7ca8376c,0x31bebd8a,0xe6d83187, + 0xd88bfef3,0xed57aff3,0xcf44edc7,0x72a645ee,0x5cbb1517,0xd4e63d0b }, + { 0xceee0ecf,0x98ce7a1c,0x5383ee8e,0x8f012633,0xa6b455e8,0x3b879078, + 0xc7658c06,0xcbcd3d96,0x0783336a,0x721d6fe7,0x5a677136,0xf21a7263 } }, + /* 131 */ + { { 0x9586ba11,0x19d8b3cd,0x8a5c0480,0xd9e0aeb2,0x2230ef5c,0xe4261dbf, + 0x02e6bf09,0x095a9dee,0x80dc7784,0x8963723c,0x145157b1,0x5c97dbaf }, + { 0x4bc4503e,0x97e74434,0x85a6b370,0x0fb1cb31,0xcd205d4b,0x3e8df2be, + 0xf8f765da,0x497dd1bc,0x6c988a1a,0x92ef95c7,0x64dc4cfa,0x3f924baa } }, + /* 132 */ + { { 0x7268b448,0x6bf1b8dd,0xefd79b94,0xd4c28ba1,0xe4e3551f,0x2fa1f8c8, + 0x5c9187a9,0x769e3ad4,0x40326c0d,0x28843b4d,0x50d5d669,0xfefc8094 }, + { 0x90339366,0x30c85bfd,0x5ccf6c3a,0x4eeb56f1,0x28ccd1dc,0x0e72b149, + 0xf2ce978e,0x73ee85b5,0x3165bb23,0xcdeb2bf3,0x4e410abf,0x8106c923 } }, + /* 133 */ + { { 0x7d02f4ee,0xc8df0161,0x18e21225,0x8a781547,0x6acf9e40,0x4ea895eb, + 0x6e5a633d,0x8b000cb5,0x7e981ffb,0xf31d86d5,0x4475bc32,0xf5c8029c }, + { 0x1b568973,0x764561ce,0xa62996ec,0x2f809b81,0xda085408,0x9e513d64, + 0xe61ce309,0xc27d815d,0x272999e0,0x0da6ff99,0xfead73f7,0xbd284779 } }, + /* 134 */ + { { 0x9b1cdf2b,0x6033c2f9,0xbc5fa151,0x2a99cf06,0x12177b3b,0x7d27d259, + 0xc4485483,0xb1f15273,0x102e2297,0x5fd57d81,0xc7f6acb7,0x3d43e017 }, + { 0x3a70eb28,0x41a8bb0b,0x3e80b06b,0x67de2d8e,0x70c28de5,0x09245a41, + 0xa7b26023,0xad7dbcb1,0x2cbc6c1e,0x70b08a35,0x9b33041f,0xb504fb66 } }, + /* 135 */ + { { 0xf97a27c2,0xa8e85ab5,0xc10a011b,0x6ac5ec8b,0xffbcf161,0x55745533, + 0x65790a60,0x01780e85,0x99ee75b0,0xe451bf85,0x39c29881,0x8907a63b }, + { 0x260189ed,0x76d46738,0x47bd35cb,0x284a4436,0x20cab61e,0xd74e8c40, + 0x416cf20a,0x6264bf8c,0x5fd820ce,0xfa5a6c95,0xf24bb5fc,0xfa7154d0 } }, + /* 136 */ + { { 0x9b3f5034,0x18482cec,0xcd9e68fd,0x962d445a,0x95746f23,0x266fb1d6, + 0x58c94a4b,0xc66ade5a,0xed68a5b6,0xdbbda826,0x7ab0d6ae,0x05664a4d }, + { 0x025e32fc,0xbcd4fe51,0xa96df252,0x61a5aebf,0x31592a31,0xd88a07e2, + 0x98905517,0x5d9d94de,0x5fd440e7,0x96bb4010,0xe807db4c,0x1b0c47a2 } }, + /* 137 */ + { { 0x08223878,0x5c2a6ac8,0xe65a5558,0xba08c269,0x9bbc27fd,0xd22b1b9b, + 0x72b9607d,0x919171bf,0xe588dc58,0x9ab455f9,0x23662d93,0x6d54916e }, + { 0x3b1de0c1,0x8da8e938,0x804f278f,0xa84d186a,0xd3461695,0xbf4988cc, + 0xe10eb0cb,0xf5eae3be,0xbf2a66ed,0x1ff8b68f,0xc305b570,0xa68daf67 } }, + /* 138 */ + { { 0x44b2e045,0xc1004cff,0x4b1c05d4,0x91b5e136,0x88a48a07,0x53ae4090, + 0xea11bb1a,0x73fb2995,0x3d93a4ea,0x32048570,0x3bfc8a5f,0xcce45de8 }, + { 0xc2b3106e,0xaff4a97e,0xb6848b4f,0x9069c630,0xed76241c,0xeda837a6, + 0x6cc3f6cf,0x8a0daf13,0x3da018a8,0x199d049d,0xd9093ba3,0xf867c6b1 } }, + /* 139 */ + { { 0x56527296,0xe4d42a56,0xce71178d,0xae26c73d,0x6c251664,0x70a0adac, + 0x5dc0ae1d,0x813483ae,0xdaab2daf,0x7574eacd,0xc2d55f4f,0xc56b52dc }, + { 0x95f32923,0x872bc167,0x5bdd2a89,0x4be17581,0xa7699f00,0x9b57f1e7, + 0x3ac2de02,0x5fcd9c72,0x92377739,0x83af3ba1,0xfc50b97f,0xa64d4e2b } }, + /* 140 */ + { { 0x0e552b40,0x2172dae2,0xd34d52e8,0x62f49725,0x07958f98,0x7930ee40, + 0x751fdd74,0x56da2a90,0xf53e48c3,0xf1192834,0x8e53c343,0x34d2ac26 }, + { 0x13111286,0x1073c218,0xda9d9827,0x201dac14,0xee95d378,0xec2c29db, + 0x1f3ee0b1,0x9316f119,0x544ce71c,0x7890c9f0,0x27612127,0xd77138af } }, + /* 141 */ + { { 0x3b4ad1cd,0x78045e6d,0x4aa49bc1,0xcd86b94e,0xfd677a16,0x57e51f1d, + 0xfa613697,0xd9290935,0x34f4d893,0x7a3f9593,0x5d5fcf9b,0x8c9c248b }, + { 0x6f70d4e9,0x9f23a482,0x63190ae9,0x17273454,0x5b081a48,0x4bdd7c13, + 0x28d65271,0x1e2de389,0xe5841d1f,0x0bbaaa25,0x746772e5,0xc4c18a79 } }, + /* 142 */ + { { 0x593375ac,0x10ee2681,0x7dd5e113,0x4f3288be,0x240f3538,0x9a97b2fb, + 0x1de6b1e2,0xfa11089f,0x1351bc58,0x516da562,0x2dfa85b5,0x573b6119 }, + { 0x6cba7df5,0x89e96683,0x8c28ab40,0xf299be15,0xad43fcbf,0xe91c9348, + 0x9a1cefb3,0xe9bbc7cc,0x738b2775,0xc8add876,0x775eaa01,0x6e3b1f2e } }, + /* 143 */ + { { 0xb677788b,0x0365a888,0x3fd6173c,0x634ae8c4,0x9e498dbe,0x30498761, + 0xc8f779ab,0x08c43e6d,0x4c09aca9,0x068ae384,0x2018d170,0x2380c70b }, + { 0xa297c5ec,0xcf77fbc3,0xca457948,0xdacbc853,0x336bec7e,0x3690de04, + 0x14eec461,0x26bbac64,0x1f713abf,0xd1c23c7e,0xe6fd569e,0xf08bbfcd } }, + /* 144 */ + { { 0x84770ee3,0x5f8163f4,0x744a1706,0x0e0c7f94,0xe1b2d46d,0x9c8f05f7, + 0xd01fd99a,0x417eafe7,0x11440e5b,0x2ba15df5,0x91a6fbcf,0xdc5c552a }, + { 0xa270f721,0x86271d74,0xa004485b,0x32c0a075,0x8defa075,0x9d1a87e3, + 0xbf0d20fe,0xb590a7ac,0x8feda1f5,0x430c41c2,0x58f6ec24,0x454d2879 } }, + /* 145 */ + { { 0x7c525435,0x52b7a635,0x37c4bdbc,0x3d9ef57f,0xdffcc475,0x2bb93e9e, + 0x7710f3be,0xf7b8ba98,0x21b727de,0x42ee86da,0x2e490d01,0x55ac3f19 }, + { 0xc0c1c390,0x487e3a6e,0x446cde7b,0x036fb345,0x496ae951,0x089eb276, + 0x71ed1234,0xedfed4d9,0x900f0b46,0x661b0dd5,0x8582f0d3,0x11bd6f1b } }, + /* 146 */ + { { 0x076bc9d1,0x5cf9350f,0xcf3cd2c3,0x15d903be,0x25af031c,0x21cfc8c2, + 0x8b1cc657,0xe0ad3248,0x70014e87,0xdd9fb963,0x297f1658,0xf0f3a5a1 }, + { 0xf1f703aa,0xbb908fba,0x2f6760ba,0x2f9cc420,0x66a38b51,0x00ceec66, + 0x05d645da,0x4deda330,0xf7de3394,0xb9cf5c72,0x1ad4c906,0xaeef6502 } }, + /* 147 */ + { { 0x7a19045d,0x0583c8b1,0xd052824c,0xae7c3102,0xff6cfa58,0x2a234979, + 0x62c733c0,0xfe9dffc9,0x9c0c4b09,0x3a7fa250,0x4fe21805,0x516437bb }, + { 0xc2a23ddb,0x9454e3d5,0x289c104e,0x0726d887,0x4fd15243,0x8977d918, + 0x6d7790ba,0xc559e73f,0x465af85f,0x8fd3e87d,0x5feee46b,0xa2615c74 } }, + /* 148 */ + { { 0x4335167d,0xc8d607a8,0xe0f5c887,0x8b42d804,0x398d11f9,0x5f9f13df, + 0x20740c67,0x5aaa5087,0xa3d9234b,0x83da9a6a,0x2a54bad1,0xbd3a5c4e }, + { 0x2db0f658,0xdd13914c,0x5a3f373a,0x29dcb66e,0x5245a72b,0xbfd62df5, + 0x91e40847,0x19d18023,0xb136b1ae,0xd9df74db,0x3f93bc5b,0x72a06b6b } }, + /* 149 */ + { { 0xad19d96f,0x6da19ec3,0xfb2a4099,0xb342daa4,0x662271ea,0x0e61633a, + 0xce8c054b,0x3bcece81,0x8bd62dc6,0x7cc8e061,0xee578d8b,0xae189e19 }, + { 0xdced1eed,0x73e7a25d,0x7875d3ab,0xc1257f0a,0x1cfef026,0x2cb2d5a2, + 0xb1fdf61c,0xd98ef39b,0x24e83e6c,0xcd8e6f69,0xc7b7088b,0xd71e7076 } }, + /* 150 */ + { { 0x9d4245bf,0x33936830,0x2ac2953b,0x22d96217,0x56c3c3cd,0xb3bf5a82, + 0x0d0699e8,0x50c9be91,0x8f366459,0xec094463,0x513b7c35,0x6c056dba }, + { 0x045ab0e3,0x687a6a83,0x445c9295,0x8d40b57f,0xa16f5954,0x0f345048, + 0x3d8f0a87,0x64b5c639,0x9f71c5e2,0x106353a2,0x874f0dd4,0xdd58b475 } }, + /* 151 */ + { { 0x62230c72,0x67ec084f,0x481385e3,0xf14f6cca,0x4cda7774,0xf58bb407, + 0xaa2dbb6b,0xe15011b1,0x0c035ab1,0xd488369d,0x8245f2fd,0xef83c24a }, + { 0x9fdc2538,0xfb57328f,0x191fe46a,0x79808293,0x32ede548,0xe28f5c44, + 0xea1a022c,0x1b3cda99,0x3df2ec7f,0x39e639b7,0x760e9a18,0x77b6272b } }, + /* 152 */ + { { 0xa65d56d5,0x2b1d51bd,0x7ea696e0,0x3a9b71f9,0x9904f4c4,0x95250ecc, + 0xe75774b7,0x8bc4d6eb,0xeaeeb9aa,0x0e343f8a,0x930e04cb,0xc473c1d1 }, + { 0x064cd8ae,0x282321b1,0x5562221c,0xf4b4371e,0xd1bf1221,0xc1cc81ec, + 0xe2c8082f,0xa52a07a9,0xba64a958,0x350d8e59,0x6fb32c9a,0x29e4f3de } }, + /* 153 */ + { { 0xba89aaa5,0x0aa9d56c,0xc4c6059e,0xf0208ac0,0xbd6ddca4,0x7400d9c6, + 0xf2c2f74a,0xb384e475,0xb1562dd3,0x4c1061fc,0x2e153b8d,0x3924e248 }, + { 0x849808ab,0xf38b8d98,0xa491aa36,0x29bf3260,0x88220ede,0x85159ada, + 0xbe5bc422,0x8b47915b,0xd7300967,0xa934d72e,0x2e515d0d,0xc4f30398 } }, + /* 154 */ + { { 0x1b1de38b,0xe3e9ee42,0x42636760,0xa124e25a,0x90165b1a,0x90bf73c0, + 0x146434c5,0x21802a34,0x2e1fa109,0x54aa83f2,0xed9c51e9,0x1d4bd03c }, + { 0x798751e6,0xc2d96a38,0x8c3507f5,0xed27235f,0xc8c24f88,0xb5fb80e2, + 0xd37f4f78,0xf873eefa,0xf224ba96,0x7229fd74,0x9edd7149,0x9dcd9199 } }, + /* 155 */ + { { 0x4e94f22a,0xee9f81a6,0xf71ec341,0xe5609892,0xa998284e,0x6c818ddd, + 0x3b54b098,0x9fd47295,0x0e8a7cc9,0x47a6ac03,0xb207a382,0xde684e5e }, + { 0x2b6b956b,0x4bdd1ecd,0xf01b3583,0x09084414,0x55233b14,0xe2f80b32, + 0xef5ebc5e,0x5a0fec54,0xbf8b29a2,0x74cf25e6,0x7f29e014,0x1c757fa0 } }, + /* 156 */ + { { 0xeb0fdfe4,0x1bcb5c4a,0xf0899367,0xd7c649b3,0x05bc083b,0xaef68e3f, + 0xa78aa607,0x57a06e46,0x21223a44,0xa2136ecc,0x52f5a50b,0x89bd6484 }, + { 0x4455f15a,0x724411b9,0x08a9c0fd,0x23dfa970,0x6db63bef,0x7b0da4d1, + 0xfb162443,0x6f8a7ec1,0xe98284fb,0xc1ac9cee,0x33566022,0x085a582b } }, + /* 157 */ + { { 0xec1f138a,0x15cb61f9,0x668f0c28,0x11c9a230,0xdf93f38f,0xac829729, + 0x4048848d,0xcef25698,0x2bba8fbf,0x3f686da0,0x111c619a,0xed5fea78 }, + { 0xd6d1c833,0x9b4f73bc,0x86e7bf80,0x50951606,0x042b1d51,0xa2a73508, + 0x5fb89ec2,0x9ef6ea49,0x5ef8b892,0xf1008ce9,0x9ae8568b,0x78a7e684 } }, + /* 158 */ + { { 0x10470cd8,0x3fe83a7c,0xf86df000,0x92734682,0xda9409b5,0xb5dac06b, + 0x94939c5f,0x1e7a9660,0x5cc116dc,0xdec6c150,0x66bac8cc,0x1a52b408 }, + { 0x6e864045,0x5303a365,0x9139efc1,0x45eae72a,0x6f31d54f,0x83bec646, + 0x6e958a6d,0x2fb4a86f,0x4ff44030,0x6760718e,0xe91ae0df,0x008117e3 } }, + /* 159 */ + { { 0x384310a2,0x5d5833ba,0x1fd6c9fc,0xbdfb4edc,0x849c4fb8,0xb9a4f102, + 0x581c1e1f,0xe5fb239a,0xd0a9746d,0xba44b2e7,0x3bd942b9,0x78f7b768 }, + { 0xc87607ae,0x076c8ca1,0xd5caaa7e,0x82b23c2e,0x2763e461,0x6a581f39, + 0x3886df11,0xca8a5e4a,0x264e7f22,0xc87e90cf,0x215cfcfc,0x04f74870 } }, + /* 160 */ + { { 0x141d161c,0x5285d116,0x93c4ed17,0x67cd2e0e,0x7c36187e,0x12c62a64, + 0xed2584ca,0xf5329539,0x42fbbd69,0xc4c777c4,0x1bdfc50a,0x107de776 }, + { 0xe96beebd,0x9976dcc5,0xa865a151,0xbe2aff95,0x9d8872af,0x0e0a9da1, + 0xa63c17cc,0x5e357a3d,0xe15cc67c,0xd31fdfd8,0x7970c6d8,0xc44bbefd } }, + /* 161 */ + { { 0x4c0c62f1,0x703f83e2,0x4e195572,0x9b1e28ee,0xfe26cced,0x6a82858b, + 0xc43638fa,0xd381c84b,0xa5ba43d8,0x94f72867,0x10b82743,0x3b4a783d }, + { 0x7576451e,0xee1ad7b5,0x14b6b5c8,0xc3d0b597,0xfcacc1b8,0x3dc30954, + 0x472c9d7b,0x55df110e,0x02f8a328,0x97c86ed7,0x88dc098f,0xd0433413 } }, + /* 162 */ + { { 0x2ca8f2fe,0x1a60d152,0x491bd41f,0x61640948,0x58dfe035,0x6dae29a5, + 0x278e4863,0x9a615bea,0x9ad7c8e5,0xbbdb4477,0x2ceac2fc,0x1c706630 }, + { 0x99699b4b,0x5e2b54c6,0x239e17e8,0xb509ca6d,0xea063a82,0x728165fe, + 0xb6a22e02,0x6b5e609d,0xb26ee1df,0x12813905,0x439491fa,0x07b9f722 } }, + /* 163 */ + { { 0x48ff4e49,0x1592ec14,0x6d644129,0x3e4e9f17,0x1156acc0,0x7acf8288, + 0xbb092b0b,0x5aa34ba8,0x7d38393d,0xcd0f9022,0xea4f8187,0x416724dd }, + { 0xc0139e73,0x3c4e641c,0x91e4d87d,0xe0fe46cf,0xcab61f8a,0xedb3c792, + 0xd3868753,0x4cb46de4,0x20f1098a,0xe449c21d,0xf5b8ea6e,0x5e5fd059 } }, + /* 164 */ + { { 0x75856031,0x7fcadd46,0xeaf2fbd0,0x89c7a4cd,0x7a87c480,0x1af523ce, + 0x61d9ae90,0xe5fc1095,0xbcdb95f5,0x3fb5864f,0xbb5b2c7d,0xbeb5188e }, + { 0x3ae65825,0x3d1563c3,0x0e57d641,0x116854c4,0x1942ebd3,0x11f73d34, + 0xc06955b3,0x24dc5904,0x995a0a62,0x8a0d4c83,0x5d577b7d,0xfb26b86d } }, + /* 165 */ + { { 0xc686ae17,0xc53108e7,0xd1c1da56,0x9090d739,0x9aec50ae,0x4583b013, + 0xa49a6ab2,0xdd9a088b,0xf382f850,0x28192eea,0xf5fe910e,0xcc8df756 }, + { 0x9cab7630,0x877823a3,0xfb8e7fc1,0x64984a9a,0x364bfc16,0x5448ef9c, + 0xc44e2a9a,0xbbb4f871,0x435c95e9,0x901a41ab,0xaaa50a06,0xc6c23e5f } }, + /* 166 */ + { { 0x9034d8dd,0xb78016c1,0x0b13e79b,0x856bb44b,0xb3241a05,0x85c6409a, + 0x2d78ed21,0x8d2fe19a,0x726eddf2,0xdcc7c26d,0x25104f04,0x3ccaff5f }, + { 0x6b21f843,0x397d7edc,0xe975de4c,0xda88e4dd,0x4f5ab69e,0x5273d396, + 0x9aae6cc0,0x537680e3,0x3e6f9461,0xf749cce5,0x957bffd3,0x021ddbd9 } }, + /* 167 */ + { { 0x777233cf,0x7b64585f,0x0942a6f0,0xfe6771f6,0xdfe6eef0,0x636aba7a, + 0x86038029,0x63bbeb56,0xde8fcf36,0xacee5842,0xd4a20524,0x48d9aa99 }, + { 0x0da5e57a,0xcff7a74c,0xe549d6c9,0xc232593c,0xf0f2287b,0x68504bcc, + 0xbc8360b5,0x6d7d098d,0x5b402f41,0xeac5f149,0xb87d1bf1,0x61936f11 } }, + /* 168 */ + { { 0xb8153a9d,0xaa9da167,0x9e83ecf0,0xa49fe3ac,0x1b661384,0x14c18f8e, + 0x38434de1,0x61c24dab,0x283dae96,0x3d973c3a,0x82754fc9,0xc99baa01 }, + { 0x4c26b1e3,0x477d198f,0xa7516202,0x12e8e186,0x362addfa,0x386e52f6, + 0xc3962853,0x31e8f695,0x6aaedb60,0xdec2af13,0x29cf74ac,0xfcfdb4c6 } }, + /* 169 */ + { { 0xcca40298,0x6b3ee958,0xf2f5d195,0xc3878153,0xed2eae5b,0x0c565630, + 0x3a697cf2,0xd089b37e,0xad5029ea,0xc2ed2ac7,0x0f0dda6a,0x7e5cdfad }, + { 0xd9b86202,0xf98426df,0x4335e054,0xed1960b1,0x3f14639e,0x1fdb0246, + 0x0db6c670,0x17f709c3,0x773421e1,0xbfc687ae,0x26c1a8ac,0x13fefc4a } }, + /* 170 */ + { { 0x7ffa0a5f,0xe361a198,0xc63fe109,0xf4b26102,0x6c74e111,0x264acbc5, + 0x77abebaf,0x4af445fa,0x24cddb75,0x448c4fdd,0x44506eea,0x0b13157d }, + { 0x72e9993d,0x22a6b159,0x85e5ecbe,0x2c3c57e4,0xfd83e1a1,0xa673560b, + 0xc3b8c83b,0x6be23f82,0x40bbe38e,0x40b13a96,0xad17399b,0x66eea033 } }, + /* 171 */ + { { 0xb4c6c693,0x49fc6e95,0x36af7d38,0xefc735de,0x35fe42fc,0xe053343d, + 0x6a9ab7c3,0xf0aa427c,0x4a0fcb24,0xc79f0436,0x93ebbc50,0x16287243 }, + { 0x16927e1e,0x5c3d6bd0,0x673b984c,0x40158ed2,0x4cd48b9a,0xa7f86fc8, + 0x60ea282d,0x1643eda6,0xe2a1beed,0x45b393ea,0x19571a94,0x664c839e } }, + /* 172 */ + { { 0x27eeaf94,0x57745750,0xea99e1e7,0x2875c925,0x5086adea,0xc127e7ba, + 0x86fe424f,0x765252a0,0x2b6c0281,0x1143cc6c,0xd671312d,0xc9bb2989 }, + { 0x51acb0a5,0x880c337c,0xd3c60f78,0xa3710915,0x9262b6ed,0x496113c0, + 0x9ce48182,0x5d25d9f8,0xb3813586,0x53b6ad72,0x4c0e159c,0x0ea3bebc } }, + /* 173 */ + { { 0xc5e49bea,0xcaba450a,0x7c05da59,0x684e5415,0xde7ac36c,0xa2e9cab9, + 0x2e6f957b,0x4ca79b5f,0x09b817b1,0xef7b0247,0x7d89df0f,0xeb304990 }, + { 0x46fe5096,0x508f7307,0x2e04eaaf,0x695810e8,0x3512f76c,0x88ef1bd9, + 0x3ebca06b,0x77661351,0xccf158b7,0xf7d4863a,0x94ee57da,0xb2a81e44 } }, + /* 174 */ + { { 0x6d53e6ba,0xff288e5b,0x14484ea2,0xa90de1a9,0xed33c8ec,0x2fadb60c, + 0x28b66a40,0x579d6ef3,0xec24372d,0x4f2dd6dd,0x1d66ec7d,0xe9e33fc9 }, + { 0x039eab6e,0x110899d2,0x3e97bb5e,0xa31a667a,0xcfdce68e,0x6200166d, + 0x5137d54b,0xbe83ebae,0x4800acdf,0x085f7d87,0x0c6f8c86,0xcf4ab133 } }, + /* 175 */ + { { 0x931e08fb,0x03f65845,0x1506e2c0,0x6438551e,0x9c36961f,0x5791f0dc, + 0xe3dcc916,0x68107b29,0xf495d2ca,0x83242374,0x6ee5895b,0xd8cfb663 }, + { 0xa0349b1b,0x525e0f16,0x4a0fab86,0x33cd2c6c,0x2af8dda9,0x46c12ee8, + 0x71e97ad3,0x7cc424ba,0x37621eb0,0x69766ddf,0xa5f0d390,0x95565f56 } }, + /* 176 */ + { { 0x1a0f5e94,0xe0e7bbf2,0x1d82d327,0xf771e115,0xceb111fa,0x10033e3d, + 0xd3426638,0xd269744d,0x00d01ef6,0xbdf2d9da,0xa049ceaf,0x1cb80c71 }, + { 0x9e21c677,0x17f18328,0x19c8f98b,0x6452af05,0x80b67997,0x35b9c5f7, + 0x40f8f3d4,0x5c2e1cbe,0x66d667ca,0x43f91656,0xcf9d6e79,0x9faaa059 } }, + /* 177 */ + { { 0x0a078fe6,0x8ad24618,0x464fd1dd,0xf6cc73e6,0xc3e37448,0x4d2ce34d, + 0xe3271b5f,0x624950c5,0xefc5af72,0x62910f5e,0xaa132bc6,0x8b585bf8 }, + { 0xa839327f,0x11723985,0x4aac252f,0x34e2d27d,0x6296cc4e,0x402f59ef, + 0x47053de9,0x00ae055c,0x28b4f09b,0xfc22a972,0xfa0c180e,0xa9e86264 } }, + /* 178 */ + { { 0xbc310ecc,0x0b7b6224,0x67fa14ed,0x8a1a74f1,0x7214395c,0x87dd0960, + 0xf5c91128,0xdf1b3d09,0x86b264a8,0x39ff23c6,0x3e58d4c5,0xdc2d49d0 }, + { 0xa9d6f501,0x2152b7d3,0xc04094f7,0xf4c32e24,0xd938990f,0xc6366596, + 0x94fb207f,0x084d078f,0x328594cb,0xfd99f1d7,0xcb2d96b3,0x36defa64 } }, + /* 179 */ + { { 0x13ed7cbe,0x4619b781,0x9784bd0e,0x95e50015,0x2c7705fe,0x2a32251c, + 0x5f0dd083,0xa376af99,0x0361a45b,0x55425c6c,0x1f291e7b,0x812d2cef }, + { 0x5fd94972,0xccf581a0,0xe56dc383,0x26e20e39,0x63dbfbf0,0x0093685d, + 0x36b8c575,0x1fc164cc,0x390ef5e7,0xb9c5ab81,0x26908c66,0x40086beb } }, + /* 180 */ + { { 0x37e3c115,0xe5e54f79,0xc1445a8a,0x69b8ee8c,0xb7659709,0x79aedff2, + 0x1b46fbe6,0xe288e163,0xd18d7bb7,0xdb4844f0,0x48aa6424,0xe0ea23d0 }, + { 0xf3d80a73,0x714c0e4e,0x3bd64f98,0x87a0aa9e,0x2ec63080,0x8844b8a8, + 0x255d81a3,0xe0ac9c30,0x455397fc,0x86151237,0x2f820155,0x0b979464 } }, + /* 181 */ + { { 0x4ae03080,0x127a255a,0x580a89fb,0x232306b4,0x6416f539,0x04e8cd6a, + 0x13b02a0e,0xaeb70dee,0x4c09684a,0xa3038cf8,0x28e433ee,0xa710ec3c }, + { 0x681b1f7d,0x77a72567,0x2fc28170,0x86fbce95,0xf5735ac8,0xd3408683, + 0x6bd68e93,0x3a324e2a,0xc027d155,0x7ec74353,0xd4427177,0xab60354c } }, + /* 182 */ + { { 0xef4c209d,0x32a5342a,0x08d62704,0x2ba75274,0xc825d5fe,0x4bb4af6f, + 0xd28e7ff1,0x1c3919ce,0xde0340f6,0x1dfc2fdc,0x29f33ba9,0xc6580baf }, + { 0x41d442cb,0xae121e75,0x3a4724e4,0x4c7727fd,0x524f3474,0xe556d6a4, + 0x785642a2,0x87e13cc7,0xa17845fd,0x182efbb1,0x4e144857,0xdcec0cf1 } }, + /* 183 */ + { { 0xe9539819,0x1cb89541,0x9d94dbf1,0xc8cb3b4f,0x417da578,0x1d353f63, + 0x8053a09e,0xb7a697fb,0xc35d8b78,0x8d841731,0xb656a7a9,0x85748d6f }, + { 0xc1859c5d,0x1fd03947,0x535d22a2,0x6ce965c1,0x0ca3aadc,0x1966a13e, + 0x4fb14eff,0x9802e41d,0x76dd3fcd,0xa9048cbb,0xe9455bba,0x89b182b5 } }, + /* 184 */ + { { 0x43360710,0xd777ad6a,0x55e9936b,0x841287ef,0x04a21b24,0xbaf5c670, + 0x35ad86f1,0xf2c0725f,0xc707e72e,0x338fa650,0xd8883e52,0x2bf8ed2e }, + { 0xb56e0d6a,0xb0212cf4,0x6843290c,0x50537e12,0x98b3dc6f,0xd8b184a1, + 0x0210b722,0xd2be9a35,0x559781ee,0x407406db,0x0bc18534,0x5a78d591 } }, + /* 185 */ + { { 0xd748b02c,0x4d57aa2a,0xa12b3b95,0xbe5b3451,0x64711258,0xadca7a45, + 0x322153db,0x597e091a,0x32eb1eab,0xf3271006,0x2873f301,0xbd9adcba }, + { 0x38543f7f,0xd1dc79d1,0x921b1fef,0x00022092,0x1e5df8ed,0x86db3ef5, + 0x9e6b944a,0x888cae04,0x791a32b4,0x71bd29ec,0xa6d1c13e,0xd3516206 } }, + /* 186 */ + { { 0x55924f43,0x2ef6b952,0x4f9de8d5,0xd2f401ae,0xadc68042,0xfc73e8d7, + 0x0d9d1bb4,0x627ea70c,0xbbf35679,0xc3bb3e3e,0xd882dee4,0x7e8a254a }, + { 0xb5924407,0x08906f50,0xa1ad444a,0xf14a0e61,0x65f3738e,0xaa0efa21, + 0xae71f161,0xd60c7dd6,0xf175894d,0x9e8390fa,0x149f4c00,0xd115cd20 } }, + /* 187 */ + { { 0xa52abf77,0x2f2e2c1d,0x54232568,0xc2a0dca5,0x54966dcc,0xed423ea2, + 0xcd0dd039,0xe48c93c7,0x176405c7,0x1e54a225,0x70d58f2e,0x1efb5b16 }, + { 0x94fb1471,0xa751f9d9,0x67d2941d,0xfdb31e1f,0x53733698,0xa6c74eb2, + 0x89a0f64a,0xd3155d11,0xa4b8d2b6,0x4414cfe4,0xf7a8e9e3,0x8d5a4be8 } }, + /* 188 */ + { { 0x52669e98,0x5c96b4d4,0x8fd42a03,0x4547f922,0xd285174e,0xcf5c1319, + 0x064bffa0,0x805cd1ae,0x246d27e7,0x50e8bc4f,0xd5781e11,0xf89ef98f }, + { 0xdee0b63f,0xb4ff95f6,0x222663a4,0xad850047,0x4d23ce9c,0x02691860, + 0x50019f59,0x3e5309ce,0x69a508ae,0x27e6f722,0x267ba52c,0xe9376652 } }, + /* 189 */ + { { 0xc0368708,0xa04d289c,0x5e306e1d,0xc458872f,0x33112fea,0x76fa23de, + 0x6efde42e,0x718e3974,0x1d206091,0xf0c98cdc,0x14a71987,0x5fa3ca62 }, + { 0xdcaa9f2a,0xeee8188b,0x589a860d,0x312cc732,0xc63aeb1f,0xf9808dd6, + 0x4ea62b53,0x70fd43db,0x890b6e97,0x2c2bfe34,0xfa426aa6,0x105f863c } }, + /* 190 */ + { { 0xb38059ad,0x0b29795d,0x90647ea0,0x5686b77e,0xdb473a3e,0xeff0470e, + 0xf9b6d1e2,0x278d2340,0xbd594ec7,0xebbff95b,0xd3a7f23d,0xf4b72334 }, + { 0xa5a83f0b,0x2a285980,0x9716a8b3,0x0786c41a,0x22511812,0x138901bd, + 0xe2fede6e,0xd1b55221,0xdf4eb590,0x0806e264,0x762e462e,0x6c4c897e } }, + /* 191 */ + { { 0xb4b41d9d,0xd10b905f,0x4523a65b,0x826ca466,0xb699fa37,0x535bbd13, + 0x73bc8f90,0x5b9933d7,0xcd2118ad,0x9332d61f,0xd4a65fd0,0x158c693e }, + { 0xe6806e63,0x4ddfb2a8,0xb5de651b,0xe31ed3ec,0x819bc69a,0xf9460e51, + 0x2c76b1f8,0x6229c0d6,0x901970a3,0xbb78f231,0x9cee72b8,0x31f3820f } }, + /* 192 */ + { { 0xc09e1c72,0xe931caf2,0x12990cf4,0x0715f298,0x943262d8,0x33aad81d, + 0x73048d3f,0x5d292b7a,0xdc7415f6,0xb152aaa4,0x0fd19587,0xc3d10fd9 }, + { 0x75ddadd0,0xf76b35c5,0x1e7b694c,0x9f5f4a51,0xc0663025,0x2f1ab7eb, + 0x920260b0,0x01c9cc87,0x05d39da6,0xc4b1f61a,0xeb4a9c4e,0x6dcd76c4 } }, + /* 193 */ + { { 0xfdc83f01,0x0ba0916f,0x9553e4f9,0x354c8b44,0xffc5e622,0xa6cc511a, + 0xe95be787,0xb954726a,0x75b41a62,0xcb048115,0xebfde989,0xfa2ae6cd }, + { 0x0f24659a,0x6376bbc7,0x4c289c43,0x13a999fd,0xec9abd8b,0xc7134184, + 0xa789ab04,0x28c02bf6,0xd3e526ec,0xff841ebc,0x640893a8,0x442b191e } }, + /* 194 */ + { { 0xfa2b6e20,0x4cac6c62,0xf6d69861,0x97f29e9b,0xbc96d12d,0x228ab1db, + 0x5e8e108d,0x6eb91327,0x40771245,0xd4b3d4d1,0xca8a803a,0x61b20623 }, + { 0xa6a560b1,0x2c2f3b41,0x3859fcf4,0x879e1d40,0x024dbfc3,0x7cdb5145, + 0x3bfa5315,0x55d08f15,0xaa93823a,0x2f57d773,0xc6a2c9a2,0xa97f259c } }, + /* 195 */ + { { 0xe58edbbb,0xc306317b,0x79dfdf13,0x25ade51c,0x16d83dd6,0x6b5beaf1, + 0x1dd8f925,0xe8038a44,0xb2a87b6b,0x7f00143c,0xf5b438de,0xa885d00d }, + { 0xcf9e48bd,0xe9f76790,0xa5162768,0xf0bdf9f0,0xad7b57cb,0x0436709f, + 0xf7c15db7,0x7e151c12,0x5d90ee3b,0x3514f022,0x2c361a8d,0x2e84e803 } }, + /* 196 */ + { { 0x563ec8d8,0x2277607d,0xe3934cb7,0xa661811f,0xf58fd5de,0x3ca72e7a, + 0x62294c6a,0x7989da04,0xf6bbefe9,0x88b3708b,0x53ed7c82,0x0d524cf7 }, + { 0x2f30c073,0x69f699ca,0x9dc1dcf3,0xf0fa264b,0x05f0aaf6,0x44ca4568, + 0xd19b9baf,0x0f5b23c7,0xeabd1107,0x39193f41,0x2a7c9b83,0x9e3e10ad } }, + /* 197 */ + { { 0xd4ae972f,0xa90824f0,0xc6e846e7,0x43eef02b,0x29d2160a,0x7e460612, + 0xfe604e91,0x29a178ac,0x4eb184b2,0x23056f04,0xeb54cdf4,0x4fcad55f }, + { 0xae728d15,0xa0ff96f3,0xc6a00331,0x8a2680c6,0x7ee52556,0x5f84cae0, + 0xc5a65dad,0x5e462c3a,0xe2d23f4f,0x5d2b81df,0xc5b1eb07,0x6e47301b } }, + /* 198 */ + { { 0xaf8219b9,0x77411d68,0x51b1907a,0xcb883ce6,0x101383b5,0x25c87e57, + 0x982f970d,0x9c7d9859,0x118305d2,0xaa6abca5,0x9013a5db,0x725fed2f }, + { 0xababd109,0x487cdbaf,0x87586528,0xc0f8cf56,0x8ad58254,0xa02591e6, + 0xdebbd526,0xc071b1d1,0x961e7e31,0x927dfe8b,0x9263dfe1,0x55f895f9 } }, + /* 199 */ + { { 0xb175645b,0xf899b00d,0xb65b4b92,0x51f3a627,0xb67399ef,0xa2f3ac8d, + 0xe400bc20,0xe717867f,0x1967b952,0x42cc9020,0x3ecd1de1,0x3d596751 }, + { 0xdb979775,0xd41ebcde,0x6a2e7e88,0x99ba61bc,0x321504f2,0x039149a5, + 0x27ba2fad,0xe7dc2314,0xb57d8368,0x9f556308,0x57da80a7,0x2b6d16c9 } }, + /* 200 */ + { { 0x279ad982,0x84af5e76,0x9c8b81a6,0x9bb4c92d,0x0e698e67,0xd79ad44e, + 0x265fc167,0xe8be9048,0x0c3a4ccc,0xf135f7e6,0xb8863a33,0xa0a10d38 }, + { 0xd386efd9,0xe197247c,0xb52346c2,0x0eefd3f9,0x78607bc8,0xc22415f9, + 0x508674ce,0xa2a8f862,0xc8c9d607,0xa72ad09e,0x50fa764f,0xcd9f0ede } }, + /* 201 */ + { { 0xd1a46d4d,0x063391c7,0x9eb01693,0x2df51c11,0x849e83de,0xc5849800, + 0x8ad08382,0x48fd09aa,0xaa742736,0xa405d873,0xe1f9600c,0xee49e61e }, + { 0x48c76f73,0xd76676be,0x01274b2a,0xd9c100f6,0x83f8718d,0x110bb67c, + 0x02fc0d73,0xec85a420,0x744656ad,0xc0449e1e,0x37d9939b,0x28ce7376 } }, + /* 202 */ + { { 0x44544ac7,0x97e9af72,0xba010426,0xf2c658d5,0xfb3adfbd,0x732dec39, + 0xa2df0b07,0xd12faf91,0x2171e208,0x8ac26725,0x5b24fa54,0xf820cdc8 }, + { 0x94f4cf77,0x307a6eea,0x944a33c6,0x18c783d2,0x0b741ac5,0x4b939d4c, + 0x3ffbb6e4,0x1d7acd15,0x7a255e44,0x06a24858,0xce336d50,0x14fbc494 } }, + /* 203 */ + { { 0x51584e3c,0x9b920c0c,0xf7e54027,0xc7733c59,0x88422bbe,0xe24ce139, + 0x523bd6ab,0x11ada812,0xb88e6def,0xde068800,0xfe8c582d,0x7b872671 }, + { 0x7de53510,0x4e746f28,0xf7971968,0x492f8b99,0x7d928ac2,0x1ec80bc7, + 0x432eb1b5,0xb3913e48,0x32028f6e,0xad084866,0x8fc2f38b,0x122bb835 } }, + /* 204 */ + { { 0x3b0b29c3,0x0a9f3b1e,0x4fa44151,0x837b6432,0x17b28ea7,0xb9905c92, + 0x98451750,0xf39bc937,0xce8b6da1,0xcd383c24,0x010620b2,0x299f57db }, + { 0x58afdce3,0x7b6ac396,0x3d05ef47,0xa15206b3,0xb9bb02ff,0xa0ae37e2, + 0x9db3964c,0x107760ab,0x67954bea,0xe29de9a0,0x431c3f82,0x446a1ad8 } }, + /* 205 */ + { { 0x5c6b8195,0xc6fecea0,0xf49e71b9,0xd744a7c5,0x177a7ae7,0xa8e96acc, + 0x358773a7,0x1a05746c,0x37567369,0xa4162146,0x87d1c971,0xaa0217f7 }, + { 0x77fd3226,0x61e9d158,0xe4f600be,0x0f6f2304,0x7a6dff07,0xa9c4cebc, + 0x09f12a24,0xd15afa01,0x8c863ee9,0x2bbadb22,0xe5eb8c78,0xa28290e4 } }, + /* 206 */ + { { 0x3e9de330,0x55b87fa0,0x195c145b,0x12b26066,0xa920bef0,0xe08536e0, + 0x4d195adc,0x7bff6f2c,0x945f4187,0x7f319e9d,0xf892ce47,0xf9848863 }, + { 0x4fe37657,0xd0efc1d3,0x5cf0e45a,0x3c58de82,0x8b0ccbbe,0x626ad21a, + 0xaf952fc5,0xd2a31208,0xeb437357,0x81791995,0x98e95d4f,0x5f19d30f } }, + /* 207 */ + { { 0x0e6865bb,0x72e83d9a,0xf63456a6,0x22f5af3b,0x463c8d9e,0x409e9c73, + 0xdfe6970e,0x40e9e578,0x711b91ca,0x876b6efa,0x942625a3,0x895512cf }, + { 0xcb4e462b,0x84c8eda8,0x4412e7c8,0x84c0154a,0xceb7b71f,0x04325db1, + 0x66f70877,0x1537dde3,0x1992b9ac,0xf3a09399,0xd498ae77,0xa7316606 } }, + /* 208 */ + { { 0xcad260f5,0x13990d2f,0xeec0e8c0,0x76c3be29,0x0f7bd7d5,0x7dc5bee0, + 0xefebda4b,0x9be167d2,0x9122b87e,0xcce3dde6,0x82b5415c,0x75a28b09 }, + { 0xe84607a6,0xf6810bcd,0x6f4dbf0d,0xc6d58128,0x1b4dafeb,0xfead577d, + 0x066b28eb,0x9bc440b2,0x8b17e84b,0x53f1da97,0xcda9a575,0x0459504b } }, + /* 209 */ + { { 0x329e5836,0x13e39a02,0xf717269d,0x2c9e7d51,0xf26c963b,0xc5ac58d6, + 0x79967bf5,0x3b0c6c43,0x55908d9d,0x60bbea3f,0xf07c9ad1,0xd84811e7 }, + { 0x5bd20e4a,0xfe7609a7,0x0a70baa8,0xe4325dd2,0xb3600386,0x3711f370, + 0xd0924302,0x97f9562f,0x4acc4436,0x040dc0c3,0xde79cdd4,0xfd6d725c } }, + /* 210 */ + { { 0xcf13eafb,0xb3efd0e3,0x5aa0ae5f,0x21009cbb,0x79022279,0xe480c553, + 0xb2fc9a6d,0x755cf334,0x07096ae7,0x8564a5bf,0xbd238139,0xddd649d0 }, + { 0x8a045041,0xd0de10b1,0xc957d572,0x6e05b413,0x4e0fb25c,0x5c5ff806, + 0x641162fb,0xd933179b,0xe57439f9,0x42d48485,0x8a8d72aa,0x70c5bd0a } }, + /* 211 */ + { { 0x97bdf646,0xa7671738,0xab329f7c,0xaa1485b4,0xf8f25fdf,0xce3e11d6, + 0xc6221824,0x76a3fc7e,0xf3924740,0x045f281f,0x96d13a9a,0x24557d4e }, + { 0xdd4c27cd,0x875c804b,0x0f5c7fea,0x11c5f0f4,0xdc55ff7e,0xac8c880b, + 0x1103f101,0x2acddec5,0xf99faa89,0x38341a21,0xce9d6b57,0xc7b67a2c } }, + /* 212 */ + { { 0x8e357586,0x9a0d724f,0xdf648da0,0x1d7f4ff5,0xfdee62a5,0x9c3e6c9b, + 0x0389b372,0x0499cef0,0x98eab879,0xe904050d,0x6c051617,0xe8eef1b6 }, + { 0xc37e3ca9,0xebf5bfeb,0xa4e0b91d,0x7c5e946d,0x2c4bea28,0x79097314, + 0xee67b2b7,0x81f6c109,0xdafc5ede,0xaf237d9b,0x2abb04c7,0xd2e60201 } }, + /* 213 */ + { { 0x8a4f57bf,0x6156060c,0xff11182a,0xf9758696,0x6296ef00,0x8336773c, + 0xff666899,0x9c054bce,0x719cd11c,0xd6a11611,0xdbe1acfa,0x9824a641 }, + { 0xba89fd01,0x0b7b7a5f,0x889f79d8,0xf8d3b809,0xf578285c,0xc5e1ea08, + 0xae6d8288,0x7ac74536,0x7521ef5f,0x5d37a200,0xb260a25d,0x5ecc4184 } }, + /* 214 */ + { { 0xa708c8d3,0xddcebb19,0xc63f81ec,0xe63ed04f,0x11873f95,0xd045f5a0, + 0x79f276d5,0x3b5ad544,0x425ae5b3,0x81272a3d,0x10ce1605,0x8bfeb501 }, + { 0x888228bf,0x4233809c,0xb2aff7df,0x4bd82acf,0x0cbd4a7f,0x9c68f180, + 0x6b44323d,0xfcd77124,0x891db957,0x60c0fcf6,0x04da8f7f,0xcfbb4d89 } }, + /* 215 */ + { { 0x3b26139a,0x9a6a5df9,0xb2cc7eb8,0x3e076a83,0x5a964bcd,0x47a8e82d, + 0xb9278d6b,0x8a4e2a39,0xe4443549,0x93506c98,0xf1e0d566,0x06497a8f }, + { 0x2b1efa05,0x3dee8d99,0x45393e33,0x2da63ca8,0xcf0579ad,0xa4af7277, + 0x3236d8ea,0xaf4b4639,0x32b617f5,0x6ccad95b,0xb88bb124,0xce76d8b8 } }, + /* 216 */ + { { 0x083843dc,0x63d2537a,0x1e4153b4,0x89eb3514,0xea9afc94,0x5175ebc4, + 0x8ed1aed7,0x7a652580,0xd85e8297,0x67295611,0xb584b73d,0x8dd2d68b }, + { 0x0133c3a4,0x237139e6,0x4bd278ea,0x9de838ab,0xc062fcd9,0xe829b072, + 0x63ba8706,0x70730d4f,0xd3cd05ec,0x6080483f,0x0c85f84d,0x872ab5b8 } }, + /* 217 */ + { { 0x999d4d49,0xfc0776d3,0xec3f45e7,0xa3eb59de,0x0dae1fc1,0xbc990e44, + 0xa15371ff,0x33596b1e,0x9bc7ab25,0xd447dcb2,0x35979582,0xcd5b63e9 }, + { 0x77d1ff11,0xae3366fa,0xedee6903,0x59f28f05,0xa4433bf2,0x6f43fed1, + 0xdf9ce00e,0x15409c9b,0xaca9c5dc,0x21b5cded,0x82d7bdb4,0xf9f33595 } }, + /* 218 */ + { { 0x9422c792,0x95944378,0xc958b8bf,0x239ea923,0xdf076541,0x4b61a247, + 0xbb9fc544,0x4d29ce85,0x0b424559,0x9a692a67,0x0e486900,0x6e0ca5a0 }, + { 0x85b3bece,0x6b79a782,0xc61f9892,0x41f35e39,0xae747f82,0xff82099a, + 0xd0ca59d6,0x58c8ae3f,0x99406b5f,0x4ac930e2,0x9df24243,0x2ce04eb9 } }, + /* 219 */ + { { 0x1ac37b82,0x4366b994,0x25b04d83,0xff0c728d,0x19c47b7c,0x1f551361, + 0xbeff13e7,0xdbf2d5ed,0xe12a683d,0xf78efd51,0x989cf9c4,0x82cd85b9 }, + { 0xe0cb5d37,0xe23c6db6,0x72ee1a15,0x818aeebd,0x28771b14,0x8212aafd, + 0x1def817d,0x7bc221d9,0x9445c51f,0xdac403a2,0x12c3746b,0x711b0517 } }, + /* 220 */ + { { 0x5ea99ecc,0x0ed9ed48,0xb8cab5e1,0xf799500d,0xb570cbdc,0xa8ec87dc, + 0xd35dfaec,0x52cfb2c2,0x6e4d80a4,0x8d31fae2,0xdcdeabe5,0xe6a37dc9 }, + { 0x1deca452,0x5d365a34,0x0d68b44e,0x09a5f8a5,0xa60744b1,0x59238ea5, + 0xbb4249e9,0xf2fedc0d,0xa909b2e3,0xe395c74e,0x39388250,0xe156d1a5 } }, + /* 221 */ + { { 0x47181ae9,0xd796b3d0,0x44197808,0xbaf44ba8,0x34cf3fac,0xe6933094, + 0xc3bd5c46,0x41aa6ade,0xeed947c6,0x4fda75d8,0x9ea5a525,0xacd9d412 }, + { 0xd430301b,0x65cc55a3,0x7b52ea49,0x3c9a5bcf,0x159507f0,0x22d319cf, + 0xde74a8dd,0x2ee0b9b5,0x877ac2b6,0x20c26a1e,0x92e7c314,0x387d73da } }, + /* 222 */ + { { 0x8cd3fdac,0x13c4833e,0x332e5b8e,0x76fcd473,0xe2fe1fd3,0xff671b4b, + 0x5d98d8ec,0x4d734e8b,0x514bbc11,0xb1ead3c6,0x7b390494,0xd14ca858 }, + { 0x5d2d37e9,0x95a443af,0x00464622,0x73c6ea73,0x15755044,0xa44aeb4b, + 0xfab58fee,0xba3f8575,0xdc680a6f,0x9779dbc9,0x7b37ddfc,0xe1ee5f5a } }, + /* 223 */ + { { 0x12d29f46,0xcd0b4648,0x0ed53137,0x93295b0b,0x80bef6c9,0xbfe26094, + 0x54248b00,0xa6565788,0x80e7f9c4,0x69c43fca,0xbe141ea1,0x2190837b }, + { 0xa1b26cfb,0x875e159a,0x7affe852,0x90ca9f87,0x92ca598e,0x15e6550d, + 0x1938ad11,0xe3e0945d,0x366ef937,0xef7636bb,0xb39869e5,0xb6034d0b } }, + /* 224 */ + { { 0x26d8356e,0x4d255e30,0xd314626f,0xf83666ed,0xd0c8ed64,0x421ddf61, + 0x26677b61,0x96e473c5,0x9e9b18b3,0xdad4af7e,0xa9393f75,0xfceffd4a }, + { 0x11c731d5,0x843138a1,0xb2f141d9,0x05bcb3a1,0x617b7671,0x20e1fa95, + 0x88ccec7b,0xbefce812,0x90f1b568,0x582073dc,0x1f055cb7,0xf572261a } }, + /* 225 */ + { { 0x36973088,0xf3148277,0x86a9f980,0xc008e708,0xe046c261,0x1b795947, + 0xca76bca0,0xdf1e6a7d,0x71acddf0,0xabafd886,0x1364d8f4,0xff7054d9 }, + { 0xe2260594,0x2cf63547,0xd73b277e,0x468a5372,0xef9bd35e,0xc7419e24, + 0x24043cc3,0x2b4a1c20,0x890b39cd,0xa28f047a,0x46f9a2e3,0xdca2cea1 } }, + /* 226 */ + { { 0x53277538,0xab788736,0xcf697738,0xa734e225,0x6b22e2c1,0x66ee1d1e, + 0xebe1d212,0x2c615389,0x02bb0766,0xf36cad40,0x3e64f207,0x120885c3 }, + { 0x90fbfec2,0x59e77d56,0xd7a574ae,0xf9e781aa,0x5d045e53,0x801410b0, + 0xa91b5f0e,0xd3b5f0aa,0x7fbb3521,0xb3d1df00,0xc72bee9a,0x11c4b33e } }, + /* 227 */ + { { 0x83c3a7f3,0xd32b9832,0x88d8a354,0x8083abcf,0x50f4ec5a,0xdeb16404, + 0x641e2907,0x18d747f0,0xf1bbf03e,0x4e8978ae,0x88a0cd89,0x932447dc }, + { 0xcf3d5897,0x561e0feb,0x13600e6d,0xfc3a682f,0xd16a6b73,0xc78b9d73, + 0xd29bf580,0xe713fede,0x08d69e5c,0x0a225223,0x1ff7fda4,0x3a924a57 } }, + /* 228 */ + { { 0xb4093bee,0xfb64554c,0xa58c6ec0,0xa6d65a25,0x43d0ed37,0x4126994d, + 0x55152d44,0xa5689a51,0x284caa8d,0xb8e5ea8c,0xd1f25538,0x33f05d4f }, + { 0x1b615d6e,0xe0fdfe09,0x705507da,0x2ded7e8f,0x17bbcc80,0xdd5631e5, + 0x267fd11f,0x4f87453e,0xff89d62d,0xc6da723f,0xe3cda21d,0x55cbcae2 } }, + /* 229 */ + { { 0x6b4e84f3,0x336bc94e,0x4ef72c35,0x72863031,0xeeb57f99,0x6d85fdee, + 0xa42ece1b,0x7f4e3272,0x36f0320a,0x7f86cbb5,0x923331e6,0xf09b6a2b }, + { 0x56778435,0x21d3ecf1,0x8323b2d2,0x2977ba99,0x1704bc0f,0x6a1b57fb, + 0x389f048a,0xd777cf8b,0xac6b42cd,0x9ce2174f,0x09e6c55a,0x404e2bff } }, + /* 230 */ + { { 0x204c5ddb,0x9b9b135e,0x3eff550e,0x9dbfe044,0xec3be0f6,0x35eab4bf, + 0x0a43e56f,0x8b4c3f0d,0x0e73f9b3,0x4c1c6673,0x2c78c905,0x92ed38bd }, + { 0xa386e27c,0xc7003f6a,0xaced8507,0xb9c4f46f,0x59df5464,0xea024ec8, + 0x429572ea,0x4af96152,0xe1fc1194,0x279cd5e2,0x281e358c,0xaa376a03 } }, + /* 231 */ + { { 0x3cdbc95c,0x07859223,0xef2e337a,0xaae1aa6a,0x472a8544,0xc040108d, + 0x8d037b7d,0x80c853e6,0x8c7eee24,0xd221315c,0x8ee47752,0x195d3856 }, + { 0xdacd7fbe,0xd4b1ba03,0xd3e0c52b,0x4b5ac61e,0x6aab7b52,0x68d3c052, + 0x660e3fea,0xf0d7248c,0x3145efb4,0xafdb3f89,0x8f40936d,0xa73fd9a3 } }, + /* 232 */ + { { 0xbb1b17ce,0x891b9ef3,0xc6127f31,0x14023667,0x305521fd,0x12b2e58d, + 0xe3508088,0x3a47e449,0xff751507,0xe49fc84b,0x5310d16e,0x4023f722 }, + { 0xb73399fa,0xa608e5ed,0xd532aa3e,0xf12632d8,0x845e8415,0x13a2758e, + 0x1fc2d861,0xae4b6f85,0x339d02f2,0x3879f5b1,0x80d99ebd,0x446d22a6 } }, + /* 233 */ + { { 0x4be164f1,0x0f502302,0x88b81920,0x8d09d2d6,0x984aceff,0x514056f1, + 0x75e9e80d,0xa5c4ddf0,0xdf496a93,0x38cb47e6,0x38df6bf7,0x899e1d6b }, + { 0xb59eb2a6,0x69e87e88,0x9b47f38b,0x280d9d63,0x3654e955,0x599411ea, + 0x969aa581,0xcf8dd4fd,0x530742a7,0xff5c2baf,0x1a373085,0xa4391536 } }, + /* 234 */ + { { 0xa8a4bdd2,0x6ace72a3,0xb68ef702,0xc656cdd1,0x90c4dad8,0xd4a33e7e, + 0x9d951c50,0x4aece08a,0x085d68e6,0xea8005ae,0x6f7502b8,0xfdd7a7d7 }, + { 0x98d6fa45,0xce6fb0a6,0x1104eb8c,0x228f8672,0xda09d7dc,0xd23d8787, + 0x2ae93065,0x5521428b,0xea56c366,0x95faba3d,0x0a88aca5,0xedbe5039 } }, + /* 235 */ + { { 0xbfb26c82,0xd64da0ad,0x952c2f9c,0xe5d70b3c,0xf7e77f68,0xf5e8f365, + 0x08f2d695,0x7234e002,0xd12e7be6,0xfaf900ee,0x4acf734e,0x27dc6934 }, + { 0xc260a46a,0x80e4ff5e,0x2dc31c28,0x7da5ebce,0xca69f552,0x485c5d73, + 0x69cc84c2,0xcdfb6b29,0xed6d4eca,0x031c5afe,0x22247637,0xc7bbf4c8 } }, + /* 236 */ + { { 0x49fe01b2,0x9d5b72c7,0x793a91b8,0x34785186,0xcf460438,0xa3ba3c54, + 0x3ab21b6f,0x73e8e43d,0xbe57b8ab,0x50cde8e0,0xdd204264,0x6488b3a7 }, + { 0xdddc4582,0xa9e398b3,0x5bec46fe,0x1698c1a9,0x156d3843,0x7f1446ef, + 0x770329a2,0x3fd25dd8,0x2c710668,0x05b1221a,0xa72ee6cf,0x65b2dc2a } }, + /* 237 */ + { { 0xcd021d63,0x21a885f7,0xfea61f08,0x3f344b15,0xc5cf73e6,0xad5ba6dd, + 0x227a8b23,0x154d0d8f,0xdc559311,0x9b74373c,0x98620fa1,0x4feab715 }, + { 0x7d9ec924,0x5098938e,0x6d47e550,0x84d54a5e,0x1b617506,0x1a2d1bdc, + 0x615868a4,0x99fe1782,0x3005a924,0x171da780,0x7d8f79b6,0xa70bf5ed } }, + /* 238 */ + { { 0xfe2216c5,0x0bc1250d,0x7601b351,0x2c37e250,0xd6f06b7e,0xb6300175, + 0x8bfeb9b7,0x4dde8ca1,0xb82f843d,0x4f210432,0xb1ac0afd,0x8d70e2f9 }, + { 0xaae91abb,0x25c73b78,0x863028f2,0x0230dca3,0xe5cf30b7,0x8b923ecf, + 0x5506f265,0xed754ec2,0x729a5e39,0x8e41b88c,0xbabf889b,0xee67cec2 } }, + /* 239 */ + { { 0x1be46c65,0xe183acf5,0xe7565d7a,0x9789538f,0xd9627b4e,0x87873391, + 0x9f1d9187,0xbf4ac4c1,0x4691f5c8,0x5db99f63,0x74a1fb98,0xa68df803 }, + { 0xbf92b5fa,0x3c448ed1,0x3e0bdc32,0xa098c841,0x79bf016c,0x8e74cd55, + 0x115e244d,0x5df0d09c,0x3410b66e,0x9418ad01,0x17a02130,0x8b6124cb } }, + /* 240 */ + { { 0xc26e3392,0x425ec3af,0xa1722e00,0xc07f8470,0xe2356b43,0xdcc28190, + 0xb1ef59a6,0x4ed97dff,0xc63028c1,0xc22b3ad1,0x68c18988,0x070723c2 }, + { 0x4cf49e7d,0x70da302f,0x3f12a522,0xc5e87c93,0x18594148,0x74acdd1d, + 0xca74124c,0xad5f73ab,0xd69fd478,0xe72e4a3e,0x7b117cc3,0x61593868 } }, + /* 241 */ + { { 0xa9aa0486,0x7b7b9577,0xa063d557,0x6e41fb35,0xda9047d7,0xb017d5c7, + 0x68a87ba9,0x8c748280,0xdf08ad93,0xab45fa5c,0x4c288a28,0xcd9fb217 }, + { 0x5747843d,0x59544642,0xa56111e3,0x34d64c6c,0x4bfce8d5,0x12e47ea1, + 0x6169267f,0x17740e05,0xeed03fb5,0x5c49438e,0x4fc3f513,0x9da30add } }, + /* 242 */ + { { 0xccfa5200,0xc4e85282,0x6a19b13d,0x2707608f,0xf5726e2f,0xdcb9a53d, + 0xe9427de5,0x612407c9,0xd54d582a,0x3e5a17e1,0x655ae118,0xb99877de }, + { 0x015254de,0x6f0e972b,0xf0a6f7c5,0x92a56db1,0xa656f8b2,0xd297e4e1, + 0xad981983,0x99fe0052,0x07cfed84,0xd3652d2f,0x843c1738,0xc784352e } }, + /* 243 */ + { { 0x7e9b2d8a,0x6ee90af0,0x57cf1964,0xac8d7018,0x71f28efc,0xf6ed9031, + 0x6812b20e,0x7f70d5a9,0xf1c61eee,0x27b557f4,0xc6263758,0xf1c9bd57 }, + { 0x2a1a6194,0x5cf7d014,0x1890ab84,0xdd614e0b,0x0e93c2a6,0x3ef9de10, + 0xe0cd91c5,0xf98cf575,0x14befc32,0x504ec0c6,0x6279d68c,0xd0513a66 } }, + /* 244 */ + { { 0xa859fb6a,0xa8eadbad,0xdb283666,0xcf8346e7,0x3e22e355,0x7b35e61a, + 0x99639c6b,0x293ece2c,0x56f241c8,0xfa0162e2,0xbf7a1dda,0xd2e6c7b9 }, + { 0x40075e63,0xd0de6253,0xf9ec8286,0x2405aa61,0x8fe45494,0x2237830a, + 0x364e9c8c,0x4fd01ac7,0x904ba750,0x4d9c3d21,0xaf1b520b,0xd589be14 } }, + /* 245 */ + { { 0x4662e53b,0x13576a4f,0xf9077676,0x35ec2f51,0x97c0af97,0x66297d13, + 0x9e598b58,0xed3201fe,0x5e70f604,0x49bc752a,0xbb12d951,0xb54af535 }, + { 0x212c1c76,0x36ea4c2b,0xeb250dfd,0x18f5bbc7,0x9a0a1a46,0xa0d466cc, + 0xdac2d917,0x52564da4,0x8e95fab5,0x206559f4,0x9ca67a33,0x7487c190 } }, + /* 246 */ + { { 0xdde98e9c,0x75abfe37,0x2a411199,0x99b90b26,0xdcdb1f7c,0x1b410996, + 0x8b3b5675,0xab346f11,0xf1f8ae1e,0x04852193,0x6b8b98c1,0x1ec4d227 }, + { 0x45452baa,0xba3bc926,0xacc4a572,0x387d1858,0xe51f171e,0x9478eff6, + 0x931e1c00,0xf357077d,0xe54c8ca8,0xffee77cd,0x551dc9a4,0xfb4892ff } }, + /* 247 */ + { { 0x2db8dff8,0x5b1bdad0,0x5a2285a2,0xd462f4fd,0xda00b461,0x1d6aad8e, + 0x41306d1b,0x43fbefcf,0x6a13fe19,0x428e86f3,0x17f89404,0xc8b2f118 }, + { 0xf0d51afb,0x762528aa,0x549b1d06,0xa3e2fea4,0xea3ddf66,0x86fad8f2, + 0x4fbdd206,0x0d9ccc4b,0xc189ff5a,0xcde97d4c,0x199f19a6,0xc36793d6 } }, + /* 248 */ + { { 0x51b85197,0xea38909b,0xb4c92895,0xffb17dd0,0x1ddb3f3f,0x0eb0878b, + 0xc57cf0f2,0xb05d28ff,0x1abd57e2,0xd8bde2e7,0xc40c1b20,0x7f2be28d }, + { 0x299a2d48,0x6554dca2,0x8377982d,0x5130ba2e,0x1071971a,0x8863205f, + 0x7cf2825d,0x15ee6282,0x03748f2b,0xd4b6c57f,0x430385a0,0xa9e3f4da } }, + /* 249 */ + { { 0x83fbc9c6,0x33eb7cec,0x4541777e,0x24a311c7,0x4f0767fc,0xc81377f7, + 0x4ab702da,0x12adae36,0x2a779696,0xb7fcb6db,0x01cea6ad,0x4a6fb284 }, + { 0xcdfc73de,0x5e8b1d2a,0x1b02fd32,0xd0efae8d,0xd81d8519,0x3f99c190, + 0xfc808971,0x3c18f7fa,0x51b7ae7b,0x41f713e7,0xf07fc3f8,0x0a4b3435 } }, + /* 250 */ + { { 0x019b7d2e,0x7dda3c4c,0xd4dc4b89,0x631c8d1a,0x1cdb313c,0x5489cd6e, + 0x4c07bb06,0xd44aed10,0x75f000d1,0x8f97e13a,0xdda5df4d,0x0e9ee64f }, + { 0x3e346910,0xeaa99f3b,0xfa294ad7,0x622f6921,0x0d0b2fe9,0x22aaa20d, + 0x1e5881ba,0x4fed2f99,0xc1571802,0x9af3b2d6,0xdc7ee17c,0x919e67a8 } }, + /* 251 */ + { { 0x76250533,0xc724fe4c,0x7d817ef8,0x8a2080e5,0x172c9751,0xa2afb0f4, + 0x17c0702e,0x9b10cdeb,0xc9b7e3e9,0xbf3975e3,0x1cd0cdc5,0x206117df }, + { 0xbe05ebd5,0xfb049e61,0x16c782c0,0xeb0bb55c,0xab7fed09,0x13a331b8, + 0x632863f0,0xf6c58b1d,0x4d3b6195,0x6264ef6e,0x9a53f116,0x92c51b63 } }, + /* 252 */ + { { 0x288b364d,0xa57c7bc8,0x7b41e5c4,0x4a562e08,0x698a9a11,0x699d21c6, + 0xf3f849b9,0xa4ed9581,0x9eb726ba,0xa223eef3,0xcc2884f9,0x13159c23 }, + { 0x3a3f4963,0x73931e58,0x0ada6a81,0x96500389,0x5ab2950b,0x3ee8a1c6, + 0x775fab52,0xeedf4949,0x4f2671b6,0x63d652e1,0x3c4e2f55,0xfed4491c } }, + /* 253 */ + { { 0xf4eb453e,0x335eadc3,0xcadd1a5b,0x5ff74b63,0x5d84a91a,0x6933d0d7, + 0xb49ba337,0x9ca3eeb9,0xc04c15b8,0x1f6facce,0xdc09a7e4,0x4ef19326 }, + { 0x3dca3233,0x53d2d324,0xa2259d4b,0x0ee40590,0x5546f002,0x18c22edb, + 0x09ea6b71,0x92429801,0xb0e91e61,0xaada0add,0x99963c50,0x5fe53ef4 } }, + /* 254 */ + { { 0x90c28c65,0x372dd06b,0x119ce47d,0x1765242c,0x6b22fc82,0xc041fb80, + 0xb0a7ccc1,0x667edf07,0x1261bece,0xc79599e7,0x19cff22a,0xbc69d9ba }, + { 0x13c06819,0x009d77cd,0xe282b79d,0x635a66ae,0x225b1be8,0x4edac4a6, + 0x524008f9,0x57d4f4e4,0xb056af84,0xee299ac5,0x3a0bc386,0xcc38444c } }, + /* 255 */ + { { 0xcd4c2356,0x490643b1,0x750547be,0x740a4851,0xd4944c04,0x643eaf29, + 0x299a98a0,0xba572479,0xee05fdf9,0x48b29f16,0x089b2d7b,0x33fb4f61 }, + { 0xa950f955,0x86704902,0xfedc3ddf,0x97e1034d,0x05fbb6a2,0x211320b6, + 0x432299bb,0x23d7b93f,0x8590e4a3,0x1fe1a057,0xf58c0ce6,0x8e1d0586 } }, +}; + +/* 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. + * 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_12(sp_point_384* r, const sp_digit* k, + int map, void* heap) +{ + return sp_384_ecc_mulmod_stripe_12(r, &p384_base, p384_table, + k, map, heap); +} + +#endif + +/* Multiply the base point of P384 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_384(mp_int* km, ecc_point* r, int map, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 p; + sp_digit kd[12]; +#endif + sp_point_384* point; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_384_point_new_12(heap, p, point); +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 12, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + } +#else + k = kd; +#endif + if (err == MP_OKAY) { + sp_384_from_mp(k, 12, km); + + err = sp_384_ecc_mulmod_base_12(point, k, map, heap); + } + if (err == MP_OKAY) { + err = sp_384_point_to_ecc_point_12(point, r); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + 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. + * Implementation is constant time. + * + * a Number to check. + * returns 1 if the number is zero and 0 otherwise. + */ +static int sp_384_iszero_12(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]) == 0; +} + +#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN || HAVE_ECC_SIGN || HAVE_ECC_VERIFY */ +/* Add 1 to a. (a = a + 1) + * + * a A single precision integer. + */ +static void sp_384_add_one_12(sp_digit* a) +{ + __asm__ __volatile__ ( + "ldr r1, [%[a], #0]\n\t" + "ldr r2, [%[a], #4]\n\t" + "ldr r3, [%[a], #8]\n\t" + "ldr r4, [%[a], #12]\n\t" + "adds r1, r1, #1\n\t" + "adcs r2, r2, #0\n\t" + "adcs r3, r3, #0\n\t" + "adcs r4, r4, #0\n\t" + "str r1, [%[a], #0]\n\t" + "str r2, [%[a], #4]\n\t" + "str r3, [%[a], #8]\n\t" + "str r4, [%[a], #12]\n\t" + "ldr r1, [%[a], #16]\n\t" + "ldr r2, [%[a], #20]\n\t" + "ldr r3, [%[a], #24]\n\t" + "ldr r4, [%[a], #28]\n\t" + "adcs r1, r1, #0\n\t" + "adcs r2, r2, #0\n\t" + "adcs r3, r3, #0\n\t" + "adcs r4, r4, #0\n\t" + "str r1, [%[a], #16]\n\t" + "str r2, [%[a], #20]\n\t" + "str r3, [%[a], #24]\n\t" + "str r4, [%[a], #28]\n\t" + "ldr r1, [%[a], #32]\n\t" + "ldr r2, [%[a], #36]\n\t" + "ldr r3, [%[a], #40]\n\t" + "ldr r4, [%[a], #44]\n\t" + "adcs r1, r1, #0\n\t" + "adcs r2, r2, #0\n\t" + "adcs r3, r3, #0\n\t" + "adcs r4, r4, #0\n\t" + "str r1, [%[a], #32]\n\t" + "str r2, [%[a], #36]\n\t" + "str r3, [%[a], #40]\n\t" + "str r4, [%[a], #44]\n\t" + : + : [a] "r" (a) + : "memory", "r1", "r2", "r3", "r4" + ); +} + +/* 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_384_from_bin(sp_digit* r, int size, const byte* a, int n) +{ + int i, 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; + } +} + +/* Generates a scalar that is in the range 1..order-1. + * + * rng Random number generator. + * k Scalar value. + * returns RNG failures, MEMORY_E when memory allocation fails and + * MP_OKAY on success. + */ +static int sp_384_ecc_gen_k_12(WC_RNG* rng, sp_digit* k) +{ + int err; + byte buf[48]; + + do { + err = wc_RNG_GenerateBlock(rng, buf, sizeof(buf)); + if (err == 0) { + sp_384_from_bin(k, 12, buf, (int)sizeof(buf)); + if (sp_384_cmp_12(k, p384_order2) < 0) { + sp_384_add_one_12(k); + break; + } + } + } + while (err == 0); + + return err; +} + +/* Makes a random EC key pair. + * + * rng Random number generator. + * priv Generated private value. + * pub Generated public point. + * heap Heap to use for allocation. + * returns ECC_INF_E when the point does not have the correct order, RNG + * failures, MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_make_key_384(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 p; + sp_digit kd[12]; +#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN + sp_point_384 inf; +#endif +#endif + sp_point_384* point; + sp_digit* k = NULL; +#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN + sp_point_384* infinity; +#endif + int err; + + (void)heap; + + err = sp_384_point_new_12(heap, p, point); +#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN + if (err == MP_OKAY) { + err = sp_384_point_new_12(heap, inf, infinity); + } +#endif +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 12, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + } +#else + k = kd; +#endif + + if (err == MP_OKAY) { + err = sp_384_ecc_gen_k_12(rng, k); + } + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_base_12(point, k, 1, NULL); + } + +#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_12(infinity, point, p384_order, 1, NULL); + } + if (err == MP_OKAY) { + if ((sp_384_iszero_12(point->x) == 0) || (sp_384_iszero_12(point->y) == 0)) { + err = ECC_INF_E; + } + } +#endif + + if (err == MP_OKAY) { + err = sp_384_to_mp(k, priv); + } + if (err == MP_OKAY) { + err = sp_384_point_to_ecc_point_12(point, pub); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif +#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN + sp_384_point_free_12(infinity, 1, heap); +#endif + sp_384_point_free_12(point, 1, heap); + + return err; +} + +#ifdef HAVE_ECC_DHE +/* Write r as big endian to byte array. + * Fixed length number of bytes written: 48 + * + * r A single precision integer. + * a Byte array. + */ +static void sp_384_to_bin(sp_digit* r, byte* a) +{ + int i, j, s = 0, b; + + j = 384 / 8 - 1; + a[j] = 0; + for (i=0; i<12 && j>=0; i++) { + b = 0; + /* lint allow cast of mismatch sp_digit and int */ + a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ + if (j < 0) { + break; + } + while (b < 32) { + a[j--] = r[i] >> b; b += 8; + if (j < 0) { + break; + } + } + s = 8 - (b - 32); + if (j >= 0) { + a[j] = 0; + } + if (s != 0) { + j++; + } + } +} + +/* Multiply the point by the scalar and serialize the X ordinate. + * The number is 0 padded to maximum size on output. + * + * priv Scalar to multiply the point by. + * pub Point to multiply. + * out Buffer to hold X ordinate. + * outLen On entry, size of the buffer in bytes. + * On exit, length of data in buffer in bytes. + * heap Heap to use for allocation. + * 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, + word32* outLen, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 p; + sp_digit kd[12]; +#endif + sp_point_384* point = NULL; + sp_digit* k = NULL; + int err = MP_OKAY; + + if (*outLen < 48U) { + err = BUFFER_E; + } + + if (err == MP_OKAY) { + err = sp_384_point_new_12(heap, p, point); + } +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 12, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) + err = MEMORY_E; + } +#else + k = kd; +#endif + + if (err == MP_OKAY) { + sp_384_from_mp(k, 12, priv); + sp_384_point_from_ecc_point_12(point, pub); + err = sp_384_ecc_mulmod_12(point, point, k, 1, heap); + } + if (err == MP_OKAY) { + sp_384_to_bin(point->x, out); + *outLen = 48; + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_12(point, 0, heap); + + return err; +} +#endif /* HAVE_ECC_DHE */ + +#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) +#endif +#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) +#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_384_sub_in_place_12(sp_digit* a, const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "mov r14, #0\n\t" + "add r12, %[a], #48\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; +} + +#else +/* Sub b from a into a. (a -= b) + * + * a A single precision integer and result. + * b A single precision integer. + */ +static sp_digit sp_384_sub_in_place_12(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" + "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; +} + +#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_384_mul_d_12(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, #48\n\t" + "blt 1b\n\t" + "str r3, [%[r], #48]\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" + "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" + "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" + "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" + "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" + "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" + "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" + "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" + "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" + "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" + "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" + "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" + "adc r3, r3, r7\n\t" + "str r5, [%[r], #44]\n\t" + "str r3, [%[r], #48]\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_384_word_12(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" + "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_384_mask_12(sp_digit* r, const sp_digit* a, sp_digit m) +{ +#ifdef WOLFSSL_SP_SMALL + int i; + + for (i=0; i<12; 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; + r[8] = a[8] & m; + r[9] = a[9] & m; + r[10] = a[10] & m; + r[11] = a[11] & m; +#endif +} + +/* 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 Nmber 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_384_div_12(const sp_digit* a, const sp_digit* d, sp_digit* m, + sp_digit* r) +{ + sp_digit t1[24], t2[13]; + sp_digit div, r1; + int i; + + (void)m; + + + div = d[11]; + XMEMCPY(t1, a, sizeof(*t1) * 2 * 12); + for (i=11; i>=0; i--) { + r1 = div_384_word_12(t1[12 + i], t1[12 + i - 1], div); + + sp_384_mul_d_12(t2, d, r1); + t1[12 + i] += sp_384_sub_in_place_12(&t1[i], t2); + t1[12 + i] -= t2[12]; + sp_384_mask_12(t2, d, t1[12 + i]); + t1[12 + i] += sp_384_add_12(&t1[i], &t1[i], t2); + sp_384_mask_12(t2, d, t1[12 + i]); + t1[12 + i] += sp_384_add_12(&t1[i], &t1[i], t2); + } + + r1 = sp_384_cmp_12(t1, d) >= 0; + sp_384_cond_sub_12(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_384_mod_12(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + return sp_384_div_12(a, m, NULL, r); +} + +#endif +#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) +#ifdef WOLFSSL_SP_SMALL +/* Order-2 for the P384 curve. */ +static const uint32_t p384_order_minus_2[12] = { + 0xccc52971U,0xecec196aU,0x48b0a77aU,0x581a0db2U,0xf4372ddfU,0xc7634d81U, + 0xffffffffU,0xffffffffU,0xffffffffU,0xffffffffU,0xffffffffU,0xffffffffU +}; +#else +/* 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 */ + +/* Multiply two number mod the order of P384 curve. (r = a * b mod order) + * + * r Result of the multiplication. + * a First operand of the multiplication. + * b Second operand of the multiplication. + */ +static void sp_384_mont_mul_order_12(sp_digit* r, const sp_digit* a, const sp_digit* b) +{ + sp_384_mul_12(r, a, b); + sp_384_mont_reduce_order_12(r, p384_order, p384_mp_order); +} + +/* Square number mod the order of P384 curve. (r = a * a mod order) + * + * r Result of the squaring. + * a Number to square. + */ +static void sp_384_mont_sqr_order_12(sp_digit* r, const sp_digit* a) +{ + sp_384_sqr_12(r, a); + sp_384_mont_reduce_order_12(r, p384_order, p384_mp_order); +} + +#ifndef WOLFSSL_SP_SMALL +/* Square number mod the order of P384 curve a number of times. + * (r = a ^ n mod order) + * + * r Result of the squaring. + * a Number to square. + */ +static void sp_384_mont_sqr_n_order_12(sp_digit* r, const sp_digit* a, int n) +{ + int i; + + sp_384_mont_sqr_order_12(r, a); + for (i=1; i=0; i--) { + sp_384_mont_sqr_order_12(t, t); + if ((p384_order_minus_2[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { + sp_384_mont_mul_order_12(t, t, a); + } + } + XMEMCPY(r, t, sizeof(sp_digit) * 12U); +#else + sp_digit* t = td; + sp_digit* t2 = td + 2 * 12; + sp_digit* t3 = td + 4 * 12; + int i; + + /* t = a^2 */ + sp_384_mont_sqr_order_12(t, a); + /* t = a^3 = t * a */ + sp_384_mont_mul_order_12(t, t, a); + /* t2= a^c = t ^ 2 ^ 2 */ + sp_384_mont_sqr_n_order_12(t2, t, 2); + /* t = a^f = t2 * t */ + sp_384_mont_mul_order_12(t, t2, t); + /* t2= a^f0 = t ^ 2 ^ 4 */ + sp_384_mont_sqr_n_order_12(t2, t, 4); + /* t = a^ff = t2 * t */ + sp_384_mont_mul_order_12(t, t2, t); + /* t2= a^ff00 = t ^ 2 ^ 8 */ + sp_384_mont_sqr_n_order_12(t2, t, 8); + /* t3= a^ffff = t2 * t */ + sp_384_mont_mul_order_12(t3, t2, t); + /* t2= a^ffff0000 = t3 ^ 2 ^ 16 */ + sp_384_mont_sqr_n_order_12(t2, t3, 16); + /* t = a^ffffffff = t2 * t3 */ + sp_384_mont_mul_order_12(t, t2, t3); + /* t2= a^ffffffff0000 = t ^ 2 ^ 16 */ + sp_384_mont_sqr_n_order_12(t2, t, 16); + /* t = a^ffffffffffff = t2 * t3 */ + sp_384_mont_mul_order_12(t, t2, t3); + /* t2= a^ffffffffffff000000000000 = t ^ 2 ^ 48 */ + sp_384_mont_sqr_n_order_12(t2, t, 48); + /* t= a^fffffffffffffffffffffffff = t2 * t */ + sp_384_mont_mul_order_12(t, t2, t); + /* t2= a^ffffffffffffffffffffffff000000000000000000000000 */ + sp_384_mont_sqr_n_order_12(t2, t, 96); + /* t2= a^ffffffffffffffffffffffffffffffffffffffffffffffff = t2 * t */ + 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) { + sp_384_mont_mul_order_12(t2, t2, a); + } + } + sp_384_mont_sqr_order_12(t2, t2); + sp_384_mont_mul_order_12(r, t2, a); +#endif /* WOLFSSL_SP_SMALL */ +} + +#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 + +/* Sign the hash using the private key. + * e = [hash, 384 bits] from binary + * r = (k.G)->x mod order + * s = (r * x + e) / k mod order + * The hash is truncated to the first 384 bits. + * + * hash Hash to sign. + * hashLen Length of the hash data. + * rng Random number generator. + * priv Private part of key - scalar. + * 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. + */ +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) +{ +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_digit* d = NULL; +#else + sp_digit ed[2*12]; + sp_digit xd[2*12]; + sp_digit kd[2*12]; + sp_digit rd[2*12]; + sp_digit td[3 * 2*12]; + sp_point_384 p; +#endif + sp_digit* e = NULL; + sp_digit* x = NULL; + sp_digit* k = NULL; + 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 i; + + (void)heap; + + err = sp_384_point_new_12(heap, p, point); +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7 * 2 * 12, heap, + DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + e = d + 0 * 12; + x = d + 2 * 12; + k = d + 4 * 12; + r = d + 6 * 12; + tmp = d + 8 * 12; +#else + e = ed; + x = xd; + k = kd; + r = rd; + tmp = td; +#endif + s = e; + kInv = k; + + if (hashLen > 48U) { + hashLen = 48U; + } + + sp_384_from_bin(e, 12, hash, (int)hashLen); + } + + 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); + } + else { + sp_384_from_mp(k, 12, km); + mp_zero(km); + } + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_base_12(point, k, 1, NULL); + } + + if (err == MP_OKAY) { + /* r = point->x mod order */ + XMEMCPY(r, point->x, sizeof(sp_digit) * 12U); + sp_384_norm_12(r); + c = sp_384_cmp_12(r, p384_order); + 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); + 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); + + /* Check that signature is usable. */ + if (sp_384_iszero_12(s) == 0) { + break; + } + } + } + + if (i == 0) { + err = RNG_FAILURE_E; + } + + if (err == MP_OKAY) { + err = sp_384_to_mp(r, rm); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(s, sm); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (d != NULL) { + XMEMSET(d, 0, sizeof(sp_digit) * 8 * 12); + XFREE(d, heap, DYNAMIC_TYPE_ECC); + } +#else + XMEMSET(e, 0, sizeof(sp_digit) * 2U * 12U); + 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); + + return err; +} +#endif /* HAVE_ECC_SIGN */ + +#ifdef HAVE_ECC_VERIFY +/* Verify the signature values with the hash and public key. + * e = Truncate(hash, 384) + * u1 = e/s mod order + * u2 = r/s mod order + * r == (u1.G + u2.Q)->x mod order + * Optimization: Leave point in projective form. + * (x, y, 1) == (x' / z'*z', y' / z'*z'*z', z' / z') + * (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' + * The hash is truncated to the first 384 bits. + * + * hash Hash to sign. + * hashLen Length of the hash data. + * rng Random number generator. + * priv Private part of key - scalar. + * 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. + */ +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) +{ +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_digit* d = NULL; +#else + sp_digit u1d[2*12]; + sp_digit u2d[2*12]; + sp_digit sd[2*12]; + sp_digit tmpd[2*12 * 5]; + sp_point_384 p1d; + sp_point_384 p2d; +#endif + sp_digit* u1 = NULL; + sp_digit* u2 = NULL; + sp_digit* s = NULL; + sp_digit* tmp = NULL; + sp_point_384* p1; + sp_point_384* p2 = NULL; + sp_digit carry; + int32_t c; + int err; + + err = sp_384_point_new_12(heap, p1d, p1); + if (err == MP_OKAY) { + err = sp_384_point_new_12(heap, p2d, p2); + } +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 12, heap, + DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + u1 = d + 0 * 12; + u2 = d + 2 * 12; + s = d + 4 * 12; + tmp = d + 6 * 12; +#else + u1 = u1d; + u2 = u2d; + s = sd; + tmp = tmpd; +#endif + + if (hashLen > 48U) { + hashLen = 48U; + } + + sp_384_from_bin(u1, 12, hash, (int)hashLen); + sp_384_from_mp(u2, 12, r); + sp_384_from_mp(s, 12, sm); + sp_384_from_mp(p2->x, 12, pX); + sp_384_from_mp(p2->y, 12, pY); + sp_384_from_mp(p2->z, 12, pZ); + + { + 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); + { + 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); + } + + err = sp_384_ecc_mulmod_base_12(p1, u1, 0, heap); + } + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_12(p2, p2, u2, 0, heap); + } + + 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); + err = sp_384_mod_mul_norm_12(u2, u2, p384_mod); + } + + if (err == MP_OKAY) { + /* u1 = r.z'.z' mod prime */ + sp_384_mont_sqr_12(p1->z, p1->z, p384_mod, p384_mp_mod); + 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) { + /* Reload r and add order. */ + sp_384_from_mp(u2, 12, r); + carry = sp_384_add_12(u2, u2, p384_order); + /* Carry means result is greater than mod and is not valid. */ + if (carry == 0) { + sp_384_norm_12(u2); + + /* 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 defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (d != NULL) + XFREE(d, heap, DYNAMIC_TYPE_ECC); +#endif + sp_384_point_free_12(p1, 0, heap); + sp_384_point_free_12(p2, 0, heap); + + return err; +} +#endif /* HAVE_ECC_VERIFY */ + +#ifdef HAVE_ECC_CHECK_KEY +/* 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_384_ecc_is_point_12(sp_point_384* point, void* heap) +{ +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_digit* d = NULL; +#else + sp_digit t1d[2*12]; + sp_digit t2d[2*12]; +#endif + sp_digit* t1; + sp_digit* t2; + int err = MP_OKAY; + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 12 * 4, heap, DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + t1 = d + 0 * 12; + t2 = d + 2 * 12; +#else + (void)heap; + + t1 = t1d; + t2 = t2d; +#endif + + sp_384_sqr_12(t1, point->y); + (void)sp_384_mod_12(t1, t1, p384_mod); + sp_384_sqr_12(t2, point->x); + (void)sp_384_mod_12(t2, t2, p384_mod); + sp_384_mul_12(t2, t2, point->x); + (void)sp_384_mod_12(t2, t2, p384_mod); + (void)sp_384_sub_12(t2, p384_mod, t2); + sp_384_mont_add_12(t1, t1, t2, p384_mod); + + sp_384_mont_add_12(t1, t1, point->x, p384_mod); + sp_384_mont_add_12(t1, t1, point->x, p384_mod); + sp_384_mont_add_12(t1, t1, point->x, p384_mod); + + if (sp_384_cmp_12(t1, p384_b) != 0) { + err = MP_VAL; + } + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + 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_384(mp_int* pX, mp_int* pY) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 pubd; +#endif + sp_point_384* pub; + byte one[1] = { 1 }; + int err; + + err = sp_384_point_new_12(NULL, pubd, pub); + if (err == MP_OKAY) { + sp_384_from_mp(pub->x, 12, pX); + sp_384_from_mp(pub->y, 12, pY); + sp_384_from_bin(pub->z, 12, one, (int)sizeof(one)); + + err = sp_384_ecc_is_point_12(pub, NULL); + } + + sp_384_point_free_12(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_384(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_digit privd[12]; + sp_point_384 pubd; + sp_point_384 pd; +#endif + sp_digit* priv = NULL; + sp_point_384* pub; + sp_point_384* p = NULL; + byte one[1] = { 1 }; + int err; + + err = sp_384_point_new_12(heap, pubd, pub); + if (err == MP_OKAY) { + err = sp_384_point_new_12(heap, pd, p); + } +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + priv = (sp_digit*)XMALLOC(sizeof(sp_digit) * 12, heap, + DYNAMIC_TYPE_ECC); + if (priv == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if !(defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) + priv = privd; +#endif + + sp_384_from_mp(pub->x, 12, pX); + sp_384_from_mp(pub->y, 12, pY); + sp_384_from_bin(pub->z, 12, one, (int)sizeof(one)); + sp_384_from_mp(priv, 12, privm); + + /* Check point at infinitiy. */ + if ((sp_384_iszero_12(pub->x) != 0) && + (sp_384_iszero_12(pub->y) != 0)) { + err = ECC_INF_E; + } + } + + 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; + } + } + + if (err == MP_OKAY) { + /* Check point is on curve */ + err = sp_384_ecc_is_point_12(pub, heap); + } + + if (err == MP_OKAY) { + /* Point * order = infinity */ + err = sp_384_ecc_mulmod_12(p, pub, p384_order, 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; + } + } + + if (err == MP_OKAY) { + /* Base * private = point */ + err = sp_384_ecc_mulmod_base_12(p, priv, 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; + } + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (priv != NULL) { + XFREE(priv, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_12(p, 0, heap); + sp_384_point_free_12(pub, 0, heap); + + return err; +} +#endif +#ifdef WOLFSSL_PUBLIC_ECC_ADD_DBL +/* Add two projective EC points together. + * (pX, pY, pZ) + (qX, qY, qZ) = (rX, rY, rZ) + * + * pX First EC point's X ordinate. + * pY First EC point's Y ordinate. + * pZ First EC point's Z ordinate. + * qX Second EC point's X ordinate. + * qY Second EC point's Y ordinate. + * qZ Second EC point's Z ordinate. + * rX Resultant EC point's X ordinate. + * rY Resultant EC point's Y ordinate. + * rZ Resultant EC point's Z ordinate. + * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise. + */ +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) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_digit tmpd[2 * 12 * 5]; + sp_point_384 pd; + sp_point_384 qd; +#endif + sp_digit* tmp; + sp_point_384* p; + sp_point_384* q = NULL; + int err; + + err = sp_384_point_new_12(NULL, pd, p); + if (err == MP_OKAY) { + err = sp_384_point_new_12(NULL, qd, q); + } +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 12 * 5, NULL, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) { + err = MEMORY_E; + } + } +#else + tmp = tmpd; +#endif + + if (err == MP_OKAY) { + sp_384_from_mp(p->x, 12, pX); + sp_384_from_mp(p->y, 12, pY); + sp_384_from_mp(p->z, 12, pZ); + sp_384_from_mp(q->x, 12, qX); + sp_384_from_mp(q->y, 12, qY); + sp_384_from_mp(q->z, 12, qZ); + + sp_384_proj_point_add_12(p, p, q, tmp); + } + + if (err == MP_OKAY) { + err = sp_384_to_mp(p->x, rX); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->y, rY); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->z, rZ); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (tmp != NULL) { + XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_12(q, 0, NULL); + sp_384_point_free_12(p, 0, NULL); + + return err; +} + +/* Double a projective EC point. + * (pX, pY, pZ) + (pX, pY, pZ) = (rX, rY, rZ) + * + * pX EC point's X ordinate. + * pY EC point's Y ordinate. + * pZ EC point's Z ordinate. + * rX Resultant EC point's X ordinate. + * rY Resultant EC point's Y ordinate. + * rZ Resultant EC point's Z ordinate. + * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise. + */ +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) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_digit tmpd[2 * 12 * 2]; + sp_point_384 pd; +#endif + sp_digit* tmp; + sp_point_384* p; + int err; + + err = sp_384_point_new_12(NULL, pd, p); +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 12 * 2, NULL, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) { + err = MEMORY_E; + } + } +#else + tmp = tmpd; +#endif + + if (err == MP_OKAY) { + sp_384_from_mp(p->x, 12, pX); + sp_384_from_mp(p->y, 12, pY); + sp_384_from_mp(p->z, 12, pZ); + + sp_384_proj_point_dbl_12(p, p, tmp); + } + + if (err == MP_OKAY) { + err = sp_384_to_mp(p->x, rX); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->y, rY); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->z, rZ); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (tmp != NULL) { + XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_12(p, 0, NULL); + + return err; +} + +/* Map a projective EC point to affine in place. + * pZ will be one. + * + * pX EC point's X ordinate. + * pY EC point's Y ordinate. + * pZ EC point's Z ordinate. + * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise. + */ +int sp_ecc_map_384(mp_int* pX, mp_int* pY, mp_int* pZ) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_digit tmpd[2 * 12 * 6]; + sp_point_384 pd; +#endif + sp_digit* tmp; + sp_point_384* p; + int err; + + err = sp_384_point_new_12(NULL, pd, p); +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 12 * 6, NULL, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) { + err = MEMORY_E; + } + } +#else + tmp = tmpd; +#endif + if (err == MP_OKAY) { + sp_384_from_mp(p->x, 12, pX); + sp_384_from_mp(p->y, 12, pY); + sp_384_from_mp(p->z, 12, pZ); + + sp_384_map_12(p, p, tmp); + } + + if (err == MP_OKAY) { + err = sp_384_to_mp(p->x, pX); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->y, pY); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->z, pZ); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (tmp != NULL) { + XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_12(p, 0, NULL); + + return err; +} +#endif /* WOLFSSL_PUBLIC_ECC_ADD_DBL */ +#ifdef HAVE_COMP_KEY +/* Find the square root of a number mod the prime of the curve. + * + * y The number to operate on and the result. + * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise. + */ +static int sp_384_mont_sqrt_12(sp_digit* y) +{ +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_digit* d; +#else + sp_digit t1d[2 * 12]; + sp_digit t2d[2 * 12]; + sp_digit t3d[2 * 12]; + sp_digit t4d[2 * 12]; + sp_digit t5d[2 * 12]; +#endif + sp_digit* t1; + sp_digit* t2; + sp_digit* t3; + sp_digit* t4; + sp_digit* t5; + int err = MP_OKAY; + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 5 * 2 * 12, NULL, DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + t1 = d + 0 * 12; + t2 = d + 2 * 12; + t3 = d + 4 * 12; + t4 = d + 6 * 12; + t5 = d + 8 * 12; +#else + t1 = t1d; + t2 = t2d; + t3 = t3d; + t4 = t4d; + t5 = t5d; +#endif + + { + /* t2 = y ^ 0x2 */ + sp_384_mont_sqr_12(t2, y, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x3 */ + sp_384_mont_mul_12(t1, t2, y, p384_mod, p384_mp_mod); + /* t5 = y ^ 0xc */ + sp_384_mont_sqr_n_12(t5, t1, 2, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xf */ + sp_384_mont_mul_12(t1, t1, t5, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x1e */ + sp_384_mont_sqr_12(t2, t1, p384_mod, p384_mp_mod); + /* t3 = y ^ 0x1f */ + sp_384_mont_mul_12(t3, t2, y, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3e0 */ + sp_384_mont_sqr_n_12(t2, t3, 5, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x3ff */ + sp_384_mont_mul_12(t1, t3, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x7fe0 */ + sp_384_mont_sqr_n_12(t2, t1, 5, p384_mod, p384_mp_mod); + /* t3 = y ^ 0x7fff */ + sp_384_mont_mul_12(t3, t3, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3fff800 */ + sp_384_mont_sqr_n_12(t2, t3, 15, p384_mod, p384_mp_mod); + /* t4 = y ^ 0x3ffffff */ + sp_384_mont_mul_12(t4, t3, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0xffffffc000000 */ + sp_384_mont_sqr_n_12(t2, t4, 30, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xfffffffffffff */ + sp_384_mont_mul_12(t1, t4, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0xfffffffffffffff000000000000000 */ + sp_384_mont_sqr_n_12(t2, t1, 60, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xffffffffffffffffffffffffffffff */ + sp_384_mont_mul_12(t1, t1, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0xffffffffffffffffffffffffffffff000000000000000000000000000000 */ + sp_384_mont_sqr_n_12(t2, t1, 120, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */ + sp_384_mont_mul_12(t1, t1, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000 */ + sp_384_mont_sqr_n_12(t2, t1, 15, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */ + sp_384_mont_mul_12(t1, t3, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000 */ + sp_384_mont_sqr_n_12(t2, t1, 31, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffff */ + sp_384_mont_mul_12(t1, t4, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffff0 */ + sp_384_mont_sqr_n_12(t2, t1, 4, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffc */ + sp_384_mont_mul_12(t1, t5, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000 */ + sp_384_mont_sqr_n_12(t2, t1, 62, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000001 */ + sp_384_mont_mul_12(t1, y, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffc00000000000000040000000 */ + sp_384_mont_sqr_n_12(y, t1, 30, p384_mod, p384_mp_mod); + } + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (d != NULL) { + XFREE(d, NULL, DYNAMIC_TYPE_ECC); + } +#endif + + return err; +} + + +/* Uncompress the point given the X ordinate. + * + * xm X ordinate. + * odd Whether the Y ordinate is odd. + * ym Calculated Y ordinate. + * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise. + */ +int sp_ecc_uncompress_384(mp_int* xm, int odd, mp_int* ym) +{ +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_digit* d; +#else + sp_digit xd[2 * 12]; + sp_digit yd[2 * 12]; +#endif + sp_digit* x = NULL; + sp_digit* y = NULL; + int err = MP_OKAY; + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4 * 12, NULL, DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + x = d + 0 * 12; + y = d + 2 * 12; +#else + x = xd; + y = yd; +#endif + + sp_384_from_mp(x, 12, xm); + err = sp_384_mod_mul_norm_12(x, x, p384_mod); + } + if (err == MP_OKAY) { + /* y = x^3 */ + { + sp_384_mont_sqr_12(y, x, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(y, y, x, p384_mod, p384_mp_mod); + } + /* y = x^3 - 3x */ + sp_384_mont_sub_12(y, y, x, p384_mod); + sp_384_mont_sub_12(y, y, x, p384_mod); + sp_384_mont_sub_12(y, y, x, p384_mod); + /* y = x^3 - 3x + b */ + err = sp_384_mod_mul_norm_12(x, p384_b, p384_mod); + } + if (err == MP_OKAY) { + sp_384_mont_add_12(y, y, x, p384_mod); + /* y = sqrt(x^3 - 3x + b) */ + err = sp_384_mont_sqrt_12(y); + } + if (err == MP_OKAY) { + XMEMSET(y + 12, 0, 12U * sizeof(sp_digit)); + sp_384_mont_reduce_12(y, p384_mod, p384_mp_mod); + if ((((word32)y[0] ^ (word32)odd) & 1U) != 0U) { + sp_384_mont_sub_12(y, p384_mod, y, p384_mod); + } + + err = sp_384_to_mp(y, ym); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (d != NULL) { + XFREE(d, NULL, DYNAMIC_TYPE_ECC); + } +#endif + + return err; +} +#endif +#endif /* WOLFSSL_SP_384 */ #endif /* WOLFSSL_HAVE_SP_ECC */ #endif /* WOLFSSL_SP_ARM32_ASM */ #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 be9fab2e2..5f9704332 100644 --- a/wolfcrypt/src/sp_arm64.c +++ b/wolfcrypt/src/sp_arm64.c @@ -1929,7 +1929,7 @@ static void sp_2048_mul_d_32(sp_digit* r, const sp_digit* a, "str x3, [%[r], 256]\n\t" : : [r] "r" (r), [a] "r" (a), [b] "r" (b) - : "memory", "x3", "x4", "x5", "x6", "x7", "x8" + : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9" ); #else __asm__ __volatile__ ( @@ -2219,7 +2219,7 @@ static void sp_2048_mul_d_32(sp_digit* r, const sp_digit* a, "str x5, [%[r], 256]\n\t" : : [r] "r" (r), [a] "r" (a), [b] "r" (b) - : "memory", "x3", "x4", "x5", "x6", "x7", "x8" + : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9" ); #endif } @@ -2613,7 +2613,7 @@ static void sp_2048_mul_d_16(sp_digit* r, const sp_digit* a, "str x3, [%[r], 128]\n\t" : : [r] "r" (r), [a] "r" (a), [b] "r" (b) - : "memory", "x3", "x4", "x5", "x6", "x7", "x8" + : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9" ); #else __asm__ __volatile__ ( @@ -2759,7 +2759,7 @@ static void sp_2048_mul_d_16(sp_digit* r, const sp_digit* a, "str x4, [%[r], 128]\n\t" : : [r] "r" (r), [a] "r" (a), [b] "r" (b) - : "memory", "x3", "x4", "x5", "x6", "x7", "x8" + : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9" ); #endif } @@ -8605,7 +8605,7 @@ static void sp_3072_mul_d_48(sp_digit* r, const sp_digit* a, "str x3, [%[r], 384]\n\t" : : [r] "r" (r), [a] "r" (a), [b] "r" (b) - : "memory", "x3", "x4", "x5", "x6", "x7", "x8" + : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9" ); #else __asm__ __volatile__ ( @@ -9039,7 +9039,7 @@ static void sp_3072_mul_d_48(sp_digit* r, const sp_digit* a, "str x3, [%[r], 384]\n\t" : : [r] "r" (r), [a] "r" (a), [b] "r" (b) - : "memory", "x3", "x4", "x5", "x6", "x7", "x8" + : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9" ); #endif } @@ -9553,7 +9553,7 @@ static void sp_3072_mul_d_24(sp_digit* r, const sp_digit* a, "str x3, [%[r], 192]\n\t" : : [r] "r" (r), [a] "r" (a), [b] "r" (b) - : "memory", "x3", "x4", "x5", "x6", "x7", "x8" + : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9" ); #else __asm__ __volatile__ ( @@ -9771,7 +9771,7 @@ static void sp_3072_mul_d_24(sp_digit* r, const sp_digit* a, "str x3, [%[r], 192]\n\t" : : [r] "r" (r), [a] "r" (a), [b] "r" (b) - : "memory", "x3", "x4", "x5", "x6", "x7", "x8" + : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9" ); #endif } @@ -26852,7 +26852,7 @@ static void sp_4096_mul_d_64(sp_digit* r, const sp_digit* a, "str x3, [%[r], 512]\n\t" : : [r] "r" (r), [a] "r" (a), [b] "r" (b) - : "memory", "x3", "x4", "x5", "x6", "x7", "x8" + : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9" ); #else __asm__ __volatile__ ( @@ -27430,7 +27430,7 @@ static void sp_4096_mul_d_64(sp_digit* r, const sp_digit* a, "str x4, [%[r], 512]\n\t" : : [r] "r" (r), [a] "r" (a), [b] "r" (b) - : "memory", "x3", "x4", "x5", "x6", "x7", "x8" + : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9" ); #endif } @@ -30498,12 +30498,12 @@ int sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen, #ifndef WOLFSSL_SP_NO_256 /* Point structure to use. */ -typedef struct sp_point { +typedef struct sp_point_256 { sp_digit x[2 * 4]; sp_digit y[2 * 4]; sp_digit z[2 * 4]; int infinity; -} sp_point; +} sp_point_256; /* The modulus (prime) of the curve P256. */ static const sp_digit p256_mod[4] = { @@ -30543,21 +30543,24 @@ static const sp_digit p256_mp_order = 0xccd1c8aaee00bc4fL; #endif #ifdef WOLFSSL_SP_SMALL /* The base point of curve P256. */ -static const sp_point p256_base = { +static const sp_point_256 p256_base = { /* X ordinate */ { 0xf4a13945d898c296L,0x77037d812deb33a0L,0xf8bce6e563a440f2L, - 0x6b17d1f2e12c4247L, 0L, 0L, 0L, 0L + 0x6b17d1f2e12c4247L, + 0L, 0L, 0L, 0L }, /* Y ordinate */ { 0xcbb6406837bf51f5L,0x2bce33576b315eceL,0x8ee7eb4a7c0f9e16L, - 0x4fe342e2fe1a7f9bL, 0L, 0L, 0L, 0L + 0x4fe342e2fe1a7f9bL, + 0L, 0L, 0L, 0L }, /* Z ordinate */ { 0x0000000000000001L,0x0000000000000000L,0x0000000000000000L, - 0x0000000000000000L, 0L, 0L, 0L, 0L + 0x0000000000000000L, + 0L, 0L, 0L, 0L }, /* infinity */ 0 @@ -30570,34 +30573,32 @@ static const sp_digit p256_b[4] = { }; #endif -static int sp_ecc_point_new_ex(void* heap, sp_point* sp, sp_point** p) +static int sp_256_point_new_ex_4(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) + (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; } - else { - #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - *p = (sp_point*)XMALLOC(sizeof(sp_point), heap, DYNAMIC_TYPE_ECC); - (void)sp; - #else - *p = sp; - (void)heap; - #endif - } return ret; } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) /* Allocate memory for point and return error. */ -#define sp_ecc_point_new(heap, sp, p) sp_ecc_point_new_ex((heap), NULL, &(p)) +#define sp_256_point_new_4(heap, sp, p) sp_256_point_new_ex_4((heap), NULL, &(p)) #else /* Set pointer to data and return no error. */ -#define sp_ecc_point_new(heap, sp, p) sp_ecc_point_new_ex((heap), &(sp), &(p)) +#define sp_256_point_new_4(heap, sp, p) sp_256_point_new_ex_4((heap), &(sp), &(p)) #endif -static void sp_ecc_point_free(sp_point* p, int clear, void* heap) +static void sp_256_point_free_4(sp_point_256* p, int clear, void* heap) { #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) /* If valid pointer then clear point data if requested and free data. */ @@ -30765,12 +30766,12 @@ static void sp_256_from_mp(sp_digit* r, int size, const mp_int* a) #endif } -/* Convert a point of type ecc_point to type sp_point. +/* Convert a point of type ecc_point to type sp_point_256. * - * p Point of type sp_point (result). + * 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* 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)); @@ -30845,14 +30846,14 @@ static int sp_256_to_mp(const sp_digit* a, mp_int* r) return err; } -/* Convert a point of type sp_point to type ecc_point. +/* Convert a point of type sp_point_256 to type ecc_point. * - * p Point of type sp_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_4(const sp_point* p, ecc_point* pm) +static int sp_256_point_to_ecc_point_4(const sp_point_256* p, ecc_point* pm) { int err; @@ -30901,259 +30902,6 @@ static void sp_256_cond_copy_4(sp_digit* r, const sp_digit* a, sp_digit m) ); } -/* 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_256_cmp_4(const sp_digit* a, const sp_digit* b) -{ - sp_digit r = -1; - sp_digit one = 1; - -#ifdef WOLFSSL_SP_SMALL - __asm__ __volatile__ ( - "mov x3, -1\n\t" - "mov x6, 24\n\t" - "1:\n\t" - "ldr x4, [%[a], x6]\n\t" - "ldr x5, [%[b], x6]\n\t" - "and x4, x4, x3\n\t" - "and x5, x5, x3\n\t" - "subs x4, x4, x5\n\t" - "csel %[r], %[one], %[r], hi\n\t" - "csel %[r], x3, %[r], lo\n\t" - "csel x3, x3, xzr, eq\n\t" - "subs x6, x6, #8\n\t" - "b.cs 1b\n\t" - "eor %[r], %[r], x3\n\t" - : [r] "+r" (r) - : [a] "r" (a), [b] "r" (b), [one] "r" (one) - : "x2", "x3", "x4", "x5", "x6" - ); -#else - __asm__ __volatile__ ( - "mov x3, -1\n\t" - "ldr x4, [%[a], 24]\n\t" - "ldr x5, [%[b], 24]\n\t" - "and x4, x4, x3\n\t" - "and x5, x5, x3\n\t" - "subs x4, x4, x5\n\t" - "csel %[r], %[one], %[r], hi\n\t" - "csel %[r], x3, %[r], lo\n\t" - "csel x3, x3, xzr, eq\n\t" - "ldr x4, [%[a], 16]\n\t" - "ldr x5, [%[b], 16]\n\t" - "and x4, x4, x3\n\t" - "and x5, x5, x3\n\t" - "subs x4, x4, x5\n\t" - "csel %[r], %[one], %[r], hi\n\t" - "csel %[r], x3, %[r], lo\n\t" - "csel x3, x3, xzr, eq\n\t" - "ldr x4, [%[a], 8]\n\t" - "ldr x5, [%[b], 8]\n\t" - "and x4, x4, x3\n\t" - "and x5, x5, x3\n\t" - "subs x4, x4, x5\n\t" - "csel %[r], %[one], %[r], hi\n\t" - "csel %[r], x3, %[r], lo\n\t" - "csel x3, x3, xzr, eq\n\t" - "ldr x4, [%[a], 0]\n\t" - "ldr x5, [%[b], 0]\n\t" - "and x4, x4, x3\n\t" - "and x5, x5, x3\n\t" - "subs x4, x4, x5\n\t" - "csel %[r], %[one], %[r], hi\n\t" - "csel %[r], x3, %[r], lo\n\t" - "csel x3, x3, xzr, eq\n\t" - "eor %[r], %[r], x3\n\t" - : [r] "+r" (r) - : [a] "r" (a), [b] "r" (b), [one] "r" (one) - : "x2", "x3", "x4", "x5", "x6" - ); -#endif - - return r; -} - -/* Normalize the values in each word to 64. - * - * a Array of sp_digit to normalize. - */ -#define sp_256_norm_4(a) - -/* 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_256_cond_sub_4(sp_digit* r, const sp_digit* a, const sp_digit* b, - sp_digit m) -{ - sp_digit c = 0; - - __asm__ __volatile__ ( - - "ldr x4, [%[a], 0]\n\t" - "ldr x6, [%[a], 8]\n\t" - "ldr x5, [%[b], 0]\n\t" - "ldr x7, [%[b], 8]\n\t" - "and x5, x5, %[m]\n\t" - "and x7, x7, %[m]\n\t" - "subs x4, x4, x5\n\t" - "sbcs x6, x6, x7\n\t" - "str x4, [%[r], 0]\n\t" - "str x6, [%[r], 8]\n\t" - "ldr x4, [%[a], 16]\n\t" - "ldr x6, [%[a], 24]\n\t" - "ldr x5, [%[b], 16]\n\t" - "ldr x7, [%[b], 24]\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" - "str x4, [%[r], 16]\n\t" - "str x6, [%[r], 24]\n\t" - "csetm %[c], cc\n\t" - : [c] "+r" (c) - : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) - : "memory", "x4", "x6", "x5", "x7", "x8" - ); - - 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. - */ -static sp_digit sp_256_sub_4(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - sp_digit c = 0; - - __asm__ __volatile__ ( - "ldp x3, x4, [%[a], 0]\n\t" - "ldp x5, x6, [%[a], 16]\n\t" - "ldp x7, x8, [%[b], 0]\n\t" - "ldp x9, x10, [%[b], 16]\n\t" - "subs x3, x3, x7\n\t" - "sbcs x4, x4, x8\n\t" - "sbcs x5, x5, x9\n\t" - "sbcs x6, x6, x10\n\t" - "stp x3, x4, [%[r], 0]\n\t" - "stp x5, x6, [%[r], 16]\n\t" - "csetm %[c], cc\n\t" - : [c] "+r" (c) - : [r] "r" (r), [a] "r" (a), [b] "r" (b) - : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10" - ); - - return c; -} - -#define sp_256_mont_reduce_order_4 sp_256_mont_reduce_4 - -/* 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. - */ -SP_NOINLINE static void sp_256_mont_reduce_4(sp_digit* a, const sp_digit* m, - sp_digit mp) -{ - __asm__ __volatile__ ( - "# i = 0\n\t" - "mov x9, xzr\n\t" - "mov x8, xzr\n\t" - "mov x6, %[a]\n\t" - "\n1:\n\t" - "# mu = a[i] * mp\n\t" - "ldr x5, [x6, 0]\n\t" - "mov x7, x5\n\t" - "mul x5, %[mp], x5\n\t" - "# a[i+0] += m[0] * mu\n\t" - "ldr x4, [%[m], 0]\n\t" - "ldr x11, [%[m], 8]\n\t" - "mul x3, x4, x5\n\t" - "umulh x10, x4, x5\n\t" - "adds x7, x7, x3\n\t" - "str x7, [x6, 0]\n\t" - "adc x10, x10, xzr\n\t" - "# a[i+1] += m[1] * mu\n\t" - "mul x3, x11, x5\n\t" - "umulh x12, x11, x5\n\t" - "ldr x11, [%[m], 16]\n\t" - "ldr x7, [x6, 8]\n\t" - "adds x3, x3, x10\n\t" - "adc x12, x12, xzr\n\t" - "adds x7, x7, x3\n\t" - "str x7, [x6, 8]\n\t" - "adc x12, x12, xzr\n\t" - "# a[i+2] += m[2] * mu\n\t" - "mul x3, x11, x5\n\t" - "umulh x10, x11, x5\n\t" - "ldr x11, [%[m], 24]\n\t" - "ldr x7, [x6, 16]\n\t" - "adds x3, x3, x12\n\t" - "adc x10, x10, xzr\n\t" - "adds x7, x7, x3\n\t" - "str x7, [x6, 16]\n\t" - "adc x10, x10, xzr\n\t" - "# a[i+3] += m[3] * mu\n\t" - "mul x3, x11, x5\n\t" - "umulh x4, x11, x5\n\t" - "ldr x7, [x6, 24]\n\t" - "ldr x12, [x6, 32]\n\t" - "adds x3, x3, x10\n\t" - "adcs x4, x4, x9\n\t" - "cset x9, cs\n\t" - "adds x7, x7, x3\n\t" - "str x7, [x6, 24]\n\t" - "adcs x12, x12, x4\n\t" - "str x12, [x6, 32]\n\t" - "adc x9, x9, xzr\n\t" - "# i += 1\n\t" - "add x6, x6, 8\n\t" - "add x8, x8, 8\n\t" - "cmp x8, 32\n\t" - "b.lt 1b\n\t" - "ldr x5, [%[a], 32]\n\t" - "ldr x6, [%[a], 40]\n\t" - "ldr x7, [%[a], 48]\n\t" - "ldr x8, [%[a], 56]\n\t" - "sub x3, xzr, x9\n\t" - "ldr x9, [%[m], 0]\n\t" - "ldr x10, [%[m], 8]\n\t" - "ldr x11, [%[m], 16]\n\t" - "ldr x12, [%[m], 24]\n\t" - "and x9, x9, x3\n\t" - "and x10, x10, x3\n\t" - "and x11, x11, x3\n\t" - "and x12, x12, x3\n\t" - "subs x5, x5, x9\n\t" - "sbcs x6, x6, x10\n\t" - "sbcs x7, x7, x11\n\t" - "sbc x8, x8, x12\n\t" - "str x5, [%[a], 0]\n\t" - "str x6, [%[a], 8]\n\t" - "str x7, [%[a], 16]\n\t" - "str x8, [%[a], 24]\n\t" - : - : [a] "r" (a), [m] "r" (m), [mp] "r" (mp) - : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", - "x12" - ); -} - /* Multiply two Montogmery form numbers mod the modulus (prime). * (r = a * b mod m) * @@ -31540,7 +31288,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 */ #ifdef WOLFSSL_SP_SMALL /* Mod-2 for the P256 curve. */ -static const uint64_t p256_mod_2[4] = { +static const uint64_t p256_mod_minus_2[4] = { 0xfffffffffffffffdU,0x00000000ffffffffU,0x0000000000000000U, 0xffffffff00000001U }; @@ -31562,71 +31310,319 @@ static void sp_256_mont_inv_4(sp_digit* r, const sp_digit* a, sp_digit* td) XMEMCPY(t, a, sizeof(sp_digit) * 4); for (i=254; i>=0; i--) { sp_256_mont_sqr_4(t, t, p256_mod, p256_mp_mod); - if (p256_mod_2[i / 64] & ((sp_digit)1 << (i % 64))) + if (p256_mod_minus_2[i / 64] & ((sp_digit)1 << (i % 64))) sp_256_mont_mul_4(t, t, a, p256_mod, p256_mp_mod); } XMEMCPY(r, t, sizeof(sp_digit) * 4); #else - sp_digit* t = td; + sp_digit* t1 = td; sp_digit* t2 = td + 2 * 4; sp_digit* t3 = td + 4 * 4; - - /* t = a^2 */ - sp_256_mont_sqr_4(t, a, p256_mod, p256_mp_mod); - /* t = a^3 = t * a */ - sp_256_mont_mul_4(t, t, a, p256_mod, p256_mp_mod); - /* t2= a^c = t ^ 2 ^ 2 */ - sp_256_mont_sqr_n_4(t2, t, 2, p256_mod, p256_mp_mod); - /* t3= a^d = t2 * a */ - sp_256_mont_mul_4(t3, t2, a, p256_mod, p256_mp_mod); - /* t = a^f = t2 * t */ - sp_256_mont_mul_4(t, t2, t, p256_mod, p256_mp_mod); - /* t2= a^f0 = t ^ 2 ^ 4 */ - sp_256_mont_sqr_n_4(t2, t, 4, p256_mod, p256_mp_mod); - /* t3= a^fd = t2 * t3 */ - sp_256_mont_mul_4(t3, t2, t3, p256_mod, p256_mp_mod); - /* t = a^ff = t2 * t */ - sp_256_mont_mul_4(t, t2, t, p256_mod, p256_mp_mod); - /* t2= a^ff00 = t ^ 2 ^ 8 */ - sp_256_mont_sqr_n_4(t2, t, 8, p256_mod, p256_mp_mod); - /* t3= a^fffd = t2 * t3 */ - sp_256_mont_mul_4(t3, t2, t3, p256_mod, p256_mp_mod); - /* t = a^ffff = t2 * t */ - sp_256_mont_mul_4(t, t2, t, p256_mod, p256_mp_mod); - /* t2= a^ffff0000 = t ^ 2 ^ 16 */ - sp_256_mont_sqr_n_4(t2, t, 16, p256_mod, p256_mp_mod); - /* t3= a^fffffffd = t2 * t3 */ - sp_256_mont_mul_4(t3, t2, t3, p256_mod, p256_mp_mod); - /* t = a^ffffffff = t2 * t */ - sp_256_mont_mul_4(t, t2, t, p256_mod, p256_mp_mod); - /* t = a^ffffffff00000000 = t ^ 2 ^ 32 */ - sp_256_mont_sqr_n_4(t2, t, 32, p256_mod, p256_mp_mod); - /* t2= a^ffffffffffffffff = t2 * t */ - sp_256_mont_mul_4(t, t2, t, p256_mod, p256_mp_mod); - /* t2= a^ffffffff00000001 = t2 * a */ - sp_256_mont_mul_4(t2, t2, a, p256_mod, p256_mp_mod); - /* t2= a^ffffffff000000010000000000000000000000000000000000000000 - * = t2 ^ 2 ^ 160 */ - sp_256_mont_sqr_n_4(t2, t2, 160, p256_mod, p256_mp_mod); - /* t2= a^ffffffff00000001000000000000000000000000ffffffffffffffff - * = t2 * t */ - sp_256_mont_mul_4(t2, t2, t, p256_mod, p256_mp_mod); - /* t2= a^ffffffff00000001000000000000000000000000ffffffffffffffff00000000 - * = t2 ^ 2 ^ 32 */ - sp_256_mont_sqr_n_4(t2, t2, 32, p256_mod, p256_mp_mod); - /* r = a^ffffffff00000001000000000000000000000000fffffffffffffffffffffffd - * = t2 * t3 */ - sp_256_mont_mul_4(r, t2, t3, p256_mod, p256_mp_mod); + /* 0x2 */ + sp_256_mont_sqr_4(t1, a, p256_mod, p256_mp_mod); + /* 0x3 */ + sp_256_mont_mul_4(t2, t1, a, p256_mod, p256_mp_mod); + /* 0xc */ + sp_256_mont_sqr_n_4(t1, t2, 2, p256_mod, p256_mp_mod); + /* 0xd */ + sp_256_mont_mul_4(t3, t1, a, p256_mod, p256_mp_mod); + /* 0xf */ + sp_256_mont_mul_4(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xf0 */ + sp_256_mont_sqr_n_4(t1, t2, 4, p256_mod, p256_mp_mod); + /* 0xfd */ + sp_256_mont_mul_4(t3, t3, t1, p256_mod, p256_mp_mod); + /* 0xff */ + sp_256_mont_mul_4(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xff00 */ + sp_256_mont_sqr_n_4(t1, t2, 8, p256_mod, p256_mp_mod); + /* 0xfffd */ + sp_256_mont_mul_4(t3, t3, t1, p256_mod, p256_mp_mod); + /* 0xffff */ + sp_256_mont_mul_4(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xffff0000 */ + sp_256_mont_sqr_n_4(t1, t2, 16, p256_mod, p256_mp_mod); + /* 0xfffffffd */ + sp_256_mont_mul_4(t3, t3, t1, p256_mod, p256_mp_mod); + /* 0xffffffff */ + sp_256_mont_mul_4(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xffffffff00000000 */ + sp_256_mont_sqr_n_4(t1, t2, 32, p256_mod, p256_mp_mod); + /* 0xffffffffffffffff */ + sp_256_mont_mul_4(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xffffffff00000001 */ + sp_256_mont_mul_4(r, t1, a, p256_mod, p256_mp_mod); + /* 0xffffffff000000010000000000000000000000000000000000000000 */ + sp_256_mont_sqr_n_4(r, r, 160, p256_mod, p256_mp_mod); + /* 0xffffffff00000001000000000000000000000000ffffffffffffffff */ + sp_256_mont_mul_4(r, r, t2, p256_mod, p256_mp_mod); + /* 0xffffffff00000001000000000000000000000000ffffffffffffffff00000000 */ + sp_256_mont_sqr_n_4(r, r, 32, p256_mod, p256_mp_mod); + /* 0xffffffff00000001000000000000000000000000fffffffffffffffffffffffd */ + sp_256_mont_mul_4(r, r, t3, p256_mod, p256_mp_mod); #endif /* WOLFSSL_SP_SMALL */ } +/* 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_256_cmp_4(const sp_digit* a, const sp_digit* b) +{ + sp_digit r = -1; + sp_digit one = 1; + +#ifdef WOLFSSL_SP_SMALL + __asm__ __volatile__ ( + "mov x3, -1\n\t" + "mov x6, 24\n\t" + "1:\n\t" + "ldr x4, [%[a], x6]\n\t" + "ldr x5, [%[b], x6]\n\t" + "and x4, x4, x3\n\t" + "and x5, x5, x3\n\t" + "subs x4, x4, x5\n\t" + "csel %[r], %[one], %[r], hi\n\t" + "csel %[r], x3, %[r], lo\n\t" + "csel x3, x3, xzr, eq\n\t" + "subs x6, x6, #8\n\t" + "b.cs 1b\n\t" + "eor %[r], %[r], x3\n\t" + : [r] "+r" (r) + : [a] "r" (a), [b] "r" (b), [one] "r" (one) + : "x2", "x3", "x4", "x5", "x6" + ); +#else + __asm__ __volatile__ ( + "mov x3, -1\n\t" + "ldr x4, [%[a], 24]\n\t" + "ldr x5, [%[b], 24]\n\t" + "and x4, x4, x3\n\t" + "and x5, x5, x3\n\t" + "subs x4, x4, x5\n\t" + "csel %[r], %[one], %[r], hi\n\t" + "csel %[r], x3, %[r], lo\n\t" + "csel x3, x3, xzr, eq\n\t" + "ldr x4, [%[a], 16]\n\t" + "ldr x5, [%[b], 16]\n\t" + "and x4, x4, x3\n\t" + "and x5, x5, x3\n\t" + "subs x4, x4, x5\n\t" + "csel %[r], %[one], %[r], hi\n\t" + "csel %[r], x3, %[r], lo\n\t" + "csel x3, x3, xzr, eq\n\t" + "ldr x4, [%[a], 8]\n\t" + "ldr x5, [%[b], 8]\n\t" + "and x4, x4, x3\n\t" + "and x5, x5, x3\n\t" + "subs x4, x4, x5\n\t" + "csel %[r], %[one], %[r], hi\n\t" + "csel %[r], x3, %[r], lo\n\t" + "csel x3, x3, xzr, eq\n\t" + "ldr x4, [%[a], 0]\n\t" + "ldr x5, [%[b], 0]\n\t" + "and x4, x4, x3\n\t" + "and x5, x5, x3\n\t" + "subs x4, x4, x5\n\t" + "csel %[r], %[one], %[r], hi\n\t" + "csel %[r], x3, %[r], lo\n\t" + "csel x3, x3, xzr, eq\n\t" + "eor %[r], %[r], x3\n\t" + : [r] "+r" (r) + : [a] "r" (a), [b] "r" (b), [one] "r" (one) + : "x2", "x3", "x4", "x5", "x6" + ); +#endif + + return r; +} + +/* Normalize the values in each word to 64. + * + * a Array of sp_digit to normalize. + */ +#define sp_256_norm_4(a) + +/* 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_256_cond_sub_4(sp_digit* r, const sp_digit* a, const sp_digit* b, + sp_digit m) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + + "ldr x4, [%[a], 0]\n\t" + "ldr x6, [%[a], 8]\n\t" + "ldr x5, [%[b], 0]\n\t" + "ldr x7, [%[b], 8]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "subs x4, x4, x5\n\t" + "sbcs x6, x6, x7\n\t" + "str x4, [%[r], 0]\n\t" + "str x6, [%[r], 8]\n\t" + "ldr x4, [%[a], 16]\n\t" + "ldr x6, [%[a], 24]\n\t" + "ldr x5, [%[b], 16]\n\t" + "ldr x7, [%[b], 24]\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" + "str x4, [%[r], 16]\n\t" + "str x6, [%[r], 24]\n\t" + "csetm %[c], cc\n\t" + : [c] "+r" (c) + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) + : "memory", "x4", "x6", "x5", "x7", "x8" + ); + + 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. + */ +static sp_digit sp_256_sub_4(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "ldp x3, x4, [%[a], 0]\n\t" + "ldp x5, x6, [%[a], 16]\n\t" + "ldp x7, x8, [%[b], 0]\n\t" + "ldp x9, x10, [%[b], 16]\n\t" + "subs x3, x3, x7\n\t" + "sbcs x4, x4, x8\n\t" + "sbcs x5, x5, x9\n\t" + "sbcs x6, x6, x10\n\t" + "stp x3, x4, [%[r], 0]\n\t" + "stp x5, x6, [%[r], 16]\n\t" + "csetm %[c], cc\n\t" + : [c] "+r" (c) + : [r] "r" (r), [a] "r" (a), [b] "r" (b) + : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10" + ); + + return c; +} + +#define sp_256_mont_reduce_order_4 sp_256_mont_reduce_4 + +/* 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. + */ +SP_NOINLINE static void sp_256_mont_reduce_4(sp_digit* a, const sp_digit* m, + sp_digit mp) +{ + __asm__ __volatile__ ( + "# i = 0\n\t" + "mov x9, xzr\n\t" + "mov x8, xzr\n\t" + "mov x6, %[a]\n\t" + "\n1:\n\t" + "# mu = a[i] * mp\n\t" + "ldr x5, [x6, 0]\n\t" + "mov x7, x5\n\t" + "mul x5, %[mp], x5\n\t" + "# a[i+0] += m[0] * mu\n\t" + "ldr x4, [%[m], 0]\n\t" + "ldr x11, [%[m], 8]\n\t" + "mul x3, x4, x5\n\t" + "umulh x10, x4, x5\n\t" + "adds x7, x7, x3\n\t" + "str x7, [x6, 0]\n\t" + "adc x10, x10, xzr\n\t" + "# a[i+1] += m[1] * mu\n\t" + "mul x3, x11, x5\n\t" + "umulh x12, x11, x5\n\t" + "ldr x11, [%[m], 16]\n\t" + "ldr x7, [x6, 8]\n\t" + "adds x3, x3, x10\n\t" + "adc x12, x12, xzr\n\t" + "adds x7, x7, x3\n\t" + "str x7, [x6, 8]\n\t" + "adc x12, x12, xzr\n\t" + "# a[i+2] += m[2] * mu\n\t" + "mul x3, x11, x5\n\t" + "umulh x10, x11, x5\n\t" + "ldr x11, [%[m], 24]\n\t" + "ldr x7, [x6, 16]\n\t" + "adds x3, x3, x12\n\t" + "adc x10, x10, xzr\n\t" + "adds x7, x7, x3\n\t" + "str x7, [x6, 16]\n\t" + "adc x10, x10, xzr\n\t" + "# a[i+3] += m[3] * mu\n\t" + "mul x3, x11, x5\n\t" + "umulh x4, x11, x5\n\t" + "ldr x7, [x6, 24]\n\t" + "ldr x12, [x6, 32]\n\t" + "adds x3, x3, x10\n\t" + "adcs x4, x4, x9\n\t" + "cset x9, cs\n\t" + "adds x7, x7, x3\n\t" + "str x7, [x6, 24]\n\t" + "adcs x12, x12, x4\n\t" + "str x12, [x6, 32]\n\t" + "adc x9, x9, xzr\n\t" + "# i += 1\n\t" + "add x6, x6, 8\n\t" + "add x8, x8, 8\n\t" + "cmp x8, 32\n\t" + "b.lt 1b\n\t" + "ldr x5, [%[a], 32]\n\t" + "ldr x6, [%[a], 40]\n\t" + "ldr x7, [%[a], 48]\n\t" + "ldr x8, [%[a], 56]\n\t" + "sub x3, xzr, x9\n\t" + "ldr x9, [%[m], 0]\n\t" + "ldr x10, [%[m], 8]\n\t" + "ldr x11, [%[m], 16]\n\t" + "ldr x12, [%[m], 24]\n\t" + "and x9, x9, x3\n\t" + "and x10, x10, x3\n\t" + "and x11, x11, x3\n\t" + "and x12, x12, x3\n\t" + "subs x5, x5, x9\n\t" + "sbcs x6, x6, x10\n\t" + "sbcs x7, x7, x11\n\t" + "sbc x8, x8, x12\n\t" + "str x5, [%[a], 0]\n\t" + "str x6, [%[a], 8]\n\t" + "str x7, [%[a], 16]\n\t" + "str x8, [%[a], 24]\n\t" + : + : [a] "r" (a), [m] "r" (m), [mp] "r" (mp) + : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", + "x12" + ); +} + /* 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_4(sp_point* r, const sp_point* 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; @@ -31882,9 +31878,9 @@ static void sp_256_div2_4(sp_digit* r, const sp_digit* a, const sp_digit* m) * p Point to double. * t Temporary ordinate data. */ -static void sp_256_proj_point_dbl_4(sp_point* r, const sp_point* p, sp_digit* t) +static void sp_256_proj_point_dbl_4(sp_point_256* r, const sp_point_256* p, sp_digit* t) { - sp_point* rp[2]; + sp_point_256* rp[2]; sp_digit* t1 = t; sp_digit* t2 = t + 2*4; sp_digit* x; @@ -31896,8 +31892,8 @@ static void sp_256_proj_point_dbl_4(sp_point* r, const sp_point* p, sp_digit* t) rp[0] = r; /*lint allow cast to different type of pointer*/ - rp[1] = (sp_point*)t; /*lint !e9087 !e740*/ - XMEMSET(rp[1], 0, sizeof(sp_point)); + rp[1] = (sp_point_256*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_256)); x = rp[p->infinity]->x; y = rp[p->infinity]->y; z = rp[p->infinity]->z; @@ -31961,10 +31957,10 @@ static void sp_256_proj_point_dbl_4(sp_point* r, const sp_point* p, sp_digit* t) * n Number of times to double * t Temporary ordinate data. */ -static void sp_256_proj_point_dbl_n_4(sp_point* r, const sp_point* p, int n, +static void sp_256_proj_point_dbl_n_4(sp_point_256* r, const sp_point_256* p, int n, sp_digit* t) { - sp_point* rp[2]; + sp_point_256* rp[2]; sp_digit* w = t; sp_digit* a = t + 2*4; sp_digit* b = t + 4*4; @@ -31978,8 +31974,8 @@ static void sp_256_proj_point_dbl_n_4(sp_point* r, const sp_point* p, int n, rp[0] = r; /*lint allow cast to different type of pointer*/ - rp[1] = (sp_point*)t; /*lint !e9087 !e740*/ - XMEMSET(rp[1], 0, sizeof(sp_point)); + rp[1] = (sp_point_256*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_256)); x = rp[p->infinity]->x; y = rp[p->infinity]->y; z = rp[p->infinity]->z; @@ -32050,11 +32046,11 @@ static int sp_256_cmp_equal_4(const sp_digit* a, const sp_digit* b) * q Second point to add. * t Temporary ordinate data. */ -static void sp_256_proj_point_add_4(sp_point* r, const sp_point* p, const sp_point* q, +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* ap[2]; - sp_point* rp[2]; + const sp_point_256* ap[2]; + sp_point_256* rp[2]; sp_digit* t1 = t; sp_digit* t2 = t + 2*4; sp_digit* t3 = t + 4*4; @@ -32067,7 +32063,7 @@ static void sp_256_proj_point_add_4(sp_point* r, const sp_point* p, const sp_poi /* Ensure only the first point is the same as the result. */ if (q == r) { - const sp_point* a = p; + const sp_point_256* a = p; p = q; q = a; } @@ -32083,8 +32079,8 @@ static void sp_256_proj_point_add_4(sp_point* r, const sp_point* p, const sp_poi rp[0] = r; /*lint allow cast to different type of pointer*/ - rp[1] = (sp_point*)t; /*lint !e9087 !e740*/ - XMEMSET(rp[1], 0, sizeof(sp_point)); + rp[1] = (sp_point_256*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_256)); x = rp[p->infinity | q->infinity]->x; y = rp[p->infinity | q->infinity]->y; z = rp[p->infinity | q->infinity]->z; @@ -32144,7 +32140,7 @@ static void sp_256_proj_point_add_4(sp_point* r, const sp_point* p, const sp_poi * n Number of times to double * t Temporary ordinate data. */ -static void sp_256_proj_point_dbl_n_store_4(sp_point* r, const sp_point* p, +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; @@ -32214,8 +32210,8 @@ static void sp_256_proj_point_dbl_n_store_4(sp_point* r, const sp_point* p, * q Second point to add. * t Temporary ordinate data. */ -static void sp_256_proj_point_add_sub_4(sp_point* ra, sp_point* rs, - const sp_point* p, const sp_point* q, sp_digit* t) +static void sp_256_proj_point_add_sub_4(sp_point_256* ra, sp_point_256* rs, + const sp_point_256* p, const sp_point_256* q, sp_digit* t) { sp_digit* t1 = t; sp_digit* t2 = t + 2*4; @@ -32285,12 +32281,12 @@ static void sp_256_proj_point_add_sub_4(sp_point* ra, sp_point* rs, } /* Structure used to describe recoding of scalar multiplication. */ -typedef struct ecc_recode { +typedef struct ecc_recode_256 { /* Index into pre-computation table. */ uint8_t i; /* Use the negative of the point. */ uint8_t neg; -} ecc_recode; +} ecc_recode_256; /* The index into pre-computation table to use. */ static const uint8_t recode_index_4_6[66] = { @@ -32316,7 +32312,7 @@ static const uint8_t recode_neg_4_6[66] = { * k Scalar to multiply by. * v Vector of operations to perform. */ -static void sp_256_ecc_recode_6_4(const sp_digit* k, ecc_recode* v) +static void sp_256_ecc_recode_6_4(const sp_digit* k, ecc_recode_256* v) { int i, j; uint8_t y; @@ -32364,30 +32360,30 @@ static void sp_256_ecc_recode_6_4(const sp_digit* k, ecc_recode* v) * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_win_add_sub_4(sp_point* r, const sp_point* g, +static int sp_256_ecc_mulmod_win_add_sub_4(sp_point_256* r, const sp_point_256* g, const sp_digit* k, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point td[33]; - sp_point rtd, pd; + sp_point_256 td[33]; + sp_point_256 rtd, pd; sp_digit tmpd[2 * 4 * 6]; #endif - sp_point* t; - sp_point* rt; - sp_point* p = NULL; + sp_point_256* t; + sp_point_256* rt; + sp_point_256* p = NULL; sp_digit* tmp; sp_digit* negy; int i; - ecc_recode v[43]; + ecc_recode_256 v[43]; int err; (void)heap; - err = sp_ecc_point_new(heap, rtd, rt); + err = sp_256_point_new_4(heap, rtd, rt); if (err == MP_OKAY) - err = sp_ecc_point_new(heap, pd, p); + err = sp_256_point_new_4(heap, pd, p); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - t = (sp_point*)XMALLOC(sizeof(sp_point) * 33, heap, DYNAMIC_TYPE_ECC); + t = (sp_point_256*)XMALLOC(sizeof(sp_point_256) * 33, heap, DYNAMIC_TYPE_ECC); if (t == NULL) err = MEMORY_E; tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 4 * 6, heap, @@ -32443,11 +32439,11 @@ static int sp_256_ecc_mulmod_win_add_sub_4(sp_point* r, const sp_point* g, sp_256_ecc_recode_6_4(k, v); i = 42; - XMEMCPY(rt, &t[v[i].i], sizeof(sp_point)); + XMEMCPY(rt, &t[v[i].i], sizeof(sp_point_256)); for (--i; i>=0; i--) { sp_256_proj_point_dbl_n_4(rt, rt, 6, tmp); - XMEMCPY(p, &t[v[i].i], sizeof(sp_point)); + XMEMCPY(p, &t[v[i].i], sizeof(sp_point_256)); sp_256_sub_4(negy, p256_mod, p->y); sp_256_cond_copy_4(p->y, negy, (sp_digit)0 - v[i].neg); sp_256_proj_point_add_4(rt, rt, p, tmp); @@ -32457,7 +32453,7 @@ static int sp_256_ecc_mulmod_win_add_sub_4(sp_point* r, const sp_point* g, sp_256_map_4(r, rt, tmp); } else { - XMEMCPY(r, rt, sizeof(sp_point)); + XMEMCPY(r, rt, sizeof(sp_point_256)); } } @@ -32467,17 +32463,17 @@ static int sp_256_ecc_mulmod_win_add_sub_4(sp_point* r, const sp_point* g, if (tmp != NULL) XFREE(tmp, heap, DYNAMIC_TYPE_ECC); #endif - sp_ecc_point_free(p, 0, heap); - sp_ecc_point_free(rt, 0, heap); + sp_256_point_free_4(p, 0, heap); + sp_256_point_free_4(rt, 0, heap); return err; } /* A table entry for pre-computed points. */ -typedef struct sp_table_entry { +typedef struct sp_table_entry_256 { sp_digit x[4]; sp_digit y[4]; -} sp_table_entry; +} sp_table_entry_256; #if defined(FP_ECC) || defined(WOLFSSL_SP_SMALL) #endif /* FP_ECC || WOLFSSL_SP_SMALL */ @@ -32490,11 +32486,11 @@ typedef struct sp_table_entry { * q Second point to add. * t Temporary ordinate data. */ -static void sp_256_proj_point_add_qz1_4(sp_point* r, const sp_point* p, - const sp_point* q, sp_digit* t) +static void sp_256_proj_point_add_qz1_4(sp_point_256* r, const sp_point_256* p, + const sp_point_256* q, sp_digit* t) { - const sp_point* ap[2]; - sp_point* rp[2]; + const sp_point_256* ap[2]; + sp_point_256* rp[2]; sp_digit* t1 = t; sp_digit* t2 = t + 2*4; sp_digit* t3 = t + 4*4; @@ -32516,8 +32512,8 @@ static void sp_256_proj_point_add_qz1_4(sp_point* r, const sp_point* p, rp[0] = r; /*lint allow cast to different type of pointer*/ - rp[1] = (sp_point*)t; /*lint !e9087 !e740*/ - XMEMSET(rp[1], 0, sizeof(sp_point)); + rp[1] = (sp_point_256*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_256)); x = rp[p->infinity | q->infinity]->x; y = rp[p->infinity | q->infinity]->y; z = rp[p->infinity | q->infinity]->z; @@ -32570,7 +32566,7 @@ static void sp_256_proj_point_add_qz1_4(sp_point* r, const sp_point* p, * a Point to convert. * t Temporary data. */ -static void sp_256_proj_to_affine_4(sp_point* a, sp_digit* t) +static void sp_256_proj_to_affine_4(sp_point_256* a, sp_digit* t) { sp_digit* t1 = t; sp_digit* t2 = t + 2 * 4; @@ -32593,26 +32589,26 @@ static void sp_256_proj_to_affine_4(sp_point* a, sp_digit* t) * tmp Temporary data. * heap Heap to use for allocation. */ -static int sp_256_gen_stripe_table_4(const sp_point* a, - sp_table_entry* table, sp_digit* tmp, void* heap) +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) - sp_point td, s1d, s2d; + sp_point_256 td, s1d, s2d; #endif - sp_point* t; - sp_point* s1 = NULL; - sp_point* s2 = NULL; + sp_point_256* t; + sp_point_256* s1 = NULL; + sp_point_256* s2 = NULL; int i, j; int err; (void)heap; - err = sp_ecc_point_new(heap, td, t); + err = sp_256_point_new_4(heap, td, t); if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, s1d, s1); + err = sp_256_point_new_4(heap, s1d, s1); } if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, s2d, s2); + err = sp_256_point_new_4(heap, s2d, s2); } if (err == MP_OKAY) { @@ -32634,7 +32630,7 @@ static int sp_256_gen_stripe_table_4(const sp_point* a, s2->infinity = 0; /* table[0] = {0, 0, infinity} */ - XMEMSET(&table[0], 0, sizeof(sp_table_entry)); + XMEMSET(&table[0], 0, sizeof(sp_table_entry_256)); /* 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)); @@ -32660,9 +32656,9 @@ static int sp_256_gen_stripe_table_4(const sp_point* a, } } - sp_ecc_point_free(s2, 0, heap); - sp_ecc_point_free(s1, 0, heap); - sp_ecc_point_free( t, 0, heap); + sp_256_point_free_4(s2, 0, heap); + sp_256_point_free_4(s1, 0, heap); + sp_256_point_free_4( t, 0, heap); return err; } @@ -32678,16 +32674,16 @@ static int sp_256_gen_stripe_table_4(const sp_point* a, * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_stripe_4(sp_point* r, const sp_point* g, - const sp_table_entry* table, const sp_digit* k, int map, void* heap) +static int sp_256_ecc_mulmod_stripe_4(sp_point_256* r, const sp_point_256* g, + const sp_table_entry_256* table, const sp_digit* k, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point rtd; - sp_point pd; + sp_point_256 rtd; + sp_point_256 pd; sp_digit td[2 * 4 * 5]; #endif - sp_point* rt; - sp_point* p = NULL; + sp_point_256* rt; + sp_point_256* p = NULL; sp_digit* t; int i, j; int y, x; @@ -32696,9 +32692,10 @@ static int sp_256_ecc_mulmod_stripe_4(sp_point* r, const sp_point* g, (void)g; (void)heap; - err = sp_ecc_point_new(heap, rtd, rt); + + err = sp_256_point_new_4(heap, rtd, rt); if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, pd, p); + err = sp_256_point_new_4(heap, pd, p); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 4 * 5, heap, @@ -32738,7 +32735,7 @@ static int sp_256_ecc_mulmod_stripe_4(sp_point* r, const sp_point* g, sp_256_map_4(r, rt, t); } else { - XMEMCPY(r, rt, sizeof(sp_point)); + XMEMCPY(r, rt, sizeof(sp_point_256)); } } @@ -32747,8 +32744,8 @@ static int sp_256_ecc_mulmod_stripe_4(sp_point* r, const sp_point* g, XFREE(t, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(p, 0, heap); - sp_ecc_point_free(rt, 0, heap); + sp_256_point_free_4(p, 0, heap); + sp_256_point_free_4(rt, 0, heap); return err; } @@ -32759,43 +32756,43 @@ static int sp_256_ecc_mulmod_stripe_4(sp_point* r, const sp_point* g, #define FP_ENTRIES 16 #endif -typedef struct sp_cache_t { +typedef struct sp_cache_256_t { sp_digit x[4]; sp_digit y[4]; - sp_table_entry table[256]; + sp_table_entry_256 table[256]; uint32_t cnt; int set; -} sp_cache_t; +} sp_cache_256_t; -static THREAD_LS_T sp_cache_t sp_cache[FP_ENTRIES]; -static THREAD_LS_T int sp_cache_last = -1; -static THREAD_LS_T int sp_cache_inited = 0; +static THREAD_LS_T sp_cache_256_t sp_cache_256[FP_ENTRIES]; +static THREAD_LS_T int sp_cache_256_last = -1; +static THREAD_LS_T int sp_cache_256_inited = 0; #ifndef HAVE_THREAD_LS - static volatile int initCacheMutex = 0; - static wolfSSL_Mutex sp_cache_lock; + static volatile int initCacheMutex_256 = 0; + static wolfSSL_Mutex sp_cache_256_lock; #endif -static void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache) +static void sp_ecc_get_cache_256(const sp_point_256* g, sp_cache_256_t** cache) { int i, j; uint32_t least; - if (sp_cache_inited == 0) { + if (sp_cache_256_inited == 0) { for (i=0; ix, sp_cache[i].x) & - sp_256_cmp_equal_4(g->y, sp_cache[i].y)) { - sp_cache[i].cnt++; + if (sp_256_cmp_equal_4(g->x, sp_cache_256[i].x) & + sp_256_cmp_equal_4(g->y, sp_cache_256[i].y)) { + sp_cache_256[i].cnt++; break; } } @@ -32803,32 +32800,32 @@ static void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache) /* No match. */ if (i == FP_ENTRIES) { /* Find empty entry. */ - i = (sp_cache_last + 1) % FP_ENTRIES; - for (; i != sp_cache_last; i=(i+1)%FP_ENTRIES) { - if (!sp_cache[i].set) { + i = (sp_cache_256_last + 1) % FP_ENTRIES; + for (; i != sp_cache_256_last; i=(i+1)%FP_ENTRIES) { + if (!sp_cache_256[i].set) { break; } } /* Evict least used. */ - if (i == sp_cache_last) { - least = sp_cache[0].cnt; + if (i == sp_cache_256_last) { + least = sp_cache_256[0].cnt; for (j=1; jx, sizeof(sp_cache[i].x)); - XMEMCPY(sp_cache[i].y, g->y, sizeof(sp_cache[i].y)); - sp_cache[i].set = 1; - sp_cache[i].cnt = 1; + XMEMCPY(sp_cache_256[i].x, g->x, sizeof(sp_cache_256[i].x)); + XMEMCPY(sp_cache_256[i].y, g->y, sizeof(sp_cache_256[i].y)); + sp_cache_256[i].set = 1; + sp_cache_256[i].cnt = 1; } - *cache = &sp_cache[i]; - sp_cache_last = i; + *cache = &sp_cache_256[i]; + sp_cache_256_last = i; } #endif /* FP_ECC */ @@ -32842,32 +32839,32 @@ static void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache) * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_4(sp_point* r, const sp_point* g, const sp_digit* k, +static int sp_256_ecc_mulmod_4(sp_point_256* r, const sp_point_256* g, const sp_digit* k, int map, void* heap) { #ifndef FP_ECC return sp_256_ecc_mulmod_win_add_sub_4(r, g, k, map, heap); #else sp_digit tmp[2 * 4 * 5]; - sp_cache_t* cache; + sp_cache_256_t* cache; int err = MP_OKAY; #ifndef HAVE_THREAD_LS - if (initCacheMutex == 0) { - wc_InitMutex(&sp_cache_lock); - initCacheMutex = 1; + if (initCacheMutex_256 == 0) { + wc_InitMutex(&sp_cache_256_lock); + initCacheMutex_256 = 1; } - if (wc_LockMutex(&sp_cache_lock) != 0) + if (wc_LockMutex(&sp_cache_256_lock) != 0) err = BAD_MUTEX_E; #endif /* HAVE_THREAD_LS */ if (err == MP_OKAY) { - sp_ecc_get_cache(g, &cache); + sp_ecc_get_cache_256(g, &cache); if (cache->cnt == 2) sp_256_gen_stripe_table_4(g, cache->table, tmp, heap); #ifndef HAVE_THREAD_LS - wc_UnLockMutex(&sp_cache_lock); + wc_UnLockMutex(&sp_cache_256_lock); #endif /* HAVE_THREAD_LS */ if (cache->cnt < 2) { @@ -32897,15 +32894,14 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point p; - sp_digit k[4]; -#else - sp_digit* k = NULL; + sp_point_256 p; + sp_digit kd[4]; #endif - sp_point* point; - int err; + sp_point_256* point; + sp_digit* k = NULL; + int err = MP_OKAY; - err = sp_ecc_point_new(heap, p, point); + err = sp_256_point_new_4(heap, p, point); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4, heap, @@ -32913,6 +32909,8 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, if (k == NULL) err = MEMORY_E; } +#else + k = kd; #endif if (err == MP_OKAY) { sp_256_from_mp(k, 4, km); @@ -32929,13 +32927,13 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, XFREE(k, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(point, 0, heap); + sp_256_point_free_4(point, 0, heap); return err; } #ifdef WOLFSSL_SP_SMALL -static const sp_table_entry p256_table[256] = { +static const sp_table_entry_256 p256_table[256] = { /* 0 */ { { 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00 } }, @@ -34225,7 +34223,7 @@ static const sp_table_entry p256_table[256] = { * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_base_4(sp_point* r, const sp_digit* k, +static int sp_256_ecc_mulmod_base_4(sp_point_256* r, const sp_digit* k, int map, void* heap) { return sp_256_ecc_mulmod_stripe_4(r, &p256_base, p256_table, @@ -34265,7 +34263,7 @@ static const uint8_t recode_neg_4_7[130] = { * k Scalar to multiply by. * v Vector of operations to perform. */ -static void sp_256_ecc_recode_7_4(const sp_digit* k, ecc_recode* v) +static void sp_256_ecc_recode_7_4(const sp_digit* k, ecc_recode_256* v) { int i, j; uint8_t y; @@ -34303,7 +34301,7 @@ static void sp_256_ecc_recode_7_4(const sp_digit* k, ecc_recode* v) } } -static const sp_table_entry p256_table[2405] = { +static const sp_table_entry_256 p256_table[2405] = { /* 0 << 0 */ { { 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00 } }, @@ -46266,28 +46264,28 @@ static const sp_table_entry p256_table[2405] = { * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_add_only_4(sp_point* r, const sp_point* g, - const sp_table_entry* table, const sp_digit* k, int map, void* heap) +static int sp_256_ecc_mulmod_add_only_4(sp_point_256* r, const sp_point_256* g, + const sp_table_entry_256* table, const sp_digit* k, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point rtd; - sp_point pd; + sp_point_256 rtd; + sp_point_256 pd; sp_digit tmpd[2 * 4 * 5]; #endif - sp_point* rt; - sp_point* p = NULL; + sp_point_256* rt; + sp_point_256* p = NULL; sp_digit* tmp; sp_digit* negy; int i; - ecc_recode v[37]; + ecc_recode_256 v[37]; int err; (void)g; (void)heap; - err = sp_ecc_point_new(heap, rtd, rt); + err = sp_256_point_new_4(heap, rtd, rt); if (err == MP_OKAY) - err = sp_ecc_point_new(heap, pd, p); + err = sp_256_point_new_4(heap, pd, p); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 4 * 5, heap, DYNAMIC_TYPE_ECC); @@ -46320,7 +46318,7 @@ static int sp_256_ecc_mulmod_add_only_4(sp_point* r, const sp_point* g, sp_256_map_4(r, rt, tmp); } else { - XMEMCPY(r, rt, sizeof(sp_point)); + XMEMCPY(r, rt, sizeof(sp_point_256)); } } @@ -46332,8 +46330,8 @@ static int sp_256_ecc_mulmod_add_only_4(sp_point* r, const sp_point* g, #else ForceZero(tmp, sizeof(sp_digit) * 2 * 4 * 5); #endif - sp_ecc_point_free(p, 0, heap); - sp_ecc_point_free(rt, 0, heap); + sp_256_point_free_4(p, 0, heap); + sp_256_point_free_4(rt, 0, heap); return MP_OKAY; } @@ -46347,7 +46345,7 @@ static int sp_256_ecc_mulmod_add_only_4(sp_point* r, const sp_point* g, * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_base_4(sp_point* r, const sp_digit* k, +static int sp_256_ecc_mulmod_base_4(sp_point_256* r, const sp_digit* k, int map, void* heap) { return sp_256_ecc_mulmod_add_only_4(r, NULL, p256_table, @@ -46367,15 +46365,14 @@ static int sp_256_ecc_mulmod_base_4(sp_point* r, const sp_digit* k, int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point p; - sp_digit k[4]; -#else - sp_digit* k = NULL; + sp_point_256 p; + sp_digit kd[4]; #endif - sp_point* point; - int err; + sp_point_256* point; + sp_digit* k = NULL; + int err = MP_OKAY; - err = sp_ecc_point_new(heap, p, point); + err = sp_256_point_new_4(heap, p, point); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4, heap, @@ -46384,6 +46381,8 @@ int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) err = MEMORY_E; } } +#else + k = kd; #endif if (err == MP_OKAY) { sp_256_from_mp(k, 4, km); @@ -46399,7 +46398,7 @@ int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) XFREE(k, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(point, 0, heap); + sp_256_point_free_4(point, 0, heap); return err; } @@ -46425,8 +46424,8 @@ static int sp_256_iszero_4(const sp_digit* a) static void sp_256_add_one_4(sp_digit* a) { __asm__ __volatile__ ( - "ldp x1, x2, [%[a], 0]\n\t" - "ldp x3, x4, [%[a], 16]\n\t" + "ldp x1, x2, [%[a], 0]\n\t" + "ldp x3, x4, [%[a], 16]\n\t" "adds x1, x1, #1\n\t" "adcs x2, x2, xzr\n\t" "adcs x3, x3, xzr\n\t" @@ -46512,26 +46511,25 @@ static int sp_256_ecc_gen_k_4(WC_RNG* rng, sp_digit* k) int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point p; - sp_digit k[4]; + sp_point_256 p; + sp_digit kd[4]; #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN - sp_point inf; + sp_point_256 inf; #endif -#else +#endif + sp_point_256* point; sp_digit* k = NULL; -#endif - sp_point* point; #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN - sp_point* infinity; + sp_point_256* infinity; #endif int err; (void)heap; - err = sp_ecc_point_new(heap, p, point); + err = sp_256_point_new_4(heap, p, point); #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, inf, infinity); + err = sp_256_point_new_4(heap, inf, infinity); } #endif #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) @@ -46542,6 +46540,8 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) err = MEMORY_E; } } +#else + k = kd; #endif if (err == MP_OKAY) { @@ -46575,9 +46575,9 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) } #endif #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN - sp_ecc_point_free(infinity, 1, heap); + sp_256_point_free_4(infinity, 1, heap); #endif - sp_ecc_point_free(point, 1, heap); + sp_256_point_free_4(point, 1, heap); return err; } @@ -46634,12 +46634,11 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, word32* outLen, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point p; - sp_digit k[4]; -#else - sp_digit* k = NULL; + sp_point_256 p; + sp_digit kd[4]; #endif - sp_point* point = NULL; + sp_point_256* point = NULL; + sp_digit* k = NULL; int err = MP_OKAY; if (*outLen < 32U) { @@ -46647,7 +46646,7 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, } if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, p, point); + err = sp_256_point_new_4(heap, p, point); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { @@ -46656,6 +46655,8 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, if (k == NULL) err = MEMORY_E; } +#else + k = kd; #endif if (err == MP_OKAY) { @@ -46673,7 +46674,7 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, XFREE(k, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(point, 0, heap); + sp_256_point_free_4(point, 0, heap); return err; } @@ -46962,7 +46963,7 @@ static void sp_256_mul_d_4(sp_digit* r, const sp_digit* a, "str x4, [%[r], 32]\n\t" : : [r] "r" (r), [a] "r" (a), [b] "r" (b) - : "memory", "x3", "x4", "x5", "x6", "x7", "x8" + : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9" ); } @@ -47276,7 +47277,7 @@ static void sp_256_sqr_4(sp_digit* r, const sp_digit* a) #endif /* WOLFSSL_SP_SMALL */ #ifdef WOLFSSL_SP_SMALL /* Order-2 for the P256 curve. */ -static const uint64_t p256_order_2[4] = { +static const uint64_t p256_order_minus_2[4] = { 0xf3b9cac2fc63254fU,0xbce6faada7179e84U,0xffffffffffffffffU, 0xffffffff00000000U }; @@ -47345,7 +47346,7 @@ static void sp_256_mont_inv_order_4(sp_digit* r, const sp_digit* a, XMEMCPY(t, a, sizeof(sp_digit) * 4); for (i=254; i>=0; i--) { sp_256_mont_sqr_order_4(t, t); - if ((p256_order_2[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) { + if ((p256_order_minus_2[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) { sp_256_mont_mul_order_4(t, t, a); } } @@ -47461,24 +47462,24 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_digit kd[2*4]; sp_digit rd[2*4]; sp_digit td[3 * 2*4]; - sp_point p; + sp_point_256 p; #endif sp_digit* e = NULL; sp_digit* x = NULL; sp_digit* k = NULL; sp_digit* r = NULL; sp_digit* tmp = NULL; - sp_point* point = NULL; + sp_point_256* point = NULL; sp_digit carry; sp_digit* s = NULL; sp_digit* kInv = NULL; - int err; + int err = MP_OKAY; int64_t c; int i; (void)heap; - err = sp_ecc_point_new(heap, p, point); + err = sp_256_point_new_4(heap, p, point); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7 * 2 * 4, heap, @@ -47594,7 +47595,7 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, XMEMSET(r, 0, sizeof(sp_digit) * 2U * 4U); XMEMSET(tmp, 0, sizeof(sp_digit) * 3U * 2U * 4U); #endif - sp_ecc_point_free(point, 1, heap); + sp_256_point_free_4(point, 1, heap); return err; } @@ -47631,22 +47632,22 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, sp_digit u2d[2*4]; sp_digit sd[2*4]; sp_digit tmpd[2*4 * 5]; - sp_point p1d; - sp_point p2d; + sp_point_256 p1d; + sp_point_256 p2d; #endif sp_digit* u1 = NULL; sp_digit* u2 = NULL; sp_digit* s = NULL; sp_digit* tmp = NULL; - sp_point* p1; - sp_point* p2 = NULL; + sp_point_256* p1; + sp_point_256* p2 = NULL; sp_digit carry; int64_t c; int err; - err = sp_ecc_point_new(heap, p1d, p1); + err = sp_256_point_new_4(heap, p1d, p1); if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, p2d, p2); + err = sp_256_point_new_4(heap, p2d, p2); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { @@ -47758,8 +47759,8 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, if (d != NULL) XFREE(d, heap, DYNAMIC_TYPE_ECC); #endif - sp_ecc_point_free(p1, 0, heap); - sp_ecc_point_free(p2, 0, heap); + sp_256_point_free_4(p1, 0, heap); + sp_256_point_free_4(p2, 0, heap); return err; } @@ -47773,10 +47774,10 @@ 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* point, void* heap) +static int sp_256_ecc_is_point_4(sp_point_256* point, void* heap) { #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - sp_digit* d; + sp_digit* d = NULL; #else sp_digit t1d[2*4]; sp_digit t2d[2*4]; @@ -47840,13 +47841,13 @@ static int sp_256_ecc_is_point_4(sp_point* point, void* heap) int sp_ecc_is_point_256(mp_int* pX, mp_int* pY) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point pubd; + sp_point_256 pubd; #endif - sp_point* pub; + sp_point_256* pub; byte one[1] = { 1 }; int err; - err = sp_ecc_point_new(NULL, pubd, pub); + err = sp_256_point_new_4(NULL, pubd, pub); if (err == MP_OKAY) { sp_256_from_mp(pub->x, 4, pX); sp_256_from_mp(pub->y, 4, pY); @@ -47855,7 +47856,7 @@ int sp_ecc_is_point_256(mp_int* pX, mp_int* pY) err = sp_256_ecc_is_point_4(pub, NULL); } - sp_ecc_point_free(pub, 0, NULL); + sp_256_point_free_4(pub, 0, NULL); return err; } @@ -47875,18 +47876,18 @@ int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_digit privd[4]; - sp_point pubd; - sp_point pd; + sp_point_256 pubd; + sp_point_256 pd; #endif sp_digit* priv = NULL; - sp_point* pub; - sp_point* p = NULL; + sp_point_256* pub; + sp_point_256* p = NULL; byte one[1] = { 1 }; int err; - err = sp_ecc_point_new(heap, pubd, pub); + err = sp_256_point_new_4(heap, pubd, pub); if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, pd, p); + err = sp_256_point_new_4(heap, pd, p); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { @@ -47957,8 +47958,8 @@ int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) XFREE(priv, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(p, 0, heap); - sp_ecc_point_free(pub, 0, heap); + sp_256_point_free_4(p, 0, heap); + sp_256_point_free_4(pub, 0, heap); return err; } @@ -47984,17 +47985,17 @@ int sp_ecc_proj_add_point_256(mp_int* pX, mp_int* pY, mp_int* pZ, { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_digit tmpd[2 * 4 * 5]; - sp_point pd; - sp_point qd; + sp_point_256 pd; + sp_point_256 qd; #endif sp_digit* tmp; - sp_point* p; - sp_point* q = NULL; + sp_point_256* p; + sp_point_256* q = NULL; int err; - err = sp_ecc_point_new(NULL, pd, p); + err = sp_256_point_new_4(NULL, pd, p); if (err == MP_OKAY) { - err = sp_ecc_point_new(NULL, qd, q); + err = sp_256_point_new_4(NULL, qd, q); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { @@ -48034,8 +48035,8 @@ int sp_ecc_proj_add_point_256(mp_int* pX, mp_int* pY, mp_int* pZ, XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(q, 0, NULL); - sp_ecc_point_free(p, 0, NULL); + sp_256_point_free_4(q, 0, NULL); + sp_256_point_free_4(p, 0, NULL); return err; } @@ -48056,13 +48057,13 @@ int sp_ecc_proj_dbl_point_256(mp_int* pX, mp_int* pY, mp_int* pZ, { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_digit tmpd[2 * 4 * 2]; - sp_point pd; + sp_point_256 pd; #endif sp_digit* tmp; - sp_point* p; + sp_point_256* p; int err; - err = sp_ecc_point_new(NULL, pd, p); + err = sp_256_point_new_4(NULL, pd, p); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 4 * 2, NULL, @@ -48098,7 +48099,7 @@ int sp_ecc_proj_dbl_point_256(mp_int* pX, mp_int* pY, mp_int* pZ, XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(p, 0, NULL); + sp_256_point_free_4(p, 0, NULL); return err; } @@ -48115,13 +48116,13 @@ int sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_digit tmpd[2 * 4 * 4]; - sp_point pd; + sp_point_256 pd; #endif sp_digit* tmp; - sp_point* p; + sp_point_256* p; int err; - err = sp_ecc_point_new(NULL, pd, p); + err = sp_256_point_new_4(NULL, pd, p); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 4 * 4, NULL, @@ -48156,7 +48157,7 @@ int sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ) XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(p, 0, NULL); + sp_256_point_free_4(p, 0, NULL); return err; } @@ -48237,6 +48238,7 @@ static int sp_256_mont_sqrt_4(sp_digit* y) return err; } + /* Uncompress the point given the X ordinate. * * xm X ordinate. @@ -48313,6 +48315,5749 @@ int sp_ecc_uncompress_256(mp_int* xm, int odd, mp_int* ym) } #endif #endif /* !WOLFSSL_SP_NO_256 */ +#ifdef WOLFSSL_SP_384 + +/* Point structure to use. */ +typedef struct sp_point_384 { + sp_digit x[2 * 6]; + sp_digit y[2 * 6]; + sp_digit z[2 * 6]; + int infinity; +} sp_point_384; + +/* The modulus (prime) of the curve P384. */ +static const sp_digit p384_mod[6] = { + 0x00000000ffffffffL,0xffffffff00000000L,0xfffffffffffffffeL, + 0xffffffffffffffffL,0xffffffffffffffffL,0xffffffffffffffffL +}; +/* The Montogmery normalizer for modulus of the curve P384. */ +static const sp_digit p384_norm_mod[6] = { + 0xffffffff00000001L,0x00000000ffffffffL,0x0000000000000001L, + 0x0000000000000000L,0x0000000000000000L,0x0000000000000000L +}; +/* The Montogmery multiplier for modulus of the curve P384. */ +static sp_digit p384_mp_mod = 0x0000000100000001; +#if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \ + defined(HAVE_ECC_VERIFY) +/* The order of the curve P384. */ +static const sp_digit p384_order[6] = { + 0xecec196accc52973L,0x581a0db248b0a77aL,0xc7634d81f4372ddfL, + 0xffffffffffffffffL,0xffffffffffffffffL,0xffffffffffffffffL +}; +#endif +/* The order of the curve P384 minus 2. */ +static const sp_digit p384_order2[6] = { + 0xecec196accc52971L,0x581a0db248b0a77aL,0xc7634d81f4372ddfL, + 0xffffffffffffffffL,0xffffffffffffffffL,0xffffffffffffffffL +}; +#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[6] = { + 0x1313e695333ad68dL,0xa7e5f24db74f5885L,0x389cb27e0bc8d220L, + 0x0000000000000000L,0x0000000000000000L,0x0000000000000000L +}; +#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; +#endif +/* The base point of curve P384. */ +static const sp_point_384 p384_base = { + /* X ordinate */ + { + 0x3a545e3872760ab7L,0x5502f25dbf55296cL,0x59f741e082542a38L, + 0x6e1d3b628ba79b98L,0x8eb1c71ef320ad74L,0xaa87ca22be8b0537L, + 0L, 0L, 0L, 0L, 0L, 0L + }, + /* Y ordinate */ + { + 0x7a431d7c90ea0e5fL,0x0a60b1ce1d7e819dL,0xe9da3113b5f0b8c0L, + 0xf8f41dbd289a147cL,0x5d9e98bf9292dc29L,0x3617de4a96262c6fL, + 0L, 0L, 0L, 0L, 0L, 0L + }, + /* Z ordinate */ + { + 0x0000000000000001L,0x0000000000000000L,0x0000000000000000L, + 0x0000000000000000L,0x0000000000000000L,0x0000000000000000L, + 0L, 0L, 0L, 0L, 0L, 0L + }, + /* infinity */ + 0 +}; +#if defined(HAVE_ECC_CHECK_KEY) || defined(HAVE_COMP_KEY) +static const sp_digit p384_b[6] = { + 0x2a85c8edd3ec2aefL,0xc656398d8a2ed19dL,0x0314088f5013875aL, + 0x181d9c6efe814112L,0x988e056be3f82d19L,0xb3312fa7e23ee7e4L +}; +#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) + (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) +/* 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) +/* 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) + 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) + 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) + 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) + 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] |= a[i] << s; + r->dp[j] &= (1L << DIGIT_BIT) - 1; + s = DIGIT_BIT - s; + r->dp[++j] = 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] = 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__ ( + "ldr x3, [%[r], 0]\n\t" + "ldr x4, [%[r], 8]\n\t" + "ldr x5, [%[a], 0]\n\t" + "ldr x6, [%[a], 8]\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" + "str x3, [%[r], 0]\n\t" + "str x4, [%[r], 8]\n\t" + "ldr x3, [%[r], 16]\n\t" + "ldr x4, [%[r], 24]\n\t" + "ldr x5, [%[a], 16]\n\t" + "ldr x6, [%[a], 24]\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" + "str x3, [%[r], 16]\n\t" + "str x4, [%[r], 24]\n\t" + "ldr x3, [%[r], 32]\n\t" + "ldr x4, [%[r], 40]\n\t" + "ldr x5, [%[a], 32]\n\t" + "ldr x6, [%[a], 40]\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" + "str x3, [%[r], 32]\n\t" + "str x4, [%[r], 40]\n\t" + : + : [r] "r" (r), [a] "r" (a), [m] "r" (m) + : "memory", "x3", "x4", "x5", "x6" + ); +} + +#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_384_mul_6(sp_digit* r, const sp_digit* a, const sp_digit* b) +{ + sp_digit tmp[12]; + + __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, 40\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, 48\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, 80\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_384_mul_6(sp_digit* r, const sp_digit* a, const sp_digit* b) +{ + sp_digit tmp[6]; + + __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, [%[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 x3, x8, x14\n\t" + "umulh x4, x8, x14\n\t" + "str x3, [%[tmp]]\n\t" + "# A[0] * B[1]\n\t" + "mul x6, x8, x15\n\t" + "umulh x7, x8, x15\n\t" + "adds x4, x4, x6\n\t" + "adc x5, xzr, x7\n\t" + "# A[1] * B[0]\n\t" + "mul x6, x9, x14\n\t" + "umulh x7, x9, x14\n\t" + "adds x4, x4, x6\n\t" + "adcs x5, x5, x7\n\t" + "adc x3, xzr, xzr\n\t" + "str x4, [%[tmp], 8]\n\t" + "# A[0] * B[2]\n\t" + "mul x6, x8, x16\n\t" + "umulh x7, x8, x16\n\t" + "adds x5, x5, x6\n\t" + "adcs x3, x3, x7\n\t" + "adc x4, xzr, xzr\n\t" + "# A[1] * B[1]\n\t" + "mul x6, x9, x15\n\t" + "umulh x7, x9, x15\n\t" + "adds x5, x5, x6\n\t" + "adcs x3, x3, x7\n\t" + "adc x4, x4, xzr\n\t" + "# A[2] * B[0]\n\t" + "mul x6, x10, x14\n\t" + "umulh x7, x10, x14\n\t" + "adds x5, x5, x6\n\t" + "adcs x3, x3, x7\n\t" + "adc x4, x4, xzr\n\t" + "str x5, [%[tmp], 16]\n\t" + "# A[0] * B[3]\n\t" + "mul x6, x8, x17\n\t" + "umulh x7, x8, x17\n\t" + "adds x3, x3, x6\n\t" + "adcs x4, x4, x7\n\t" + "adc x5, xzr, xzr\n\t" + "# A[1] * B[2]\n\t" + "mul x6, x9, x16\n\t" + "umulh x7, x9, x16\n\t" + "adds x3, x3, x6\n\t" + "adcs x4, x4, x7\n\t" + "adc x5, x5, xzr\n\t" + "# A[2] * B[1]\n\t" + "mul x6, x10, x15\n\t" + "umulh x7, x10, x15\n\t" + "adds x3, x3, x6\n\t" + "adcs x4, x4, x7\n\t" + "adc x5, x5, xzr\n\t" + "# A[3] * B[0]\n\t" + "mul x6, x11, x14\n\t" + "umulh x7, x11, x14\n\t" + "adds x3, x3, x6\n\t" + "adcs x4, x4, x7\n\t" + "adc x5, x5, xzr\n\t" + "str x3, [%[tmp], 24]\n\t" + "# A[0] * B[4]\n\t" + "mul x6, x8, x19\n\t" + "umulh x7, x8, x19\n\t" + "adds x4, x4, x6\n\t" + "adcs x5, x5, x7\n\t" + "adc x3, xzr, xzr\n\t" + "# A[1] * B[3]\n\t" + "mul x6, x9, x17\n\t" + "umulh x7, x9, x17\n\t" + "adds x4, x4, x6\n\t" + "adcs x5, x5, x7\n\t" + "adc x3, x3, xzr\n\t" + "# A[2] * B[2]\n\t" + "mul x6, x10, x16\n\t" + "umulh x7, x10, x16\n\t" + "adds x4, x4, x6\n\t" + "adcs x5, x5, x7\n\t" + "adc x3, x3, xzr\n\t" + "# A[3] * B[1]\n\t" + "mul x6, x11, x15\n\t" + "umulh x7, x11, x15\n\t" + "adds x4, x4, x6\n\t" + "adcs x5, x5, x7\n\t" + "adc x3, x3, xzr\n\t" + "# A[4] * B[0]\n\t" + "mul x6, x12, x14\n\t" + "umulh x7, x12, x14\n\t" + "adds x4, x4, x6\n\t" + "adcs x5, x5, x7\n\t" + "adc x3, x3, xzr\n\t" + "str x4, [%[tmp], 32]\n\t" + "# A[0] * B[5]\n\t" + "mul x6, x8, x20\n\t" + "umulh x7, x8, x20\n\t" + "adds x5, x5, x6\n\t" + "adcs x3, x3, x7\n\t" + "adc x4, xzr, xzr\n\t" + "# A[1] * B[4]\n\t" + "mul x6, x9, x19\n\t" + "umulh x7, x9, x19\n\t" + "adds x5, x5, x6\n\t" + "adcs x3, x3, x7\n\t" + "adc x4, x4, xzr\n\t" + "# A[2] * B[3]\n\t" + "mul x6, x10, x17\n\t" + "umulh x7, x10, x17\n\t" + "adds x5, x5, x6\n\t" + "adcs x3, x3, x7\n\t" + "adc x4, x4, xzr\n\t" + "# A[3] * B[2]\n\t" + "mul x6, x11, x16\n\t" + "umulh x7, x11, x16\n\t" + "adds x5, x5, x6\n\t" + "adcs x3, x3, x7\n\t" + "adc x4, x4, xzr\n\t" + "# A[4] * B[1]\n\t" + "mul x6, x12, x15\n\t" + "umulh x7, x12, x15\n\t" + "adds x5, x5, x6\n\t" + "adcs x3, x3, x7\n\t" + "adc x4, x4, xzr\n\t" + "# A[5] * B[0]\n\t" + "mul x6, x13, x14\n\t" + "umulh x7, x13, x14\n\t" + "adds x5, x5, x6\n\t" + "adcs x3, x3, x7\n\t" + "adc x4, x4, xzr\n\t" + "str x5, [%[tmp], 40]\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" + "adcs x4, x4, x7\n\t" + "adc x5, xzr, xzr\n\t" + "# A[2] * B[4]\n\t" + "mul x6, x10, x19\n\t" + "umulh x7, x10, x19\n\t" + "adds x3, x3, x6\n\t" + "adcs x4, x4, x7\n\t" + "adc x5, x5, xzr\n\t" + "# A[3] * B[3]\n\t" + "mul x6, x11, x17\n\t" + "umulh x7, x11, x17\n\t" + "adds x3, x3, x6\n\t" + "adcs x4, x4, x7\n\t" + "adc x5, x5, xzr\n\t" + "# A[4] * B[2]\n\t" + "mul x6, x12, x16\n\t" + "umulh x7, x12, x16\n\t" + "adds x3, x3, x6\n\t" + "adcs x4, x4, x7\n\t" + "adc x5, x5, xzr\n\t" + "# A[5] * B[1]\n\t" + "mul x6, x13, x15\n\t" + "umulh x7, x13, x15\n\t" + "adds x3, x3, x6\n\t" + "adcs x4, x4, x7\n\t" + "adc x5, x5, xzr\n\t" + "str x3, [%[r], 48]\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" + "adcs x5, x5, x7\n\t" + "adc x3, xzr, xzr\n\t" + "# A[3] * B[4]\n\t" + "mul x6, x11, x19\n\t" + "umulh x7, x11, x19\n\t" + "adds x4, x4, x6\n\t" + "adcs x5, x5, x7\n\t" + "adc x3, x3, xzr\n\t" + "# A[4] * B[3]\n\t" + "mul x6, x12, x17\n\t" + "umulh x7, x12, x17\n\t" + "adds x4, x4, x6\n\t" + "adcs x5, x5, x7\n\t" + "adc x3, x3, xzr\n\t" + "# A[5] * B[2]\n\t" + "mul x6, x13, x16\n\t" + "umulh x7, x13, x16\n\t" + "adds x4, x4, x6\n\t" + "adcs x5, x5, x7\n\t" + "adc x3, x3, xzr\n\t" + "str x4, [%[r], 56]\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" + "adcs x3, x3, x7\n\t" + "adc x4, xzr, xzr\n\t" + "# A[4] * B[4]\n\t" + "mul x6, x12, x19\n\t" + "umulh x7, x12, x19\n\t" + "adds x5, x5, x6\n\t" + "adcs x3, x3, x7\n\t" + "adc x4, x4, xzr\n\t" + "# A[5] * B[3]\n\t" + "mul x6, x13, x17\n\t" + "umulh x7, x13, x17\n\t" + "adds x5, x5, x6\n\t" + "adcs x3, x3, x7\n\t" + "adc x4, x4, xzr\n\t" + "str x5, [%[r], 64]\n\t" + "# A[4] * B[5]\n\t" + "mul x6, x12, x20\n\t" + "umulh x7, x12, x20\n\t" + "adds x3, x3, x6\n\t" + "adcs x4, x4, x7\n\t" + "adc x5, xzr, xzr\n\t" + "# A[5] * B[4]\n\t" + "mul x6, x13, x19\n\t" + "umulh x7, x13, x19\n\t" + "adds x3, x3, x6\n\t" + "adcs x4, x4, x7\n\t" + "adc x5, x5, xzr\n\t" + "str x3, [%[r], 72]\n\t" + "# A[5] * B[5]\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", "x3", "x4", "x5", "x6", "x7", "x8", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17", "x19", "x20" + ); + + XMEMCPY(r, tmp, sizeof(tmp)); +} + +#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) +{ + sp_digit c = 0; + +#ifdef WOLFSSL_SP_SMALL + __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, 48\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" + ); +#else + __asm__ __volatile__ ( + + "ldr x4, [%[a], 0]\n\t" + "ldr x6, [%[a], 8]\n\t" + "ldr x5, [%[b], 0]\n\t" + "ldr x7, [%[b], 8]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "subs x4, x4, x5\n\t" + "sbcs x6, x6, x7\n\t" + "str x4, [%[r], 0]\n\t" + "str x6, [%[r], 8]\n\t" + "ldr x4, [%[a], 16]\n\t" + "ldr x6, [%[a], 24]\n\t" + "ldr x5, [%[b], 16]\n\t" + "ldr x7, [%[b], 24]\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" + "str x4, [%[r], 16]\n\t" + "str x6, [%[r], 24]\n\t" + "ldr x4, [%[a], 32]\n\t" + "ldr x6, [%[a], 40]\n\t" + "ldr x5, [%[b], 32]\n\t" + "ldr x7, [%[b], 40]\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" + "str x4, [%[r], 32]\n\t" + "str x6, [%[r], 40]\n\t" + "csetm %[c], cc\n\t" + : [c] "+r" (c) + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) + : "memory", "x4", "x6", "x5", "x7", "x8" + ); +#endif /* WOLFSSL_SP_SMALL */ + + return c; +} + +#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 x12, x13, [%[m], 0]\n\t" + "ldp x14, x15, [%[m], 16]\n\t" + "ldp x16, x17, [%[m], 32]\n\t" + "# i = 0\n\t" + "mov x3, 0\n\t" + "ldp x10, x11, [%[a], 0]\n\t" + "\n1:\n\t" + "# mu = a[i] * mp\n\t" + "mul x8, %[mp], x10\n\t" + "# a[i+0] += m[0] * mu\n\t" + "ldr x9, [%[a], 0]\n\t" + "mul x6, x12, x8\n\t" + "umulh x7, x12, x8\n\t" + "adds x10, x10, x6\n\t" + "adc x5, x7, xzr\n\t" + "# a[i+1] += m[1] * mu\n\t" + "ldr x9, [%[a], 8]\n\t" + "mul x6, x13, x8\n\t" + "umulh x7, x13, x8\n\t" + "adds x10, x11, x6\n\t" + "adc x4, x7, xzr\n\t" + "adds x10, x10, x5\n\t" + "adc x4, x4, xzr\n\t" + "# a[i+2] += m[2] * mu\n\t" + "ldr x11, [%[a], 16]\n\t" + "mul x6, x14, x8\n\t" + "umulh x7, x14, x8\n\t" + "adds x11, x11, x6\n\t" + "adc x5, x7, xzr\n\t" + "adds x11, x11, x4\n\t" + "adc x5, x5, xzr\n\t" + "# a[i+3] += m[3] * mu\n\t" + "ldr x9, [%[a], 24]\n\t" + "mul x6, x15, x8\n\t" + "umulh x7, x15, x8\n\t" + "adds x9, x9, x6\n\t" + "adc x4, x7, xzr\n\t" + "adds x9, x9, x5\n\t" + "str x9, [%[a], 24]\n\t" + "adc x4, x4, xzr\n\t" + "# a[i+4] += m[4] * mu\n\t" + "ldr x9, [%[a], 32]\n\t" + "mul x6, x16, x8\n\t" + "umulh x7, x16, x8\n\t" + "adds x9, x9, x6\n\t" + "adc x5, x7, xzr\n\t" + "adds x9, x9, x4\n\t" + "str x9, [%[a], 32]\n\t" + "adc x5, x5, xzr\n\t" + "# a[i+5] += m[5] * mu\n\t" + "ldr x9, [%[a], 40]\n\t" + "mul x6, x17, x8\n\t" + "umulh x7, x17, x8\n\t" + "adds x5, x5, x6\n\t" + "adcs x7, x7, %[ca]\n\t" + "cset %[ca], cs\n\t" + "adds x9, x9, x5\n\t" + "str x9, [%[a], 40]\n\t" + "ldr x9, [%[a], 48]\n\t" + "adcs x9, x9, x7\n\t" + "str x9, [%[a], 48]\n\t" + "adc %[ca], %[ca], xzr\n\t" + "# i += 1\n\t" + "add %[a], %[a], 8\n\t" + "add x3, x3, 8\n\t" + "cmp x3, 48\n\t" + "blt 1b\n\t" + "str x10, [%[a], 0]\n\t" + "str x11, [%[a], 8]\n\t" + : [ca] "+r" (ca), [a] "+r" (a) + : [m] "r" (m), [mp] "r" (mp) + : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15", "x16", "x17" + ); + + 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) + * + * r A single precision integer. + * a A single precision integer. + */ +static void sp_384_sqr_6(sp_digit* r, const sp_digit* a) +{ + sp_digit tmp[12]; + + __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, 40\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, 48\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, 80\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)); +} + +#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_6(sp_digit* r, const sp_digit* a) +{ + sp_digit tmp[6]; + + __asm__ __volatile__ ( + "ldp x10, x11, [%[a], 0]\n\t" + "ldp x12, x13, [%[a], 16]\n\t" + "ldp x14, x15, [%[a], 32]\n\t" + "# A[0] * A[0]\n\t" + "mul x2, x10, x10\n\t" + "umulh x3, x10, x10\n\t" + "str x2, [%[tmp]]\n\t" + "mov x4, 0\n\t" + "# A[0] * A[1]\n\t" + "mul x8, x10, x11\n\t" + "umulh x9, x10, x11\n\t" + "adds x3, x3, x8\n\t" + "adcs x4, x4, x9\n\t" + "adc x2, xzr, xzr\n\t" + "adds x3, x3, x8\n\t" + "adcs x4, x4, x9\n\t" + "adc x2, x2, xzr\n\t" + "str x3, [%[tmp], 8]\n\t" + "# A[0] * A[2]\n\t" + "mul x8, x10, x12\n\t" + "umulh x9, x10, x12\n\t" + "adds x4, x4, x8\n\t" + "adcs x2, x2, x9\n\t" + "adc x3, xzr, xzr\n\t" + "adds x4, x4, x8\n\t" + "adcs x2, x2, x9\n\t" + "adc x3, x3, xzr\n\t" + "# A[1] * A[1]\n\t" + "mul x8, x11, x11\n\t" + "umulh x9, x11, x11\n\t" + "adds x4, x4, x8\n\t" + "adcs x2, x2, x9\n\t" + "adc x3, x3, xzr\n\t" + "str x4, [%[tmp], 16]\n\t" + "# A[0] * A[3]\n\t" + "mul x8, x10, x13\n\t" + "umulh x9, x10, x13\n\t" + "adds x2, x2, x8\n\t" + "adcs x3, x3, x9\n\t" + "adc x4, xzr, xzr\n\t" + "adds x2, x2, x8\n\t" + "adcs x3, x3, x9\n\t" + "adc x4, x4, xzr\n\t" + "# A[1] * A[2]\n\t" + "mul x8, x11, x12\n\t" + "umulh x9, x11, x12\n\t" + "adds x2, x2, x8\n\t" + "adcs x3, x3, x9\n\t" + "adc x4, x4, xzr\n\t" + "adds x2, x2, x8\n\t" + "adcs x3, x3, x9\n\t" + "adc x4, x4, xzr\n\t" + "str x2, [%[tmp], 24]\n\t" + "# A[0] * A[4]\n\t" + "mul x8, x10, x14\n\t" + "umulh x9, x10, x14\n\t" + "adds x3, x3, x8\n\t" + "adcs x4, x4, x9\n\t" + "adc x2, xzr, xzr\n\t" + "adds x3, x3, x8\n\t" + "adcs x4, x4, x9\n\t" + "adc x2, x2, xzr\n\t" + "# A[1] * A[3]\n\t" + "mul x8, x11, x13\n\t" + "umulh x9, x11, x13\n\t" + "adds x3, x3, x8\n\t" + "adcs x4, x4, x9\n\t" + "adc x2, x2, xzr\n\t" + "adds x3, x3, x8\n\t" + "adcs x4, x4, x9\n\t" + "adc x2, x2, xzr\n\t" + "# A[2] * A[2]\n\t" + "mul x8, x12, x12\n\t" + "umulh x9, x12, x12\n\t" + "adds x3, x3, x8\n\t" + "adcs x4, x4, x9\n\t" + "adc x2, x2, xzr\n\t" + "str x3, [%[tmp], 32]\n\t" + "# A[0] * A[5]\n\t" + "mul x5, x10, x15\n\t" + "umulh x6, x10, x15\n\t" + "mov x3, 0\n\t" + "mov x7, 0\n\t" + "# A[1] * A[4]\n\t" + "mul x8, x11, x14\n\t" + "umulh x9, x11, x14\n\t" + "adds x5, x5, x8\n\t" + "adcs x6, x6, x9\n\t" + "adc x7, x7, xzr\n\t" + "# A[2] * A[3]\n\t" + "mul x8, x12, x13\n\t" + "umulh x9, x12, x13\n\t" + "adds x5, x5, x8\n\t" + "adcs x6, x6, x9\n\t" + "adc x7, x7, xzr\n\t" + "adds x5, x5, x5\n\t" + "adcs x6, x6, x6\n\t" + "adc x7, x7, x7\n\t" + "adds x4, x4, x5\n\t" + "adcs x2, x2, x6\n\t" + "adc x3, x3, x7\n\t" + "str x4, [%[tmp], 40]\n\t" + "# A[1] * A[5]\n\t" + "mul x8, x11, x15\n\t" + "umulh x9, x11, x15\n\t" + "adds x2, x2, x8\n\t" + "adcs x3, x3, x9\n\t" + "adc x4, xzr, xzr\n\t" + "adds x2, x2, x8\n\t" + "adcs x3, x3, x9\n\t" + "adc x4, x4, xzr\n\t" + "# A[2] * A[4]\n\t" + "mul x8, x12, x14\n\t" + "umulh x9, x12, x14\n\t" + "adds x2, x2, x8\n\t" + "adcs x3, x3, x9\n\t" + "adc x4, x4, xzr\n\t" + "adds x2, x2, x8\n\t" + "adcs x3, x3, x9\n\t" + "adc x4, x4, xzr\n\t" + "# A[3] * A[3]\n\t" + "mul x8, x13, x13\n\t" + "umulh x9, x13, x13\n\t" + "adds x2, x2, x8\n\t" + "adcs x3, x3, x9\n\t" + "adc x4, x4, xzr\n\t" + "str x2, [%[r], 48]\n\t" + "# A[2] * A[5]\n\t" + "mul x8, x12, x15\n\t" + "umulh x9, x12, x15\n\t" + "adds x3, x3, x8\n\t" + "adcs x4, x4, x9\n\t" + "adc x2, xzr, xzr\n\t" + "adds x3, x3, x8\n\t" + "adcs x4, x4, x9\n\t" + "adc x2, x2, xzr\n\t" + "# A[3] * A[4]\n\t" + "mul x8, x13, x14\n\t" + "umulh x9, x13, x14\n\t" + "adds x3, x3, x8\n\t" + "adcs x4, x4, x9\n\t" + "adc x2, x2, xzr\n\t" + "adds x3, x3, x8\n\t" + "adcs x4, x4, x9\n\t" + "adc x2, x2, xzr\n\t" + "str x3, [%[r], 56]\n\t" + "# A[3] * A[5]\n\t" + "mul x8, x13, x15\n\t" + "umulh x9, x13, x15\n\t" + "adds x4, x4, x8\n\t" + "adcs x2, x2, x9\n\t" + "adc x3, xzr, xzr\n\t" + "adds x4, x4, x8\n\t" + "adcs x2, x2, x9\n\t" + "adc x3, x3, xzr\n\t" + "# A[4] * A[4]\n\t" + "mul x8, x14, x14\n\t" + "umulh x9, x14, x14\n\t" + "adds x4, x4, x8\n\t" + "adcs x2, x2, x9\n\t" + "adc x3, x3, xzr\n\t" + "str x4, [%[r], 64]\n\t" + "# A[4] * A[5]\n\t" + "mul x8, x14, x15\n\t" + "umulh x9, x14, x15\n\t" + "adds x2, x2, x8\n\t" + "adcs x3, x3, x9\n\t" + "adc x4, xzr, xzr\n\t" + "adds x2, x2, x8\n\t" + "adcs x3, x3, x9\n\t" + "adc x4, x4, xzr\n\t" + "str x2, [%[r], 72]\n\t" + "# A[5] * A[5]\n\t" + "mul x8, x15, x15\n\t" + "umulh x9, x15, x15\n\t" + "adds x3, x3, x8\n\t" + "adc x4, x4, x9\n\t" + "stp x3, x4, [%[r], 80]\n\t" + : + : [r] "r" (r), [a] "r" (a), [tmp] "r" (tmp) + : "memory", "x2", "x3", "x4", "x8", "x9", "x10", "x5", "x6", "x7", "x10", "x11", "x12", "x13", "x14", "x15" + ); + + XMEMCPY(r, tmp, sizeof(tmp)); +} + +#endif /* WOLFSSL_SP_SMALL */ +/* 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_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); +} + +#if !defined(WOLFSSL_SP_SMALL) || defined(HAVE_COMP_KEY) +/* Square the Montgomery form number a number of times. (r = a ^ n mod m) + * + * r Result of squaring. + * a Number to square in Montogmery form. + * n Number of times to square. + * m Modulus (prime). + * mp Montogmery mulitplier. + */ +static void sp_384_mont_sqr_n_6(sp_digit* r, const sp_digit* a, int n, + const sp_digit* m, sp_digit mp) +{ + sp_384_mont_sqr_6(r, a, m, mp); + for (; n > 1; n--) { + sp_384_mont_sqr_6(r, r, m, mp); + } +} + +#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] = { + 0x00000000fffffffdU,0xffffffff00000000U,0xfffffffffffffffeU, + 0xffffffffffffffffU,0xffffffffffffffffU,0xffffffffffffffffU +}; +#endif /* !WOLFSSL_SP_SMALL */ + +/* Invert the number, in Montgomery form, modulo the modulus (prime) of the + * P384 curve. (r = 1 / a mod m) + * + * r Inverse result. + * a Number to invert. + * td Temporary data. + */ +static void sp_384_mont_inv_6(sp_digit* r, const sp_digit* a, sp_digit* td) +{ +#ifdef WOLFSSL_SP_SMALL + sp_digit* t = td; + int i; + + XMEMCPY(t, a, sizeof(sp_digit) * 6); + for (i=382; i>=0; i--) { + sp_384_mont_sqr_6(t, t, p384_mod, p384_mp_mod); + if (p384_mod_minus_2[i / 64] & ((sp_digit)1 << (i % 64))) + sp_384_mont_mul_6(t, t, a, p384_mod, p384_mp_mod); + } + XMEMCPY(r, t, sizeof(sp_digit) * 6); +#else + sp_digit* t1 = td; + sp_digit* t2 = td + 2 * 6; + sp_digit* t3 = td + 4 * 6; + sp_digit* t4 = td + 6 * 6; + sp_digit* t5 = td + 8 * 6; + + /* 0x2 */ + sp_384_mont_sqr_6(t1, a, p384_mod, p384_mp_mod); + /* 0x3 */ + sp_384_mont_mul_6(t5, t1, a, p384_mod, p384_mp_mod); + /* 0xc */ + sp_384_mont_sqr_n_6(t1, t5, 2, p384_mod, p384_mp_mod); + /* 0xf */ + sp_384_mont_mul_6(t2, t5, t1, p384_mod, p384_mp_mod); + /* 0x1e */ + sp_384_mont_sqr_6(t1, t2, p384_mod, p384_mp_mod); + /* 0x1f */ + sp_384_mont_mul_6(t4, t1, a, p384_mod, p384_mp_mod); + /* 0x3e0 */ + sp_384_mont_sqr_n_6(t1, t4, 5, p384_mod, p384_mp_mod); + /* 0x3ff */ + sp_384_mont_mul_6(t2, t4, t1, p384_mod, p384_mp_mod); + /* 0x7fe0 */ + sp_384_mont_sqr_n_6(t1, t2, 5, p384_mod, p384_mp_mod); + /* 0x7fff */ + sp_384_mont_mul_6(t4, t4, t1, p384_mod, p384_mp_mod); + /* 0x3fff8000 */ + sp_384_mont_sqr_n_6(t1, t4, 15, p384_mod, p384_mp_mod); + /* 0x3fffffff */ + sp_384_mont_mul_6(t2, t4, t1, p384_mod, p384_mp_mod); + /* 0xfffffffc */ + sp_384_mont_sqr_n_6(t3, t2, 2, p384_mod, p384_mp_mod); + /* 0xfffffffd */ + sp_384_mont_mul_6(r, t3, a, p384_mod, p384_mp_mod); + /* 0xffffffff */ + sp_384_mont_mul_6(t3, t5, t3, p384_mod, p384_mp_mod); + /* 0xfffffffc0000000 */ + sp_384_mont_sqr_n_6(t1, t2, 30, p384_mod, p384_mp_mod); + /* 0xfffffffffffffff */ + sp_384_mont_mul_6(t2, t2, t1, p384_mod, p384_mp_mod); + /* 0xfffffffffffffff000000000000000 */ + sp_384_mont_sqr_n_6(t1, t2, 60, p384_mod, p384_mp_mod); + /* 0xffffffffffffffffffffffffffffff */ + sp_384_mont_mul_6(t2, t2, t1, p384_mod, p384_mp_mod); + /* 0xffffffffffffffffffffffffffffff000000000000000000000000000000 */ + sp_384_mont_sqr_n_6(t1, t2, 120, p384_mod, p384_mp_mod); + /* 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */ + sp_384_mont_mul_6(t2, t2, t1, p384_mod, p384_mp_mod); + /* 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000 */ + sp_384_mont_sqr_n_6(t1, t2, 15, p384_mod, p384_mp_mod); + /* 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */ + sp_384_mont_mul_6(t2, t4, t1, p384_mod, p384_mp_mod); + /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00000000 */ + sp_384_mont_sqr_n_6(t1, t2, 33, p384_mod, p384_mp_mod); + /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff */ + sp_384_mont_mul_6(t2, t3, t1, p384_mod, p384_mp_mod); + /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff000000000000000000000000 */ + sp_384_mont_sqr_n_6(t1, t2, 96, p384_mod, p384_mp_mod); + /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffd */ + sp_384_mont_mul_6(r, r, t1, p384_mod, p384_mp_mod); + +#endif /* WOLFSSL_SP_SMALL */ +} + +/* 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_384_cmp_6(const sp_digit* a, const sp_digit* b) +{ + sp_digit r = -1; + sp_digit one = 1; + +#ifdef WOLFSSL_SP_SMALL + __asm__ __volatile__ ( + "mov x3, -1\n\t" + "mov x6, 40\n\t" + "1:\n\t" + "ldr x4, [%[a], x6]\n\t" + "ldr x5, [%[b], x6]\n\t" + "and x4, x4, x3\n\t" + "and x5, x5, x3\n\t" + "subs x4, x4, x5\n\t" + "csel %[r], %[one], %[r], hi\n\t" + "csel %[r], x3, %[r], lo\n\t" + "csel x3, x3, xzr, eq\n\t" + "subs x6, x6, #8\n\t" + "b.cs 1b\n\t" + "eor %[r], %[r], x3\n\t" + : [r] "+r" (r) + : [a] "r" (a), [b] "r" (b), [one] "r" (one) + : "x2", "x3", "x4", "x5", "x6" + ); +#else + __asm__ __volatile__ ( + "mov x3, -1\n\t" + "ldr x4, [%[a], 40]\n\t" + "ldr x5, [%[b], 40]\n\t" + "and x4, x4, x3\n\t" + "and x5, x5, x3\n\t" + "subs x4, x4, x5\n\t" + "csel %[r], %[one], %[r], hi\n\t" + "csel %[r], x3, %[r], lo\n\t" + "csel x3, x3, xzr, eq\n\t" + "ldr x4, [%[a], 32]\n\t" + "ldr x5, [%[b], 32]\n\t" + "and x4, x4, x3\n\t" + "and x5, x5, x3\n\t" + "subs x4, x4, x5\n\t" + "csel %[r], %[one], %[r], hi\n\t" + "csel %[r], x3, %[r], lo\n\t" + "csel x3, x3, xzr, eq\n\t" + "ldr x4, [%[a], 24]\n\t" + "ldr x5, [%[b], 24]\n\t" + "and x4, x4, x3\n\t" + "and x5, x5, x3\n\t" + "subs x4, x4, x5\n\t" + "csel %[r], %[one], %[r], hi\n\t" + "csel %[r], x3, %[r], lo\n\t" + "csel x3, x3, xzr, eq\n\t" + "ldr x4, [%[a], 16]\n\t" + "ldr x5, [%[b], 16]\n\t" + "and x4, x4, x3\n\t" + "and x5, x5, x3\n\t" + "subs x4, x4, x5\n\t" + "csel %[r], %[one], %[r], hi\n\t" + "csel %[r], x3, %[r], lo\n\t" + "csel x3, x3, xzr, eq\n\t" + "ldr x4, [%[a], 8]\n\t" + "ldr x5, [%[b], 8]\n\t" + "and x4, x4, x3\n\t" + "and x5, x5, x3\n\t" + "subs x4, x4, x5\n\t" + "csel %[r], %[one], %[r], hi\n\t" + "csel %[r], x3, %[r], lo\n\t" + "csel x3, x3, xzr, eq\n\t" + "ldr x4, [%[a], 0]\n\t" + "ldr x5, [%[b], 0]\n\t" + "and x4, x4, x3\n\t" + "and x5, x5, x3\n\t" + "subs x4, x4, x5\n\t" + "csel %[r], %[one], %[r], hi\n\t" + "csel %[r], x3, %[r], lo\n\t" + "csel x3, x3, xzr, eq\n\t" + "eor %[r], %[r], x3\n\t" + : [r] "+r" (r) + : [a] "r" (a), [b] "r" (b), [one] "r" (one) + : "x2", "x3", "x4", "x5", "x6" + ); +#endif + + return r; +} + +/* Normalize the values in each word to 64. + * + * a Array of sp_digit to normalize. + */ +#define sp_384_norm_6(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_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; + int64_t n; + + sp_384_mont_inv_6(t1, p->z, t + 2*6); + + sp_384_mont_sqr_6(t2, t1, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(t1, t2, t1, p384_mod, p384_mp_mod); + + /* x /= z^2 */ + sp_384_mont_mul_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); + /* 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) ? + (sp_digit)1 : (sp_digit)0)); + sp_384_norm_6(r->x); + + /* y /= z^3 */ + sp_384_mont_mul_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); + /* 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_digit)1 : (sp_digit)0)); + sp_384_norm_6(r->y); + + XMEMSET(r->z, 0, sizeof(r->z)); + r->z[0] = 1; + +} + +/* 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) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "ldp x3, x4, [%[a], 0]\n\t" + "ldp x5, x6, [%[a], 16]\n\t" + "ldp x7, x8, [%[b], 0]\n\t" + "ldp x9, x10, [%[b], 16]\n\t" + "adds x3, x3, x7\n\t" + "adcs x4, x4, x8\n\t" + "adcs x5, x5, x9\n\t" + "adcs x6, x6, x10\n\t" + "stp x3, x4, [%[r], 0]\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 %[c], cs\n\t" + : [c] "+r" (c) + : [r] "r" (r), [a] "r" (a), [b] "r" (b) + : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10" + ); + + return c; +} + +/* 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_384_mont_add_6(sp_digit* r, const sp_digit* a, const sp_digit* b, + const sp_digit* m) +{ + sp_digit o; + + o = sp_384_add_6(r, a, b); + sp_384_cond_sub_6(r, r, m, 0 - o); +} + +/* 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_384_mont_dbl_6(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + sp_digit o; + + o = sp_384_add_6(r, a, a); + sp_384_cond_sub_6(r, r, m, 0 - o); +} + +/* 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_384_mont_tpl_6(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + sp_digit o; + + o = sp_384_add_6(r, a, a); + sp_384_cond_sub_6(r, r, m, 0 - o); + o = sp_384_add_6(r, r, a); + 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) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "ldp x3, x4, [%[a], 0]\n\t" + "ldp x5, x6, [%[a], 16]\n\t" + "ldp x7, x8, [%[b], 0]\n\t" + "ldp x9, x10, [%[b], 16]\n\t" + "subs x3, x3, x7\n\t" + "sbcs x4, x4, x8\n\t" + "sbcs x5, x5, x9\n\t" + "sbcs x6, x6, x10\n\t" + "stp x3, x4, [%[r], 0]\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 %[c], cc\n\t" + : [c] "+r" (c) + : [r] "r" (r), [a] "r" (a), [b] "r" (b) + : "memory", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10" + ); + + return c; +} + +/* 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_384_cond_add_6(sp_digit* r, const sp_digit* a, const sp_digit* b, + sp_digit m) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "ldr x4, [%[a], 0]\n\t" + "ldr x6, [%[a], 8]\n\t" + "ldr x5, [%[b], 0]\n\t" + "ldr x7, [%[b], 8]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adds x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x4, [%[r], 0]\n\t" + "str x6, [%[r], 8]\n\t" + "ldr x4, [%[a], 16]\n\t" + "ldr x6, [%[a], 24]\n\t" + "ldr x5, [%[b], 16]\n\t" + "ldr x7, [%[b], 24]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x4, [%[r], 16]\n\t" + "str x6, [%[r], 24]\n\t" + "ldr x4, [%[a], 32]\n\t" + "ldr x6, [%[a], 40]\n\t" + "ldr x5, [%[b], 32]\n\t" + "ldr x7, [%[b], 40]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x4, [%[r], 32]\n\t" + "str x6, [%[r], 40]\n\t" + "cset %[c], cs\n\t" + : [c] "+r" (c) + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) + : "memory", "x4", "x6", "x5", "x7" + ); + + return c; +} + +/* 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_384_mont_sub_6(sp_digit* r, const sp_digit* a, const sp_digit* b, + const sp_digit* m) +{ + sp_digit o; + + o = sp_384_sub_6(r, a, b); + sp_384_cond_add_6(r, r, m, o); +} + +static void sp_384_rshift1_6(sp_digit* r, sp_digit* a) +{ + __asm__ __volatile__ ( + "ldr x2, [%[a]]\n\t" + "ldr x3, [%[a], 8]\n\t" + "ldr x4, [%[a], 16]\n\t" + "ldr x5, [%[a], 24]\n\t" + "ldr x6, [%[a], 32]\n\t" + "ldr x7, [%[a], 40]\n\t" + "lsr x11, x6, 1\n\t" + "lsr x10, x5, 1\n\t" + "lsr x9, x4, 1\n\t" + "lsr x8, x3, 1\n\t" + "lsr x2, x2, 1\n\t" + "orr x2, x2, x3, lsl 63\n\t" + "orr x3, x8, x4, lsl 63\n\t" + "orr x4, x9, x5, lsl 63\n\t" + "orr x5, x10, x6, lsl 63\n\t" + "orr x6, x11, x7, lsl 63\n\t" + "lsr x7, x7, 1\n\t" + "str x2, [%[r]]\n\t" + "str x3, [%[r], 8]\n\t" + "str x4, [%[r], 16]\n\t" + "str x5, [%[r], 24]\n\t" + "str x6, [%[r], 32]\n\t" + "str x7, [%[r], 40]\n\t" + : + : [r] "r" (r), [a] "r" (a) + : "memory", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9", "x10", "x11" + ); +} + +/* 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_384_div2_6(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + sp_digit o; + + o = sp_384_cond_add_6(r, a, m, 0 - (a[0] & 1)); + sp_384_rshift1_6(r, r); + r[5] |= o << 63; +} + +/* Double the Montgomery form projective point p. + * + * r Result of doubling point. + * p Point to double. + * t Temporary ordinate data. + */ +static void sp_384_proj_point_dbl_6(sp_point_384* r, const sp_point_384* p, sp_digit* t) +{ + sp_point_384* rp[2]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*6; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + /* When infinity don't double point passed in - constant time. */ + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_384*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_384)); + x = rp[p->infinity]->x; + y = rp[p->infinity]->y; + z = rp[p->infinity]->z; + /* Put point to double into result - good for infinity. */ + if (r != p) { + for (i=0; i<6; i++) { + r->x[i] = p->x[i]; + } + for (i=0; i<6; i++) { + r->y[i] = p->y[i]; + } + for (i=0; i<6; i++) { + r->z[i] = p->z[i]; + } + r->infinity = p->infinity; + } + + /* T1 = Z * Z */ + sp_384_mont_sqr_6(t1, z, p384_mod, p384_mp_mod); + /* Z = Y * Z */ + sp_384_mont_mul_6(z, y, z, p384_mod, p384_mp_mod); + /* Z = 2Z */ + sp_384_mont_dbl_6(z, z, p384_mod); + /* T2 = X - T1 */ + sp_384_mont_sub_6(t2, x, t1, p384_mod); + /* T1 = X + T1 */ + sp_384_mont_add_6(t1, x, t1, p384_mod); + /* T2 = T1 * T2 */ + sp_384_mont_mul_6(t2, t1, t2, p384_mod, p384_mp_mod); + /* T1 = 3T2 */ + sp_384_mont_tpl_6(t1, t2, p384_mod); + /* Y = 2Y */ + sp_384_mont_dbl_6(y, y, p384_mod); + /* Y = Y * Y */ + sp_384_mont_sqr_6(y, y, p384_mod, p384_mp_mod); + /* T2 = Y * Y */ + sp_384_mont_sqr_6(t2, y, p384_mod, p384_mp_mod); + /* T2 = T2/2 */ + sp_384_div2_6(t2, t2, p384_mod); + /* Y = Y * X */ + sp_384_mont_mul_6(y, y, x, p384_mod, p384_mp_mod); + /* X = T1 * T1 */ + sp_384_mont_mul_6(x, t1, t1, p384_mod, p384_mp_mod); + /* X = X - Y */ + sp_384_mont_sub_6(x, x, y, p384_mod); + /* X = X - Y */ + sp_384_mont_sub_6(x, x, y, p384_mod); + /* Y = Y - X */ + sp_384_mont_sub_6(y, y, x, p384_mod); + /* Y = Y * T1 */ + sp_384_mont_mul_6(y, y, t1, p384_mod, p384_mp_mod); + /* Y = Y - T2 */ + sp_384_mont_sub_6(y, y, t2, p384_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_384_proj_point_dbl_n_6(sp_point_384* r, const sp_point_384* p, int n, + sp_digit* t) +{ + sp_point_384* rp[2]; + sp_digit* w = t; + sp_digit* a = t + 2*6; + sp_digit* b = t + 4*6; + sp_digit* t1 = t + 6*6; + sp_digit* t2 = t + 8*6; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_384*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_384)); + x = rp[p->infinity]->x; + y = rp[p->infinity]->y; + z = rp[p->infinity]->z; + if (r != p) { + for (i=0; i<6; i++) { + r->x[i] = p->x[i]; + } + for (i=0; i<6; i++) { + r->y[i] = p->y[i]; + } + for (i=0; i<6; i++) { + r->z[i] = p->z[i]; + } + r->infinity = p->infinity; + } + + /* Y = 2*Y */ + sp_384_mont_dbl_6(y, y, p384_mod); + /* 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); + while (n-- > 0) { + /* 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); + sp_384_mont_tpl_6(a, t1, p384_mod); + /* 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 = A^2 - 2B */ + sp_384_mont_sqr_6(x, a, p384_mod, p384_mp_mod); + sp_384_mont_dbl_6(t1, b, p384_mod); + sp_384_mont_sub_6(x, x, t1, p384_mod); + /* Z = Z*Y */ + sp_384_mont_mul_6(z, z, y, p384_mod, p384_mp_mod); + /* t2 = Y^4 */ + sp_384_mont_sqr_6(t2, t2, p384_mod, p384_mp_mod); + if (n != 0) { + /* W = W*Y^4 */ + sp_384_mont_mul_6(w, w, t2, 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_mul_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, t2, p384_mod); + } + /* Y = Y/2 */ + sp_384_div2_6(y, y, p384_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_384_cmp_equal_6(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])) == 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. + */ +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]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*6; + sp_digit* t3 = t + 4*6; + sp_digit* t4 = t + 6*6; + sp_digit* t5 = t + 8*6; + 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_384* a = p; + p = q; + q = a; + } + + /* Check double */ + (void)sp_384_sub_6(t1, p384_mod, q->y); + 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); + } + else { + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_384*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_384)); + 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<6; i++) { + r->x[i] = ap[p->infinity]->x[i]; + } + for (i=0; i<6; i++) { + r->y[i] = ap[p->infinity]->y[i]; + } + for (i=0; i<6; i++) { + r->z[i] = ap[p->infinity]->z[i]; + } + r->infinity = ap[p->infinity]->infinity; + + /* U1 = X1*Z2^2 */ + sp_384_mont_sqr_6(t1, q->z, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(t3, t1, q->z, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(t1, t1, x, p384_mod, p384_mp_mod); + /* U2 = X2*Z1^2 */ + sp_384_mont_sqr_6(t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(t4, t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(t2, t2, q->x, p384_mod, p384_mp_mod); + /* S1 = Y1*Z2^3 */ + sp_384_mont_mul_6(t3, t3, y, p384_mod, p384_mp_mod); + /* S2 = Y2*Z1^3 */ + sp_384_mont_mul_6(t4, t4, q->y, p384_mod, p384_mp_mod); + /* H = U2 - U1 */ + sp_384_mont_sub_6(t2, t2, t1, p384_mod); + /* R = S2 - S1 */ + sp_384_mont_sub_6(t4, t4, t3, p384_mod); + /* Z3 = H*Z1*Z2 */ + sp_384_mont_mul_6(z, z, q->z, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(z, z, t2, p384_mod, p384_mp_mod); + /* X3 = R^2 - H^3 - 2*U1*H^2 */ + sp_384_mont_sqr_6(x, t4, p384_mod, p384_mp_mod); + sp_384_mont_sqr_6(t5, t2, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(y, t1, t5, p384_mod, p384_mp_mod); + sp_384_mont_mul_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); + /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */ + sp_384_mont_sub_6(y, y, x, p384_mod); + sp_384_mont_mul_6(y, y, t4, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(t5, t5, t3, p384_mod, p384_mp_mod); + sp_384_mont_sub_6(y, y, t5, p384_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_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; + sp_digit* b = t + 4*6; + sp_digit* t1 = t + 6*6; + sp_digit* t2 = t + 8*6; + sp_digit* x = r[2*m].x; + sp_digit* y = r[(1<x[i]; + } + for (i=0; i<6; i++) { + y[i] = p->y[i]; + } + for (i=0; i<6; i++) { + z[i] = p->z[i]; + } + + /* Y = 2*Y */ + sp_384_mont_dbl_6(y, y, p384_mod); + /* 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); + for (i=1; i<=n; i++) { + /* 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); + sp_384_mont_tpl_6(a, t1, p384_mod); + /* 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<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_384_mont_sqr_6(t1, q->z, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(t3, t1, q->z, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(t1, t1, x, p384_mod, p384_mp_mod); + /* U2 = X2*Z1^2 */ + sp_384_mont_sqr_6(t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(t4, t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(t2, t2, q->x, p384_mod, p384_mp_mod); + /* S1 = Y1*Z2^3 */ + sp_384_mont_mul_6(t3, t3, y, p384_mod, p384_mp_mod); + /* S2 = Y2*Z1^3 */ + sp_384_mont_mul_6(t4, t4, q->y, p384_mod, p384_mp_mod); + /* H = U2 - U1 */ + sp_384_mont_sub_6(t2, t2, t1, p384_mod); + /* RS = S2 + S1 */ + sp_384_mont_add_6(t6, t4, t3, p384_mod); + /* R = S2 - S1 */ + sp_384_mont_sub_6(t4, t4, t3, p384_mod); + /* Z3 = H*Z1*Z2 */ + /* ZS = H*Z1*Z2 */ + sp_384_mont_mul_6(z, z, q->z, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(z, z, t2, p384_mod, p384_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_384_mont_sqr_6(x, t4, p384_mod, p384_mp_mod); + sp_384_mont_sqr_6(xs, t6, p384_mod, p384_mp_mod); + sp_384_mont_sqr_6(t5, t2, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(y, t1, t5, p384_mod, p384_mp_mod); + sp_384_mont_mul_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); + /* 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_mul_6(y, y, t4, p384_mod, p384_mp_mod); + sp_384_sub_6(t6, p384_mod, t6); + sp_384_mont_mul_6(ys, ys, t6, p384_mod, p384_mp_mod); + sp_384_mont_mul_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); +} + +/* Structure used to describe recoding of scalar multiplication. */ +typedef struct ecc_recode_384 { + /* Index into pre-computation table. */ + uint8_t i; + /* Use the negative of the point. */ + uint8_t neg; +} ecc_recode_384; + +/* The index into pre-computation table to use. */ +static const uint8_t recode_index_6_6[66] = { + 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, 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_6[66] = { + 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, + 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_6_6(const sp_digit* k, ecc_recode_384* v) +{ + int i, j; + uint8_t y; + int carry = 0; + int o; + sp_digit n; + + j = 0; + n = k[j]; + o = 0; + for (i=0; i<65; i++) { + y = n; + if (o + 6 < 64) { + y &= 0x3f; + n >>= 6; + o += 6; + } + else if (o + 6 == 64) { + n >>= 6; + if (++j < 6) + n = k[j]; + o = 0; + } + else if (++j < 6) { + n = k[j]; + y |= (n << (64 - o)) & 0x3f; + o -= 58; + n >>= o; + } + + y += carry; + v[i].i = recode_index_6_6[y]; + v[i].neg = recode_neg_6_6[y]; + carry = (y >> 6) + v[i].neg; + } +} + +/* Multiply the point 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. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_ecc_mulmod_win_add_sub_6(sp_point_384* r, const sp_point_384* g, + const sp_digit* k, int map, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 td[33]; + sp_point_384 rtd, pd; + sp_digit tmpd[2 * 6 * 6]; +#endif + sp_point_384* t; + sp_point_384* rt; + sp_point_384* p = NULL; + sp_digit* tmp; + sp_digit* negy; + int i; + ecc_recode_384 v[65]; + int err; + + (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) + t = (sp_point_384*)XMALLOC(sizeof(sp_point_384) * 33, heap, DYNAMIC_TYPE_ECC); + if (t == NULL) + err = MEMORY_E; + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 6 * 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_384_mod_mul_norm_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); + } + if (err == MP_OKAY) { + err = sp_384_mod_mul_norm_6(t[1].z, g->z, p384_mod); + } + + if (err == MP_OKAY) { + t[1].infinity = 0; + /* t[2] ... t[32] */ + sp_384_proj_point_dbl_n_store_6(t, &t[ 1], 5, 1, tmp); + sp_384_proj_point_add_6(&t[ 3], &t[ 2], &t[ 1], tmp); + sp_384_proj_point_dbl_6(&t[ 6], &t[ 3], tmp); + sp_384_proj_point_add_sub_6(&t[ 7], &t[ 5], &t[ 6], &t[ 1], tmp); + sp_384_proj_point_dbl_6(&t[10], &t[ 5], tmp); + sp_384_proj_point_add_sub_6(&t[11], &t[ 9], &t[10], &t[ 1], tmp); + sp_384_proj_point_dbl_6(&t[12], &t[ 6], tmp); + sp_384_proj_point_dbl_6(&t[14], &t[ 7], tmp); + sp_384_proj_point_add_sub_6(&t[15], &t[13], &t[14], &t[ 1], tmp); + sp_384_proj_point_dbl_6(&t[18], &t[ 9], tmp); + sp_384_proj_point_add_sub_6(&t[19], &t[17], &t[18], &t[ 1], tmp); + sp_384_proj_point_dbl_6(&t[20], &t[10], tmp); + sp_384_proj_point_dbl_6(&t[22], &t[11], tmp); + sp_384_proj_point_add_sub_6(&t[23], &t[21], &t[22], &t[ 1], tmp); + sp_384_proj_point_dbl_6(&t[24], &t[12], tmp); + sp_384_proj_point_dbl_6(&t[26], &t[13], tmp); + sp_384_proj_point_add_sub_6(&t[27], &t[25], &t[26], &t[ 1], tmp); + sp_384_proj_point_dbl_6(&t[28], &t[14], tmp); + sp_384_proj_point_dbl_6(&t[30], &t[15], tmp); + sp_384_proj_point_add_sub_6(&t[31], &t[29], &t[30], &t[ 1], tmp); + + negy = t[0].y; + + sp_384_ecc_recode_6_6(k, v); + + i = 64; + XMEMCPY(rt, &t[v[i].i], sizeof(sp_point_384)); + for (--i; i>=0; i--) { + sp_384_proj_point_dbl_n_6(rt, rt, 6, tmp); + + XMEMCPY(p, &t[v[i].i], sizeof(sp_point_384)); + sp_384_sub_6(negy, p384_mod, p->y); + sp_384_cond_copy_6(p->y, negy, (sp_digit)0 - v[i].neg); + sp_384_proj_point_add_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) + if (t != NULL) + XFREE(t, heap, DYNAMIC_TYPE_ECC); + if (tmp != NULL) + XFREE(tmp, heap, DYNAMIC_TYPE_ECC); +#endif + sp_384_point_free_6(p, 0, heap); + sp_384_point_free_6(rt, 0, heap); + + return err; +} + +/* 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 */ +/* 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_384_proj_point_add_qz1_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]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*6; + sp_digit* t3 = t + 4*6; + sp_digit* t4 = t + 6*6; + sp_digit* t5 = t + 8*6; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + /* Check double */ + (void)sp_384_sub_6(t1, p384_mod, q->y); + 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); + } + else { + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_384*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_384)); + 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<6; i++) { + r->x[i] = ap[p->infinity]->x[i]; + } + for (i=0; i<6; i++) { + r->y[i] = ap[p->infinity]->y[i]; + } + for (i=0; i<6; i++) { + r->z[i] = ap[p->infinity]->z[i]; + } + r->infinity = ap[p->infinity]->infinity; + + /* U2 = X2*Z1^2 */ + sp_384_mont_sqr_6(t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(t4, t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(t2, t2, q->x, p384_mod, p384_mp_mod); + /* S2 = Y2*Z1^3 */ + sp_384_mont_mul_6(t4, t4, q->y, p384_mod, p384_mp_mod); + /* H = U2 - X1 */ + sp_384_mont_sub_6(t2, t2, x, p384_mod); + /* R = S2 - Y1 */ + sp_384_mont_sub_6(t4, t4, y, p384_mod); + /* Z3 = H*Z1 */ + sp_384_mont_mul_6(z, z, t2, p384_mod, p384_mp_mod); + /* X3 = R^2 - H^3 - 2*X1*H^2 */ + sp_384_mont_sqr_6(t1, t4, p384_mod, p384_mp_mod); + sp_384_mont_sqr_6(t5, t2, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(t3, x, t5, p384_mod, p384_mp_mod); + sp_384_mont_mul_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); + /* Y3 = R*(X1*H^2 - X3) - Y1*H^3 */ + sp_384_mont_sub_6(t3, t3, x, p384_mod); + sp_384_mont_mul_6(t3, t3, t4, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(t5, t5, y, p384_mod, p384_mp_mod); + sp_384_mont_sub_6(y, t3, t5, p384_mod); + } +} + +#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_6(sp_point_384* a, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 6; + sp_digit* tmp = t + 4 * 6; + + sp_384_mont_inv_6(t1, a->z, tmp); + + sp_384_mont_sqr_6(t2, t1, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(t1, t2, t1, p384_mod, p384_mp_mod); + + sp_384_mont_mul_6(a->x, a->x, t2, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(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. + * + * 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) + sp_point_384 td, s1d, s2d; +#endif + sp_point_384* t; + sp_point_384* s1 = NULL; + sp_point_384* s2 = NULL; + int i, 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, 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 */ +/* Multiply the point 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_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, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + 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, j; + int y, x; + int err; + + (void)g; + (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) + 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; + for (j=0,x=47; j<8; j++,x+=48) { + y |= ((k[x / 64] >> (x % 64)) & 1) << j; + } + 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; + for (j=0,x=i; j<8; j++,x+=48) { + y |= ((k[x / 64] >> (x % 64)) & 1) << j; + } + + sp_384_proj_point_dbl_6(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_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) + 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; +} + +#ifdef FP_ECC +#ifndef FP_ENTRIES + #define FP_ENTRIES 16 +#endif + +typedef struct sp_cache_384_t { + sp_digit x[6]; + sp_digit y[6]; + sp_table_entry_384 table[256]; + uint32_t cnt; + int set; +} sp_cache_384_t; + +static THREAD_LS_T sp_cache_384_t sp_cache_384[FP_ENTRIES]; +static THREAD_LS_T int sp_cache_384_last = -1; +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 + +static void sp_ecc_get_cache_384(const sp_point_384* g, sp_cache_384_t** cache) +{ + int i, 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. + * 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, void* heap) +{ +#ifndef FP_ECC + return sp_384_ecc_mulmod_win_add_sub_6(r, g, k, map, 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, heap); + } + else { + err = sp_384_ecc_mulmod_stripe_6(r, g, cache->table, k, + map, 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_384(mp_int* km, ecc_point* gm, ecc_point* r, int map, + void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 p; + sp_digit kd[6]; +#endif + sp_point_384* point; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_384_point_new_6(heap, p, point); +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 6, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) + err = MEMORY_E; + } +#else + k = kd; +#endif + if (err == MP_OKAY) { + sp_384_from_mp(k, 6, km); + sp_384_point_from_ecc_point_6(point, gm); + + err = sp_384_ecc_mulmod_6(point, point, k, map, heap); + } + if (err == MP_OKAY) { + err = sp_384_point_to_ecc_point_6(point, r); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_6(point, 0, heap); + + return err; +} + +static const sp_table_entry_384 p384_table[256] = { + /* 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 */ + { { 0x298647532b0c535bL,0x90dd695370506296L,0x038cd6b4216ab9acL, + 0x3df9b7b7be12d76aL,0x13f4d9785f347bdbL,0x222c5c9c13e94489L }, + { 0x5f8e796f2680dc64L,0x120e7cb758352417L,0x254b5d8ad10740b8L, + 0xc38b8efb5337dee6L,0xf688c2e194f02247L,0x7b5c75f36c25bc4cL } }, + /* 3 */ + { { 0xe26a3cc39edffea5L,0x35bbfd1c37d7e9fcL,0xf0e7700d9bde3ef6L, + 0x0380eb471a538f5aL,0x2e9da8bb05bf9eb3L,0xdbb93c731a460c3eL }, + { 0x37dba260f526b605L,0x95d4978efd785537L,0x24ed793aed72a04aL, + 0x2694837776005b1aL,0x99f557b99e681f82L,0xae5f9557d64954efL } }, + /* 4 */ + { { 0x24480c57f26feef9L,0xc31a26943a0e1240L,0x735002c3273e2bc7L, + 0x8c42e9c53ef1ed4cL,0x028babf67f4948e8L,0x6a502f438a978632L }, + { 0xf5f13a46b74536feL,0x1d218babd8a9f0ebL,0x30f36bcc37232768L, + 0xc5317b31576e8c18L,0xef1d57a69bbcb766L,0x917c4930b3e3d4dcL } }, + /* 5 */ + { { 0x11426e2ee349ddd0L,0x9f117ef99b2fc250L,0xff36b480ec0174a6L, + 0x4f4bde7618458466L,0x2f2edb6d05806049L,0x8adc75d119dfca92L }, + { 0xa619d097b7d5a7ceL,0x874275e5a34411e9L,0x5403e0470da4b4efL, + 0x2ebaafd977901d8fL,0x5e63ebcea747170fL,0x12a369447f9d8036L } }, + /* 6 */ + { { 0x28f9c07a4fc52870L,0xce0b37481a53a961L,0xd550fa180e1828d9L, + 0xa24abaf76adb225aL,0xd11ed0a56e58a348L,0xf3d811e6948acb62L }, + { 0x8618dd774c61ed22L,0x0bb747f980b47c9dL,0x22bf796fde6b8559L, + 0xfdfd1c6d680a21e9L,0xc0db15772af2c9ddL,0xa09379e6c1e90f3dL } }, + /* 7 */ + { { 0x386c66efe085c629L,0x5fc2a461095bc89aL,0x1353d631203f4b41L, + 0x7ca1972b7e4bd8f5L,0xb077380aa7df8ce9L,0xd8a90389ee7e4ea3L }, + { 0x1bc74dc7e7b14461L,0xdc2cb0140c9c4f78L,0x52b4b3a684ef0a10L, + 0xbde6ea5d20327fe2L,0xb71ec435660f9615L,0xeede5a04b8ad8173L } }, + /* 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 */ + { { 0x73ade4da2341c342L,0xdd326e54ea704422L,0x336c7d983741cef3L, + 0x1eafa00d59e61549L,0xcd3ed892bd9a3efdL,0x03faf26cc5c6c7e4L }, + { 0x087e2fcf3045f8acL,0x14a65532174f1e73L,0x2cf84f28fe0af9a7L, + 0xddfd7a842cdc935bL,0x4c0f117b6929c895L,0x356572d64c8bcfccL } }, + /* 18 */ + { { 0x7ecbac017d8c1bbaL,0x6058f9c390b0f3d5L,0xaee116e3f6197d0fL, + 0xc4dd70684033b128L,0xf084dba6c209b983L,0x97c7c2cf831dbc4aL }, + { 0x2f4e61ddf96010e8L,0xd97e4e20529faa17L,0x4ee6666069d37f20L, + 0xccc139ed3d366d72L,0x690b6ee213488e0fL,0x7cad1dc5f3a6d533L } }, + /* 19 */ + { { 0x660a9a81da57a41fL,0xe74a0412ec0039b6L,0x42343c6b5e1dad15L, + 0x284f3ff546681d4cL,0xb51087f163749e89L,0x070f23cc6f9f2f13L }, + { 0x542211da5d186e14L,0x84748f37fddb0dffL,0x41a3aab4db1f4180L, + 0x25ed667ba6402d0eL,0x2f2924a902f58355L,0x5844ee7cfa44a689L } }, + /* 20 */ + { { 0xfab086073f3b236fL,0x19e9d41d81e221daL,0xf3f6571e3927b428L, + 0x4348a9337550f1f6L,0x7167b996a85e62f0L,0x62d437597f5452bfL }, + { 0xd85feb9ef2955926L,0x440a561f6df78353L,0x389668ec9ca36b59L, + 0x052bf1a1a22da016L,0xbdfbff72f6093254L,0x94e50f28e22209f3L } }, + /* 21 */ + { { 0x90b2e5b33062e8afL,0xa8572375e8a3d369L,0x3fe1b00b201db7b1L, + 0xe926def0ee651aa2L,0x6542c9beb9b10ad7L,0x098e309ba2fcbe74L }, + { 0x779deeb3fff1d63fL,0x23d0e80a20bfd374L,0x8452bb3b8768f797L, + 0xcf75bb4d1f952856L,0x8fe6b40029ea3faaL,0x12bd3e4081373a53L } }, + /* 22 */ + { { 0xc023780d104cbba5L,0x6207e747fa35dd4cL,0x35c239281ca9b6a3L, + 0x4ff19be897987b10L,0xb8476bbf8022eee8L,0xaa0a4a14d3bbe74dL }, + { 0x20f94331187d4543L,0x3215387079f6e066L,0x83b0f74eac7e82e1L, + 0xa7748ba2828f06abL,0xc5f0298ac26ef35fL,0x0f0c50708e9a7dbdL } }, + /* 23 */ + { { 0x0c5c244cdef029ddL,0x3dabc687850661b8L,0x9992b865fe11d981L, + 0xe9801b8f6274dbadL,0xe54e6319098da242L,0x9929a91a91a53d08L }, + { 0x37bffd7235285887L,0xbc759425f1418102L,0x9280cc35fd2e6e20L, + 0x735c600cfbc42ee5L,0xb7ad28648837619aL,0xa3627231a778c57bL } }, + /* 24 */ + { { 0xae799b5c91361ed8L,0x47d71b756c63366cL,0x54cdd5211b265a6aL, + 0xe0215a5998d77b74L,0x4424d9b7bab29db0L,0x8b0ffacc7fd9e536L }, + { 0x46d85d1237b5d9efL,0x5b106d62bfa91747L,0xed0479f85f99ba2dL, + 0x0e6f39231d104de4L,0x83a84c8425e8983fL,0xa9507e0af8105a70L } }, + /* 25 */ + { { 0xf6c68a6e14cf381cL,0xaf9d27bdc22e31ccL,0x23568d4daa8a5ccbL, + 0xe431eec0e338e4d2L,0xf1a828fe8f52ad1fL,0xdb6a0579e86acd80L }, + { 0x2885672e4507832aL,0x73fc275f887e5289L,0x65f8027805610d08L, + 0x8d9b4554075ff5b0L,0x3a8e8fb109f712b5L,0x39f0ac862ebe9cf2L } }, + /* 26 */ + { { 0xd8fabf784c52edf5L,0xdcd737e5a589ae53L,0x94918bf0d791ab17L, + 0xb5fbd956bcff06c9L,0xf6d3032edca46d45L,0x2cdff7e141a3e486L }, + { 0x6674b3ba61f47ec8L,0x8a882163eef84608L,0xa257c7054c687f90L, + 0xe30cb2edf6cdf227L,0x2c4c64ca7f6ea846L,0x186fa17ccc6bcd3cL } }, + /* 27 */ + { { 0x48a3f5361dfcb91eL,0x83595e13646d358aL,0xbd15827b91128798L, + 0x3ce612b82187757aL,0x873150a161bd7372L,0xf4684530b662f568L }, + { 0x8833950b401896f6L,0xe11cb89a77f3e090L,0xb2f12cac48e7f4a5L, + 0x313dd769f606677eL,0xfdcf08b316579f93L,0x6429cec946b8f22bL } }, + /* 28 */ + { { 0x4984dd54bb75f9a4L,0x4aef06b929d3b570L,0xb5f84ca23d6e4c1eL, + 0x24c61c11b083ef35L,0xce4a7392392ca9ffL,0x865d65176730a800L }, + { 0xca3dfe76722b4a2bL,0x12c04bf97b083e0eL,0x803ce5b51b86b8a5L, + 0x3fc7632d6a7e3e0cL,0xc89970c2c81adbe4L,0x3cbcd3ad120e16b1L } }, + /* 29 */ + { { 0xfbfb4cc7ec30ce93L,0x10ed6c7db72720a2L,0xec675bf747b55500L, + 0x90725903333ff7c3L,0xc7c3973e5075bfc0L,0xb049ecb007acf31bL }, + { 0xb4076eaf4f58839cL,0x101896daa2b05e4fL,0x3f6033b0ab40c66eL, + 0x19ee9eebc8d864baL,0xeb6cf15547bf6d2aL,0x8e5a9663f826477dL } }, + /* 30 */ + { { 0x69e62fddf7fbd5e1L,0x38ecfe5476912b1dL,0x845a3d56d1da3bfbL, + 0x0494950e1c86f0d4L,0x83cadbf93bc36ce8L,0x41fce5724fccc8d1L }, + { 0x05f939c28332c144L,0xb17f248b0871e46eL,0x3d8534e266e8aff6L, + 0x1d06f1dc3b85c629L,0xdb06a32ea3131b73L,0xf295184d8b3f64e5L } }, + /* 31 */ + { { 0xd9653ff736ddc103L,0x25f43e3795ef606fL,0x09e301fcfe06dce8L, + 0x85af234130b6eebfL,0x79b12b530ff56b20L,0x9b4fb499fe9a3c6bL }, + { 0x0154f89251d27ac2L,0xd33167e356ca5389L,0x7828ec1fafc065a6L, + 0x0959a2587f746c9bL,0xb18f1be30c44f837L,0xa7946117c4132fdbL } }, + /* 32 */ + { { 0xc0426b775e3c647bL,0xbfcbd9398cf05348L,0x31d312e3172c0d3dL, + 0x5f49fde6ee754737L,0x895530f06da7ee61L,0xcf281b0ae8b3a5fbL }, + { 0xfd14973541b8a543L,0x41a625a73080dd30L,0xe2baae07653908cfL, + 0xc3d01436ba02a278L,0xa0d0222e7b21b8f8L,0xfdc270e9d7ec1297L } }, + /* 33 */ + { { 0x00873c0cbc7f41d6L,0xd976113e1b7ad641L,0x2a536ff4238443fbL, + 0x030d00e241e62e45L,0x532e98675f545fc6L,0xcd0331088e91208cL }, + { 0xd1a04c999797612cL,0xd4393e02eea674e2L,0xd56fa69ee19742a1L, + 0xdd2ab48085f0590eL,0xa5cefc5248a2243dL,0x48cc67b654383f41L } }, + /* 34 */ + { { 0x4e50430efc14ab48L,0x195b7f4f26706a74L,0x2fe8a228cc881ff6L, + 0xb1b968e2d945013dL,0x936aa5794b92162bL,0x4fb766b7364e754aL }, + { 0x13f93bca31e1ff7fL,0x696eb5cace4f2691L,0xff754bf8a2b09e02L, + 0x58f13c9ce58e3ff8L,0xb757346f1678c0b0L,0xd54200dba86692b3L } }, + /* 35 */ + { { 0x9a030bbd6dda1265L,0xf7b4f3fce89718ddL,0xa6a4931f936065b8L, + 0xbce72d875f72241cL,0x6cbb51cb65775857L,0xc71618154e993675L }, + { 0xe81a0f792ee32189L,0xef2fab26277dc0b2L,0x9e64f6feb71f469fL, + 0xb448ce33dfdaf859L,0x3f5c1c4cbe6b5df1L,0xfb8dfb001de45f7bL } }, + /* 36 */ + { { 0xc7345fa74d5bb921L,0x5c7e04be4d2b667eL,0x47ed3a80282d7a3eL, + 0x5c2777f87e47b2a4L,0x89b3b10008488e2eL,0x9aad77c2b2eb5b45L }, + { 0xd681bca7daac34aeL,0x2452e4e526afb326L,0x0c88792441a1ee14L, + 0x743b04d4c2407adeL,0xcb5e999bfc17a2acL,0x4dca2f824a701a06L } }, + /* 37 */ + { { 0x68e31ca61127bc1aL,0xa3edd59b17ead3beL,0x67b6b645e25f5a15L, + 0x76221794a420e15eL,0x794fd83b4b1e872eL,0x7cab3f03b2dece1bL }, + { 0x7119bf15ca9b3586L,0xa55459244d250bd7L,0x173633eacc6bcf24L, + 0x9bd308c2b1b6f884L,0x3bae06f5447d38c3L,0x54dcc135f341fe1cL } }, + /* 38 */ + { { 0x56d3598d943caf0dL,0xce044ea9225ff133L,0x9edf6a7c563fadeaL, + 0x632eb94473e8dc27L,0x814b467e3190dcabL,0x2d4f4f316dbb1e31L }, + { 0x8d69811ca143b7caL,0x4ec1ac32de7cf950L,0x223ab5fd37b5fe82L, + 0xe82616e49390f1d9L,0xabff4b2075804610L,0x11b9be15875b08f0L } }, + /* 39 */ + { { 0x4ae31a3d3bbe682cL,0xbc7c5d2674eef2ddL,0x92afd10a3c47dd40L, + 0xec7e0a3bc14ab9e1L,0x6a6c3dd1b2e495e4L,0x085ee5e9309bcd85L }, + { 0xf381a9088c2e67fdL,0x32083a80e261eaf2L,0x0fcd6a4996deee15L, + 0xe3b8fb035e524c79L,0x8dc360d91d5b08b9L,0x3a06e2c87f26719fL } }, + /* 40 */ + { { 0x5cd9f5a87237cac0L,0x93f0b59d43586794L,0x4384a764e94f6c4eL, + 0x8304ed2bb62782d3L,0x0b8db8b3cde06015L,0x4336dd535dbe190fL }, + { 0x5744355392ab473aL,0x031c7275be5ed046L,0x3e78678c21909aa4L, + 0x4ab7e04f99202ddbL,0x2648d2066977e635L,0xd427d184093198beL } }, + /* 41 */ + { { 0x822848f50f9b5a31L,0xbb003468baadb62aL,0x233a04723357559cL, + 0x49ef688079aee843L,0xa89867a0aeb9e1e3L,0xc151931b1f6f9a55L }, + { 0xd264eb0bad74251eL,0x37b9b2634abf295eL,0xb600921b04960d10L, + 0x0de53dbc4da77dc0L,0x01d9bab3d2b18697L,0xad54ec7af7156ddfL } }, + /* 42 */ + { { 0x8e74dc3579efdc58L,0x456bd3694ff68ddbL,0x724e74ccd32096a5L, + 0xe41cff42386783d0L,0xa04c7f217c70d8a4L,0x41199d2fe61a19a2L }, + { 0xd389a3e029c05dd2L,0x535f2a6be7e3fda9L,0x26ecf72d7c2b4df8L, + 0x678275f4fe745294L,0x6319c9cc9d23f519L,0x1e05a02d88048fc4L } }, + /* 43 */ + { { 0x75cc8e2ed4d5ffe8L,0xf8bb4896dbea17f2L,0x35059790cee3cb4aL, + 0x4c06ee85a47c6165L,0xf98fff2592935d2fL,0x34c4a57232ffd7c7L }, + { 0xc4b14806ea0376a2L,0x2ea5e7504f115e02L,0x532d76e21e55d7c0L, + 0x68dc9411f31044daL,0x9272e46571b77993L,0xadaa38bb93a8cfd5L } }, + /* 44 */ + { { 0x4bf0c7127d4ed72aL,0xda0e9264ba1f79a3L,0x48c0258bf4c39ea4L, + 0xa5394ed82a715138L,0x4af511cebf06c660L,0xfcebceefec5c37cdL }, + { 0xf23b75aa779ae8c1L,0xdeff59ccad1e606eL,0xf3f526fd22755c82L, + 0x64c5ab44bb32cefdL,0xa96e11a2915bdefdL,0xab19746a1143813eL } }, + /* 45 */ + { { 0x43c78585ec837d7dL,0xca5b6fbcb8ee0ba4L,0x34e924d9d5dbb5eeL, + 0x3f4fa104bb4f1ca5L,0x15458b72398640f7L,0x4231faa9d7f407eaL }, + { 0x53e0661ef96e6896L,0x554e4c69d03b0f9dL,0xd4fcb07b9c7858d1L, + 0x7e95279352cb04faL,0x5f5f15748974e7f7L,0x2e3fa5586b6d57c8L } }, + /* 46 */ + { { 0x42cd48036a9951a8L,0xa8b15b8842792ad0L,0x18e8bcf9abb29a73L, + 0xbfd9a092409933e8L,0x760a3594efb88dc4L,0x1441886340724458L }, + { 0x162a56ee99caedc7L,0x8fb12ecd91d101c9L,0xea671967393202daL, + 0x1aac8c4aa4ccd796L,0x7db050361cf185a8L,0x0c9f86cd8cfd095aL } }, + /* 47 */ + { { 0x9a72814710b2a556L,0x767ca964327b70b2L,0x04ed9e125e3799b7L, + 0x6781d2dc22a3eb2aL,0x5bd116eb0d9450acL,0xeccac1fca7ebe08aL }, + { 0xde68444fdc2d6e94L,0x3621f42935ecf21bL,0x14e2d54329e03a2cL, + 0x53e42cd57d3e7f0aL,0xbba26c0973ed00b9L,0x00297c39c57d2272L } }, + /* 48 */ + { { 0x3aaaab10b8243a7dL,0x6eeef93e8fa58c5bL,0xf866fca39ae7f764L, + 0x64105a2661ab04d3L,0xa3578d8a03945d66L,0xb08cd3e4791b848cL }, + { 0x45edc5f8756d2411L,0xd4a790d9a755128cL,0xc2cf096349e5f6a0L, + 0xc66d267df649beaaL,0x3ce6d9688467039eL,0x50046c6b42f7816fL } }, + /* 49 */ + { { 0x92ae160266425043L,0x1ff66afdf08db890L,0x386f5a7f8f162ce5L, + 0x18d2dea0fcf5598fL,0x78372b3a1a8ca18eL,0xdf0d20eb8cd0e6f7L }, + { 0x7edd5e1d75bb4045L,0x252a47ceb96d94b7L,0xbdb293582c626776L, + 0x853c394340dd1031L,0x9dc9becf7d5f47fdL,0x27c2302fbae4044aL } }, + /* 50 */ + { { 0x2d1d208a8f2d49ceL,0x0d91aa02162df0a2L,0x9c5cce8709a07f65L, + 0xdf07238b84339012L,0x5028e2c8419442cdL,0x2dcbd35872062abaL }, + { 0xb5fbc3cbe4680967L,0x2a7bc6459f92d72cL,0x806c76e1116c369dL, + 0x5c50677a3177e8d8L,0x753739eb4569df57L,0x2d481ef636c3f40bL } }, + /* 51 */ + { { 0x1a2d39fdfea1103eL,0xeaae559295f81b17L,0xdbd0aa18f59b264aL, + 0x90c39c1acb592ee0L,0xdf62f80d9750cca3L,0xda4d8283df97cc6cL }, + { 0x0a6dd3461e201067L,0x1531f85969fb1f6bL,0x4895e5521d60121fL, + 0x0b21aab04c041c91L,0x9d896c46bcc1ccf8L,0xd24da3b33141bde7L } }, + /* 52 */ + { { 0x575a053753b0a354L,0x392ff2f40c6ddcd8L,0x0b8e8cff56157b94L, + 0x073e57bd3b1b80d1L,0x2a75e0f03fedee15L,0x752380e4aa8e6f19L }, + { 0x1f4e227c6558ffe9L,0x3a34861819ec5415L,0xab382d5ef7997085L, + 0x5e6deaffddc46ac2L,0xe5144078fc8d094cL,0xf674fe51f60e37c6L } }, + /* 53 */ + { { 0x6fb87ae5af63408fL,0xa39c36a9cd75a737L,0x7833313fcf4c618dL, + 0xfbcd4482f034c88dL,0x4469a76139b35288L,0x77a711c566b5d9c9L }, + { 0x4a695dc7944f8d65L,0xe6da5f65161aaba8L,0x8654e9c324601669L, + 0xbc8b93f528ae7491L,0x5f1d1e838f5580d8L,0x8ccf9a1acea32cc8L } }, + /* 54 */ + { { 0x28ab110c7196fee2L,0x75799d63874c8945L,0xa262934829aedaddL, + 0x9714cc7b2be88ff4L,0xf71293cfd58d60d6L,0xda6b6cb332a564e9L }, + { 0xf43fddb13dd821c2L,0xf2f2785f90dd323dL,0x91246419048489f8L, + 0x61660f26d24c6749L,0x961d9e8cc803c15cL,0x631c6158faadc4c9L } }, + /* 55 */ + { { 0xacf2ebe0fd752366L,0xb93c340e139be88bL,0x98f664850f20179eL, + 0x14820254ff1da785L,0x5278e2764f85c16eL,0xa246ee457aab1913L }, + { 0x43861eb453763b33L,0xc49f03fc45c0bc0dL,0xafff16bcad6b1ea1L, + 0xce33908b6fd49c99L,0x5c51e9bff7fde8c3L,0x076a7a39ff142c5eL } }, + /* 56 */ + { { 0x04639dfe9e338d10L,0x8ee6996ff42b411bL,0x960461d1a875cef2L, + 0x1057b6d695b4d0baL,0x27639252a906e0bcL,0x2c19f09ae1c20f8aL }, + { 0x5b8fc3f0eef4c43dL,0xe2e1b1a807a84aa9L,0x5f455528835d2bdbL, + 0x0f4aee4d207132ddL,0xe9f8338c3907f675L,0x7a874dc90e0531f0L } }, + /* 57 */ + { { 0x84b22d4597c27050L,0xbd0b8df759e70bf8L,0xb4d6740579738b9bL, + 0x47f4d5f5cd917c4fL,0x9099c4ce13ce6e33L,0x942bfd39521d0f8bL }, + { 0x5028f0f6a43b566dL,0xaf6e866921bff7deL,0x83f6f856c44232cdL, + 0x65680579f915069aL,0xd12095a2ecfecb85L,0xcf7f06aedb01ba16L } }, + /* 58 */ + { { 0x0f56e3c48ef96c80L,0xd521f2b33ddb609cL,0x2be941027dc1450dL, + 0x2d21a07102a91fe2L,0x2e6f74fa1efa37deL,0x9a9a90b8156c28a1L }, + { 0xc54ea9ea9dc7dfcbL,0xc74e66fc2c2c1d62L,0x9f23f96749d3e067L, + 0x1c7c3a4654dd38adL,0xc70058845946cee3L,0x8985636845cc045dL } }, + /* 59 */ + { { 0x29da7cd4fce73946L,0x8f697db523168563L,0x8e235e9ccba92ec6L, + 0x55d4655f9f91d3eaL,0xf3689f23aa50a6cdL,0xdcf21c2621e6a1a0L }, + { 0xcffbc82e61b818bfL,0xc74a2f96da47a243L,0x234e980a8bc1a0cfL, + 0xf35fd6b57929cb6dL,0x81468e12efe17d6cL,0xddea6ae558b2dafbL } }, + /* 60 */ + { { 0x294de8877e787b2eL,0x258acc1f39a9310dL,0x92d9714aac14265dL, + 0x18b5591c708b48a0L,0x27cc6bb0e1abbf71L,0xc0581fa3568307b9L }, + { 0x9e0f58a3f24d4d58L,0xfebe9bb8e0ce2327L,0x91fd6a419d1be702L, + 0x9a7d8a45facac993L,0xabc0a08c9e50d66dL,0x02c342f706498201L } }, + /* 61 */ + { { 0xccd71407157bdbc2L,0x72fa89c6ad0e1605L,0xb1d3da2bb92a015fL, + 0x8ad9e7cda0a3fe56L,0x160edcbd24f06737L,0x79d4db3361275be6L }, + { 0xd3d31fd95f3497c4L,0x8cafeaee04192fb0L,0xe13ca74513a50af3L, + 0x188261678c85aae5L,0xce06cea89eb556ffL,0x2eef1995bdb549f3L } }, + /* 62 */ + { { 0x8ed7d3eb50596edcL,0xaa359362905243a2L,0xa212c2c2a4b6d02bL, + 0x611fd727c4fbec68L,0x8a0b8ff7b84f733dL,0xd85a6b905f0daf0eL }, + { 0x60e899f5d4091cf7L,0x4fef2b672eff2768L,0xc1f195cb10c33964L, + 0x8275d36993626a8fL,0xc77904f40d6c840aL,0x88d8b7fd7a868acdL } }, + /* 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 } }, +}; + +/* 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. + * 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, void* heap) +{ + return sp_384_ecc_mulmod_stripe_6(r, &p384_base, p384_table, + k, map, heap); +} + +/* Multiply the base point of P384 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_384(mp_int* km, ecc_point* r, int map, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 p; + sp_digit kd[6]; +#endif + sp_point_384* point; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_384_point_new_6(heap, p, point); +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 6, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + } +#else + k = kd; +#endif + if (err == MP_OKAY) { + sp_384_from_mp(k, 6, km); + + err = sp_384_ecc_mulmod_base_6(point, k, map, heap); + } + if (err == MP_OKAY) { + err = sp_384_point_to_ecc_point_6(point, r); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + 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. + * Implementation is constant time. + * + * a Number to check. + * returns 1 if the number is zero and 0 otherwise. + */ +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 */ +/* Add 1 to a. (a = a + 1) + * + * a A single precision integer. + */ +static void sp_384_add_one_6(sp_digit* a) +{ + __asm__ __volatile__ ( + "ldp x1, x2, [%[a], 0]\n\t" + "ldp x3, x4, [%[a], 16]\n\t" + "adds x1, x1, #1\n\t" + "adcs x2, x2, xzr\n\t" + "adcs x3, x3, xzr\n\t" + "adcs x4, x4, xzr\n\t" + "stp x1, x2, [%[a], 0]\n\t" + "stp x3, x4, [%[a], 16]\n\t" + "ldp x1, x2, [%[a], 32]\n\t" + "adcs x1, x1, xzr\n\t" + "adcs x2, x2, xzr\n\t" + "stp x1, x2, [%[a], 32]\n\t" + : + : [a] "r" (a) + : "memory", "x1", "x2", "x3", "x4" + ); +} + +/* 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_384_from_bin(sp_digit* r, int size, const byte* a, int n) +{ + int i, j = 0; + word32 s = 0; + + r[0] = 0; + for (i = n-1; i >= 0; i--) { + r[j] |= (((sp_digit)a[i]) << s); + if (s >= 56U) { + r[j] &= 0xffffffffffffffffl; + s = 64U - 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; + } +} + +/* Generates a scalar that is in the range 1..order-1. + * + * rng Random number generator. + * k Scalar value. + * returns RNG failures, MEMORY_E when memory allocation fails and + * MP_OKAY on success. + */ +static int sp_384_ecc_gen_k_6(WC_RNG* rng, sp_digit* k) +{ + int err; + byte buf[48]; + + do { + err = wc_RNG_GenerateBlock(rng, buf, sizeof(buf)); + if (err == 0) { + sp_384_from_bin(k, 6, buf, (int)sizeof(buf)); + if (sp_384_cmp_6(k, p384_order2) < 0) { + sp_384_add_one_6(k); + break; + } + } + } + while (err == 0); + + return err; +} + +/* Makes a random EC key pair. + * + * rng Random number generator. + * priv Generated private value. + * pub Generated public point. + * heap Heap to use for allocation. + * returns ECC_INF_E when the point does not have the correct order, RNG + * failures, MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_make_key_384(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 p; + sp_digit kd[6]; +#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN + sp_point_384 inf; +#endif +#endif + sp_point_384* point; + sp_digit* k = NULL; +#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN + sp_point_384* infinity; +#endif + int err; + + (void)heap; + + err = sp_384_point_new_6(heap, p, point); +#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN + if (err == MP_OKAY) { + err = sp_384_point_new_6(heap, inf, infinity); + } +#endif +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 6, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + } +#else + k = kd; +#endif + + if (err == MP_OKAY) { + err = sp_384_ecc_gen_k_6(rng, k); + } + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_base_6(point, k, 1, NULL); + } + +#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_6(infinity, point, p384_order, 1, NULL); + } + if (err == MP_OKAY) { + if ((sp_384_iszero_6(point->x) == 0) || (sp_384_iszero_6(point->y) == 0)) { + err = ECC_INF_E; + } + } +#endif + + if (err == MP_OKAY) { + err = sp_384_to_mp(k, priv); + } + if (err == MP_OKAY) { + err = sp_384_point_to_ecc_point_6(point, pub); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif +#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN + sp_384_point_free_6(infinity, 1, heap); +#endif + sp_384_point_free_6(point, 1, heap); + + return err; +} + +#ifdef HAVE_ECC_DHE +/* Write r as big endian to byte array. + * Fixed length number of bytes written: 48 + * + * r A single precision integer. + * a Byte array. + */ +static void sp_384_to_bin(sp_digit* r, byte* a) +{ + int i, j, s = 0, b; + + j = 384 / 8 - 1; + a[j] = 0; + for (i=0; i<6 && j>=0; i++) { + b = 0; + /* lint allow cast of mismatch sp_digit and int */ + a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ + if (j < 0) { + break; + } + while (b < 64) { + a[j--] = r[i] >> b; b += 8; + if (j < 0) { + break; + } + } + s = 8 - (b - 64); + if (j >= 0) { + a[j] = 0; + } + if (s != 0) { + j++; + } + } +} + +/* Multiply the point by the scalar and serialize the X ordinate. + * The number is 0 padded to maximum size on output. + * + * priv Scalar to multiply the point by. + * pub Point to multiply. + * out Buffer to hold X ordinate. + * outLen On entry, size of the buffer in bytes. + * On exit, length of data in buffer in bytes. + * heap Heap to use for allocation. + * 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, + word32* outLen, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 p; + sp_digit kd[6]; +#endif + sp_point_384* point = NULL; + sp_digit* k = NULL; + int err = MP_OKAY; + + if (*outLen < 48U) { + err = BUFFER_E; + } + + if (err == MP_OKAY) { + err = sp_384_point_new_6(heap, p, point); + } +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 6, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) + err = MEMORY_E; + } +#else + k = kd; +#endif + + if (err == MP_OKAY) { + sp_384_from_mp(k, 6, priv); + sp_384_point_from_ecc_point_6(point, pub); + err = sp_384_ecc_mulmod_6(point, point, k, 1, heap); + } + if (err == MP_OKAY) { + sp_384_to_bin(point->x, out); + *outLen = 48; + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_6(point, 0, heap); + + return err; +} +#endif /* HAVE_ECC_DHE */ + +#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) +#endif +#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) +/* Sub b from a into a. (a -= b) + * + * a A single precision integer and result. + * b A single precision integer. + */ +static sp_digit sp_384_sub_in_place_6(sp_digit* a, const sp_digit* b) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "ldp x2, x3, [%[a], 0]\n\t" + "ldp x4, x5, [%[a], 16]\n\t" + "ldp x6, x7, [%[b], 0]\n\t" + "ldp x8, x9, [%[b], 16]\n\t" + "subs x2, x2, x6\n\t" + "sbcs x3, x3, x7\n\t" + "sbcs x4, x4, x8\n\t" + "sbcs x5, x5, x9\n\t" + "stp x2, x3, [%[a], 0]\n\t" + "stp x4, x5, [%[a], 16]\n\t" + "ldr x2, [%[a], 32]\n\t" + "ldr x3, [%[a], 40]\n\t" + "ldr x6, [%[b], 32]\n\t" + "ldr x7, [%[b], 40]\n\t" + "sbcs x2, x2, x6\n\t" + "sbcs x3, x3, x7\n\t" + "str x2, [%[a], 32]\n\t" + "str x3, [%[a], 40]\n\t" + "csetm %[c], cc\n\t" + : [c] "+r" (c) + : [a] "r" (a), [b] "r" (b) + : "memory", "x2", "x3", "x4", "x5", "x6", "x7", "x8", "x9" + ); + + return c; +} + +/* 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_384_mul_d_6(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, 48\n\t" + "b.lt 1b\n\t" + "str x3, [%[r], 48]\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" + "ldr x8, [%[a]]\n\t" + "mul x3, %[b], x8\n\t" + "umulh x4, %[b], x8\n\t" + "mov x5, 0\n\t" + "str x3, [%[r]]\n\t" + "# A[1] * B\n\t" + "ldr x8, [%[a], 8]\n\t" + "mov x3, 0\n\t" + "mul x6, %[b], x8\n\t" + "umulh x7, %[b], x8\n\t" + "adds x4, x4, x6\n\t" + "adcs x5, x5, x7\n\t" + "adc x3, xzr, xzr\n\t" + "str x4, [%[r], 8]\n\t" + "# A[2] * B\n\t" + "ldr x8, [%[a], 16]\n\t" + "mov x4, 0\n\t" + "mul x6, %[b], x8\n\t" + "umulh x7, %[b], x8\n\t" + "adds x5, x5, x6\n\t" + "adcs x3, x3, x7\n\t" + "adc x4, xzr, xzr\n\t" + "str x5, [%[r], 16]\n\t" + "# A[3] * B\n\t" + "ldr x8, [%[a], 24]\n\t" + "mov x5, 0\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], 24]\n\t" + "# A[4] * B\n\t" + "ldr x8, [%[a], 32]\n\t" + "mov x3, 0\n\t" + "mul x6, %[b], x8\n\t" + "umulh x7, %[b], x8\n\t" + "adds x4, x4, x6\n\t" + "adcs x5, x5, x7\n\t" + "adc x3, xzr, xzr\n\t" + "str x4, [%[r], 32]\n\t" + "# A[5] * B\n\t" + "ldr x8, [%[a], 40]\n\t" + "mul x6, %[b], x8\n\t" + "umulh x7, %[b], x8\n\t" + "adds x5, x5, x6\n\t" + "adc x3, x3, x7\n\t" + "str x5, [%[r], 40]\n\t" + "str x3, [%[r], 48]\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_384_word_6(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" + + "lsl x3, %[d1], 32\n\t" + "orr x3, x3, %[d0], lsr 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" + + "lsl x3, %[d1], 32\n\t" + "orr x3, x3, %[d0], lsr 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" + + "udiv x3, %[d0], %[div]\n\t" + "add x6, x6, x3\n\t" + "mul x3, %[div], x3\n\t" + "sub %[d0], %[d0], x3\n\t" + "mov %[r], x6\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_384_mask_6(sp_digit* r, const sp_digit* a, sp_digit m) +{ +#ifdef WOLFSSL_SP_SMALL + int i; + + for (i=0; i<6; 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; +#endif +} + +/* 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 Nmber 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_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; + int i; + + (void)m; + + div = d[5]; + XMEMCPY(t1, a, sizeof(*t1) * 2 * 6); + for (i=5; i>=0; i--) { + r1 = div_384_word_6(t1[6 + i], t1[6 + i - 1], div); + + sp_384_mul_d_6(t2, d, r1); + t1[6 + i] += sp_384_sub_in_place_6(&t1[i], t2); + t1[6 + i] -= t2[6]; + sp_384_mask_6(t2, d, t1[6 + i]); + t1[6 + i] += sp_384_add_6(&t1[i], &t1[i], t2); + sp_384_mask_6(t2, d, t1[6 + i]); + t1[6 + i] += sp_384_add_6(&t1[i], &t1[i], t2); + } + + r1 = sp_384_cmp_6(t1, d) >= 0; + sp_384_cond_sub_6(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_384_mod_6(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + return sp_384_div_6(a, m, NULL, r); +} + +#endif +#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) +#ifdef WOLFSSL_SP_SMALL +/* Order-2 for the P384 curve. */ +static const uint64_t p384_order_minus_2[6] = { + 0xecec196accc52971U,0x581a0db248b0a77aU,0xc7634d81f4372ddfU, + 0xffffffffffffffffU,0xffffffffffffffffU,0xffffffffffffffffU +}; +#else +/* 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 */ + +/* Multiply two number mod the order of P384 curve. (r = a * b mod order) + * + * r Result of the multiplication. + * a First operand of the multiplication. + * b Second operand of the multiplication. + */ +static void sp_384_mont_mul_order_6(sp_digit* r, const sp_digit* a, const sp_digit* b) +{ + sp_384_mul_6(r, a, b); + sp_384_mont_reduce_order_6(r, p384_order, p384_mp_order); +} + +/* Square number mod the order of P384 curve. (r = a * a mod order) + * + * r Result of the squaring. + * a Number to square. + */ +static void sp_384_mont_sqr_order_6(sp_digit* r, const sp_digit* a) +{ + sp_384_sqr_6(r, a); + sp_384_mont_reduce_order_6(r, p384_order, p384_mp_order); +} + +#ifndef WOLFSSL_SP_SMALL +/* Square number mod the order of P384 curve a number of times. + * (r = a ^ n mod order) + * + * r Result of the squaring. + * a Number to square. + */ +static void sp_384_mont_sqr_n_order_6(sp_digit* r, const sp_digit* a, int n) +{ + int i; + + sp_384_mont_sqr_order_6(r, a); + for (i=1; i=0; i--) { + sp_384_mont_sqr_order_6(t, t); + if ((p384_order_minus_2[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) { + sp_384_mont_mul_order_6(t, t, a); + } + } + XMEMCPY(r, t, sizeof(sp_digit) * 6U); +#else + sp_digit* t = td; + sp_digit* t2 = td + 2 * 6; + sp_digit* t3 = td + 4 * 6; + int i; + + /* t = a^2 */ + sp_384_mont_sqr_order_6(t, a); + /* t = a^3 = t * a */ + sp_384_mont_mul_order_6(t, t, a); + /* t2= a^c = t ^ 2 ^ 2 */ + sp_384_mont_sqr_n_order_6(t2, t, 2); + /* t = a^f = t2 * t */ + sp_384_mont_mul_order_6(t, t2, t); + /* t2= a^f0 = t ^ 2 ^ 4 */ + sp_384_mont_sqr_n_order_6(t2, t, 4); + /* t = a^ff = t2 * t */ + sp_384_mont_mul_order_6(t, t2, t); + /* t2= a^ff00 = t ^ 2 ^ 8 */ + sp_384_mont_sqr_n_order_6(t2, t, 8); + /* t3= a^ffff = t2 * t */ + sp_384_mont_mul_order_6(t3, t2, t); + /* t2= a^ffff0000 = t3 ^ 2 ^ 16 */ + sp_384_mont_sqr_n_order_6(t2, t3, 16); + /* t = a^ffffffff = t2 * t3 */ + sp_384_mont_mul_order_6(t, t2, t3); + /* t2= a^ffffffff0000 = t ^ 2 ^ 16 */ + sp_384_mont_sqr_n_order_6(t2, t, 16); + /* t = a^ffffffffffff = t2 * t3 */ + sp_384_mont_mul_order_6(t, t2, t3); + /* t2= a^ffffffffffff000000000000 = t ^ 2 ^ 48 */ + sp_384_mont_sqr_n_order_6(t2, t, 48); + /* t= a^fffffffffffffffffffffffff = t2 * t */ + sp_384_mont_mul_order_6(t, t2, t); + /* t2= a^ffffffffffffffffffffffff000000000000000000000000 */ + sp_384_mont_sqr_n_order_6(t2, t, 96); + /* t2= a^ffffffffffffffffffffffffffffffffffffffffffffffff = t2 * t */ + 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) { + sp_384_mont_mul_order_6(t2, t2, a); + } + } + sp_384_mont_sqr_order_6(t2, t2); + sp_384_mont_mul_order_6(r, t2, a); +#endif /* WOLFSSL_SP_SMALL */ +} + +#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 + +/* Sign the hash using the private key. + * e = [hash, 384 bits] from binary + * r = (k.G)->x mod order + * s = (r * x + e) / k mod order + * The hash is truncated to the first 384 bits. + * + * hash Hash to sign. + * hashLen Length of the hash data. + * rng Random number generator. + * priv Private part of key - scalar. + * 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. + */ +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) +{ +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_digit* d = NULL; +#else + sp_digit ed[2*6]; + sp_digit xd[2*6]; + sp_digit kd[2*6]; + sp_digit rd[2*6]; + sp_digit td[3 * 2*6]; + sp_point_384 p; +#endif + sp_digit* e = NULL; + sp_digit* x = NULL; + sp_digit* k = NULL; + 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 i; + + (void)heap; + + err = sp_384_point_new_6(heap, p, point); +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7 * 2 * 6, heap, + DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + e = d + 0 * 6; + x = d + 2 * 6; + k = d + 4 * 6; + r = d + 6 * 6; + tmp = d + 8 * 6; +#else + e = ed; + x = xd; + k = kd; + r = rd; + tmp = td; +#endif + s = e; + kInv = k; + + if (hashLen > 48U) { + hashLen = 48U; + } + + sp_384_from_bin(e, 6, hash, (int)hashLen); + } + + 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); + } + else { + sp_384_from_mp(k, 6, km); + mp_zero(km); + } + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_base_6(point, k, 1, NULL); + } + + if (err == MP_OKAY) { + /* r = point->x mod order */ + XMEMCPY(r, point->x, sizeof(sp_digit) * 6U); + sp_384_norm_6(r); + c = sp_384_cmp_6(r, p384_order); + 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); + 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); + + /* Check that signature is usable. */ + if (sp_384_iszero_6(s) == 0) { + break; + } + } + } + + if (i == 0) { + err = RNG_FAILURE_E; + } + + if (err == MP_OKAY) { + err = sp_384_to_mp(r, rm); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(s, sm); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (d != NULL) { + XMEMSET(d, 0, sizeof(sp_digit) * 8 * 6); + XFREE(d, heap, DYNAMIC_TYPE_ECC); + } +#else + XMEMSET(e, 0, sizeof(sp_digit) * 2U * 6U); + 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); + + return err; +} +#endif /* HAVE_ECC_SIGN */ + +#ifdef HAVE_ECC_VERIFY +/* Verify the signature values with the hash and public key. + * e = Truncate(hash, 384) + * u1 = e/s mod order + * u2 = r/s mod order + * r == (u1.G + u2.Q)->x mod order + * Optimization: Leave point in projective form. + * (x, y, 1) == (x' / z'*z', y' / z'*z'*z', z' / z') + * (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' + * The hash is truncated to the first 384 bits. + * + * hash Hash to sign. + * hashLen Length of the hash data. + * rng Random number generator. + * priv Private part of key - scalar. + * 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. + */ +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) +{ +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_digit* d = NULL; +#else + sp_digit u1d[2*6]; + sp_digit u2d[2*6]; + sp_digit sd[2*6]; + sp_digit tmpd[2*6 * 5]; + sp_point_384 p1d; + sp_point_384 p2d; +#endif + sp_digit* u1 = NULL; + sp_digit* u2 = NULL; + sp_digit* s = NULL; + sp_digit* tmp = NULL; + sp_point_384* p1; + sp_point_384* p2 = NULL; + sp_digit carry; + int64_t c; + int err; + + err = sp_384_point_new_6(heap, p1d, p1); + if (err == MP_OKAY) { + err = sp_384_point_new_6(heap, p2d, p2); + } +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 6, heap, + DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + u1 = d + 0 * 6; + u2 = d + 2 * 6; + s = d + 4 * 6; + tmp = d + 6 * 6; +#else + u1 = u1d; + u2 = u2d; + s = sd; + tmp = tmpd; +#endif + + if (hashLen > 48U) { + hashLen = 48U; + } + + sp_384_from_bin(u1, 6, hash, (int)hashLen); + sp_384_from_mp(u2, 6, r); + sp_384_from_mp(s, 6, sm); + sp_384_from_mp(p2->x, 6, pX); + sp_384_from_mp(p2->y, 6, pY); + sp_384_from_mp(p2->z, 6, pZ); + + { + 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); + { + 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); + } + + err = sp_384_ecc_mulmod_base_6(p1, u1, 0, heap); + } + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_6(p2, p2, u2, 0, heap); + } + + 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); + err = sp_384_mod_mul_norm_6(u2, u2, p384_mod); + } + + if (err == MP_OKAY) { + /* u1 = r.z'.z' mod prime */ + sp_384_mont_sqr_6(p1->z, p1->z, p384_mod, p384_mp_mod); + 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) { + /* Reload r and add order. */ + sp_384_from_mp(u2, 6, r); + carry = sp_384_add_6(u2, u2, p384_order); + /* Carry means result is greater than mod and is not valid. */ + if (carry == 0) { + sp_384_norm_6(u2); + + /* 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 defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (d != NULL) + XFREE(d, heap, DYNAMIC_TYPE_ECC); +#endif + sp_384_point_free_6(p1, 0, heap); + sp_384_point_free_6(p2, 0, heap); + + return err; +} +#endif /* HAVE_ECC_VERIFY */ + +#ifdef HAVE_ECC_CHECK_KEY +/* 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_384_ecc_is_point_6(sp_point_384* point, void* heap) +{ +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_digit* d = NULL; +#else + sp_digit t1d[2*6]; + sp_digit t2d[2*6]; +#endif + sp_digit* t1; + sp_digit* t2; + int err = MP_OKAY; + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 6 * 4, heap, DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + t1 = d + 0 * 6; + t2 = d + 2 * 6; +#else + (void)heap; + + t1 = t1d; + t2 = t2d; +#endif + + sp_384_sqr_6(t1, point->y); + (void)sp_384_mod_6(t1, t1, p384_mod); + sp_384_sqr_6(t2, point->x); + (void)sp_384_mod_6(t2, t2, p384_mod); + sp_384_mul_6(t2, t2, point->x); + (void)sp_384_mod_6(t2, t2, p384_mod); + (void)sp_384_sub_6(t2, p384_mod, t2); + sp_384_mont_add_6(t1, t1, t2, p384_mod); + + sp_384_mont_add_6(t1, t1, point->x, p384_mod); + sp_384_mont_add_6(t1, t1, point->x, p384_mod); + sp_384_mont_add_6(t1, t1, point->x, p384_mod); + + if (sp_384_cmp_6(t1, p384_b) != 0) { + err = MP_VAL; + } + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + 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_384(mp_int* pX, mp_int* pY) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 pubd; +#endif + sp_point_384* pub; + byte one[1] = { 1 }; + int err; + + err = sp_384_point_new_6(NULL, pubd, pub); + if (err == MP_OKAY) { + sp_384_from_mp(pub->x, 6, pX); + sp_384_from_mp(pub->y, 6, pY); + sp_384_from_bin(pub->z, 6, one, (int)sizeof(one)); + + err = sp_384_ecc_is_point_6(pub, NULL); + } + + sp_384_point_free_6(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_384(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_digit privd[6]; + sp_point_384 pubd; + sp_point_384 pd; +#endif + sp_digit* priv = NULL; + sp_point_384* pub; + sp_point_384* p = NULL; + byte one[1] = { 1 }; + int err; + + err = sp_384_point_new_6(heap, pubd, pub); + if (err == MP_OKAY) { + err = sp_384_point_new_6(heap, pd, p); + } +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + priv = (sp_digit*)XMALLOC(sizeof(sp_digit) * 6, heap, + DYNAMIC_TYPE_ECC); + if (priv == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if !(defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) + priv = privd; +#endif + + sp_384_from_mp(pub->x, 6, pX); + sp_384_from_mp(pub->y, 6, pY); + sp_384_from_bin(pub->z, 6, one, (int)sizeof(one)); + sp_384_from_mp(priv, 6, privm); + + /* Check point at infinitiy. */ + if ((sp_384_iszero_6(pub->x) != 0) && + (sp_384_iszero_6(pub->y) != 0)) { + err = ECC_INF_E; + } + } + + 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; + } + } + + if (err == MP_OKAY) { + /* Check point is on curve */ + err = sp_384_ecc_is_point_6(pub, heap); + } + + if (err == MP_OKAY) { + /* Point * order = infinity */ + err = sp_384_ecc_mulmod_6(p, pub, p384_order, 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; + } + } + + if (err == MP_OKAY) { + /* Base * private = point */ + err = sp_384_ecc_mulmod_base_6(p, priv, 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; + } + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (priv != NULL) { + XFREE(priv, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_6(p, 0, heap); + sp_384_point_free_6(pub, 0, heap); + + return err; +} +#endif +#ifdef WOLFSSL_PUBLIC_ECC_ADD_DBL +/* Add two projective EC points together. + * (pX, pY, pZ) + (qX, qY, qZ) = (rX, rY, rZ) + * + * pX First EC point's X ordinate. + * pY First EC point's Y ordinate. + * pZ First EC point's Z ordinate. + * qX Second EC point's X ordinate. + * qY Second EC point's Y ordinate. + * qZ Second EC point's Z ordinate. + * rX Resultant EC point's X ordinate. + * rY Resultant EC point's Y ordinate. + * rZ Resultant EC point's Z ordinate. + * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise. + */ +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) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_digit tmpd[2 * 6 * 5]; + sp_point_384 pd; + sp_point_384 qd; +#endif + sp_digit* tmp; + sp_point_384* p; + sp_point_384* q = NULL; + int err; + + err = sp_384_point_new_6(NULL, pd, p); + if (err == MP_OKAY) { + err = sp_384_point_new_6(NULL, qd, q); + } +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 6 * 5, NULL, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) { + err = MEMORY_E; + } + } +#else + tmp = tmpd; +#endif + + if (err == MP_OKAY) { + sp_384_from_mp(p->x, 6, pX); + sp_384_from_mp(p->y, 6, pY); + sp_384_from_mp(p->z, 6, pZ); + sp_384_from_mp(q->x, 6, qX); + sp_384_from_mp(q->y, 6, qY); + sp_384_from_mp(q->z, 6, qZ); + + sp_384_proj_point_add_6(p, p, q, tmp); + } + + if (err == MP_OKAY) { + err = sp_384_to_mp(p->x, rX); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->y, rY); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->z, rZ); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (tmp != NULL) { + XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_6(q, 0, NULL); + sp_384_point_free_6(p, 0, NULL); + + return err; +} + +/* Double a projective EC point. + * (pX, pY, pZ) + (pX, pY, pZ) = (rX, rY, rZ) + * + * pX EC point's X ordinate. + * pY EC point's Y ordinate. + * pZ EC point's Z ordinate. + * rX Resultant EC point's X ordinate. + * rY Resultant EC point's Y ordinate. + * rZ Resultant EC point's Z ordinate. + * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise. + */ +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) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_digit tmpd[2 * 6 * 2]; + sp_point_384 pd; +#endif + sp_digit* tmp; + sp_point_384* p; + int err; + + err = sp_384_point_new_6(NULL, pd, p); +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 6 * 2, NULL, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) { + err = MEMORY_E; + } + } +#else + tmp = tmpd; +#endif + + if (err == MP_OKAY) { + sp_384_from_mp(p->x, 6, pX); + sp_384_from_mp(p->y, 6, pY); + sp_384_from_mp(p->z, 6, pZ); + + sp_384_proj_point_dbl_6(p, p, tmp); + } + + if (err == MP_OKAY) { + err = sp_384_to_mp(p->x, rX); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->y, rY); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->z, rZ); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (tmp != NULL) { + XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_6(p, 0, NULL); + + return err; +} + +/* Map a projective EC point to affine in place. + * pZ will be one. + * + * pX EC point's X ordinate. + * pY EC point's Y ordinate. + * pZ EC point's Z ordinate. + * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise. + */ +int sp_ecc_map_384(mp_int* pX, mp_int* pY, mp_int* pZ) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_digit tmpd[2 * 6 * 6]; + sp_point_384 pd; +#endif + sp_digit* tmp; + sp_point_384* p; + int err; + + err = sp_384_point_new_6(NULL, pd, p); +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 6 * 6, NULL, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) { + err = MEMORY_E; + } + } +#else + tmp = tmpd; +#endif + if (err == MP_OKAY) { + sp_384_from_mp(p->x, 6, pX); + sp_384_from_mp(p->y, 6, pY); + sp_384_from_mp(p->z, 6, pZ); + + sp_384_map_6(p, p, tmp); + } + + if (err == MP_OKAY) { + err = sp_384_to_mp(p->x, pX); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->y, pY); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->z, pZ); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (tmp != NULL) { + XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_6(p, 0, NULL); + + return err; +} +#endif /* WOLFSSL_PUBLIC_ECC_ADD_DBL */ +#ifdef HAVE_COMP_KEY +/* Find the square root of a number mod the prime of the curve. + * + * y The number to operate on and the result. + * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise. + */ +static int sp_384_mont_sqrt_6(sp_digit* y) +{ +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_digit* d; +#else + sp_digit t1d[2 * 6]; + sp_digit t2d[2 * 6]; + sp_digit t3d[2 * 6]; + sp_digit t4d[2 * 6]; + sp_digit t5d[2 * 6]; +#endif + sp_digit* t1; + sp_digit* t2; + sp_digit* t3; + sp_digit* t4; + sp_digit* t5; + int err = MP_OKAY; + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 5 * 2 * 6, NULL, DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + t1 = d + 0 * 6; + t2 = d + 2 * 6; + t3 = d + 4 * 6; + t4 = d + 6 * 6; + t5 = d + 8 * 6; +#else + t1 = t1d; + t2 = t2d; + t3 = t3d; + t4 = t4d; + t5 = t5d; +#endif + + { + /* t2 = y ^ 0x2 */ + sp_384_mont_sqr_6(t2, y, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x3 */ + sp_384_mont_mul_6(t1, t2, y, p384_mod, p384_mp_mod); + /* t5 = y ^ 0xc */ + sp_384_mont_sqr_n_6(t5, t1, 2, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xf */ + sp_384_mont_mul_6(t1, t1, t5, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x1e */ + sp_384_mont_sqr_6(t2, t1, p384_mod, p384_mp_mod); + /* t3 = y ^ 0x1f */ + sp_384_mont_mul_6(t3, t2, y, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3e0 */ + sp_384_mont_sqr_n_6(t2, t3, 5, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x3ff */ + sp_384_mont_mul_6(t1, t3, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x7fe0 */ + sp_384_mont_sqr_n_6(t2, t1, 5, p384_mod, p384_mp_mod); + /* t3 = y ^ 0x7fff */ + sp_384_mont_mul_6(t3, t3, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3fff800 */ + sp_384_mont_sqr_n_6(t2, t3, 15, p384_mod, p384_mp_mod); + /* t4 = y ^ 0x3ffffff */ + sp_384_mont_mul_6(t4, t3, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0xffffffc000000 */ + sp_384_mont_sqr_n_6(t2, t4, 30, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xfffffffffffff */ + sp_384_mont_mul_6(t1, t4, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0xfffffffffffffff000000000000000 */ + sp_384_mont_sqr_n_6(t2, t1, 60, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xffffffffffffffffffffffffffffff */ + sp_384_mont_mul_6(t1, t1, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0xffffffffffffffffffffffffffffff000000000000000000000000000000 */ + sp_384_mont_sqr_n_6(t2, t1, 120, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */ + sp_384_mont_mul_6(t1, t1, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000 */ + sp_384_mont_sqr_n_6(t2, t1, 15, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */ + sp_384_mont_mul_6(t1, t3, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000 */ + sp_384_mont_sqr_n_6(t2, t1, 31, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffff */ + sp_384_mont_mul_6(t1, t4, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffff0 */ + sp_384_mont_sqr_n_6(t2, t1, 4, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffc */ + sp_384_mont_mul_6(t1, t5, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000 */ + sp_384_mont_sqr_n_6(t2, t1, 62, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000001 */ + sp_384_mont_mul_6(t1, y, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffc00000000000000040000000 */ + sp_384_mont_sqr_n_6(y, t1, 30, p384_mod, p384_mp_mod); + } + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (d != NULL) { + XFREE(d, NULL, DYNAMIC_TYPE_ECC); + } +#endif + + return err; +} + + +/* Uncompress the point given the X ordinate. + * + * xm X ordinate. + * odd Whether the Y ordinate is odd. + * ym Calculated Y ordinate. + * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise. + */ +int sp_ecc_uncompress_384(mp_int* xm, int odd, mp_int* ym) +{ +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_digit* d; +#else + sp_digit xd[2 * 6]; + sp_digit yd[2 * 6]; +#endif + sp_digit* x = NULL; + sp_digit* y = NULL; + int err = MP_OKAY; + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4 * 6, NULL, DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + x = d + 0 * 6; + y = d + 2 * 6; +#else + x = xd; + y = yd; +#endif + + sp_384_from_mp(x, 6, xm); + err = sp_384_mod_mul_norm_6(x, x, p384_mod); + } + if (err == MP_OKAY) { + /* y = x^3 */ + { + sp_384_mont_sqr_6(y, x, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(y, y, x, p384_mod, p384_mp_mod); + } + /* y = x^3 - 3x */ + sp_384_mont_sub_6(y, y, x, p384_mod); + sp_384_mont_sub_6(y, y, x, p384_mod); + sp_384_mont_sub_6(y, y, x, p384_mod); + /* y = x^3 - 3x + b */ + err = sp_384_mod_mul_norm_6(x, p384_b, p384_mod); + } + if (err == MP_OKAY) { + sp_384_mont_add_6(y, y, x, p384_mod); + /* y = sqrt(x^3 - 3x + b) */ + err = sp_384_mont_sqrt_6(y); + } + if (err == MP_OKAY) { + XMEMSET(y + 6, 0, 6U * sizeof(sp_digit)); + sp_384_mont_reduce_6(y, p384_mod, p384_mp_mod); + if ((((word32)y[0] ^ (word32)odd) & 1U) != 0U) { + sp_384_mont_sub_6(y, p384_mod, y, p384_mod); + } + + err = sp_384_to_mp(y, ym); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (d != NULL) { + XFREE(d, NULL, DYNAMIC_TYPE_ECC); + } +#endif + + return err; +} +#endif +#endif /* WOLFSSL_SP_384 */ #endif /* WOLFSSL_HAVE_SP_ECC */ #endif /* WOLFSSL_SP_ARM64_ASM */ #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 06bb969b6..a1d239f8a 100644 --- a/wolfcrypt/src/sp_armthumb.c +++ b/wolfcrypt/src/sp_armthumb.c @@ -15642,12 +15642,12 @@ int sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen, #ifndef WOLFSSL_SP_NO_256 /* Point structure to use. */ -typedef struct sp_point { +typedef struct sp_point_256 { sp_digit x[2 * 8]; sp_digit y[2 * 8]; sp_digit z[2 * 8]; int infinity; -} sp_point; +} sp_point_256; /* The modulus (prime) of the curve P256. */ static const sp_digit p256_mod[8] = { @@ -15686,21 +15686,24 @@ static const sp_digit p256_norm_order[8] = { static const sp_digit p256_mp_order = 0xee00bc4f; #endif /* The base point of curve P256. */ -static const sp_point p256_base = { +static const sp_point_256 p256_base = { /* X ordinate */ { 0xd898c296,0xf4a13945,0x2deb33a0,0x77037d81,0x63a440f2,0xf8bce6e5, - 0xe12c4247,0x6b17d1f2, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + 0xe12c4247,0x6b17d1f2, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L }, /* Y ordinate */ { 0x37bf51f5,0xcbb64068,0x6b315ece,0x2bce3357,0x7c0f9e16,0x8ee7eb4a, - 0xfe1a7f9b,0x4fe342e2, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + 0xfe1a7f9b,0x4fe342e2, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L }, /* Z ordinate */ { 0x00000001,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + 0x00000000,0x00000000, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L }, /* infinity */ 0 @@ -15712,34 +15715,32 @@ static const sp_digit p256_b[8] = { }; #endif -static int sp_ecc_point_new_ex(void* heap, sp_point* sp, sp_point** p) +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) + (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; } - else { - #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - *p = (sp_point*)XMALLOC(sizeof(sp_point), heap, DYNAMIC_TYPE_ECC); - (void)sp; - #else - *p = sp; - (void)heap; - #endif - } return ret; } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) /* Allocate memory for point and return error. */ -#define sp_ecc_point_new(heap, sp, p) sp_ecc_point_new_ex((heap), NULL, &(p)) +#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_ecc_point_new(heap, sp, p) sp_ecc_point_new_ex((heap), &(sp), &(p)) +#define sp_256_point_new_8(heap, sp, p) sp_256_point_new_ex_8((heap), &(sp), &(p)) #endif -static void sp_ecc_point_free(sp_point* p, int clear, void* heap) +static void sp_256_point_free_8(sp_point_256* p, int clear, void* heap) { #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) /* If valid pointer then clear point data if requested and free data. */ @@ -15911,12 +15912,12 @@ static void sp_256_from_mp(sp_digit* r, int size, const mp_int* a) #endif } -/* Convert a point of type ecc_point to type sp_point. +/* Convert a point of type ecc_point to type sp_point_256. * - * p Point of type sp_point (result). + * 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* 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)); @@ -15991,14 +15992,14 @@ static int sp_256_to_mp(const sp_digit* a, mp_int* r) return err; } -/* Convert a point of type sp_point to type ecc_point. +/* Convert a point of type sp_point_256 to type ecc_point. * - * p Point of type sp_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* p, ecc_point* pm) +static int sp_256_point_to_ecc_point_8(const sp_point_256* p, ecc_point* pm) { int err; @@ -16013,55 +16014,106 @@ static int sp_256_point_to_ecc_point_8(const sp_point* p, ecc_point* pm) return err; } -/* Compare a with b in constant time. +/* Multiply a and b into r. (r = a * b) * + * r A single precision integer. * 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_256_cmp_8(const sp_digit* a, const sp_digit* b) +SP_NOINLINE static void sp_256_mul_8(sp_digit* r, const sp_digit* a, + const sp_digit* b) { - sp_digit r = 0; - - + sp_digit tmp[8 * 2]; __asm__ __volatile__ ( "mov r3, #0\n\t" - "mvn r3, r3\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, #32\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, #28\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" + "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, #56\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" ); - return r; + XMEMCPY(r, tmp, sizeof(tmp)); } -/* Normalize the values in each word to 32. - * - * a Array of sp_digit to normalize. - */ -#define sp_256_norm_8(a) - /* Conditionally subtract b from a using the mask m. * m is -1 to subtract and 0 when not copying. * @@ -16367,106 +16419,6 @@ SP_NOINLINE static void sp_256_mont_reduce_order_8(sp_digit* a, const sp_digit* sp_256_cond_sub_8(a - 8, a, m, (sp_digit)0 - ca); } -/* 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[8 * 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, #32\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, #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 %[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, #56\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)); -} - /* Multiply two Montogmery form numbers mod the modulus (prime). * (r = a * b mod m) * @@ -16666,7 +16618,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 */ #ifdef WOLFSSL_SP_SMALL /* Mod-2 for the P256 curve. */ -static const uint32_t p256_mod_2[8] = { +static const uint32_t p256_mod_minus_2[8] = { 0xfffffffdU,0xffffffffU,0xffffffffU,0x00000000U,0x00000000U,0x00000000U, 0x00000001U,0xffffffffU }; @@ -16688,71 +16640,115 @@ static void sp_256_mont_inv_8(sp_digit* r, const sp_digit* a, sp_digit* td) XMEMCPY(t, a, sizeof(sp_digit) * 8); for (i=254; i>=0; i--) { sp_256_mont_sqr_8(t, t, p256_mod, p256_mp_mod); - if (p256_mod_2[i / 32] & ((sp_digit)1 << (i % 32))) + if (p256_mod_minus_2[i / 32] & ((sp_digit)1 << (i % 32))) sp_256_mont_mul_8(t, t, a, p256_mod, p256_mp_mod); } XMEMCPY(r, t, sizeof(sp_digit) * 8); #else - sp_digit* t = td; + sp_digit* t1 = td; sp_digit* t2 = td + 2 * 8; sp_digit* t3 = td + 4 * 8; - - /* t = a^2 */ - sp_256_mont_sqr_8(t, a, p256_mod, p256_mp_mod); - /* t = a^3 = t * a */ - sp_256_mont_mul_8(t, t, a, p256_mod, p256_mp_mod); - /* t2= a^c = t ^ 2 ^ 2 */ - sp_256_mont_sqr_n_8(t2, t, 2, p256_mod, p256_mp_mod); - /* t3= a^d = t2 * a */ - sp_256_mont_mul_8(t3, t2, a, p256_mod, p256_mp_mod); - /* t = a^f = t2 * t */ - sp_256_mont_mul_8(t, t2, t, p256_mod, p256_mp_mod); - /* t2= a^f0 = t ^ 2 ^ 4 */ - sp_256_mont_sqr_n_8(t2, t, 4, p256_mod, p256_mp_mod); - /* t3= a^fd = t2 * t3 */ - sp_256_mont_mul_8(t3, t2, t3, p256_mod, p256_mp_mod); - /* t = a^ff = t2 * t */ - sp_256_mont_mul_8(t, t2, t, p256_mod, p256_mp_mod); - /* t2= a^ff00 = t ^ 2 ^ 8 */ - sp_256_mont_sqr_n_8(t2, t, 8, p256_mod, p256_mp_mod); - /* t3= a^fffd = t2 * t3 */ - sp_256_mont_mul_8(t3, t2, t3, p256_mod, p256_mp_mod); - /* t = a^ffff = t2 * t */ - sp_256_mont_mul_8(t, t2, t, p256_mod, p256_mp_mod); - /* t2= a^ffff0000 = t ^ 2 ^ 16 */ - sp_256_mont_sqr_n_8(t2, t, 16, p256_mod, p256_mp_mod); - /* t3= a^fffffffd = t2 * t3 */ - sp_256_mont_mul_8(t3, t2, t3, p256_mod, p256_mp_mod); - /* t = a^ffffffff = t2 * t */ - sp_256_mont_mul_8(t, t2, t, p256_mod, p256_mp_mod); - /* t = a^ffffffff00000000 = t ^ 2 ^ 32 */ - sp_256_mont_sqr_n_8(t2, t, 32, p256_mod, p256_mp_mod); - /* t2= a^ffffffffffffffff = t2 * t */ - sp_256_mont_mul_8(t, t2, t, p256_mod, p256_mp_mod); - /* t2= a^ffffffff00000001 = t2 * a */ - sp_256_mont_mul_8(t2, t2, a, p256_mod, p256_mp_mod); - /* t2= a^ffffffff000000010000000000000000000000000000000000000000 - * = t2 ^ 2 ^ 160 */ - sp_256_mont_sqr_n_8(t2, t2, 160, p256_mod, p256_mp_mod); - /* t2= a^ffffffff00000001000000000000000000000000ffffffffffffffff - * = t2 * t */ - sp_256_mont_mul_8(t2, t2, t, p256_mod, p256_mp_mod); - /* t2= a^ffffffff00000001000000000000000000000000ffffffffffffffff00000000 - * = t2 ^ 2 ^ 32 */ - sp_256_mont_sqr_n_8(t2, t2, 32, p256_mod, p256_mp_mod); - /* r = a^ffffffff00000001000000000000000000000000fffffffffffffffffffffffd - * = t2 * t3 */ - sp_256_mont_mul_8(r, t2, t3, p256_mod, p256_mp_mod); + /* 0x2 */ + sp_256_mont_sqr_8(t1, a, p256_mod, p256_mp_mod); + /* 0x3 */ + sp_256_mont_mul_8(t2, t1, a, p256_mod, p256_mp_mod); + /* 0xc */ + sp_256_mont_sqr_n_8(t1, t2, 2, p256_mod, p256_mp_mod); + /* 0xd */ + sp_256_mont_mul_8(t3, t1, a, p256_mod, p256_mp_mod); + /* 0xf */ + sp_256_mont_mul_8(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xf0 */ + sp_256_mont_sqr_n_8(t1, t2, 4, p256_mod, p256_mp_mod); + /* 0xfd */ + sp_256_mont_mul_8(t3, t3, t1, p256_mod, p256_mp_mod); + /* 0xff */ + sp_256_mont_mul_8(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xff00 */ + sp_256_mont_sqr_n_8(t1, t2, 8, p256_mod, p256_mp_mod); + /* 0xfffd */ + sp_256_mont_mul_8(t3, t3, t1, p256_mod, p256_mp_mod); + /* 0xffff */ + sp_256_mont_mul_8(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xffff0000 */ + sp_256_mont_sqr_n_8(t1, t2, 16, p256_mod, p256_mp_mod); + /* 0xfffffffd */ + sp_256_mont_mul_8(t3, t3, t1, p256_mod, p256_mp_mod); + /* 0xffffffff */ + sp_256_mont_mul_8(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xffffffff00000000 */ + sp_256_mont_sqr_n_8(t1, t2, 32, p256_mod, p256_mp_mod); + /* 0xffffffffffffffff */ + sp_256_mont_mul_8(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xffffffff00000001 */ + sp_256_mont_mul_8(r, t1, a, p256_mod, p256_mp_mod); + /* 0xffffffff000000010000000000000000000000000000000000000000 */ + sp_256_mont_sqr_n_8(r, r, 160, p256_mod, p256_mp_mod); + /* 0xffffffff00000001000000000000000000000000ffffffffffffffff */ + sp_256_mont_mul_8(r, r, t2, p256_mod, p256_mp_mod); + /* 0xffffffff00000001000000000000000000000000ffffffffffffffff00000000 */ + sp_256_mont_sqr_n_8(r, r, 32, p256_mod, p256_mp_mod); + /* 0xffffffff00000001000000000000000000000000fffffffffffffffffffffffd */ + sp_256_mont_mul_8(r, r, t3, p256_mod, p256_mp_mod); #endif /* WOLFSSL_SP_SMALL */ } +/* 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_256_cmp_8(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, #28\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; +} + +/* Normalize the values in each word to 32. + * + * a Array of sp_digit to normalize. + */ +#define sp_256_norm_8(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_256_map_8(sp_point* r, const sp_point* 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; @@ -17326,9 +17322,9 @@ SP_NOINLINE static void sp_256_div2_8(sp_digit* r, const sp_digit* a, const sp_d * p Point to double. * t Temporary ordinate data. */ -static void sp_256_proj_point_dbl_8(sp_point* r, const sp_point* p, sp_digit* t) +static void sp_256_proj_point_dbl_8(sp_point_256* r, const sp_point_256* p, sp_digit* t) { - sp_point* rp[2]; + sp_point_256* rp[2]; sp_digit* t1 = t; sp_digit* t2 = t + 2*8; sp_digit* x; @@ -17340,8 +17336,8 @@ static void sp_256_proj_point_dbl_8(sp_point* r, const sp_point* p, sp_digit* t) rp[0] = r; /*lint allow cast to different type of pointer*/ - rp[1] = (sp_point*)t; /*lint !e9087 !e740*/ - XMEMSET(rp[1], 0, sizeof(sp_point)); + rp[1] = (sp_point_256*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_256)); x = rp[p->infinity]->x; y = rp[p->infinity]->y; z = rp[p->infinity]->z; @@ -17509,11 +17505,11 @@ static int sp_256_cmp_equal_8(const sp_digit* a, const sp_digit* b) * q Second point to add. * t Temporary ordinate data. */ -static void sp_256_proj_point_add_8(sp_point* r, const sp_point* p, const sp_point* q, +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* ap[2]; - sp_point* rp[2]; + const sp_point_256* ap[2]; + sp_point_256* rp[2]; sp_digit* t1 = t; sp_digit* t2 = t + 2*8; sp_digit* t3 = t + 4*8; @@ -17526,7 +17522,7 @@ static void sp_256_proj_point_add_8(sp_point* r, const sp_point* p, const sp_poi /* Ensure only the first point is the same as the result. */ if (q == r) { - const sp_point* a = p; + const sp_point_256* a = p; p = q; q = a; } @@ -17542,8 +17538,8 @@ static void sp_256_proj_point_add_8(sp_point* r, const sp_point* p, const sp_poi rp[0] = r; /*lint allow cast to different type of pointer*/ - rp[1] = (sp_point*)t; /*lint !e9087 !e740*/ - XMEMSET(rp[1], 0, sizeof(sp_point)); + rp[1] = (sp_point_256*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_256)); x = rp[p->infinity | q->infinity]->x; y = rp[p->infinity | q->infinity]->y; z = rp[p->infinity | q->infinity]->z; @@ -17606,16 +17602,16 @@ static void sp_256_proj_point_add_8(sp_point* r, const sp_point* p, const sp_poi * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_fast_8(sp_point* r, const sp_point* g, const sp_digit* k, +static int sp_256_ecc_mulmod_fast_8(sp_point_256* r, const sp_point_256* g, const sp_digit* k, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point td[16]; - sp_point rtd; + sp_point_256 td[16]; + sp_point_256 rtd; sp_digit tmpd[2 * 8 * 5]; #endif - sp_point* t; - sp_point* rt; + sp_point_256* t; + sp_point_256* rt; sp_digit* tmp; sp_digit n; int i; @@ -17624,9 +17620,9 @@ static int sp_256_ecc_mulmod_fast_8(sp_point* r, const sp_point* g, const sp_dig (void)heap; - err = sp_ecc_point_new(heap, rtd, rt); + err = sp_256_point_new_8(heap, rtd, rt); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - t = (sp_point*)XMALLOC(sizeof(sp_point) * 16, heap, DYNAMIC_TYPE_ECC); + t = (sp_point_256*)XMALLOC(sizeof(sp_point_256) * 16, heap, DYNAMIC_TYPE_ECC); if (t == NULL) err = MEMORY_E; tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 5, heap, @@ -17680,7 +17676,7 @@ static int sp_256_ecc_mulmod_fast_8(sp_point* r, const sp_point* g, const sp_dig n = k[i+1] << 0; c = 28; y = n >> 28; - XMEMCPY(rt, &t[y], sizeof(sp_point)); + XMEMCPY(rt, &t[y], sizeof(sp_point_256)); n <<= 4; for (; i>=0 || c>=4; ) { if (c < 4) { @@ -17703,7 +17699,7 @@ static int sp_256_ecc_mulmod_fast_8(sp_point* r, const sp_point* g, const sp_dig sp_256_map_8(r, rt, tmp); } else { - XMEMCPY(r, rt, sizeof(sp_point)); + XMEMCPY(r, rt, sizeof(sp_point_256)); } } @@ -17713,23 +17709,23 @@ static int sp_256_ecc_mulmod_fast_8(sp_point* r, const sp_point* g, const sp_dig XFREE(tmp, heap, DYNAMIC_TYPE_ECC); } if (t != NULL) { - XMEMSET(t, 0, sizeof(sp_point) * 16); + XMEMSET(t, 0, sizeof(sp_point_256) * 16); XFREE(t, heap, DYNAMIC_TYPE_ECC); } #else ForceZero(tmpd, sizeof(tmpd)); ForceZero(td, sizeof(td)); #endif - sp_ecc_point_free(rt, 1, heap); + sp_256_point_free_8(rt, 1, heap); return err; } /* A table entry for pre-computed points. */ -typedef struct sp_table_entry { +typedef struct sp_table_entry_256 { sp_digit x[8]; sp_digit y[8]; -} sp_table_entry; +} sp_table_entry_256; #ifdef FP_ECC /* Double the Montgomery form projective point p a number of times. @@ -17739,10 +17735,10 @@ typedef struct sp_table_entry { * n Number of times to double * t Temporary ordinate data. */ -static void sp_256_proj_point_dbl_n_8(sp_point* r, const sp_point* p, int n, +static void sp_256_proj_point_dbl_n_8(sp_point_256* r, const sp_point_256* p, int n, sp_digit* t) { - sp_point* rp[2]; + sp_point_256* rp[2]; sp_digit* w = t; sp_digit* a = t + 2*8; sp_digit* b = t + 4*8; @@ -17756,8 +17752,8 @@ static void sp_256_proj_point_dbl_n_8(sp_point* r, const sp_point* p, int n, rp[0] = r; /*lint allow cast to different type of pointer*/ - rp[1] = (sp_point*)t; /*lint !e9087 !e740*/ - XMEMSET(rp[1], 0, sizeof(sp_point)); + rp[1] = (sp_point_256*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_256)); x = rp[p->infinity]->x; y = rp[p->infinity]->y; z = rp[p->infinity]->z; @@ -17819,11 +17815,11 @@ static void sp_256_proj_point_dbl_n_8(sp_point* r, const sp_point* p, int n, * q Second point to add. * t Temporary ordinate data. */ -static void sp_256_proj_point_add_qz1_8(sp_point* r, const sp_point* p, - const sp_point* q, sp_digit* t) +static void sp_256_proj_point_add_qz1_8(sp_point_256* r, const sp_point_256* p, + const sp_point_256* q, sp_digit* t) { - const sp_point* ap[2]; - sp_point* rp[2]; + const sp_point_256* ap[2]; + sp_point_256* rp[2]; sp_digit* t1 = t; sp_digit* t2 = t + 2*8; sp_digit* t3 = t + 4*8; @@ -17845,8 +17841,8 @@ static void sp_256_proj_point_add_qz1_8(sp_point* r, const sp_point* p, rp[0] = r; /*lint allow cast to different type of pointer*/ - rp[1] = (sp_point*)t; /*lint !e9087 !e740*/ - XMEMSET(rp[1], 0, sizeof(sp_point)); + rp[1] = (sp_point_256*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_256)); x = rp[p->infinity | q->infinity]->x; y = rp[p->infinity | q->infinity]->y; z = rp[p->infinity | q->infinity]->z; @@ -17900,7 +17896,7 @@ static void sp_256_proj_point_add_qz1_8(sp_point* r, const sp_point* p, * a Point to convert. * t Temporary data. */ -static void sp_256_proj_to_affine_8(sp_point* a, sp_digit* t) +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; @@ -17923,26 +17919,26 @@ static void sp_256_proj_to_affine_8(sp_point* a, sp_digit* t) * tmp Temporary data. * heap Heap to use for allocation. */ -static int sp_256_gen_stripe_table_8(const sp_point* a, - sp_table_entry* table, sp_digit* tmp, void* heap) +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) - sp_point td, s1d, s2d; + sp_point_256 td, s1d, s2d; #endif - sp_point* t; - sp_point* s1 = NULL; - sp_point* s2 = NULL; + sp_point_256* t; + sp_point_256* s1 = NULL; + sp_point_256* s2 = NULL; int i, j; int err; (void)heap; - err = sp_ecc_point_new(heap, td, t); + err = sp_256_point_new_8(heap, td, t); if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, s1d, s1); + err = sp_256_point_new_8(heap, s1d, s1); } if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, s2d, s2); + err = sp_256_point_new_8(heap, s2d, s2); } if (err == MP_OKAY) { @@ -17964,7 +17960,7 @@ static int sp_256_gen_stripe_table_8(const sp_point* a, s2->infinity = 0; /* table[0] = {0, 0, infinity} */ - XMEMSET(&table[0], 0, sizeof(sp_table_entry)); + XMEMSET(&table[0], 0, sizeof(sp_table_entry_256)); /* 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)); @@ -17990,9 +17986,9 @@ static int sp_256_gen_stripe_table_8(const sp_point* a, } } - sp_ecc_point_free(s2, 0, heap); - sp_ecc_point_free(s1, 0, heap); - sp_ecc_point_free( t, 0, heap); + sp_256_point_free_8(s2, 0, heap); + sp_256_point_free_8(s1, 0, heap); + sp_256_point_free_8( t, 0, heap); return err; } @@ -18007,16 +18003,16 @@ static int sp_256_gen_stripe_table_8(const sp_point* a, * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_stripe_8(sp_point* r, const sp_point* g, - const sp_table_entry* table, const sp_digit* k, int map, void* heap) +static int sp_256_ecc_mulmod_stripe_8(sp_point_256* r, const sp_point_256* g, + const sp_table_entry_256* table, const sp_digit* k, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point rtd; - sp_point pd; + sp_point_256 rtd; + sp_point_256 pd; sp_digit td[2 * 8 * 5]; #endif - sp_point* rt; - sp_point* p = NULL; + sp_point_256* rt; + sp_point_256* p = NULL; sp_digit* t; int i, j; int y, x; @@ -18025,9 +18021,10 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point* r, const sp_point* g, (void)g; (void)heap; - err = sp_ecc_point_new(heap, rtd, rt); + + err = sp_256_point_new_8(heap, rtd, rt); if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, pd, p); + err = sp_256_point_new_8(heap, pd, p); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 5, heap, @@ -18067,7 +18064,7 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point* r, const sp_point* g, sp_256_map_8(r, rt, t); } else { - XMEMCPY(r, rt, sizeof(sp_point)); + XMEMCPY(r, rt, sizeof(sp_point_256)); } } @@ -18076,8 +18073,8 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point* r, const sp_point* g, XFREE(t, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(p, 0, heap); - sp_ecc_point_free(rt, 0, heap); + sp_256_point_free_8(p, 0, heap); + sp_256_point_free_8(rt, 0, heap); return err; } @@ -18087,43 +18084,43 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point* r, const sp_point* g, #define FP_ENTRIES 16 #endif -typedef struct sp_cache_t { +typedef struct sp_cache_256_t { sp_digit x[8]; sp_digit y[8]; - sp_table_entry table[16]; + sp_table_entry_256 table[16]; uint32_t cnt; int set; -} sp_cache_t; +} sp_cache_256_t; -static THREAD_LS_T sp_cache_t sp_cache[FP_ENTRIES]; -static THREAD_LS_T int sp_cache_last = -1; -static THREAD_LS_T int sp_cache_inited = 0; +static THREAD_LS_T sp_cache_256_t sp_cache_256[FP_ENTRIES]; +static THREAD_LS_T int sp_cache_256_last = -1; +static THREAD_LS_T int sp_cache_256_inited = 0; #ifndef HAVE_THREAD_LS - static volatile int initCacheMutex = 0; - static wolfSSL_Mutex sp_cache_lock; + static volatile int initCacheMutex_256 = 0; + static wolfSSL_Mutex sp_cache_256_lock; #endif -static void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache) +static void sp_ecc_get_cache_256(const sp_point_256* g, sp_cache_256_t** cache) { int i, j; uint32_t least; - if (sp_cache_inited == 0) { + if (sp_cache_256_inited == 0) { for (i=0; ix, sp_cache[i].x) & - sp_256_cmp_equal_8(g->y, sp_cache[i].y)) { - sp_cache[i].cnt++; + if (sp_256_cmp_equal_8(g->x, sp_cache_256[i].x) & + sp_256_cmp_equal_8(g->y, sp_cache_256[i].y)) { + sp_cache_256[i].cnt++; break; } } @@ -18131,32 +18128,32 @@ static void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache) /* No match. */ if (i == FP_ENTRIES) { /* Find empty entry. */ - i = (sp_cache_last + 1) % FP_ENTRIES; - for (; i != sp_cache_last; i=(i+1)%FP_ENTRIES) { - if (!sp_cache[i].set) { + i = (sp_cache_256_last + 1) % FP_ENTRIES; + for (; i != sp_cache_256_last; i=(i+1)%FP_ENTRIES) { + if (!sp_cache_256[i].set) { break; } } /* Evict least used. */ - if (i == sp_cache_last) { - least = sp_cache[0].cnt; + if (i == sp_cache_256_last) { + least = sp_cache_256[0].cnt; for (j=1; jx, sizeof(sp_cache[i].x)); - XMEMCPY(sp_cache[i].y, g->y, sizeof(sp_cache[i].y)); - sp_cache[i].set = 1; - sp_cache[i].cnt = 1; + XMEMCPY(sp_cache_256[i].x, g->x, sizeof(sp_cache_256[i].x)); + XMEMCPY(sp_cache_256[i].y, g->y, sizeof(sp_cache_256[i].y)); + sp_cache_256[i].set = 1; + sp_cache_256[i].cnt = 1; } - *cache = &sp_cache[i]; - sp_cache_last = i; + *cache = &sp_cache_256[i]; + sp_cache_256_last = i; } #endif /* FP_ECC */ @@ -18170,32 +18167,32 @@ static void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache) * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_8(sp_point* r, const sp_point* g, const sp_digit* k, +static int sp_256_ecc_mulmod_8(sp_point_256* r, const sp_point_256* g, const sp_digit* k, int map, void* heap) { #ifndef FP_ECC return sp_256_ecc_mulmod_fast_8(r, g, k, map, heap); #else sp_digit tmp[2 * 8 * 5]; - sp_cache_t* cache; + sp_cache_256_t* cache; int err = MP_OKAY; #ifndef HAVE_THREAD_LS - if (initCacheMutex == 0) { - wc_InitMutex(&sp_cache_lock); - initCacheMutex = 1; + if (initCacheMutex_256 == 0) { + wc_InitMutex(&sp_cache_256_lock); + initCacheMutex_256 = 1; } - if (wc_LockMutex(&sp_cache_lock) != 0) + if (wc_LockMutex(&sp_cache_256_lock) != 0) err = BAD_MUTEX_E; #endif /* HAVE_THREAD_LS */ if (err == MP_OKAY) { - sp_ecc_get_cache(g, &cache); + sp_ecc_get_cache_256(g, &cache); if (cache->cnt == 2) sp_256_gen_stripe_table_8(g, cache->table, tmp, heap); #ifndef HAVE_THREAD_LS - wc_UnLockMutex(&sp_cache_lock); + wc_UnLockMutex(&sp_cache_256_lock); #endif /* HAVE_THREAD_LS */ if (cache->cnt < 2) { @@ -18220,26 +18217,26 @@ static int sp_256_ecc_mulmod_8(sp_point* r, const sp_point* g, const sp_digit* k * tmp Temporary data. * heap Heap to use for allocation. */ -static int sp_256_gen_stripe_table_8(const sp_point* a, - sp_table_entry* table, sp_digit* tmp, void* heap) +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) - sp_point td, s1d, s2d; + sp_point_256 td, s1d, s2d; #endif - sp_point* t; - sp_point* s1 = NULL; - sp_point* s2 = NULL; + sp_point_256* t; + sp_point_256* s1 = NULL; + sp_point_256* s2 = NULL; int i, j; int err; (void)heap; - err = sp_ecc_point_new(heap, td, t); + err = sp_256_point_new_8(heap, td, t); if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, s1d, s1); + err = sp_256_point_new_8(heap, s1d, s1); } if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, s2d, s2); + err = sp_256_point_new_8(heap, s2d, s2); } if (err == MP_OKAY) { @@ -18261,7 +18258,7 @@ static int sp_256_gen_stripe_table_8(const sp_point* a, s2->infinity = 0; /* table[0] = {0, 0, infinity} */ - XMEMSET(&table[0], 0, sizeof(sp_table_entry)); + XMEMSET(&table[0], 0, sizeof(sp_table_entry_256)); /* 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)); @@ -18287,9 +18284,9 @@ static int sp_256_gen_stripe_table_8(const sp_point* a, } } - sp_ecc_point_free(s2, 0, heap); - sp_ecc_point_free(s1, 0, heap); - sp_ecc_point_free( t, 0, heap); + sp_256_point_free_8(s2, 0, heap); + sp_256_point_free_8(s1, 0, heap); + sp_256_point_free_8( t, 0, heap); return err; } @@ -18304,16 +18301,16 @@ static int sp_256_gen_stripe_table_8(const sp_point* a, * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_stripe_8(sp_point* r, const sp_point* g, - const sp_table_entry* table, const sp_digit* k, int map, void* heap) +static int sp_256_ecc_mulmod_stripe_8(sp_point_256* r, const sp_point_256* g, + const sp_table_entry_256* table, const sp_digit* k, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point rtd; - sp_point pd; + sp_point_256 rtd; + sp_point_256 pd; sp_digit td[2 * 8 * 5]; #endif - sp_point* rt; - sp_point* p = NULL; + sp_point_256* rt; + sp_point_256* p = NULL; sp_digit* t; int i, j; int y, x; @@ -18322,9 +18319,10 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point* r, const sp_point* g, (void)g; (void)heap; - err = sp_ecc_point_new(heap, rtd, rt); + + err = sp_256_point_new_8(heap, rtd, rt); if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, pd, p); + err = sp_256_point_new_8(heap, pd, p); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 5, heap, @@ -18364,7 +18362,7 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point* r, const sp_point* g, sp_256_map_8(r, rt, t); } else { - XMEMCPY(r, rt, sizeof(sp_point)); + XMEMCPY(r, rt, sizeof(sp_point_256)); } } @@ -18373,8 +18371,8 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point* r, const sp_point* g, XFREE(t, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(p, 0, heap); - sp_ecc_point_free(rt, 0, heap); + sp_256_point_free_8(p, 0, heap); + sp_256_point_free_8(rt, 0, heap); return err; } @@ -18384,43 +18382,43 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point* r, const sp_point* g, #define FP_ENTRIES 16 #endif -typedef struct sp_cache_t { +typedef struct sp_cache_256_t { sp_digit x[8]; sp_digit y[8]; - sp_table_entry table[256]; + sp_table_entry_256 table[256]; uint32_t cnt; int set; -} sp_cache_t; +} sp_cache_256_t; -static THREAD_LS_T sp_cache_t sp_cache[FP_ENTRIES]; -static THREAD_LS_T int sp_cache_last = -1; -static THREAD_LS_T int sp_cache_inited = 0; +static THREAD_LS_T sp_cache_256_t sp_cache_256[FP_ENTRIES]; +static THREAD_LS_T int sp_cache_256_last = -1; +static THREAD_LS_T int sp_cache_256_inited = 0; #ifndef HAVE_THREAD_LS - static volatile int initCacheMutex = 0; - static wolfSSL_Mutex sp_cache_lock; + static volatile int initCacheMutex_256 = 0; + static wolfSSL_Mutex sp_cache_256_lock; #endif -static void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache) +static void sp_ecc_get_cache_256(const sp_point_256* g, sp_cache_256_t** cache) { int i, j; uint32_t least; - if (sp_cache_inited == 0) { + if (sp_cache_256_inited == 0) { for (i=0; ix, sp_cache[i].x) & - sp_256_cmp_equal_8(g->y, sp_cache[i].y)) { - sp_cache[i].cnt++; + if (sp_256_cmp_equal_8(g->x, sp_cache_256[i].x) & + sp_256_cmp_equal_8(g->y, sp_cache_256[i].y)) { + sp_cache_256[i].cnt++; break; } } @@ -18428,32 +18426,32 @@ static void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache) /* No match. */ if (i == FP_ENTRIES) { /* Find empty entry. */ - i = (sp_cache_last + 1) % FP_ENTRIES; - for (; i != sp_cache_last; i=(i+1)%FP_ENTRIES) { - if (!sp_cache[i].set) { + i = (sp_cache_256_last + 1) % FP_ENTRIES; + for (; i != sp_cache_256_last; i=(i+1)%FP_ENTRIES) { + if (!sp_cache_256[i].set) { break; } } /* Evict least used. */ - if (i == sp_cache_last) { - least = sp_cache[0].cnt; + if (i == sp_cache_256_last) { + least = sp_cache_256[0].cnt; for (j=1; jx, sizeof(sp_cache[i].x)); - XMEMCPY(sp_cache[i].y, g->y, sizeof(sp_cache[i].y)); - sp_cache[i].set = 1; - sp_cache[i].cnt = 1; + XMEMCPY(sp_cache_256[i].x, g->x, sizeof(sp_cache_256[i].x)); + XMEMCPY(sp_cache_256[i].y, g->y, sizeof(sp_cache_256[i].y)); + sp_cache_256[i].set = 1; + sp_cache_256[i].cnt = 1; } - *cache = &sp_cache[i]; - sp_cache_last = i; + *cache = &sp_cache_256[i]; + sp_cache_256_last = i; } #endif /* FP_ECC */ @@ -18467,32 +18465,32 @@ static void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache) * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_8(sp_point* r, const sp_point* g, const sp_digit* k, +static int sp_256_ecc_mulmod_8(sp_point_256* r, const sp_point_256* g, const sp_digit* k, int map, void* heap) { #ifndef FP_ECC return sp_256_ecc_mulmod_fast_8(r, g, k, map, heap); #else sp_digit tmp[2 * 8 * 5]; - sp_cache_t* cache; + sp_cache_256_t* cache; int err = MP_OKAY; #ifndef HAVE_THREAD_LS - if (initCacheMutex == 0) { - wc_InitMutex(&sp_cache_lock); - initCacheMutex = 1; + if (initCacheMutex_256 == 0) { + wc_InitMutex(&sp_cache_256_lock); + initCacheMutex_256 = 1; } - if (wc_LockMutex(&sp_cache_lock) != 0) + if (wc_LockMutex(&sp_cache_256_lock) != 0) err = BAD_MUTEX_E; #endif /* HAVE_THREAD_LS */ if (err == MP_OKAY) { - sp_ecc_get_cache(g, &cache); + sp_ecc_get_cache_256(g, &cache); if (cache->cnt == 2) sp_256_gen_stripe_table_8(g, cache->table, tmp, heap); #ifndef HAVE_THREAD_LS - wc_UnLockMutex(&sp_cache_lock); + wc_UnLockMutex(&sp_cache_256_lock); #endif /* HAVE_THREAD_LS */ if (cache->cnt < 2) { @@ -18523,15 +18521,14 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point p; - sp_digit k[8]; -#else - sp_digit* k = NULL; + sp_point_256 p; + sp_digit kd[8]; #endif - sp_point* point; - int err; + sp_point_256* point; + sp_digit* k = NULL; + int err = MP_OKAY; - err = sp_ecc_point_new(heap, p, point); + err = sp_256_point_new_8(heap, p, point); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8, heap, @@ -18539,6 +18536,8 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, if (k == NULL) err = MEMORY_E; } +#else + k = kd; #endif if (err == MP_OKAY) { sp_256_from_mp(k, 8, km); @@ -18555,13 +18554,13 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, XFREE(k, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(point, 0, heap); + sp_256_point_free_8(point, 0, heap); return err; } #ifdef WOLFSSL_SP_SMALL -static const sp_table_entry p256_table[16] = { +static const sp_table_entry_256 p256_table[16] = { /* 0 */ { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, @@ -18651,7 +18650,7 @@ static const sp_table_entry p256_table[16] = { * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_base_8(sp_point* r, const sp_digit* k, +static int sp_256_ecc_mulmod_base_8(sp_point_256* r, const sp_digit* k, int map, void* heap) { return sp_256_ecc_mulmod_stripe_8(r, &p256_base, p256_table, @@ -18659,7 +18658,7 @@ static int sp_256_ecc_mulmod_base_8(sp_point* r, const sp_digit* k, } #else -static const sp_table_entry p256_table[256] = { +static const sp_table_entry_256 p256_table[256] = { /* 0 */ { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, @@ -19949,7 +19948,7 @@ static const sp_table_entry p256_table[256] = { * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_base_8(sp_point* r, const sp_digit* k, +static int sp_256_ecc_mulmod_base_8(sp_point_256* r, const sp_digit* k, int map, void* heap) { return sp_256_ecc_mulmod_stripe_8(r, &p256_base, p256_table, @@ -19970,15 +19969,14 @@ static int sp_256_ecc_mulmod_base_8(sp_point* r, const sp_digit* k, int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point p; - sp_digit k[8]; -#else - sp_digit* k = NULL; + sp_point_256 p; + sp_digit kd[8]; #endif - sp_point* point; - int err; + sp_point_256* point; + sp_digit* k = NULL; + int err = MP_OKAY; - err = sp_ecc_point_new(heap, p, point); + err = sp_256_point_new_8(heap, p, point); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8, heap, @@ -19987,6 +19985,8 @@ int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) err = MEMORY_E; } } +#else + k = kd; #endif if (err == MP_OKAY) { sp_256_from_mp(k, 8, km); @@ -20002,7 +20002,7 @@ int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) XFREE(k, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(point, 0, heap); + sp_256_point_free_8(point, 0, heap); return err; } @@ -20133,26 +20133,25 @@ static int sp_256_ecc_gen_k_8(WC_RNG* rng, sp_digit* k) int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point p; - sp_digit k[8]; + sp_point_256 p; + sp_digit kd[8]; #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN - sp_point inf; + sp_point_256 inf; #endif -#else +#endif + sp_point_256* point; sp_digit* k = NULL; -#endif - sp_point* point; #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN - sp_point* infinity; + sp_point_256* infinity; #endif int err; (void)heap; - err = sp_ecc_point_new(heap, p, point); + err = sp_256_point_new_8(heap, p, point); #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, inf, infinity); + err = sp_256_point_new_8(heap, inf, infinity); } #endif #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) @@ -20163,6 +20162,8 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) err = MEMORY_E; } } +#else + k = kd; #endif if (err == MP_OKAY) { @@ -20196,9 +20197,9 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) } #endif #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN - sp_ecc_point_free(infinity, 1, heap); + sp_256_point_free_8(infinity, 1, heap); #endif - sp_ecc_point_free(point, 1, heap); + sp_256_point_free_8(point, 1, heap); return err; } @@ -20255,12 +20256,11 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, word32* outLen, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point p; - sp_digit k[8]; -#else - sp_digit* k = NULL; + sp_point_256 p; + sp_digit kd[8]; #endif - sp_point* point = NULL; + sp_point_256* point = NULL; + sp_digit* k = NULL; int err = MP_OKAY; if (*outLen < 32U) { @@ -20268,7 +20268,7 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, } if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, p, point); + err = sp_256_point_new_8(heap, p, point); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { @@ -20277,6 +20277,8 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, if (k == NULL) err = MEMORY_E; } +#else + k = kd; #endif if (err == MP_OKAY) { @@ -20294,7 +20296,7 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, XFREE(k, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(point, 0, heap); + sp_256_point_free_8(point, 0, heap); return err; } @@ -20685,7 +20687,7 @@ static WC_INLINE int sp_256_mod_8(sp_digit* r, const sp_digit* a, const sp_digit #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) #ifdef WOLFSSL_SP_SMALL /* Order-2 for the P256 curve. */ -static const uint32_t p256_order_2[8] = { +static const uint32_t p256_order_minus_2[8] = { 0xfc63254fU,0xf3b9cac2U,0xa7179e84U,0xbce6faadU,0xffffffffU,0xffffffffU, 0x00000000U,0xffffffffU }; @@ -20754,7 +20756,7 @@ static void sp_256_mont_inv_order_8(sp_digit* r, const sp_digit* a, XMEMCPY(t, a, sizeof(sp_digit) * 8); for (i=254; i>=0; i--) { sp_256_mont_sqr_order_8(t, t); - if ((p256_order_2[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { + if ((p256_order_minus_2[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { sp_256_mont_mul_order_8(t, t, a); } } @@ -20870,24 +20872,24 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_digit kd[2*8]; sp_digit rd[2*8]; sp_digit td[3 * 2*8]; - sp_point p; + sp_point_256 p; #endif sp_digit* e = NULL; sp_digit* x = NULL; sp_digit* k = NULL; sp_digit* r = NULL; sp_digit* tmp = NULL; - sp_point* point = NULL; + sp_point_256* point = NULL; sp_digit carry; sp_digit* s = NULL; sp_digit* kInv = NULL; - int err; + int err = MP_OKAY; int32_t c; int i; (void)heap; - err = sp_ecc_point_new(heap, p, point); + err = sp_256_point_new_8(heap, p, point); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7 * 2 * 8, heap, @@ -21003,7 +21005,7 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, XMEMSET(r, 0, sizeof(sp_digit) * 2U * 8U); XMEMSET(tmp, 0, sizeof(sp_digit) * 3U * 2U * 8U); #endif - sp_ecc_point_free(point, 1, heap); + sp_256_point_free_8(point, 1, heap); return err; } @@ -21040,22 +21042,22 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, sp_digit u2d[2*8]; sp_digit sd[2*8]; sp_digit tmpd[2*8 * 5]; - sp_point p1d; - sp_point p2d; + sp_point_256 p1d; + sp_point_256 p2d; #endif sp_digit* u1 = NULL; sp_digit* u2 = NULL; sp_digit* s = NULL; sp_digit* tmp = NULL; - sp_point* p1; - sp_point* p2 = NULL; + sp_point_256* p1; + sp_point_256* p2 = NULL; sp_digit carry; int32_t c; int err; - err = sp_ecc_point_new(heap, p1d, p1); + err = sp_256_point_new_8(heap, p1d, p1); if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, p2d, p2); + err = sp_256_point_new_8(heap, p2d, p2); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { @@ -21171,8 +21173,8 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, if (d != NULL) XFREE(d, heap, DYNAMIC_TYPE_ECC); #endif - sp_ecc_point_free(p1, 0, heap); - sp_ecc_point_free(p2, 0, heap); + sp_256_point_free_8(p1, 0, heap); + sp_256_point_free_8(p2, 0, heap); return err; } @@ -21186,10 +21188,10 @@ 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* point, void* heap) +static int sp_256_ecc_is_point_8(sp_point_256* point, void* heap) { #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - sp_digit* d; + sp_digit* d = NULL; #else sp_digit t1d[2*8]; sp_digit t2d[2*8]; @@ -21253,13 +21255,13 @@ static int sp_256_ecc_is_point_8(sp_point* point, void* heap) int sp_ecc_is_point_256(mp_int* pX, mp_int* pY) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point pubd; + sp_point_256 pubd; #endif - sp_point* pub; + sp_point_256* pub; byte one[1] = { 1 }; int err; - err = sp_ecc_point_new(NULL, pubd, pub); + err = sp_256_point_new_8(NULL, pubd, pub); if (err == MP_OKAY) { sp_256_from_mp(pub->x, 8, pX); sp_256_from_mp(pub->y, 8, pY); @@ -21268,7 +21270,7 @@ int sp_ecc_is_point_256(mp_int* pX, mp_int* pY) err = sp_256_ecc_is_point_8(pub, NULL); } - sp_ecc_point_free(pub, 0, NULL); + sp_256_point_free_8(pub, 0, NULL); return err; } @@ -21288,18 +21290,18 @@ int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_digit privd[8]; - sp_point pubd; - sp_point pd; + sp_point_256 pubd; + sp_point_256 pd; #endif sp_digit* priv = NULL; - sp_point* pub; - sp_point* p = NULL; + sp_point_256* pub; + sp_point_256* p = NULL; byte one[1] = { 1 }; int err; - err = sp_ecc_point_new(heap, pubd, pub); + err = sp_256_point_new_8(heap, pubd, pub); if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, pd, p); + err = sp_256_point_new_8(heap, pd, p); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { @@ -21370,8 +21372,8 @@ int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) XFREE(priv, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(p, 0, heap); - sp_ecc_point_free(pub, 0, heap); + sp_256_point_free_8(p, 0, heap); + sp_256_point_free_8(pub, 0, heap); return err; } @@ -21397,17 +21399,17 @@ int sp_ecc_proj_add_point_256(mp_int* pX, mp_int* pY, mp_int* pZ, { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_digit tmpd[2 * 8 * 5]; - sp_point pd; - sp_point qd; + sp_point_256 pd; + sp_point_256 qd; #endif sp_digit* tmp; - sp_point* p; - sp_point* q = NULL; + sp_point_256* p; + sp_point_256* q = NULL; int err; - err = sp_ecc_point_new(NULL, pd, p); + err = sp_256_point_new_8(NULL, pd, p); if (err == MP_OKAY) { - err = sp_ecc_point_new(NULL, qd, q); + err = sp_256_point_new_8(NULL, qd, q); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { @@ -21447,8 +21449,8 @@ int sp_ecc_proj_add_point_256(mp_int* pX, mp_int* pY, mp_int* pZ, XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(q, 0, NULL); - sp_ecc_point_free(p, 0, NULL); + sp_256_point_free_8(q, 0, NULL); + sp_256_point_free_8(p, 0, NULL); return err; } @@ -21469,13 +21471,13 @@ int sp_ecc_proj_dbl_point_256(mp_int* pX, mp_int* pY, mp_int* pZ, { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_digit tmpd[2 * 8 * 2]; - sp_point pd; + sp_point_256 pd; #endif sp_digit* tmp; - sp_point* p; + sp_point_256* p; int err; - err = sp_ecc_point_new(NULL, pd, p); + err = sp_256_point_new_8(NULL, pd, p); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 2, NULL, @@ -21511,7 +21513,7 @@ int sp_ecc_proj_dbl_point_256(mp_int* pX, mp_int* pY, mp_int* pZ, XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(p, 0, NULL); + sp_256_point_free_8(p, 0, NULL); return err; } @@ -21528,13 +21530,13 @@ int sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_digit tmpd[2 * 8 * 4]; - sp_point pd; + sp_point_256 pd; #endif sp_digit* tmp; - sp_point* p; + sp_point_256* p; int err; - err = sp_ecc_point_new(NULL, pd, p); + err = sp_256_point_new_8(NULL, pd, p); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 4, NULL, @@ -21569,7 +21571,7 @@ int sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ) XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(p, 0, NULL); + sp_256_point_free_8(p, 0, NULL); return err; } @@ -21650,6 +21652,7 @@ static int sp_256_mont_sqrt_8(sp_digit* y) return err; } + /* Uncompress the point given the X ordinate. * * xm X ordinate. @@ -21726,6 +21729,5847 @@ int sp_ecc_uncompress_256(mp_int* xm, int odd, mp_int* ym) } #endif #endif /* !WOLFSSL_SP_NO_256 */ +#ifdef WOLFSSL_SP_384 + +/* Point structure to use. */ +typedef struct sp_point_384 { + sp_digit x[2 * 12]; + sp_digit y[2 * 12]; + sp_digit z[2 * 12]; + int infinity; +} sp_point_384; + +/* The modulus (prime) of the curve P384. */ +static const sp_digit p384_mod[12] = { + 0xffffffff,0x00000000,0x00000000,0xffffffff,0xfffffffe,0xffffffff, + 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff +}; +/* The Montogmery normalizer for modulus of the curve P384. */ +static const sp_digit p384_norm_mod[12] = { + 0x00000001,0xffffffff,0xffffffff,0x00000000,0x00000001,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 +}; +/* The Montogmery multiplier for modulus of the curve P384. */ +static sp_digit p384_mp_mod = 0x00000001; +#if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \ + defined(HAVE_ECC_VERIFY) +/* The order of the curve P384. */ +static const sp_digit p384_order[12] = { + 0xccc52973,0xecec196a,0x48b0a77a,0x581a0db2,0xf4372ddf,0xc7634d81, + 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff +}; +#endif +/* The order of the curve P384 minus 2. */ +static const sp_digit p384_order2[12] = { + 0xccc52971,0xecec196a,0x48b0a77a,0x581a0db2,0xf4372ddf,0xc7634d81, + 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff +}; +#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[12] = { + 0x333ad68d,0x1313e695,0xb74f5885,0xa7e5f24d,0x0bc8d220,0x389cb27e, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 +}; +#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 = 0xe88fdc45; +#endif +/* The base point of curve P384. */ +static const sp_point_384 p384_base = { + /* X ordinate */ + { + 0x72760ab7,0x3a545e38,0xbf55296c,0x5502f25d,0x82542a38,0x59f741e0, + 0x8ba79b98,0x6e1d3b62,0xf320ad74,0x8eb1c71e,0xbe8b0537,0xaa87ca22, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + }, + /* Y ordinate */ + { + 0x90ea0e5f,0x7a431d7c,0x1d7e819d,0x0a60b1ce,0xb5f0b8c0,0xe9da3113, + 0x289a147c,0xf8f41dbd,0x9292dc29,0x5d9e98bf,0x96262c6f,0x3617de4a, + 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, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + }, + /* infinity */ + 0 +}; +#if defined(HAVE_ECC_CHECK_KEY) || defined(HAVE_COMP_KEY) +static const sp_digit p384_b[12] = { + 0xd3ec2aef,0x2a85c8ed,0x8a2ed19d,0xc656398d,0x5013875a,0x0314088f, + 0xfe814112,0x181d9c6e,0xe3f82d19,0x988e056b,0xe23ee7e4,0xb3312fa7 +}; +#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) + (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) +/* 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) +/* 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) + 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) + 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) + 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] |= a[i] << s; + r->dp[j] &= (1L << DIGIT_BIT) - 1; + s = DIGIT_BIT - s; + r->dp[++j] = 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] = 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. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static void sp_384_mul_12(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit tmp[12 * 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, #48\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, #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 %[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, #88\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)); +} + +/* 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_384_cond_sub_12(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "mov r5, #48\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; +} + +#define sp_384_mont_reduce_order_12 sp_384_mont_reduce_12 + +/* 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_12(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, #44\n\t" + "add r4, r9\n\t" + "cmp r10, r4\n\t" + "blt 2b\n\t" + "# a[i+11] += m[11] * mu\n\t" + "mov %[ca], #0\n\t" + "mov r4, r12\n\t" + "mov %[a], #0\n\t" + "# Multiply m[11] 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[11] 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, #48\n\t" + "cmp r11, r4\n\t" + "blt 1b\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_384_cond_sub_12(a - 12, 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_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. + * a Number to square in Montogmery form. + * 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) +{ + sp_384_sqr_12(r, a); + sp_384_mont_reduce_12(r, m, mp); +} + +#if !defined(WOLFSSL_SP_SMALL) || defined(HAVE_COMP_KEY) +/* Square the Montgomery form number a number of times. (r = a ^ n mod m) + * + * r Result of squaring. + * a Number to square in Montogmery form. + * n Number of times to square. + * m Modulus (prime). + * mp Montogmery mulitplier. + */ +static void sp_384_mont_sqr_n_12(sp_digit* r, const sp_digit* a, int n, + const sp_digit* m, sp_digit mp) +{ + sp_384_mont_sqr_12(r, a, m, mp); + for (; n > 1; n--) { + sp_384_mont_sqr_12(r, r, m, mp); + } +} + +#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] = { + 0xfffffffdU,0x00000000U,0x00000000U,0xffffffffU,0xfffffffeU,0xffffffffU, + 0xffffffffU,0xffffffffU,0xffffffffU,0xffffffffU,0xffffffffU,0xffffffffU +}; +#endif /* !WOLFSSL_SP_SMALL */ + +/* Invert the number, in Montgomery form, modulo the modulus (prime) of the + * P384 curve. (r = 1 / a mod m) + * + * r Inverse result. + * a Number to invert. + * td Temporary data. + */ +static void sp_384_mont_inv_12(sp_digit* r, const sp_digit* a, sp_digit* td) +{ +#ifdef WOLFSSL_SP_SMALL + sp_digit* t = td; + int i; + + XMEMCPY(t, a, sizeof(sp_digit) * 12); + for (i=382; i>=0; i--) { + sp_384_mont_sqr_12(t, t, p384_mod, p384_mp_mod); + if (p384_mod_minus_2[i / 32] & ((sp_digit)1 << (i % 32))) + sp_384_mont_mul_12(t, t, a, p384_mod, p384_mp_mod); + } + XMEMCPY(r, t, sizeof(sp_digit) * 12); +#else + sp_digit* t1 = td; + sp_digit* t2 = td + 2 * 12; + sp_digit* t3 = td + 4 * 12; + sp_digit* t4 = td + 6 * 12; + sp_digit* t5 = td + 8 * 12; + + /* 0x2 */ + sp_384_mont_sqr_12(t1, a, p384_mod, p384_mp_mod); + /* 0x3 */ + sp_384_mont_mul_12(t5, t1, a, p384_mod, p384_mp_mod); + /* 0xc */ + sp_384_mont_sqr_n_12(t1, t5, 2, p384_mod, p384_mp_mod); + /* 0xf */ + sp_384_mont_mul_12(t2, t5, t1, p384_mod, p384_mp_mod); + /* 0x1e */ + sp_384_mont_sqr_12(t1, t2, p384_mod, p384_mp_mod); + /* 0x1f */ + sp_384_mont_mul_12(t4, t1, a, p384_mod, p384_mp_mod); + /* 0x3e0 */ + sp_384_mont_sqr_n_12(t1, t4, 5, p384_mod, p384_mp_mod); + /* 0x3ff */ + sp_384_mont_mul_12(t2, t4, t1, p384_mod, p384_mp_mod); + /* 0x7fe0 */ + sp_384_mont_sqr_n_12(t1, t2, 5, p384_mod, p384_mp_mod); + /* 0x7fff */ + sp_384_mont_mul_12(t4, t4, t1, p384_mod, p384_mp_mod); + /* 0x3fff8000 */ + sp_384_mont_sqr_n_12(t1, t4, 15, p384_mod, p384_mp_mod); + /* 0x3fffffff */ + sp_384_mont_mul_12(t2, t4, t1, p384_mod, p384_mp_mod); + /* 0xfffffffc */ + sp_384_mont_sqr_n_12(t3, t2, 2, p384_mod, p384_mp_mod); + /* 0xfffffffd */ + sp_384_mont_mul_12(r, t3, a, p384_mod, p384_mp_mod); + /* 0xffffffff */ + sp_384_mont_mul_12(t3, t5, t3, p384_mod, p384_mp_mod); + /* 0xfffffffc0000000 */ + sp_384_mont_sqr_n_12(t1, t2, 30, p384_mod, p384_mp_mod); + /* 0xfffffffffffffff */ + sp_384_mont_mul_12(t2, t2, t1, p384_mod, p384_mp_mod); + /* 0xfffffffffffffff000000000000000 */ + sp_384_mont_sqr_n_12(t1, t2, 60, p384_mod, p384_mp_mod); + /* 0xffffffffffffffffffffffffffffff */ + sp_384_mont_mul_12(t2, t2, t1, p384_mod, p384_mp_mod); + /* 0xffffffffffffffffffffffffffffff000000000000000000000000000000 */ + sp_384_mont_sqr_n_12(t1, t2, 120, p384_mod, p384_mp_mod); + /* 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */ + sp_384_mont_mul_12(t2, t2, t1, p384_mod, p384_mp_mod); + /* 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000 */ + sp_384_mont_sqr_n_12(t1, t2, 15, p384_mod, p384_mp_mod); + /* 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */ + sp_384_mont_mul_12(t2, t4, t1, p384_mod, p384_mp_mod); + /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00000000 */ + sp_384_mont_sqr_n_12(t1, t2, 33, p384_mod, p384_mp_mod); + /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff */ + sp_384_mont_mul_12(t2, t3, t1, p384_mod, p384_mp_mod); + /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff000000000000000000000000 */ + sp_384_mont_sqr_n_12(t1, t2, 96, p384_mod, p384_mp_mod); + /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffd */ + sp_384_mont_mul_12(r, r, t1, p384_mod, p384_mp_mod); + +#endif /* WOLFSSL_SP_SMALL */ +} + +/* 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_384_cmp_12(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, #44\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; +} + +/* Normalize the values in each word to 32. + * + * a Array of sp_digit to normalize. + */ +#define sp_384_norm_12(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_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; + int32_t n; + + sp_384_mont_inv_12(t1, p->z, t + 2*12); + + 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); + + /* x /= z^2 */ + sp_384_mont_mul_12(r->x, p->x, t2, p384_mod, p384_mp_mod); + XMEMSET(r->x + 12, 0, sizeof(r->x) / 2U); + sp_384_mont_reduce_12(r->x, p384_mod, p384_mp_mod); + /* Reduce x to less than modulus */ + n = sp_384_cmp_12(r->x, p384_mod); + sp_384_cond_sub_12(r->x, r->x, p384_mod, 0 - ((n >= 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_384_norm_12(r->x); + + /* y /= z^3 */ + sp_384_mont_mul_12(r->y, p->y, t1, p384_mod, p384_mp_mod); + XMEMSET(r->y + 12, 0, sizeof(r->y) / 2U); + sp_384_mont_reduce_12(r->y, p384_mod, p384_mp_mod); + /* Reduce y to less than modulus */ + n = sp_384_cmp_12(r->y, p384_mod); + sp_384_cond_sub_12(r->y, r->y, p384_mod, 0 - ((n >= 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_384_norm_12(r->y); + + XMEMSET(r->z, 0, sizeof(r->z)); + r->z[0] = 1; + +} + +#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. + * a First number to add in Montogmery form. + * b Second number to add in Montogmery form. + * m Modulus (prime). + */ +SP_NOINLINE static void sp_384_mont_add_12(sp_digit* r, const sp_digit* a, const sp_digit* b, + const sp_digit* m) +{ + sp_digit o; + + o = sp_384_add_12(r, a, b); + sp_384_cond_sub_12(r, r, m, 0 - o); +} + +/* 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_384_mont_dbl_12(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + sp_digit o; + + o = sp_384_add_12(r, a, a); + sp_384_cond_sub_12(r, r, m, 0 - o); +} + +/* 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_384_mont_tpl_12(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + sp_digit o; + + o = sp_384_add_12(r, a, a); + sp_384_cond_sub_12(r, r, m, 0 - o); + o = sp_384_add_12(r, r, a); + 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. + * + * 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_384_cond_add_12(sp_digit* r, const sp_digit* a, const sp_digit* b, + sp_digit m) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "mov r5, #0\n\t" + "mov r7, %[a]\n\t" + "add r7, #48\n\t" + "sub r5, #1\n\t" + "mov r8, r7\n\t" + "1:\n\t" + "ldr r6, [%[a]]\n\t" + "ldr r7, [%[b]]\n\t" + "and r7, %[m]\n\t" + "add %[c], r5\n\t" + "adc r6, r7\n\t" + "str r6, [%[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" + "mov r7, r8\n\t" + "cmp %[a], r7\n\t" + "blt 1b\n\t" + : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [c] "+r" (c) + : [m] "r" (m) + : "memory", "r5", "r6", "r7", "r8" + ); + + return c; +} + +/* 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_384_mont_sub_12(sp_digit* r, const sp_digit* a, const sp_digit* b, + const sp_digit* m) +{ + sp_digit o; + + o = sp_384_sub_12(r, a, b); + sp_384_cond_add_12(r, r, m, o); +} + +static void sp_384_rshift1_12(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" + "str r3, [%[r], #40]\n\t" + "str r4, [%[r], #44]\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_384_div2_12(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + sp_digit o; + + o = sp_384_cond_add_12(r, a, m, 0 - (a[0] & 1)); + sp_384_rshift1_12(r, r); + r[11] |= o << 31; +} + +/* Double the Montgomery form projective point p. + * + * r Result of doubling point. + * p Point to double. + * t Temporary ordinate data. + */ +static void sp_384_proj_point_dbl_12(sp_point_384* r, const sp_point_384* p, sp_digit* t) +{ + sp_point_384* rp[2]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*12; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + /* When infinity don't double point passed in - constant time. */ + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_384*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_384)); + x = rp[p->infinity]->x; + y = rp[p->infinity]->y; + z = rp[p->infinity]->z; + /* Put point to double into result - good for infinity. */ + if (r != p) { + for (i=0; i<12; i++) { + r->x[i] = p->x[i]; + } + for (i=0; i<12; i++) { + r->y[i] = p->y[i]; + } + for (i=0; i<12; i++) { + r->z[i] = p->z[i]; + } + r->infinity = p->infinity; + } + + /* T1 = Z * Z */ + sp_384_mont_sqr_12(t1, z, p384_mod, p384_mp_mod); + /* Z = Y * Z */ + sp_384_mont_mul_12(z, y, z, p384_mod, p384_mp_mod); + /* Z = 2Z */ + sp_384_mont_dbl_12(z, z, p384_mod); + /* T2 = X - T1 */ + sp_384_mont_sub_12(t2, x, t1, p384_mod); + /* T1 = X + T1 */ + sp_384_mont_add_12(t1, x, t1, p384_mod); + /* T2 = T1 * T2 */ + sp_384_mont_mul_12(t2, t1, t2, p384_mod, p384_mp_mod); + /* T1 = 3T2 */ + sp_384_mont_tpl_12(t1, t2, p384_mod); + /* Y = 2Y */ + sp_384_mont_dbl_12(y, y, p384_mod); + /* Y = Y * Y */ + sp_384_mont_sqr_12(y, y, p384_mod, p384_mp_mod); + /* T2 = Y * Y */ + sp_384_mont_sqr_12(t2, y, p384_mod, p384_mp_mod); + /* T2 = T2/2 */ + sp_384_div2_12(t2, t2, p384_mod); + /* Y = Y * X */ + sp_384_mont_mul_12(y, y, x, p384_mod, p384_mp_mod); + /* X = T1 * T1 */ + sp_384_mont_mul_12(x, t1, t1, p384_mod, p384_mp_mod); + /* X = X - Y */ + sp_384_mont_sub_12(x, x, y, p384_mod); + /* X = X - Y */ + sp_384_mont_sub_12(x, x, y, p384_mod); + /* Y = Y - X */ + sp_384_mont_sub_12(y, y, x, p384_mod); + /* Y = Y * T1 */ + sp_384_mont_mul_12(y, y, t1, p384_mod, p384_mp_mod); + /* Y = Y - T2 */ + sp_384_mont_sub_12(y, y, t2, p384_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_384_cmp_equal_12(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])) == 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. + */ +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]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*12; + sp_digit* t3 = t + 4*12; + sp_digit* t4 = t + 6*12; + sp_digit* t5 = t + 8*12; + 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_384* a = p; + p = q; + q = a; + } + + /* Check double */ + (void)sp_384_sub_12(t1, p384_mod, q->y); + sp_384_norm_12(t1); + if ((sp_384_cmp_equal_12(p->x, q->x) & sp_384_cmp_equal_12(p->z, q->z) & + (sp_384_cmp_equal_12(p->y, q->y) | sp_384_cmp_equal_12(p->y, t1))) != 0) { + sp_384_proj_point_dbl_12(r, p, t); + } + else { + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_384*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_384)); + 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<12; i++) { + r->x[i] = ap[p->infinity]->x[i]; + } + for (i=0; i<12; i++) { + r->y[i] = ap[p->infinity]->y[i]; + } + for (i=0; i<12; i++) { + r->z[i] = ap[p->infinity]->z[i]; + } + r->infinity = ap[p->infinity]->infinity; + + /* U1 = X1*Z2^2 */ + sp_384_mont_sqr_12(t1, q->z, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(t3, t1, q->z, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(t1, t1, x, p384_mod, p384_mp_mod); + /* U2 = X2*Z1^2 */ + sp_384_mont_sqr_12(t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(t4, t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(t2, t2, q->x, p384_mod, p384_mp_mod); + /* S1 = Y1*Z2^3 */ + sp_384_mont_mul_12(t3, t3, y, p384_mod, p384_mp_mod); + /* S2 = Y2*Z1^3 */ + sp_384_mont_mul_12(t4, t4, q->y, p384_mod, p384_mp_mod); + /* H = U2 - U1 */ + sp_384_mont_sub_12(t2, t2, t1, p384_mod); + /* R = S2 - S1 */ + sp_384_mont_sub_12(t4, t4, t3, p384_mod); + /* Z3 = H*Z1*Z2 */ + sp_384_mont_mul_12(z, z, q->z, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(z, z, t2, p384_mod, p384_mp_mod); + /* X3 = R^2 - H^3 - 2*U1*H^2 */ + sp_384_mont_sqr_12(x, t4, p384_mod, p384_mp_mod); + sp_384_mont_sqr_12(t5, t2, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(y, t1, t5, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(t5, t5, t2, p384_mod, p384_mp_mod); + sp_384_mont_sub_12(x, x, t5, p384_mod); + sp_384_mont_dbl_12(t1, y, p384_mod); + sp_384_mont_sub_12(x, x, t1, p384_mod); + /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */ + sp_384_mont_sub_12(y, y, x, p384_mod); + sp_384_mont_mul_12(y, y, t4, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(t5, t5, t3, p384_mod, p384_mp_mod); + sp_384_mont_sub_12(y, y, t5, p384_mod); + } +} + +/* Multiply the point 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. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_ecc_mulmod_fast_12(sp_point_384* r, const sp_point_384* g, const sp_digit* k, + int map, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 td[16]; + sp_point_384 rtd; + sp_digit tmpd[2 * 12 * 6]; +#endif + sp_point_384* t; + sp_point_384* rt; + sp_digit* tmp; + sp_digit n; + int i; + int c, y; + int err; + + (void)heap; + + err = sp_384_point_new_12(heap, rtd, rt); +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + t = (sp_point_384*)XMALLOC(sizeof(sp_point_384) * 16, heap, DYNAMIC_TYPE_ECC); + if (t == NULL) + err = MEMORY_E; + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 12 * 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 */ + (void)sp_384_mod_mul_norm_12(t[1].x, g->x, p384_mod); + (void)sp_384_mod_mul_norm_12(t[1].y, g->y, p384_mod); + (void)sp_384_mod_mul_norm_12(t[1].z, g->z, p384_mod); + t[1].infinity = 0; + sp_384_proj_point_dbl_12(&t[ 2], &t[ 1], tmp); + t[ 2].infinity = 0; + sp_384_proj_point_add_12(&t[ 3], &t[ 2], &t[ 1], tmp); + t[ 3].infinity = 0; + sp_384_proj_point_dbl_12(&t[ 4], &t[ 2], tmp); + t[ 4].infinity = 0; + sp_384_proj_point_add_12(&t[ 5], &t[ 3], &t[ 2], tmp); + t[ 5].infinity = 0; + sp_384_proj_point_dbl_12(&t[ 6], &t[ 3], tmp); + t[ 6].infinity = 0; + sp_384_proj_point_add_12(&t[ 7], &t[ 4], &t[ 3], tmp); + t[ 7].infinity = 0; + sp_384_proj_point_dbl_12(&t[ 8], &t[ 4], tmp); + t[ 8].infinity = 0; + sp_384_proj_point_add_12(&t[ 9], &t[ 5], &t[ 4], tmp); + t[ 9].infinity = 0; + sp_384_proj_point_dbl_12(&t[10], &t[ 5], tmp); + t[10].infinity = 0; + sp_384_proj_point_add_12(&t[11], &t[ 6], &t[ 5], tmp); + t[11].infinity = 0; + sp_384_proj_point_dbl_12(&t[12], &t[ 6], tmp); + t[12].infinity = 0; + sp_384_proj_point_add_12(&t[13], &t[ 7], &t[ 6], tmp); + t[13].infinity = 0; + sp_384_proj_point_dbl_12(&t[14], &t[ 7], tmp); + t[14].infinity = 0; + sp_384_proj_point_add_12(&t[15], &t[ 8], &t[ 7], tmp); + t[15].infinity = 0; + + i = 10; + n = k[i+1] << 0; + c = 28; + y = n >> 28; + XMEMCPY(rt, &t[y], sizeof(sp_point_384)); + n <<= 4; + for (; i>=0 || c>=4; ) { + if (c < 4) { + n |= k[i--] << (0 - c); + c += 32; + } + y = (n >> 28) & 0xf; + n <<= 4; + c -= 4; + + sp_384_proj_point_dbl_12(rt, rt, tmp); + sp_384_proj_point_dbl_12(rt, rt, tmp); + sp_384_proj_point_dbl_12(rt, rt, tmp); + sp_384_proj_point_dbl_12(rt, rt, tmp); + + sp_384_proj_point_add_12(rt, rt, &t[y], tmp); + } + + if (map != 0) { + sp_384_map_12(r, rt, tmp); + } + else { + XMEMCPY(r, rt, sizeof(sp_point_384)); + } + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (tmp != NULL) { + XMEMSET(tmp, 0, sizeof(sp_digit) * 2 * 12 * 6); + XFREE(tmp, heap, DYNAMIC_TYPE_ECC); + } + if (t != NULL) { + XMEMSET(t, 0, sizeof(sp_point_384) * 16); + XFREE(t, heap, DYNAMIC_TYPE_ECC); + } +#else + ForceZero(tmpd, sizeof(tmpd)); + ForceZero(td, sizeof(td)); +#endif + sp_384_point_free_12(rt, 1, heap); + + 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. + * + * r Result of repeated doubling of point. + * p Point to double. + * n Number of times to double + * t Temporary ordinate data. + */ +static void sp_384_proj_point_dbl_n_12(sp_point_384* r, const sp_point_384* p, int n, + sp_digit* t) +{ + sp_point_384* rp[2]; + sp_digit* w = t; + sp_digit* a = t + 2*12; + sp_digit* b = t + 4*12; + sp_digit* t1 = t + 6*12; + sp_digit* t2 = t + 8*12; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_384*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_384)); + x = rp[p->infinity]->x; + y = rp[p->infinity]->y; + z = rp[p->infinity]->z; + if (r != p) { + for (i=0; i<12; i++) { + r->x[i] = p->x[i]; + } + for (i=0; i<12; i++) { + r->y[i] = p->y[i]; + } + for (i=0; i<12; i++) { + r->z[i] = p->z[i]; + } + r->infinity = p->infinity; + } + + /* Y = 2*Y */ + sp_384_mont_dbl_12(y, y, p384_mod); + /* W = Z^4 */ + sp_384_mont_sqr_12(w, z, p384_mod, p384_mp_mod); + sp_384_mont_sqr_12(w, w, p384_mod, p384_mp_mod); + while (n-- > 0) { + /* A = 3*(X^2 - W) */ + sp_384_mont_sqr_12(t1, x, p384_mod, p384_mp_mod); + sp_384_mont_sub_12(t1, t1, w, p384_mod); + sp_384_mont_tpl_12(a, t1, p384_mod); + /* B = X*Y^2 */ + sp_384_mont_sqr_12(t2, y, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(b, t2, x, p384_mod, p384_mp_mod); + /* X = A^2 - 2B */ + sp_384_mont_sqr_12(x, a, p384_mod, p384_mp_mod); + sp_384_mont_dbl_12(t1, b, p384_mod); + sp_384_mont_sub_12(x, x, t1, p384_mod); + /* Z = Z*Y */ + sp_384_mont_mul_12(z, z, y, p384_mod, p384_mp_mod); + /* t2 = Y^4 */ + sp_384_mont_sqr_12(t2, t2, p384_mod, p384_mp_mod); + if (n != 0) { + /* W = W*Y^4 */ + sp_384_mont_mul_12(w, w, t2, p384_mod, p384_mp_mod); + } + /* y = 2*A*(B - X) - Y^4 */ + sp_384_mont_sub_12(y, b, x, p384_mod); + sp_384_mont_mul_12(y, y, a, p384_mod, p384_mp_mod); + sp_384_mont_dbl_12(y, y, p384_mod); + sp_384_mont_sub_12(y, y, t2, p384_mod); + } + /* Y = Y/2 */ + sp_384_div2_12(y, y, p384_mod); +} + +#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_384_proj_point_add_qz1_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]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*12; + sp_digit* t3 = t + 4*12; + sp_digit* t4 = t + 6*12; + sp_digit* t5 = t + 8*12; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + /* Check double */ + (void)sp_384_sub_12(t1, p384_mod, q->y); + sp_384_norm_12(t1); + if ((sp_384_cmp_equal_12(p->x, q->x) & sp_384_cmp_equal_12(p->z, q->z) & + (sp_384_cmp_equal_12(p->y, q->y) | sp_384_cmp_equal_12(p->y, t1))) != 0) { + sp_384_proj_point_dbl_12(r, p, t); + } + else { + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_384*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_384)); + 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<12; i++) { + r->x[i] = ap[p->infinity]->x[i]; + } + for (i=0; i<12; i++) { + r->y[i] = ap[p->infinity]->y[i]; + } + for (i=0; i<12; i++) { + r->z[i] = ap[p->infinity]->z[i]; + } + r->infinity = ap[p->infinity]->infinity; + + /* U2 = X2*Z1^2 */ + sp_384_mont_sqr_12(t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(t4, t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(t2, t2, q->x, p384_mod, p384_mp_mod); + /* S2 = Y2*Z1^3 */ + sp_384_mont_mul_12(t4, t4, q->y, p384_mod, p384_mp_mod); + /* H = U2 - X1 */ + sp_384_mont_sub_12(t2, t2, x, p384_mod); + /* R = S2 - Y1 */ + sp_384_mont_sub_12(t4, t4, y, p384_mod); + /* Z3 = H*Z1 */ + sp_384_mont_mul_12(z, z, t2, p384_mod, p384_mp_mod); + /* X3 = R^2 - H^3 - 2*X1*H^2 */ + sp_384_mont_sqr_12(t1, t4, p384_mod, p384_mp_mod); + sp_384_mont_sqr_12(t5, t2, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(t3, x, t5, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(t5, t5, t2, p384_mod, p384_mp_mod); + sp_384_mont_sub_12(x, t1, t5, p384_mod); + sp_384_mont_dbl_12(t1, t3, p384_mod); + sp_384_mont_sub_12(x, x, t1, p384_mod); + /* Y3 = R*(X1*H^2 - X3) - Y1*H^3 */ + sp_384_mont_sub_12(t3, t3, x, p384_mod); + sp_384_mont_mul_12(t3, t3, t4, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(t5, t5, y, p384_mod, p384_mp_mod); + sp_384_mont_sub_12(y, t3, t5, p384_mod); + } +} + +#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. + * + * 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_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) + sp_point_384 td, s1d, s2d; +#endif + sp_point_384* t; + sp_point_384* s1 = NULL; + sp_point_384* s2 = NULL; + int i, j; + int err; + + (void)heap; + + err = sp_384_point_new_12(heap, td, t); + if (err == MP_OKAY) { + err = sp_384_point_new_12(heap, s1d, s1); + } + if (err == MP_OKAY) { + err = sp_384_point_new_12(heap, s2d, s2); + } + + if (err == MP_OKAY) { + err = sp_384_mod_mul_norm_12(t->x, a->x, p384_mod); + } + if (err == MP_OKAY) { + err = sp_384_mod_mul_norm_12(t->y, a->y, p384_mod); + } + if (err == MP_OKAY) { + err = sp_384_mod_mul_norm_12(t->z, a->z, p384_mod); + } + if (err == MP_OKAY) { + t->infinity = 0; + sp_384_proj_to_affine_12(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<4; i++) { + sp_384_proj_point_dbl_n_12(t, t, 96, tmp); + sp_384_proj_to_affine_12(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_384_proj_point_add_qz1_12(t, s1, s2, tmp); + sp_384_proj_to_affine_12(t, tmp); + XMEMCPY(table[j].x, t->x, sizeof(table->x)); + XMEMCPY(table[j].y, t->y, sizeof(table->y)); + } + } + } + + sp_384_point_free_12(s2, 0, heap); + sp_384_point_free_12(s1, 0, heap); + sp_384_point_free_12( t, 0, heap); + + return err; +} + +#endif /* FP_ECC */ +/* Multiply the point 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_384_ecc_mulmod_stripe_12(sp_point_384* r, const sp_point_384* g, + const sp_table_entry_384* table, const sp_digit* k, int map, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 rtd; + sp_point_384 pd; + sp_digit td[2 * 12 * 6]; +#endif + sp_point_384* rt; + sp_point_384* p = NULL; + sp_digit* t; + int i, j; + int y, x; + int err; + + (void)g; + (void)heap; + + + err = sp_384_point_new_12(heap, rtd, rt); + if (err == MP_OKAY) { + err = sp_384_point_new_12(heap, pd, p); + } +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 12 * 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; + for (j=0,x=95; j<4; j++,x+=96) { + y |= ((k[x / 32] >> (x % 32)) & 1) << j; + } + 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=94; i>=0; i--) { + y = 0; + for (j=0,x=i; j<4; j++,x+=96) { + y |= ((k[x / 32] >> (x % 32)) & 1) << j; + } + + sp_384_proj_point_dbl_12(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_384_proj_point_add_qz1_12(rt, rt, p, t); + } + + if (map != 0) { + sp_384_map_12(r, rt, t); + } + else { + XMEMCPY(r, rt, sizeof(sp_point_384)); + } + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (t != NULL) { + XFREE(t, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_12(p, 0, heap); + sp_384_point_free_12(rt, 0, heap); + + return err; +} + +#ifdef FP_ECC +#ifndef FP_ENTRIES + #define FP_ENTRIES 16 +#endif + +typedef struct sp_cache_384_t { + sp_digit x[12]; + sp_digit y[12]; + sp_table_entry_384 table[16]; + uint32_t cnt; + int set; +} sp_cache_384_t; + +static THREAD_LS_T sp_cache_384_t sp_cache_384[FP_ENTRIES]; +static THREAD_LS_T int sp_cache_384_last = -1; +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 + +static void sp_ecc_get_cache_384(const sp_point_384* g, sp_cache_384_t** cache) +{ + int i, j; + uint32_t least; + + if (sp_cache_384_inited == 0) { + for (i=0; ix, sp_cache_384[i].x) & + sp_384_cmp_equal_12(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. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_ecc_mulmod_12(sp_point_384* r, const sp_point_384* g, const sp_digit* k, + int map, void* heap) +{ +#ifndef FP_ECC + return sp_384_ecc_mulmod_fast_12(r, g, k, map, heap); +#else + sp_digit tmp[2 * 12 * 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_12(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_fast_12(r, g, k, map, heap); + } + else { + err = sp_384_ecc_mulmod_stripe_12(r, g, cache->table, k, + map, heap); + } + } + + return err; +#endif +} + +#else +#ifdef FP_ECC +/* Generate the pre-computed table of points for the base point. + * + * 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_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) + sp_point_384 td, s1d, s2d; +#endif + sp_point_384* t; + sp_point_384* s1 = NULL; + sp_point_384* s2 = NULL; + int i, j; + int err; + + (void)heap; + + err = sp_384_point_new_12(heap, td, t); + if (err == MP_OKAY) { + err = sp_384_point_new_12(heap, s1d, s1); + } + if (err == MP_OKAY) { + err = sp_384_point_new_12(heap, s2d, s2); + } + + if (err == MP_OKAY) { + err = sp_384_mod_mul_norm_12(t->x, a->x, p384_mod); + } + if (err == MP_OKAY) { + err = sp_384_mod_mul_norm_12(t->y, a->y, p384_mod); + } + if (err == MP_OKAY) { + err = sp_384_mod_mul_norm_12(t->z, a->z, p384_mod); + } + if (err == MP_OKAY) { + t->infinity = 0; + sp_384_proj_to_affine_12(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_12(t, t, 48, tmp); + sp_384_proj_to_affine_12(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_12(t, s1, s2, tmp); + sp_384_proj_to_affine_12(t, tmp); + XMEMCPY(table[j].x, t->x, sizeof(table->x)); + XMEMCPY(table[j].y, t->y, sizeof(table->y)); + } + } + } + + sp_384_point_free_12(s2, 0, heap); + sp_384_point_free_12(s1, 0, heap); + sp_384_point_free_12( t, 0, heap); + + return err; +} + +#endif /* FP_ECC */ +/* Multiply the point 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_384_ecc_mulmod_stripe_12(sp_point_384* r, const sp_point_384* g, + const sp_table_entry_384* table, const sp_digit* k, int map, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 rtd; + sp_point_384 pd; + sp_digit td[2 * 12 * 6]; +#endif + sp_point_384* rt; + sp_point_384* p = NULL; + sp_digit* t; + int i, j; + int y, x; + int err; + + (void)g; + (void)heap; + + + err = sp_384_point_new_12(heap, rtd, rt); + if (err == MP_OKAY) { + err = sp_384_point_new_12(heap, pd, p); + } +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 12 * 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; + for (j=0,x=47; j<8; j++,x+=48) { + y |= ((k[x / 32] >> (x % 32)) & 1) << j; + } + 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; + for (j=0,x=i; j<8; j++,x+=48) { + y |= ((k[x / 32] >> (x % 32)) & 1) << j; + } + + sp_384_proj_point_dbl_12(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_384_proj_point_add_qz1_12(rt, rt, p, t); + } + + if (map != 0) { + sp_384_map_12(r, rt, t); + } + else { + XMEMCPY(r, rt, sizeof(sp_point_384)); + } + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (t != NULL) { + XFREE(t, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_12(p, 0, heap); + sp_384_point_free_12(rt, 0, heap); + + return err; +} + +#ifdef FP_ECC +#ifndef FP_ENTRIES + #define FP_ENTRIES 16 +#endif + +typedef struct sp_cache_384_t { + sp_digit x[12]; + sp_digit y[12]; + sp_table_entry_384 table[256]; + uint32_t cnt; + int set; +} sp_cache_384_t; + +static THREAD_LS_T sp_cache_384_t sp_cache_384[FP_ENTRIES]; +static THREAD_LS_T int sp_cache_384_last = -1; +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 + +static void sp_ecc_get_cache_384(const sp_point_384* g, sp_cache_384_t** cache) +{ + int i, j; + uint32_t least; + + if (sp_cache_384_inited == 0) { + for (i=0; ix, sp_cache_384[i].x) & + sp_384_cmp_equal_12(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. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_ecc_mulmod_12(sp_point_384* r, const sp_point_384* g, const sp_digit* k, + int map, void* heap) +{ +#ifndef FP_ECC + return sp_384_ecc_mulmod_fast_12(r, g, k, map, heap); +#else + sp_digit tmp[2 * 12 * 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_12(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_fast_12(r, g, k, map, heap); + } + else { + err = sp_384_ecc_mulmod_stripe_12(r, g, cache->table, k, + map, 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_384(mp_int* km, ecc_point* gm, ecc_point* r, int map, + void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 p; + sp_digit kd[12]; +#endif + sp_point_384* point; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_384_point_new_12(heap, p, point); +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 12, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) + err = MEMORY_E; + } +#else + k = kd; +#endif + if (err == MP_OKAY) { + sp_384_from_mp(k, 12, km); + sp_384_point_from_ecc_point_12(point, gm); + + err = sp_384_ecc_mulmod_12(point, point, k, map, heap); + } + if (err == MP_OKAY) { + err = sp_384_point_to_ecc_point_12(point, r); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_12(point, 0, heap); + + return err; +} + +#ifdef WOLFSSL_SP_SMALL +static const sp_table_entry_384 p384_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 } }, + /* 1 */ + { { 0x49c0b528,0x3dd07566,0xa0d6ce38,0x20e378e2,0x541b4d6e,0x879c3afc, + 0x59a30eff,0x64548684,0x614ede2b,0x812ff723,0x299e1513,0x4d3aadc2 }, + { 0x4b03a4fe,0x23043dad,0x7bb4a9ac,0xa1bfa8bf,0x2e83b050,0x8bade756, + 0x68f4ffd9,0xc6c35219,0x3969a840,0xdd800226,0x5a15c5e9,0x2b78abc2 } }, + /* 2 */ + { { 0xf26feef9,0x24480c57,0x3a0e1240,0xc31a2694,0x273e2bc7,0x735002c3, + 0x3ef1ed4c,0x8c42e9c5,0x7f4948e8,0x028babf6,0x8a978632,0x6a502f43 }, + { 0xb74536fe,0xf5f13a46,0xd8a9f0eb,0x1d218bab,0x37232768,0x30f36bcc, + 0x576e8c18,0xc5317b31,0x9bbcb766,0xef1d57a6,0xb3e3d4dc,0x917c4930 } }, + /* 3 */ + { { 0xe349ddd0,0x11426e2e,0x9b2fc250,0x9f117ef9,0xec0174a6,0xff36b480, + 0x18458466,0x4f4bde76,0x05806049,0x2f2edb6d,0x19dfca92,0x8adc75d1 }, + { 0xb7d5a7ce,0xa619d097,0xa34411e9,0x874275e5,0x0da4b4ef,0x5403e047, + 0x77901d8f,0x2ebaafd9,0xa747170f,0x5e63ebce,0x7f9d8036,0x12a36944 } }, + /* 4 */ + { { 0x2f9fbe67,0x378205de,0x7f728e44,0xc4afcb83,0x682e00f1,0xdbcec06c, + 0x114d5423,0xf2a145c3,0x7a52463e,0xa01d9874,0x7d717b0a,0xfc0935b1 }, + { 0xd4d01f95,0x9653bc4f,0x9560ad34,0x9aa83ea8,0xaf8e3f3f,0xf77943dc, + 0xe86fe16e,0x70774a10,0xbf9ffdcf,0x6b62e6f1,0x588745c9,0x8a72f39e } }, + /* 5 */ + { { 0x2341c342,0x73ade4da,0xea704422,0xdd326e54,0x3741cef3,0x336c7d98, + 0x59e61549,0x1eafa00d,0xbd9a3efd,0xcd3ed892,0xc5c6c7e4,0x03faf26c }, + { 0x3045f8ac,0x087e2fcf,0x174f1e73,0x14a65532,0xfe0af9a7,0x2cf84f28, + 0x2cdc935b,0xddfd7a84,0x6929c895,0x4c0f117b,0x4c8bcfcc,0x356572d6 } }, + /* 6 */ + { { 0x3f3b236f,0xfab08607,0x81e221da,0x19e9d41d,0x3927b428,0xf3f6571e, + 0x7550f1f6,0x4348a933,0xa85e62f0,0x7167b996,0x7f5452bf,0x62d43759 }, + { 0xf2955926,0xd85feb9e,0x6df78353,0x440a561f,0x9ca36b59,0x389668ec, + 0xa22da016,0x052bf1a1,0xf6093254,0xbdfbff72,0xe22209f3,0x94e50f28 } }, + /* 7 */ + { { 0x3062e8af,0x90b2e5b3,0xe8a3d369,0xa8572375,0x201db7b1,0x3fe1b00b, + 0xee651aa2,0xe926def0,0xb9b10ad7,0x6542c9be,0xa2fcbe74,0x098e309b }, + { 0xfff1d63f,0x779deeb3,0x20bfd374,0x23d0e80a,0x8768f797,0x8452bb3b, + 0x1f952856,0xcf75bb4d,0x29ea3faa,0x8fe6b400,0x81373a53,0x12bd3e40 } }, + /* 8 */ + { { 0x16973cf4,0x070d34e1,0x7e4f34f7,0x20aee08b,0x5eb8ad29,0x269af9b9, + 0xa6a45dda,0xdde0a036,0x63df41e0,0xa18b528e,0xa260df2a,0x03cc71b2 }, + { 0xa06b1dd7,0x24a6770a,0x9d2675d3,0x5bfa9c11,0x96844432,0x73c1e2a1, + 0x131a6cf0,0x3660558d,0x2ee79454,0xb0289c83,0xc6d8ddcd,0xa6aefb01 } }, + /* 9 */ + { { 0x01ab5245,0xba1464b4,0xc48d93ff,0x9b8d0b6d,0x93ad272c,0x939867dc, + 0xae9fdc77,0xbebe085e,0x894ea8bd,0x73ae5103,0x39ac22e1,0x740fc89a }, + { 0x28e23b23,0x5e28b0a3,0xe13104d0,0x2352722e,0xb0a2640d,0xf4667a18, + 0x49bb37c3,0xac74a72e,0xe81e183a,0x79f734f0,0x3fd9c0eb,0xbffe5b6c } }, + /* 10 */ + { { 0x00623f3b,0x03cf2922,0x5f29ebff,0x095c7111,0x80aa6823,0x42d72247, + 0x7458c0b0,0x044c7ba1,0x0959ec20,0xca62f7ef,0xf8ca929f,0x40ae2ab7 }, + { 0xa927b102,0xb8c5377a,0xdc031771,0x398a86a0,0xc216a406,0x04908f9d, + 0x918d3300,0xb423a73a,0xe0b94739,0x634b0ff1,0x2d69f697,0xe29de725 } }, + /* 11 */ + { { 0x8435af04,0x744d1400,0xfec192da,0x5f255b1d,0x336dc542,0x1f17dc12, + 0x636a68a8,0x5c90c2a7,0x7704ca1e,0x960c9eb7,0x6fb3d65a,0x9de8cf1e }, + { 0x511d3d06,0xc60fee0d,0xf9eb52c7,0x466e2313,0x206b0914,0x743c0f5f, + 0x2191aa4d,0x42f55bac,0xffebdbc2,0xcefc7c8f,0xe6e8ed1c,0xd4fa6081 } }, + /* 12 */ + { { 0x98683186,0x867db639,0xddcc4ea9,0xfb5cf424,0xd4f0e7bd,0xcc9a7ffe, + 0x7a779f7e,0x7c57f71c,0xd6b25ef2,0x90774079,0xb4081680,0x90eae903 }, + { 0x0ee1fceb,0xdf2aae5e,0xe86c1a1f,0x3ff1da24,0xca193edf,0x80f587d6, + 0xdc9b9d6a,0xa5695523,0x85920303,0x7b840900,0xba6dbdef,0x1efa4dfc } }, + /* 13 */ + { { 0xe0540015,0xfbd838f9,0xc39077dc,0x2c323946,0xad619124,0x8b1fb9e6, + 0x0ca62ea8,0x9612440c,0x2dbe00ff,0x9ad9b52c,0xae197643,0xf52abaa1 }, + { 0x2cac32ad,0xd0e89894,0x62a98f91,0xdfb79e42,0x276f55cb,0x65452ecf, + 0x7ad23e12,0xdb1ac0d2,0xde4986f0,0xf68c5f6a,0x82ce327d,0x389ac37b } }, + /* 14 */ + { { 0xb8a9e8c9,0xcd96866d,0x5bb8091e,0xa11963b8,0x045b3cd2,0xc7f90d53, + 0x80f36504,0x755a72b5,0x21d3751c,0x46f8b399,0x53c193de,0x4bffdc91 }, + { 0xb89554e7,0xcd15c049,0xf7a26be6,0x353c6754,0xbd41d970,0x79602370, + 0x12b176c0,0xde16470b,0x40c8809d,0x56ba1175,0xe435fb1e,0xe2db35c3 } }, + /* 15 */ + { { 0x6328e33f,0xd71e4aab,0xaf8136d1,0x5486782b,0x86d57231,0x07a4995f, + 0x1651a968,0xf1f0a5bd,0x76803b6d,0xa5dc5b24,0x42dda935,0x5c587cbc }, + { 0xbae8b4c0,0x2b6cdb32,0xb1331138,0x66d1598b,0x5d7e9614,0x4a23b2d2, + 0x74a8c05d,0x93e402a6,0xda7ce82e,0x45ac94e6,0xe463d465,0xeb9f8281 } }, +}; + +/* 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. + * 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_12(sp_point_384* r, const sp_digit* k, + int map, void* heap) +{ + return sp_384_ecc_mulmod_stripe_12(r, &p384_base, p384_table, + k, map, heap); +} + +#else +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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 */ + { { 0x49c0b528,0x3dd07566,0xa0d6ce38,0x20e378e2,0x541b4d6e,0x879c3afc, + 0x59a30eff,0x64548684,0x614ede2b,0x812ff723,0x299e1513,0x4d3aadc2 }, + { 0x4b03a4fe,0x23043dad,0x7bb4a9ac,0xa1bfa8bf,0x2e83b050,0x8bade756, + 0x68f4ffd9,0xc6c35219,0x3969a840,0xdd800226,0x5a15c5e9,0x2b78abc2 } }, + /* 2 */ + { { 0x2b0c535b,0x29864753,0x70506296,0x90dd6953,0x216ab9ac,0x038cd6b4, + 0xbe12d76a,0x3df9b7b7,0x5f347bdb,0x13f4d978,0x13e94489,0x222c5c9c }, + { 0x2680dc64,0x5f8e796f,0x58352417,0x120e7cb7,0xd10740b8,0x254b5d8a, + 0x5337dee6,0xc38b8efb,0x94f02247,0xf688c2e1,0x6c25bc4c,0x7b5c75f3 } }, + /* 3 */ + { { 0x9edffea5,0xe26a3cc3,0x37d7e9fc,0x35bbfd1c,0x9bde3ef6,0xf0e7700d, + 0x1a538f5a,0x0380eb47,0x05bf9eb3,0x2e9da8bb,0x1a460c3e,0xdbb93c73 }, + { 0xf526b605,0x37dba260,0xfd785537,0x95d4978e,0xed72a04a,0x24ed793a, + 0x76005b1a,0x26948377,0x9e681f82,0x99f557b9,0xd64954ef,0xae5f9557 } }, + /* 4 */ + { { 0xf26feef9,0x24480c57,0x3a0e1240,0xc31a2694,0x273e2bc7,0x735002c3, + 0x3ef1ed4c,0x8c42e9c5,0x7f4948e8,0x028babf6,0x8a978632,0x6a502f43 }, + { 0xb74536fe,0xf5f13a46,0xd8a9f0eb,0x1d218bab,0x37232768,0x30f36bcc, + 0x576e8c18,0xc5317b31,0x9bbcb766,0xef1d57a6,0xb3e3d4dc,0x917c4930 } }, + /* 5 */ + { { 0xe349ddd0,0x11426e2e,0x9b2fc250,0x9f117ef9,0xec0174a6,0xff36b480, + 0x18458466,0x4f4bde76,0x05806049,0x2f2edb6d,0x19dfca92,0x8adc75d1 }, + { 0xb7d5a7ce,0xa619d097,0xa34411e9,0x874275e5,0x0da4b4ef,0x5403e047, + 0x77901d8f,0x2ebaafd9,0xa747170f,0x5e63ebce,0x7f9d8036,0x12a36944 } }, + /* 6 */ + { { 0x4fc52870,0x28f9c07a,0x1a53a961,0xce0b3748,0x0e1828d9,0xd550fa18, + 0x6adb225a,0xa24abaf7,0x6e58a348,0xd11ed0a5,0x948acb62,0xf3d811e6 }, + { 0x4c61ed22,0x8618dd77,0x80b47c9d,0x0bb747f9,0xde6b8559,0x22bf796f, + 0x680a21e9,0xfdfd1c6d,0x2af2c9dd,0xc0db1577,0xc1e90f3d,0xa09379e6 } }, + /* 7 */ + { { 0xe085c629,0x386c66ef,0x095bc89a,0x5fc2a461,0x203f4b41,0x1353d631, + 0x7e4bd8f5,0x7ca1972b,0xa7df8ce9,0xb077380a,0xee7e4ea3,0xd8a90389 }, + { 0xe7b14461,0x1bc74dc7,0x0c9c4f78,0xdc2cb014,0x84ef0a10,0x52b4b3a6, + 0x20327fe2,0xbde6ea5d,0x660f9615,0xb71ec435,0xb8ad8173,0xeede5a04 } }, + /* 8 */ + { { 0x893b9a2d,0x5584cbb3,0x00850c5d,0x820c660b,0x7df2d43d,0x4126d826, + 0x0109e801,0xdd5bbbf0,0x38172f1c,0x85b92ee3,0xf31430d9,0x609d4f93 }, + { 0xeadaf9d6,0x1e059a07,0x0f125fb0,0x70e6536c,0x560f20e7,0xd6220751, + 0x7aaf3a9a,0xa59489ae,0x64bae14e,0x7b70e2f6,0x76d08249,0x0dd03701 } }, + /* 9 */ + { { 0x8510521f,0x4cc13be8,0xf724cc17,0x87315ba9,0x353dc263,0xb49d83bb, + 0x0c279257,0x8b677efe,0xc93c9537,0x510a1c1c,0xa4702c99,0x33e30cd8 }, + { 0x2208353f,0xf0ffc89d,0xced42b2b,0x0170fa8d,0x26e2a5f5,0x090851ed, + 0xecb52c96,0x81276455,0x7fe1adf4,0x0646c4e1,0xb0868eab,0x513f047e } }, + /* 10 */ + { { 0xdf5bdf53,0xc07611f4,0x58b11a6d,0x45d331a7,0x1c4ee394,0x58965daf, + 0x5a5878d1,0xba8bebe7,0x82dd3025,0xaecc0a18,0xa923eb8b,0xcf2a3899 }, + { 0xd24fd048,0xf98c9281,0x8bbb025d,0x841bfb59,0xc9ab9d53,0xb8ddf8ce, + 0x7fef044e,0x538a4cb6,0x23236662,0x092ac21f,0x0b66f065,0xa919d385 } }, + /* 11 */ + { { 0x85d480d8,0x3db03b40,0x1b287a7d,0x8cd9f479,0x4a8f3bae,0x8f24dc75, + 0x3db41892,0x482eb800,0x9c56e0f5,0x38bf9eb3,0x9a91dc6f,0x8b977320 }, + { 0x7209cfc2,0xa31b05b2,0x05b2db70,0x4c49bf85,0xd619527b,0x56462498, + 0x1fac51ba,0x3fe51039,0xab4b8342,0xfb04f55e,0x04c6eabf,0xc07c10dc } }, + /* 12 */ + { { 0xdb32f048,0xad22fe4c,0x475ed6df,0x5f23bf91,0xaa66b6cb,0xa50ce0c0, + 0xf03405c0,0xdf627a89,0xf95e2d6a,0x3674837d,0xba42e64e,0x081c95b6 }, + { 0xe71d6ceb,0xeba3e036,0x6c6b0271,0xb45bcccf,0x0684701d,0x67b47e63, + 0xe712523f,0x60f8f942,0x5cd47adc,0x82423472,0x87649cbb,0x83027d79 } }, + /* 13 */ + { { 0x3615b0b8,0xb3929ea6,0xa54dac41,0xb41441fd,0xb5b6a368,0x8995d556, + 0x167ef05e,0xa80d4529,0x6d25a27f,0xf6bcb4a1,0x7bd55b68,0x210d6a4c }, + { 0x25351130,0xf3804abb,0x903e37eb,0x1d2df699,0x084c25c8,0x5f201efc, + 0xa1c68e91,0x31a28c87,0x563f62a5,0x81dad253,0xd6c415d4,0x5dd6de70 } }, + /* 14 */ + { { 0x846612ce,0x29f470fd,0xda18d997,0x986f3eec,0x2f34af86,0x6b84c161, + 0x46ddaf8b,0x5ef0a408,0xe49e795f,0x14405a00,0xaa2f7a37,0x5f491b16 }, + { 0xdb41b38d,0xc7f07ae4,0x18fbfcaa,0xef7d119e,0x14443b19,0x3a18e076, + 0x79a19926,0x4356841a,0xe2226fbe,0x91f4a91c,0x3cc88721,0xdc77248c } }, + /* 15 */ + { { 0xe4b1ec9d,0xd570ff1a,0xe7eef706,0x21d23e0e,0xca19e086,0x3cde40f4, + 0xcd4bb270,0x7d6523c4,0xbf13aa6c,0x16c1f06c,0xd14c4b60,0x5aa7245a }, + { 0x44b74de8,0x37f81467,0x620a934e,0x839e7a17,0xde8b1aa1,0xf74d14e8, + 0xf30d75e2,0x8789fa51,0xc81c261e,0x09b24052,0x33c565ee,0x654e2678 } }, + /* 16 */ + { { 0x2f9fbe67,0x378205de,0x7f728e44,0xc4afcb83,0x682e00f1,0xdbcec06c, + 0x114d5423,0xf2a145c3,0x7a52463e,0xa01d9874,0x7d717b0a,0xfc0935b1 }, + { 0xd4d01f95,0x9653bc4f,0x9560ad34,0x9aa83ea8,0xaf8e3f3f,0xf77943dc, + 0xe86fe16e,0x70774a10,0xbf9ffdcf,0x6b62e6f1,0x588745c9,0x8a72f39e } }, + /* 17 */ + { { 0x2341c342,0x73ade4da,0xea704422,0xdd326e54,0x3741cef3,0x336c7d98, + 0x59e61549,0x1eafa00d,0xbd9a3efd,0xcd3ed892,0xc5c6c7e4,0x03faf26c }, + { 0x3045f8ac,0x087e2fcf,0x174f1e73,0x14a65532,0xfe0af9a7,0x2cf84f28, + 0x2cdc935b,0xddfd7a84,0x6929c895,0x4c0f117b,0x4c8bcfcc,0x356572d6 } }, + /* 18 */ + { { 0x7d8c1bba,0x7ecbac01,0x90b0f3d5,0x6058f9c3,0xf6197d0f,0xaee116e3, + 0x4033b128,0xc4dd7068,0xc209b983,0xf084dba6,0x831dbc4a,0x97c7c2cf }, + { 0xf96010e8,0x2f4e61dd,0x529faa17,0xd97e4e20,0x69d37f20,0x4ee66660, + 0x3d366d72,0xccc139ed,0x13488e0f,0x690b6ee2,0xf3a6d533,0x7cad1dc5 } }, + /* 19 */ + { { 0xda57a41f,0x660a9a81,0xec0039b6,0xe74a0412,0x5e1dad15,0x42343c6b, + 0x46681d4c,0x284f3ff5,0x63749e89,0xb51087f1,0x6f9f2f13,0x070f23cc }, + { 0x5d186e14,0x542211da,0xfddb0dff,0x84748f37,0xdb1f4180,0x41a3aab4, + 0xa6402d0e,0x25ed667b,0x02f58355,0x2f2924a9,0xfa44a689,0x5844ee7c } }, + /* 20 */ + { { 0x3f3b236f,0xfab08607,0x81e221da,0x19e9d41d,0x3927b428,0xf3f6571e, + 0x7550f1f6,0x4348a933,0xa85e62f0,0x7167b996,0x7f5452bf,0x62d43759 }, + { 0xf2955926,0xd85feb9e,0x6df78353,0x440a561f,0x9ca36b59,0x389668ec, + 0xa22da016,0x052bf1a1,0xf6093254,0xbdfbff72,0xe22209f3,0x94e50f28 } }, + /* 21 */ + { { 0x3062e8af,0x90b2e5b3,0xe8a3d369,0xa8572375,0x201db7b1,0x3fe1b00b, + 0xee651aa2,0xe926def0,0xb9b10ad7,0x6542c9be,0xa2fcbe74,0x098e309b }, + { 0xfff1d63f,0x779deeb3,0x20bfd374,0x23d0e80a,0x8768f797,0x8452bb3b, + 0x1f952856,0xcf75bb4d,0x29ea3faa,0x8fe6b400,0x81373a53,0x12bd3e40 } }, + /* 22 */ + { { 0x104cbba5,0xc023780d,0xfa35dd4c,0x6207e747,0x1ca9b6a3,0x35c23928, + 0x97987b10,0x4ff19be8,0x8022eee8,0xb8476bbf,0xd3bbe74d,0xaa0a4a14 }, + { 0x187d4543,0x20f94331,0x79f6e066,0x32153870,0xac7e82e1,0x83b0f74e, + 0x828f06ab,0xa7748ba2,0xc26ef35f,0xc5f0298a,0x8e9a7dbd,0x0f0c5070 } }, + /* 23 */ + { { 0xdef029dd,0x0c5c244c,0x850661b8,0x3dabc687,0xfe11d981,0x9992b865, + 0x6274dbad,0xe9801b8f,0x098da242,0xe54e6319,0x91a53d08,0x9929a91a }, + { 0x35285887,0x37bffd72,0xf1418102,0xbc759425,0xfd2e6e20,0x9280cc35, + 0xfbc42ee5,0x735c600c,0x8837619a,0xb7ad2864,0xa778c57b,0xa3627231 } }, + /* 24 */ + { { 0x91361ed8,0xae799b5c,0x6c63366c,0x47d71b75,0x1b265a6a,0x54cdd521, + 0x98d77b74,0xe0215a59,0xbab29db0,0x4424d9b7,0x7fd9e536,0x8b0ffacc }, + { 0x37b5d9ef,0x46d85d12,0xbfa91747,0x5b106d62,0x5f99ba2d,0xed0479f8, + 0x1d104de4,0x0e6f3923,0x25e8983f,0x83a84c84,0xf8105a70,0xa9507e0a } }, + /* 25 */ + { { 0x14cf381c,0xf6c68a6e,0xc22e31cc,0xaf9d27bd,0xaa8a5ccb,0x23568d4d, + 0xe338e4d2,0xe431eec0,0x8f52ad1f,0xf1a828fe,0xe86acd80,0xdb6a0579 }, + { 0x4507832a,0x2885672e,0x887e5289,0x73fc275f,0x05610d08,0x65f80278, + 0x075ff5b0,0x8d9b4554,0x09f712b5,0x3a8e8fb1,0x2ebe9cf2,0x39f0ac86 } }, + /* 26 */ + { { 0x4c52edf5,0xd8fabf78,0xa589ae53,0xdcd737e5,0xd791ab17,0x94918bf0, + 0xbcff06c9,0xb5fbd956,0xdca46d45,0xf6d3032e,0x41a3e486,0x2cdff7e1 }, + { 0x61f47ec8,0x6674b3ba,0xeef84608,0x8a882163,0x4c687f90,0xa257c705, + 0xf6cdf227,0xe30cb2ed,0x7f6ea846,0x2c4c64ca,0xcc6bcd3c,0x186fa17c } }, + /* 27 */ + { { 0x1dfcb91e,0x48a3f536,0x646d358a,0x83595e13,0x91128798,0xbd15827b, + 0x2187757a,0x3ce612b8,0x61bd7372,0x873150a1,0xb662f568,0xf4684530 }, + { 0x401896f6,0x8833950b,0x77f3e090,0xe11cb89a,0x48e7f4a5,0xb2f12cac, + 0xf606677e,0x313dd769,0x16579f93,0xfdcf08b3,0x46b8f22b,0x6429cec9 } }, + /* 28 */ + { { 0xbb75f9a4,0x4984dd54,0x29d3b570,0x4aef06b9,0x3d6e4c1e,0xb5f84ca2, + 0xb083ef35,0x24c61c11,0x392ca9ff,0xce4a7392,0x6730a800,0x865d6517 }, + { 0x722b4a2b,0xca3dfe76,0x7b083e0e,0x12c04bf9,0x1b86b8a5,0x803ce5b5, + 0x6a7e3e0c,0x3fc7632d,0xc81adbe4,0xc89970c2,0x120e16b1,0x3cbcd3ad } }, + /* 29 */ + { { 0xec30ce93,0xfbfb4cc7,0xb72720a2,0x10ed6c7d,0x47b55500,0xec675bf7, + 0x333ff7c3,0x90725903,0x5075bfc0,0xc7c3973e,0x07acf31b,0xb049ecb0 }, + { 0x4f58839c,0xb4076eaf,0xa2b05e4f,0x101896da,0xab40c66e,0x3f6033b0, + 0xc8d864ba,0x19ee9eeb,0x47bf6d2a,0xeb6cf155,0xf826477d,0x8e5a9663 } }, + /* 30 */ + { { 0xf7fbd5e1,0x69e62fdd,0x76912b1d,0x38ecfe54,0xd1da3bfb,0x845a3d56, + 0x1c86f0d4,0x0494950e,0x3bc36ce8,0x83cadbf9,0x4fccc8d1,0x41fce572 }, + { 0x8332c144,0x05f939c2,0x0871e46e,0xb17f248b,0x66e8aff6,0x3d8534e2, + 0x3b85c629,0x1d06f1dc,0xa3131b73,0xdb06a32e,0x8b3f64e5,0xf295184d } }, + /* 31 */ + { { 0x36ddc103,0xd9653ff7,0x95ef606f,0x25f43e37,0xfe06dce8,0x09e301fc, + 0x30b6eebf,0x85af2341,0x0ff56b20,0x79b12b53,0xfe9a3c6b,0x9b4fb499 }, + { 0x51d27ac2,0x0154f892,0x56ca5389,0xd33167e3,0xafc065a6,0x7828ec1f, + 0x7f746c9b,0x0959a258,0x0c44f837,0xb18f1be3,0xc4132fdb,0xa7946117 } }, + /* 32 */ + { { 0x5e3c647b,0xc0426b77,0x8cf05348,0xbfcbd939,0x172c0d3d,0x31d312e3, + 0xee754737,0x5f49fde6,0x6da7ee61,0x895530f0,0xe8b3a5fb,0xcf281b0a }, + { 0x41b8a543,0xfd149735,0x3080dd30,0x41a625a7,0x653908cf,0xe2baae07, + 0xba02a278,0xc3d01436,0x7b21b8f8,0xa0d0222e,0xd7ec1297,0xfdc270e9 } }, + /* 33 */ + { { 0xbc7f41d6,0x00873c0c,0x1b7ad641,0xd976113e,0x238443fb,0x2a536ff4, + 0x41e62e45,0x030d00e2,0x5f545fc6,0x532e9867,0x8e91208c,0xcd033108 }, + { 0x9797612c,0xd1a04c99,0xeea674e2,0xd4393e02,0xe19742a1,0xd56fa69e, + 0x85f0590e,0xdd2ab480,0x48a2243d,0xa5cefc52,0x54383f41,0x48cc67b6 } }, + /* 34 */ + { { 0xfc14ab48,0x4e50430e,0x26706a74,0x195b7f4f,0xcc881ff6,0x2fe8a228, + 0xd945013d,0xb1b968e2,0x4b92162b,0x936aa579,0x364e754a,0x4fb766b7 }, + { 0x31e1ff7f,0x13f93bca,0xce4f2691,0x696eb5ca,0xa2b09e02,0xff754bf8, + 0xe58e3ff8,0x58f13c9c,0x1678c0b0,0xb757346f,0xa86692b3,0xd54200db } }, + /* 35 */ + { { 0x6dda1265,0x9a030bbd,0xe89718dd,0xf7b4f3fc,0x936065b8,0xa6a4931f, + 0x5f72241c,0xbce72d87,0x65775857,0x6cbb51cb,0x4e993675,0xc7161815 }, + { 0x2ee32189,0xe81a0f79,0x277dc0b2,0xef2fab26,0xb71f469f,0x9e64f6fe, + 0xdfdaf859,0xb448ce33,0xbe6b5df1,0x3f5c1c4c,0x1de45f7b,0xfb8dfb00 } }, + /* 36 */ + { { 0x4d5bb921,0xc7345fa7,0x4d2b667e,0x5c7e04be,0x282d7a3e,0x47ed3a80, + 0x7e47b2a4,0x5c2777f8,0x08488e2e,0x89b3b100,0xb2eb5b45,0x9aad77c2 }, + { 0xdaac34ae,0xd681bca7,0x26afb326,0x2452e4e5,0x41a1ee14,0x0c887924, + 0xc2407ade,0x743b04d4,0xfc17a2ac,0xcb5e999b,0x4a701a06,0x4dca2f82 } }, + /* 37 */ + { { 0x1127bc1a,0x68e31ca6,0x17ead3be,0xa3edd59b,0xe25f5a15,0x67b6b645, + 0xa420e15e,0x76221794,0x4b1e872e,0x794fd83b,0xb2dece1b,0x7cab3f03 }, + { 0xca9b3586,0x7119bf15,0x4d250bd7,0xa5545924,0xcc6bcf24,0x173633ea, + 0xb1b6f884,0x9bd308c2,0x447d38c3,0x3bae06f5,0xf341fe1c,0x54dcc135 } }, + /* 38 */ + { { 0x943caf0d,0x56d3598d,0x225ff133,0xce044ea9,0x563fadea,0x9edf6a7c, + 0x73e8dc27,0x632eb944,0x3190dcab,0x814b467e,0x6dbb1e31,0x2d4f4f31 }, + { 0xa143b7ca,0x8d69811c,0xde7cf950,0x4ec1ac32,0x37b5fe82,0x223ab5fd, + 0x9390f1d9,0xe82616e4,0x75804610,0xabff4b20,0x875b08f0,0x11b9be15 } }, + /* 39 */ + { { 0x3bbe682c,0x4ae31a3d,0x74eef2dd,0xbc7c5d26,0x3c47dd40,0x92afd10a, + 0xc14ab9e1,0xec7e0a3b,0xb2e495e4,0x6a6c3dd1,0x309bcd85,0x085ee5e9 }, + { 0x8c2e67fd,0xf381a908,0xe261eaf2,0x32083a80,0x96deee15,0x0fcd6a49, + 0x5e524c79,0xe3b8fb03,0x1d5b08b9,0x8dc360d9,0x7f26719f,0x3a06e2c8 } }, + /* 40 */ + { { 0x7237cac0,0x5cd9f5a8,0x43586794,0x93f0b59d,0xe94f6c4e,0x4384a764, + 0xb62782d3,0x8304ed2b,0xcde06015,0x0b8db8b3,0x5dbe190f,0x4336dd53 }, + { 0x92ab473a,0x57443553,0xbe5ed046,0x031c7275,0x21909aa4,0x3e78678c, + 0x99202ddb,0x4ab7e04f,0x6977e635,0x2648d206,0x093198be,0xd427d184 } }, + /* 41 */ + { { 0x0f9b5a31,0x822848f5,0xbaadb62a,0xbb003468,0x3357559c,0x233a0472, + 0x79aee843,0x49ef6880,0xaeb9e1e3,0xa89867a0,0x1f6f9a55,0xc151931b }, + { 0xad74251e,0xd264eb0b,0x4abf295e,0x37b9b263,0x04960d10,0xb600921b, + 0x4da77dc0,0x0de53dbc,0xd2b18697,0x01d9bab3,0xf7156ddf,0xad54ec7a } }, + /* 42 */ + { { 0x79efdc58,0x8e74dc35,0x4ff68ddb,0x456bd369,0xd32096a5,0x724e74cc, + 0x386783d0,0xe41cff42,0x7c70d8a4,0xa04c7f21,0xe61a19a2,0x41199d2f }, + { 0x29c05dd2,0xd389a3e0,0xe7e3fda9,0x535f2a6b,0x7c2b4df8,0x26ecf72d, + 0xfe745294,0x678275f4,0x9d23f519,0x6319c9cc,0x88048fc4,0x1e05a02d } }, + /* 43 */ + { { 0xd4d5ffe8,0x75cc8e2e,0xdbea17f2,0xf8bb4896,0xcee3cb4a,0x35059790, + 0xa47c6165,0x4c06ee85,0x92935d2f,0xf98fff25,0x32ffd7c7,0x34c4a572 }, + { 0xea0376a2,0xc4b14806,0x4f115e02,0x2ea5e750,0x1e55d7c0,0x532d76e2, + 0xf31044da,0x68dc9411,0x71b77993,0x9272e465,0x93a8cfd5,0xadaa38bb } }, + /* 44 */ + { { 0x7d4ed72a,0x4bf0c712,0xba1f79a3,0xda0e9264,0xf4c39ea4,0x48c0258b, + 0x2a715138,0xa5394ed8,0xbf06c660,0x4af511ce,0xec5c37cd,0xfcebceef }, + { 0x779ae8c1,0xf23b75aa,0xad1e606e,0xdeff59cc,0x22755c82,0xf3f526fd, + 0xbb32cefd,0x64c5ab44,0x915bdefd,0xa96e11a2,0x1143813e,0xab19746a } }, + /* 45 */ + { { 0xec837d7d,0x43c78585,0xb8ee0ba4,0xca5b6fbc,0xd5dbb5ee,0x34e924d9, + 0xbb4f1ca5,0x3f4fa104,0x398640f7,0x15458b72,0xd7f407ea,0x4231faa9 }, + { 0xf96e6896,0x53e0661e,0xd03b0f9d,0x554e4c69,0x9c7858d1,0xd4fcb07b, + 0x52cb04fa,0x7e952793,0x8974e7f7,0x5f5f1574,0x6b6d57c8,0x2e3fa558 } }, + /* 46 */ + { { 0x6a9951a8,0x42cd4803,0x42792ad0,0xa8b15b88,0xabb29a73,0x18e8bcf9, + 0x409933e8,0xbfd9a092,0xefb88dc4,0x760a3594,0x40724458,0x14418863 }, + { 0x99caedc7,0x162a56ee,0x91d101c9,0x8fb12ecd,0x393202da,0xea671967, + 0xa4ccd796,0x1aac8c4a,0x1cf185a8,0x7db05036,0x8cfd095a,0x0c9f86cd } }, + /* 47 */ + { { 0x10b2a556,0x9a728147,0x327b70b2,0x767ca964,0x5e3799b7,0x04ed9e12, + 0x22a3eb2a,0x6781d2dc,0x0d9450ac,0x5bd116eb,0xa7ebe08a,0xeccac1fc }, + { 0xdc2d6e94,0xde68444f,0x35ecf21b,0x3621f429,0x29e03a2c,0x14e2d543, + 0x7d3e7f0a,0x53e42cd5,0x73ed00b9,0xbba26c09,0xc57d2272,0x00297c39 } }, + /* 48 */ + { { 0xb8243a7d,0x3aaaab10,0x8fa58c5b,0x6eeef93e,0x9ae7f764,0xf866fca3, + 0x61ab04d3,0x64105a26,0x03945d66,0xa3578d8a,0x791b848c,0xb08cd3e4 }, + { 0x756d2411,0x45edc5f8,0xa755128c,0xd4a790d9,0x49e5f6a0,0xc2cf0963, + 0xf649beaa,0xc66d267d,0x8467039e,0x3ce6d968,0x42f7816f,0x50046c6b } }, + /* 49 */ + { { 0x66425043,0x92ae1602,0xf08db890,0x1ff66afd,0x8f162ce5,0x386f5a7f, + 0xfcf5598f,0x18d2dea0,0x1a8ca18e,0x78372b3a,0x8cd0e6f7,0xdf0d20eb }, + { 0x75bb4045,0x7edd5e1d,0xb96d94b7,0x252a47ce,0x2c626776,0xbdb29358, + 0x40dd1031,0x853c3943,0x7d5f47fd,0x9dc9becf,0xbae4044a,0x27c2302f } }, + /* 50 */ + { { 0x8f2d49ce,0x2d1d208a,0x162df0a2,0x0d91aa02,0x09a07f65,0x9c5cce87, + 0x84339012,0xdf07238b,0x419442cd,0x5028e2c8,0x72062aba,0x2dcbd358 }, + { 0xe4680967,0xb5fbc3cb,0x9f92d72c,0x2a7bc645,0x116c369d,0x806c76e1, + 0x3177e8d8,0x5c50677a,0x4569df57,0x753739eb,0x36c3f40b,0x2d481ef6 } }, + /* 51 */ + { { 0xfea1103e,0x1a2d39fd,0x95f81b17,0xeaae5592,0xf59b264a,0xdbd0aa18, + 0xcb592ee0,0x90c39c1a,0x9750cca3,0xdf62f80d,0xdf97cc6c,0xda4d8283 }, + { 0x1e201067,0x0a6dd346,0x69fb1f6b,0x1531f859,0x1d60121f,0x4895e552, + 0x4c041c91,0x0b21aab0,0xbcc1ccf8,0x9d896c46,0x3141bde7,0xd24da3b3 } }, + /* 52 */ + { { 0x53b0a354,0x575a0537,0x0c6ddcd8,0x392ff2f4,0x56157b94,0x0b8e8cff, + 0x3b1b80d1,0x073e57bd,0x3fedee15,0x2a75e0f0,0xaa8e6f19,0x752380e4 }, + { 0x6558ffe9,0x1f4e227c,0x19ec5415,0x3a348618,0xf7997085,0xab382d5e, + 0xddc46ac2,0x5e6deaff,0xfc8d094c,0xe5144078,0xf60e37c6,0xf674fe51 } }, + /* 53 */ + { { 0xaf63408f,0x6fb87ae5,0xcd75a737,0xa39c36a9,0xcf4c618d,0x7833313f, + 0xf034c88d,0xfbcd4482,0x39b35288,0x4469a761,0x66b5d9c9,0x77a711c5 }, + { 0x944f8d65,0x4a695dc7,0x161aaba8,0xe6da5f65,0x24601669,0x8654e9c3, + 0x28ae7491,0xbc8b93f5,0x8f5580d8,0x5f1d1e83,0xcea32cc8,0x8ccf9a1a } }, + /* 54 */ + { { 0x7196fee2,0x28ab110c,0x874c8945,0x75799d63,0x29aedadd,0xa2629348, + 0x2be88ff4,0x9714cc7b,0xd58d60d6,0xf71293cf,0x32a564e9,0xda6b6cb3 }, + { 0x3dd821c2,0xf43fddb1,0x90dd323d,0xf2f2785f,0x048489f8,0x91246419, + 0xd24c6749,0x61660f26,0xc803c15c,0x961d9e8c,0xfaadc4c9,0x631c6158 } }, + /* 55 */ + { { 0xfd752366,0xacf2ebe0,0x139be88b,0xb93c340e,0x0f20179e,0x98f66485, + 0xff1da785,0x14820254,0x4f85c16e,0x5278e276,0x7aab1913,0xa246ee45 }, + { 0x53763b33,0x43861eb4,0x45c0bc0d,0xc49f03fc,0xad6b1ea1,0xafff16bc, + 0x6fd49c99,0xce33908b,0xf7fde8c3,0x5c51e9bf,0xff142c5e,0x076a7a39 } }, + /* 56 */ + { { 0x9e338d10,0x04639dfe,0xf42b411b,0x8ee6996f,0xa875cef2,0x960461d1, + 0x95b4d0ba,0x1057b6d6,0xa906e0bc,0x27639252,0xe1c20f8a,0x2c19f09a }, + { 0xeef4c43d,0x5b8fc3f0,0x07a84aa9,0xe2e1b1a8,0x835d2bdb,0x5f455528, + 0x207132dd,0x0f4aee4d,0x3907f675,0xe9f8338c,0x0e0531f0,0x7a874dc9 } }, + /* 57 */ + { { 0x97c27050,0x84b22d45,0x59e70bf8,0xbd0b8df7,0x79738b9b,0xb4d67405, + 0xcd917c4f,0x47f4d5f5,0x13ce6e33,0x9099c4ce,0x521d0f8b,0x942bfd39 }, + { 0xa43b566d,0x5028f0f6,0x21bff7de,0xaf6e8669,0xc44232cd,0x83f6f856, + 0xf915069a,0x65680579,0xecfecb85,0xd12095a2,0xdb01ba16,0xcf7f06ae } }, + /* 58 */ + { { 0x8ef96c80,0x0f56e3c4,0x3ddb609c,0xd521f2b3,0x7dc1450d,0x2be94102, + 0x02a91fe2,0x2d21a071,0x1efa37de,0x2e6f74fa,0x156c28a1,0x9a9a90b8 }, + { 0x9dc7dfcb,0xc54ea9ea,0x2c2c1d62,0xc74e66fc,0x49d3e067,0x9f23f967, + 0x54dd38ad,0x1c7c3a46,0x5946cee3,0xc7005884,0x45cc045d,0x89856368 } }, + /* 59 */ + { { 0xfce73946,0x29da7cd4,0x23168563,0x8f697db5,0xcba92ec6,0x8e235e9c, + 0x9f91d3ea,0x55d4655f,0xaa50a6cd,0xf3689f23,0x21e6a1a0,0xdcf21c26 }, + { 0x61b818bf,0xcffbc82e,0xda47a243,0xc74a2f96,0x8bc1a0cf,0x234e980a, + 0x7929cb6d,0xf35fd6b5,0xefe17d6c,0x81468e12,0x58b2dafb,0xddea6ae5 } }, + /* 60 */ + { { 0x7e787b2e,0x294de887,0x39a9310d,0x258acc1f,0xac14265d,0x92d9714a, + 0x708b48a0,0x18b5591c,0xe1abbf71,0x27cc6bb0,0x568307b9,0xc0581fa3 }, + { 0xf24d4d58,0x9e0f58a3,0xe0ce2327,0xfebe9bb8,0x9d1be702,0x91fd6a41, + 0xfacac993,0x9a7d8a45,0x9e50d66d,0xabc0a08c,0x06498201,0x02c342f7 } }, + /* 61 */ + { { 0x157bdbc2,0xccd71407,0xad0e1605,0x72fa89c6,0xb92a015f,0xb1d3da2b, + 0xa0a3fe56,0x8ad9e7cd,0x24f06737,0x160edcbd,0x61275be6,0x79d4db33 }, + { 0x5f3497c4,0xd3d31fd9,0x04192fb0,0x8cafeaee,0x13a50af3,0xe13ca745, + 0x8c85aae5,0x18826167,0x9eb556ff,0xce06cea8,0xbdb549f3,0x2eef1995 } }, + /* 62 */ + { { 0x50596edc,0x8ed7d3eb,0x905243a2,0xaa359362,0xa4b6d02b,0xa212c2c2, + 0xc4fbec68,0x611fd727,0xb84f733d,0x8a0b8ff7,0x5f0daf0e,0xd85a6b90 }, + { 0xd4091cf7,0x60e899f5,0x2eff2768,0x4fef2b67,0x10c33964,0xc1f195cb, + 0x93626a8f,0x8275d369,0x0d6c840a,0xc77904f4,0x7a868acd,0x88d8b7fd } }, + /* 63 */ + { { 0x7bd98425,0x85f23723,0xc70b154e,0xd4463992,0x96687a2e,0xcbb00ee2, + 0xc83214fd,0x905fdbf7,0x13593684,0x2019d293,0xef51218e,0x0428c393 }, + { 0x981e909a,0x40c7623f,0x7be192da,0x92513385,0x4010907e,0x48fe480f, + 0x3120b459,0xdd7a187c,0xa1fd8f3c,0xc9d7702d,0xe358efc5,0x66e4753b } }, + /* 64 */ + { { 0x16973cf4,0x070d34e1,0x7e4f34f7,0x20aee08b,0x5eb8ad29,0x269af9b9, + 0xa6a45dda,0xdde0a036,0x63df41e0,0xa18b528e,0xa260df2a,0x03cc71b2 }, + { 0xa06b1dd7,0x24a6770a,0x9d2675d3,0x5bfa9c11,0x96844432,0x73c1e2a1, + 0x131a6cf0,0x3660558d,0x2ee79454,0xb0289c83,0xc6d8ddcd,0xa6aefb01 } }, + /* 65 */ + { { 0x01ab5245,0xba1464b4,0xc48d93ff,0x9b8d0b6d,0x93ad272c,0x939867dc, + 0xae9fdc77,0xbebe085e,0x894ea8bd,0x73ae5103,0x39ac22e1,0x740fc89a }, + { 0x28e23b23,0x5e28b0a3,0xe13104d0,0x2352722e,0xb0a2640d,0xf4667a18, + 0x49bb37c3,0xac74a72e,0xe81e183a,0x79f734f0,0x3fd9c0eb,0xbffe5b6c } }, + /* 66 */ + { { 0xc6a2123f,0xb1a358f5,0xfe28df6d,0x927b2d95,0xf199d2f9,0x89702753, + 0x1a3f82dc,0x0a73754c,0x777affe1,0x063d029d,0xdae6d34d,0x5439817e }, + { 0x6b8b83c4,0xf7979eef,0x9d945682,0x615cb214,0xc5e57eae,0x8f0e4fac, + 0x113047dd,0x042b89b8,0x93f36508,0x888356dc,0x5fd1f32f,0xbf008d18 } }, + /* 67 */ + { { 0x4e8068db,0x8012aa24,0xa5729a47,0xc72cc641,0x43f0691d,0x3c33df2c, + 0x1d92145f,0xfa057347,0xb97f7946,0xaefc0f2f,0x2f8121bf,0x813d75cb }, + { 0x4383bba6,0x05613c72,0xa4224b3f,0xa924ce70,0x5f2179a6,0xe59cecbe, + 0x79f62b61,0x78e2e8aa,0x53ad8079,0x3ac2cc3b,0xd8f4fa96,0x55518d71 } }, + /* 68 */ + { { 0x00623f3b,0x03cf2922,0x5f29ebff,0x095c7111,0x80aa6823,0x42d72247, + 0x7458c0b0,0x044c7ba1,0x0959ec20,0xca62f7ef,0xf8ca929f,0x40ae2ab7 }, + { 0xa927b102,0xb8c5377a,0xdc031771,0x398a86a0,0xc216a406,0x04908f9d, + 0x918d3300,0xb423a73a,0xe0b94739,0x634b0ff1,0x2d69f697,0xe29de725 } }, + /* 69 */ + { { 0x8435af04,0x744d1400,0xfec192da,0x5f255b1d,0x336dc542,0x1f17dc12, + 0x636a68a8,0x5c90c2a7,0x7704ca1e,0x960c9eb7,0x6fb3d65a,0x9de8cf1e }, + { 0x511d3d06,0xc60fee0d,0xf9eb52c7,0x466e2313,0x206b0914,0x743c0f5f, + 0x2191aa4d,0x42f55bac,0xffebdbc2,0xcefc7c8f,0xe6e8ed1c,0xd4fa6081 } }, + /* 70 */ + { { 0xb0ab9645,0xb5e405d3,0xd5f1f711,0xaeec7f98,0x585c2a6e,0x8ad42311, + 0x512c6944,0x045acb9e,0xa90db1c6,0xae106c4e,0x898e6563,0xb89f33d5 }, + { 0x7fed2ce4,0x43b07cd9,0xdd815b20,0xf9934e17,0x0a81a349,0x6778d4d5, + 0x52918061,0x9e616ade,0xd7e67112,0xfa06db06,0x88488091,0x1da23cf1 } }, + /* 71 */ + { { 0x42f2c4b5,0x821c46b3,0x66059e47,0x931513ef,0x66f50cd1,0x7030ae43, + 0x43e7b127,0x43b536c9,0x5fca5360,0x006258cf,0x6b557abf,0xe4e3ee79 }, + { 0x24c8b22f,0xbb6b3900,0xfcbf1054,0x2eb5e2c1,0x567492af,0x937b18c9, + 0xacf53957,0xf09432e4,0x1dbf3a56,0x585f5a9d,0xbe0887cf,0xf86751fd } }, + /* 72 */ + { { 0x9d10e0b2,0x157399cb,0x60dc51b7,0x1c0d5956,0x1f583090,0x1d496b8a, + 0x88590484,0x6658bc26,0x03213f28,0x88c08ab7,0x7ae58de4,0x8d2e0f73 }, + { 0x486cfee6,0x9b79bc95,0xe9e5bc57,0x036a26c7,0xcd8ae97a,0x1ad03601, + 0xff3a0494,0x06907f87,0x2c7eb584,0x078f4bbf,0x7e8d0a5a,0xe3731bf5 } }, + /* 73 */ + { { 0xe1cd0abe,0x72f2282b,0x87efefa2,0xd4f9015e,0x6c3834bd,0x9d189806, + 0xb8a29ced,0x9c8cdcc1,0xfee82ebc,0x0601b9f4,0x7206a756,0x371052bc }, + { 0x46f32562,0x76fa1092,0x17351bb4,0xdaad534c,0xb3636bb5,0xc3d64c37, + 0x45d54e00,0x038a8c51,0x32c09e7c,0x301e6180,0x95735151,0x9764eae7 } }, + /* 74 */ + { { 0xcbd5256a,0x8791b19f,0x6ca13a3b,0x4007e0f2,0x4cf06904,0x03b79460, + 0xb6c17589,0xb18a9c22,0x81d45908,0xa1cb7d7d,0x21bb68f1,0x6e13fa9d }, + { 0xa71e6e16,0x47183c62,0xe18749ed,0x5cf0ef8e,0x2e5ed409,0x2c9c7f9b, + 0xe6e117e1,0x042eeacc,0x13fb5a7f,0xb86d4816,0xc9e5feb1,0xea1cf0ed } }, + /* 75 */ + { { 0xcea4cc9b,0x6e6573c9,0xafcec8f3,0x5417961d,0xa438b6f6,0x804bf02a, + 0xdcd4ea88,0xb894b03c,0x3799571f,0xd0f807e9,0x862156e8,0x3466a7f5 }, + { 0x56515664,0x51e59acd,0xa3c5eb0b,0x55b0f93c,0x6a4279db,0x84a06b02, + 0xc5fae08e,0x5c850579,0xa663a1a2,0xcf07b8db,0xf46ffc8d,0x49a36bbc } }, + /* 76 */ + { { 0x46d93106,0xe47f5acc,0xaa897c9c,0x65b7ade0,0x12d7e4be,0x37cf4c94, + 0xd4b2caa9,0xa2ae9b80,0xe60357a3,0x5e7ce09c,0xc8ecd5f9,0x29f77667 }, + { 0xa8a0b1c5,0xdf6868f5,0x62978ad8,0x240858cf,0xdc0002a1,0x0f7ac101, + 0xffe9aa05,0x1d28a9d7,0x5b962c97,0x744984d6,0x3d28c8b2,0xa8a7c00b } }, + /* 77 */ + { { 0xae11a338,0x7c58a852,0xd1af96e7,0xa78613f1,0x5355cc73,0x7e9767d2, + 0x792a2de6,0x6ba37009,0x124386b2,0x7d60f618,0x11157674,0xab09b531 }, + { 0x98eb9dd0,0x95a04841,0x15070328,0xe6c17acc,0x489c6e49,0xafc6da45, + 0xbb211530,0xab45a60a,0x7d7ea933,0xc58d6592,0x095642c6,0xa3ef3c65 } }, + /* 78 */ + { { 0xdf010879,0x89d420e9,0x39576179,0x9d25255d,0xe39513b6,0x9cdefd50, + 0xd5d1c313,0xe4efe45b,0x3f7af771,0xc0149de7,0x340ab06b,0x55a6b4f4 }, + { 0xebeaf771,0xf1325251,0x878d4288,0x2ab44128,0x18e05afe,0xfcd5832e, + 0xcc1fb62b,0xef52a348,0xc1c4792a,0x2bd08274,0x877c6dc7,0x345c5846 } }, + /* 79 */ + { { 0xbea65e90,0xde15ceb0,0x2416d99c,0x0987f72b,0xfd863dec,0x44db578d, + 0xac6a3578,0xf617b74b,0xdb48e999,0x9e62bd7a,0xeab1a1be,0x877cae61 }, + { 0x3a358610,0x23adddaa,0x325e2b07,0x2fc4d6d1,0x1585754e,0x897198f5, + 0xb392b584,0xf741852c,0xb55f7de1,0x9927804c,0x1aa8efae,0xe9e6c4ed } }, + /* 80 */ + { { 0x98683186,0x867db639,0xddcc4ea9,0xfb5cf424,0xd4f0e7bd,0xcc9a7ffe, + 0x7a779f7e,0x7c57f71c,0xd6b25ef2,0x90774079,0xb4081680,0x90eae903 }, + { 0x0ee1fceb,0xdf2aae5e,0xe86c1a1f,0x3ff1da24,0xca193edf,0x80f587d6, + 0xdc9b9d6a,0xa5695523,0x85920303,0x7b840900,0xba6dbdef,0x1efa4dfc } }, + /* 81 */ + { { 0xe0540015,0xfbd838f9,0xc39077dc,0x2c323946,0xad619124,0x8b1fb9e6, + 0x0ca62ea8,0x9612440c,0x2dbe00ff,0x9ad9b52c,0xae197643,0xf52abaa1 }, + { 0x2cac32ad,0xd0e89894,0x62a98f91,0xdfb79e42,0x276f55cb,0x65452ecf, + 0x7ad23e12,0xdb1ac0d2,0xde4986f0,0xf68c5f6a,0x82ce327d,0x389ac37b } }, + /* 82 */ + { { 0xf8e60f5b,0x511188b4,0x48aa2ada,0x7fe67015,0x381abca2,0xdb333cb8, + 0xdaf3fc97,0xb15e6d9d,0x36aabc03,0x4b24f6eb,0x72a748b4,0xc59789df }, + { 0x29cf5279,0x26fcb8a5,0x01ad9a6c,0x7a3c6bfc,0x4b8bac9b,0x866cf88d, + 0x9c80d041,0xf4c89989,0x70add148,0xf0a04241,0x45d81a41,0x5a02f479 } }, + /* 83 */ + { { 0xc1c90202,0xfa5c877c,0xf8ac7570,0xd099d440,0xd17881f7,0x428a5b1b, + 0x5b2501d7,0x61e267db,0xf2e4465b,0xf889bf04,0x76aa4cb8,0x4da3ae08 }, + { 0xe3e66861,0x3ef0fe26,0x3318b86d,0x5e772953,0x747396df,0xc3c35fbc, + 0x439ffd37,0x5115a29c,0xb2d70374,0xbfc4bd97,0x56246b9d,0x088630ea } }, + /* 84 */ + { { 0xb8a9e8c9,0xcd96866d,0x5bb8091e,0xa11963b8,0x045b3cd2,0xc7f90d53, + 0x80f36504,0x755a72b5,0x21d3751c,0x46f8b399,0x53c193de,0x4bffdc91 }, + { 0xb89554e7,0xcd15c049,0xf7a26be6,0x353c6754,0xbd41d970,0x79602370, + 0x12b176c0,0xde16470b,0x40c8809d,0x56ba1175,0xe435fb1e,0xe2db35c3 } }, + /* 85 */ + { { 0x6328e33f,0xd71e4aab,0xaf8136d1,0x5486782b,0x86d57231,0x07a4995f, + 0x1651a968,0xf1f0a5bd,0x76803b6d,0xa5dc5b24,0x42dda935,0x5c587cbc }, + { 0xbae8b4c0,0x2b6cdb32,0xb1331138,0x66d1598b,0x5d7e9614,0x4a23b2d2, + 0x74a8c05d,0x93e402a6,0xda7ce82e,0x45ac94e6,0xe463d465,0xeb9f8281 } }, + /* 86 */ + { { 0xfecf5b9b,0x34e0f9d1,0xf206966a,0xa115b12b,0x1eaa0534,0x5591cf3b, + 0xfb1558f9,0x5f0293cb,0x1bc703a5,0x1c8507a4,0x862c1f81,0x92e6b81c }, + { 0xcdaf24e3,0xcc9ebc66,0x72fcfc70,0x68917ecd,0x8157ba48,0x6dc9a930, + 0xb06ab2b2,0x5d425c08,0x36e929c4,0x362f8ce7,0x62e89324,0x09f6f57c } }, + /* 87 */ + { { 0xd29375fb,0x1c7d6b78,0xe35d1157,0xfabd851e,0x4243ea47,0xf6f62dcd, + 0x8fe30b0f,0x1dd92460,0xffc6e709,0x08166dfa,0x0881e6a7,0xc6c4c693 }, + { 0xd6a53fb0,0x20368f87,0x9eb4d1f9,0x38718e9f,0xafd7e790,0x03f08acd, + 0x72fe2a1c,0x0835eb44,0x88076e5d,0x7e050903,0xa638e731,0x538f765e } }, + /* 88 */ + { { 0xc2663b4b,0x0e0249d9,0x47cd38dd,0xe700ab5b,0x2c46559f,0xb192559d, + 0x4bcde66d,0x8f9f74a8,0x3e2aced5,0xad161523,0x3dd03a5b,0xc155c047 }, + { 0x3be454eb,0x346a8799,0x83b7dccd,0x66ee94db,0xab9d2abe,0x1f6d8378, + 0x7733f355,0x4a396dd2,0xf53553c2,0x419bd40a,0x731dd943,0xd0ead98d } }, + /* 89 */ + { { 0xec142408,0x908e0b0e,0x4114b310,0x98943cb9,0x1742b1d7,0x03dbf7d8, + 0x693412f4,0xd270df6b,0x8f69e20c,0xc5065494,0x697e43a1,0xa76a90c3 }, + { 0x4624825a,0xe0fa3384,0x8acc34c2,0x82e48c0b,0xe9a14f2b,0x7b24bd14, + 0x4db30803,0x4f5dd5e2,0x932da0a3,0x0c77a9e7,0x74c653dc,0x20db90f2 } }, + /* 90 */ + { { 0x0e6c5fd9,0x261179b7,0x6c982eea,0xf8bec123,0xd4957b7e,0x47683338, + 0x0a72f66a,0xcc47e664,0x1bad9350,0xbd54bf6a,0xf454e95a,0xdfbf4c6a }, + { 0x6907f4fa,0x3f7a7afa,0x865ca735,0x7311fae0,0x2a496ada,0x24737ab8, + 0x15feb79b,0x13e425f1,0xa1b93c21,0xe9e97c50,0x4ddd3eb5,0xb26b6eac } }, + /* 91 */ + { { 0x2a2e5f2b,0x81cab9f5,0xbf385ac4,0xf93caf29,0xc909963a,0xf4bf35c3, + 0x74c9143c,0x081e7300,0xc281b4c5,0x3ea57fa8,0x9b340741,0xe497905c }, + { 0x55ab3cfb,0xf556dd8a,0x518db6ad,0xd444b96b,0x5ef4b955,0x34f5425a, + 0xecd26aa3,0xdda7a3ac,0xda655e97,0xb57da11b,0xc2024c70,0x02da3eff } }, + /* 92 */ + { { 0x6481d0d9,0xe24b0036,0x818fdfe2,0x3740dbe5,0x190fda00,0xc1fc1f45, + 0x3cf27fde,0x329c9280,0x6934f43e,0x7435cb53,0x7884e8fe,0x2b505a5d }, + { 0x711adcc9,0x6cfcc6a6,0x531e21e1,0xf034325c,0x9b2a8a99,0xa2f4a967, + 0x3c21bdff,0x9d5f3842,0x31b57d66,0xb25c7811,0x0b8093b9,0xdb5344d8 } }, + /* 93 */ + { { 0xae50a2f5,0x0d72e667,0xe4a861d1,0x9b7f8d8a,0x330df1cb,0xa129f70f, + 0xe04fefc3,0xe90aa5d7,0xe72c3ae1,0xff561ecb,0xcdb955fa,0x0d8fb428 }, + { 0xd7663784,0xd2235f73,0x7e2c456a,0xc05baec6,0x2adbfccc,0xe5c292e4, + 0xefb110d5,0x4fd17988,0xd19d49f3,0x27e57734,0x84f679fe,0x188ac4ce } }, + /* 94 */ + { { 0xa796c53e,0x7ee344cf,0x0868009b,0xbbf6074d,0x474a1295,0x1f1594f7, + 0xac11632d,0x66776edc,0x04e2fa5a,0x1862278b,0xc854a89a,0x52665cf2 }, + { 0x8104ab58,0x7e376464,0x7204fd6d,0x16775913,0x44ea1199,0x86ca06a5, + 0x1c9240dd,0xaa3f765b,0x24746149,0x5f8501a9,0xdcd251d7,0x7b982e30 } }, + /* 95 */ + { { 0xc15f3060,0xe44e9efc,0xa87ebbe6,0x5ad62f2e,0xc79500d4,0x36499d41, + 0x336fa9d1,0xa66d6dc0,0x5afd3b1f,0xf8afc495,0xe5c9822b,0x1d8ccb24 }, + { 0x79d7584b,0x4031422b,0xea3f20dd,0xc54a0580,0x958468c5,0x3f837c8f, + 0xfbea7735,0x3d82f110,0x7dffe2fc,0x679a8778,0x20704803,0x48eba63b } }, + /* 96 */ + { { 0xdf46e2f6,0x89b10d41,0x19514367,0x13ab57f8,0x1d469c87,0x067372b9, + 0x4f6c5798,0x0c195afa,0x272c9acf,0xea43a12a,0x678abdac,0x9dadd8cb }, + { 0xe182579a,0xcce56c6b,0x2d26c2d8,0x86febadb,0x2a44745c,0x1c668ee1, + 0x98dc047a,0x580acd86,0x51b9ec2d,0x5a2b79cc,0x4054f6a0,0x007da608 } }, + /* 97 */ + { { 0x17b00dd0,0x9e3ca352,0x0e81a7a6,0x046779cb,0xd482d871,0xb999fef3, + 0xd9233fbc,0xe6f38134,0xf48cd0e0,0x112c3001,0x3c6c66ae,0x934e7576 }, + { 0xd73234dc,0xb44d4fc3,0x864eafc1,0xfcae2062,0x26bef21a,0x843afe25, + 0xf3b75fdf,0x61355107,0x794c2e6b,0x8367a5aa,0x8548a372,0x3d2629b1 } }, + /* 98 */ + { { 0x437cfaf8,0x6230618f,0x2032c299,0x5b8742cb,0x2293643a,0x949f7247, + 0x09464f79,0xb8040f1a,0x4f254143,0x049462d2,0x366c7e76,0xabd6b522 }, + { 0xd5338f55,0x119b392b,0x01495a0c,0x1a80a9ce,0xf8d7537e,0xf3118ca7, + 0x6bf4b762,0xb715adc2,0xa8482b6c,0x24506165,0x96a7c84d,0xd958d7c6 } }, + /* 99 */ + { { 0xbdc21f31,0x9ad8aa87,0x8063e58c,0xadb3cab4,0xb07dd7b8,0xefd86283, + 0x1be7c6b4,0xc7b9b762,0x015582de,0x2ef58741,0x299addf3,0xc970c52e }, + { 0x22f24d66,0x78f02e2a,0x74cc100a,0xefec1d10,0x09316e1a,0xaf2a6a39, + 0x5849dd49,0xce7c2205,0x96bffc4c,0x9c1fe75c,0x7ba06ec0,0xcad98fd2 } }, + /* 100 */ + { { 0xb648b73e,0xed76e2d0,0x1cfd285e,0xa9f92ce5,0x2ed13de1,0xa8c86c06, + 0xa5191a93,0x1d3a574e,0x1ad1b8bf,0x385cdf8b,0x47d2cfe3,0xbbecc28a }, + { 0x69cec548,0x98d326c0,0xf240a0b2,0x4f5bc1dd,0x29057236,0x241a7062, + 0xc68294a4,0x0fc6e9c5,0xa319f17a,0x4d04838b,0x9ffc1c6f,0x8b612cf1 } }, + /* 101 */ + { { 0x4c3830eb,0x9bb0b501,0x8ee0d0c5,0x3d08f83c,0x79ba9389,0xa4a62642, + 0x9cbc2914,0x5d5d4044,0x074c46f0,0xae9eb83e,0x74ead7d6,0x63bb758f }, + { 0xc6bb29e0,0x1c40d2ea,0x4b02f41e,0x95aa2d87,0x53cb199a,0x92989175, + 0x51584f6d,0xdd91bafe,0x31a1aaec,0x3715efb9,0x46780f9e,0xc1b6ae5b } }, + /* 102 */ + { { 0x42772f41,0xcded3e4b,0x3bcb79d1,0x3a700d5d,0x80feee60,0x4430d50e, + 0xf5e5d4bb,0x444ef1fc,0xe6e358ff,0xc660194f,0x6a91b43c,0xe68a2f32 }, + { 0x977fe4d2,0x5842775c,0x7e2a41eb,0x78fdef5c,0xff8df00e,0x5f3bec02, + 0x5852525d,0xf4b840cd,0x4e6988bd,0x0870483a,0xcc64b837,0x39499e39 } }, + /* 103 */ + { { 0xb08df5fe,0xfc05de80,0x63ba0362,0x0c12957c,0xd5cf1428,0xea379414, + 0x54ef6216,0xc559132a,0xb9e65cf8,0x33d5f12f,0x1695d663,0x09c60278 }, + { 0x61f7a2fb,0x3ac1ced4,0xd4f5eeb8,0xdd838444,0x8318fcad,0x82a38c6c, + 0xe9f1a864,0x315be2e5,0x442daf47,0x317b5771,0x95aa5f9e,0x81b5904a } }, + /* 104 */ + { { 0x8b21d232,0x6b6b1c50,0x8c2cba75,0x87f3dbc0,0xae9f0faf,0xa7e74b46, + 0xbb7b8079,0x036a0985,0x8d974a25,0x4f185b90,0xd9af5ec9,0x5aa7cef0 }, + { 0x57dcfffc,0xe0566a70,0xb8453225,0x6ea311da,0x23368aa9,0x72ea1a8d, + 0x48cd552d,0xed9b2083,0xc80ea435,0xb987967c,0x6c104173,0xad735c75 } }, + /* 105 */ + { { 0xcee76ef4,0xaea85ab3,0xaf1d2b93,0x44997444,0xeacb923f,0x0851929b, + 0x51e3bc0c,0xb080b590,0x59be68a2,0xc4ee1d86,0x64b26cda,0xf00de219 }, + { 0xf2e90d4d,0x8d7fb5c0,0x77d9ec64,0x00e219a7,0x5d1c491c,0xc4e6febd, + 0x1a8f4585,0x080e3754,0x48d2af9c,0x4a9b86c8,0xb6679851,0x2ed70db6 } }, + /* 106 */ + { { 0x586f25cb,0xaee44116,0xa0fcf70f,0xf7b6861f,0x18a350e8,0x55d2cd20, + 0x92dc286f,0x861bf3e5,0x6226aba7,0x9ab18ffa,0xa9857b03,0xd15827be }, + { 0x92e6acef,0x26c1f547,0xac1fbac3,0x422c63c8,0xfcbfd71d,0xa2d8760d, + 0xb2511224,0x35f6a539,0x048d1a21,0xbaa88fa1,0xebf999db,0x49f1abe9 } }, + /* 107 */ + { { 0xf7492b73,0x16f9f4f4,0xcb392b1a,0xcf28ec1e,0x69ca6ffc,0x45b130d4, + 0xb72efa58,0x28ba8d40,0x5ca066f5,0xace987c7,0x4ad022eb,0x3e399246 }, + { 0x752555bb,0x63a2d84e,0x9c2ae394,0xaaa93b4a,0xc89539ca,0xcd80424e, + 0xaa119a99,0x6d6b5a6d,0x379f2629,0xbd50334c,0xef3cc7d3,0x899e925e } }, + /* 108 */ + { { 0xbf825dc4,0xb7ff3651,0x40b9c462,0x0f741cc4,0x5cc4fb5b,0x771ff5a9, + 0x47fd56fe,0xcb9e9c9b,0x5626c0d3,0xbdf053db,0xf7e14098,0xa97ce675 }, + { 0x6c934f5e,0x68afe5a3,0xccefc46f,0x6cd5e148,0xd7a88586,0xc7758570, + 0xdd558d40,0x49978f5e,0x64ae00c1,0xa1d5088a,0xf1d65bb2,0x58f2a720 } }, + /* 109 */ + { { 0x3e4daedb,0x66fdda4a,0x65d1b052,0x38318c12,0x4c4bbf5c,0x28d910a2, + 0x78a9cd14,0x762fe5c4,0xd2cc0aee,0x08e5ebaa,0xca0c654c,0xd2cdf257 }, + { 0x08b717d2,0x48f7c58b,0x386cd07a,0x3807184a,0xae7d0112,0x3240f626, + 0xc43917b0,0x03e9361b,0x20aea018,0xf261a876,0x7e1e6372,0x53f556a4 } }, + /* 110 */ + { { 0x2f512a90,0xc84cee56,0x1b0ea9f1,0x24b3c004,0xe26cc1ea,0x0ee15d2d, + 0xf0c9ef7d,0xd848762c,0xd5341435,0x1026e9c5,0xfdb16b31,0x8f5b73dc }, + { 0xd2c75d95,0x1f69bef2,0xbe064dda,0x8d33d581,0x57ed35e6,0x8c024c12, + 0xc309c281,0xf8d435f9,0xd6960193,0xfd295061,0xe9e49541,0x66618d78 } }, + /* 111 */ + { { 0x8ce382de,0x571cfd45,0xde900dde,0x175806ee,0x34aba3b5,0x61849965, + 0xde7aec95,0xe899778a,0xff4aa97f,0xe8f00f6e,0x010b0c6d,0xae971cb5 }, + { 0x3af788f1,0x1827eebc,0xe413fe2d,0xd46229ff,0x4741c9b4,0x8a15455b, + 0xf8e424eb,0x5f02e690,0xdae87712,0x40a1202e,0x64944f6d,0x49b3bda2 } }, + /* 112 */ + { { 0x035b2d69,0xd63c6067,0x6bed91b0,0xb507150d,0x7afb39b2,0x1f35f82f, + 0x16012b66,0xb9bd9c01,0xed0a5f50,0x00d97960,0x2716f7c9,0xed705451 }, + { 0x127abdb4,0x1576eff4,0xf01e701c,0x6850d698,0x3fc87e2f,0x9fa7d749, + 0xb0ce3e48,0x0b6bcc6f,0xf7d8c1c0,0xf4fbe1f5,0x02719cc6,0xcf75230e } }, + /* 113 */ + { { 0x722d94ed,0x6761d6c2,0x3718820e,0xd1ec3f21,0x25d0e7c6,0x65a40b70, + 0xbaf3cf31,0xd67f830e,0xb93ea430,0x633b3807,0x0bc96c69,0x17faa0ea }, + { 0xdf866b98,0xe6bf3482,0xa9db52d4,0x205c1ee9,0xff9ab869,0x51ef9bbd, + 0x75eeb985,0x3863dad1,0xd3cf442a,0xef216c3b,0xf9c8e321,0x3fb228e3 } }, + /* 114 */ + { { 0x0760ac07,0x94f9b70c,0x9d79bf4d,0xf3c9ccae,0xc5ffc83d,0x73cea084, + 0xdc49c38e,0xef50f943,0xbc9e7330,0xf467a2ae,0x44ea7fba,0x5ee534b6 }, + { 0x03609e7f,0x20cb6272,0x62fdc9f0,0x09844355,0x0f1457f7,0xaf5c8e58, + 0xb4b25941,0xd1f50a6c,0x2ec82395,0x77cb247c,0xda3dca33,0xa5f3e1e5 } }, + /* 115 */ + { { 0x7d85fa94,0x023489d6,0x2db9ce47,0x0ba40537,0xaed7aad1,0x0fdf7a1f, + 0x9a4ccb40,0xa57b0d73,0x5b18967c,0x48fcec99,0xb7274d24,0xf30b5b6e }, + { 0xc81c5338,0x7ccb4773,0xa3ed6bd0,0xb85639e6,0x1d56eada,0x7d9df95f, + 0x0a1607ad,0xe256d57f,0x957574d6,0x6da7ffdc,0x01c7a8c4,0x65f84046 } }, + /* 116 */ + { { 0xcba1e7f1,0x8d45d0cb,0x02b55f64,0xef0a08c0,0x17e19892,0x771ca31b, + 0x4885907e,0xe1843ecb,0x364ce16a,0x67797ebc,0x8df4b338,0x816d2b2d }, + { 0x39aa8671,0xe870b0e5,0xc102b5f5,0x9f0db3e4,0x1720c697,0x34296659, + 0x613c0d2a,0x0ad4c89e,0x418ddd61,0x1af900b2,0xd336e20e,0xe087ca72 } }, + /* 117 */ + { { 0xaba10079,0x222831ff,0x6d64fff2,0x0dc5f87b,0x3e8cb330,0x44547907, + 0x702a33fb,0xe815aaa2,0x5fba3215,0x338d6b2e,0x79f549c8,0x0f7535cb }, + { 0x2ee95923,0x471ecd97,0xc6d1c09f,0x1e868b37,0xc666ef4e,0x2bc7b8ec, + 0x808a4bfc,0xf5416589,0x3fbc4d2e,0xf23e9ee2,0x2d75125b,0x4357236c } }, + /* 118 */ + { { 0xba9cdb1b,0xfe176d95,0x2f82791e,0x45a1ca01,0x4de4cca2,0x97654af2, + 0x5cc4bcb9,0xbdbf9d0e,0xad97ac0a,0xf6a7df50,0x61359fd6,0xc52112b0 }, + { 0x4f05eae3,0x696d9ce3,0xe943ac2b,0x903adc02,0x0848be17,0xa9075347, + 0x2a3973e5,0x1e20f170,0x6feb67e9,0xe1aacc1c,0xe16bc6b9,0x2ca0ac32 } }, + /* 119 */ + { { 0xef871eb5,0xffea12e4,0xa8bf0a7a,0x94c2f25d,0x78134eaa,0x4d1e4c2a, + 0x0360fb10,0x11ed16fb,0x85fc11be,0x4029b6db,0xf4d390fa,0x5e9f7ab7 }, + { 0x30646612,0x5076d72f,0xdda1d0d8,0xa0afed1d,0x85a1d103,0x29022257, + 0x4e276bcd,0xcb499e17,0x51246c3d,0x16d1da71,0x589a0443,0xc72d56d3 } }, + /* 120 */ + { { 0xdae5bb45,0xdf5ffc74,0x261bd6dc,0x99068c4a,0xaa98ec7b,0xdc0afa7a, + 0xf121e96d,0xedd2ee00,0x1414045c,0x163cc7be,0x335af50e,0xb0b1bbce }, + { 0x01a06293,0xd440d785,0x6552e644,0xcdebab7c,0x8c757e46,0x48cb8dbc, + 0x3cabe3cb,0x81f9cf78,0xb123f59a,0xddd02611,0xeeb3784d,0x3dc7b88e } }, + /* 121 */ + { { 0xc4741456,0xe1b8d398,0x6032a121,0xa9dfa902,0x1263245b,0x1cbfc86d, + 0x5244718c,0xf411c762,0x05b0fc54,0x96521d54,0xdbaa4985,0x1afab46e }, + { 0x8674b4ad,0xa75902ba,0x5ad87d12,0x486b43ad,0x36e0d099,0x72b1c736, + 0xbb6cd6d6,0x39890e07,0x59bace4e,0x8128999c,0x7b535e33,0xd8da430b } }, + /* 122 */ + { { 0xc6b75791,0x39f65642,0x21806bfb,0x050947a6,0x1362ef84,0x0ca3e370, + 0x8c3d2391,0x9bc60aed,0x732e1ddc,0x9b488671,0xa98ee077,0x12d10d9e }, + { 0x3651b7dc,0xb6f2822d,0x80abd138,0x6345a5ba,0x472d3c84,0x62033262, + 0xacc57527,0xd54a1d40,0x424447cb,0x6ea46b3a,0x2fb1a496,0x5bc41057 } }, + /* 123 */ + { { 0xa751cd0e,0xe70c57a3,0xeba3c7d6,0x190d8419,0x9d47d55a,0xb1c3bee7, + 0xf912c6d8,0xda941266,0x407a6ad6,0x12e9aacc,0x6e838911,0xd6ce5f11 }, + { 0x70e1f2ce,0x063ca97b,0x8213d434,0xa3e47c72,0x84df810a,0xa016e241, + 0xdfd881a4,0x688ad7b0,0xa89bf0ad,0xa37d99fc,0xa23c2d23,0xd8e3f339 } }, + /* 124 */ + { { 0x750bed6f,0xbdf53163,0x83e68b0a,0x808abc32,0x5bb08a33,0x85a36627, + 0x6b0e4abe,0xf72a3a0f,0xfaf0c6ad,0xf7716d19,0x5379b25f,0x22dcc020 }, + { 0xf9a56e11,0x7400bf8d,0x56a47f21,0x6cb8bad7,0x7a6eb644,0x7c97176f, + 0xd1f5b646,0xe8fd84f7,0x44ddb054,0x98320a94,0x1dde86f5,0x07071ba3 } }, + /* 125 */ + { { 0x98f8fcb9,0x6fdfa0e5,0x94d0d70c,0x89cec8e0,0x106d20a8,0xa0899397, + 0xba8acc9c,0x915bfb9a,0x5507e01c,0x1370c94b,0x8a821ffb,0x83246a60 }, + { 0xbe3c378f,0xa8273a9f,0x35a25be9,0x7e544789,0x4dd929d7,0x6cfa4972, + 0x365bd878,0x987fed9d,0x5c29a7ae,0x4982ac94,0x5ddd7ec5,0x4589a5d7 } }, + /* 126 */ + { { 0xa95540a9,0x9fabb174,0x0162c5b0,0x7cfb886f,0xea3dee18,0x17be766b, + 0xe88e624c,0xff7da41f,0x8b919c38,0xad0b71eb,0xf31ff9a9,0x86a522e0 }, + { 0x868bc259,0xbc8e6f72,0x3ccef9e4,0x6130c638,0x9a466555,0x09f1f454, + 0x19b2bfb4,0x8e6c0f09,0x0ca7bb22,0x945c46c9,0x4dafb67b,0xacd87168 } }, + /* 127 */ + { { 0x10c53841,0x090c72ca,0x55a4fced,0xc20ae01b,0xe10234ad,0x03f7ebd5, + 0x85892064,0xb3f42a6a,0xb4a14722,0xbdbc30c0,0x8ca124cc,0x971bc437 }, + { 0x517ff2ff,0x6f79f46d,0xecba947b,0x6a9c96e2,0x62925122,0x5e79f2f4, + 0x6a4e91f1,0x30a96bb1,0x2d4c72da,0x1147c923,0x5811e4df,0x65bc311f } }, + /* 128 */ + { { 0x139b3239,0x87c7dd7d,0x4d833bae,0x8b57824e,0x9fff0015,0xbcbc4878, + 0x909eaf1a,0x8ffcef8b,0xf1443a78,0x9905f4ee,0xe15cbfed,0x020dd4a2 }, + { 0xa306d695,0xca2969ec,0xb93caf60,0xdf940cad,0x87ea6e39,0x67f7fab7, + 0xf98c4fe5,0x0d0ee10f,0xc19cb91e,0xc646879a,0x7d1d7ab4,0x4b4ea50c } }, + /* 129 */ + { { 0x7a0db57e,0x19e40945,0x9a8c9702,0xe6017cad,0x1be5cff9,0xdbf739e5, + 0xa7a938a2,0x3646b3cd,0x68350dfc,0x04511085,0x56e098b5,0xad3bd6f3 }, + { 0xee2e3e3e,0x935ebabf,0x473926cb,0xfbd01702,0x9e9fb5aa,0x7c735b02, + 0x2e3feff0,0xc52a1b85,0x046b405a,0x9199abd3,0x39039971,0xe306fcec } }, + /* 130 */ + { { 0x23e4712c,0xd6d9aec8,0xc3c198ee,0x7ca8376c,0x31bebd8a,0xe6d83187, + 0xd88bfef3,0xed57aff3,0xcf44edc7,0x72a645ee,0x5cbb1517,0xd4e63d0b }, + { 0xceee0ecf,0x98ce7a1c,0x5383ee8e,0x8f012633,0xa6b455e8,0x3b879078, + 0xc7658c06,0xcbcd3d96,0x0783336a,0x721d6fe7,0x5a677136,0xf21a7263 } }, + /* 131 */ + { { 0x9586ba11,0x19d8b3cd,0x8a5c0480,0xd9e0aeb2,0x2230ef5c,0xe4261dbf, + 0x02e6bf09,0x095a9dee,0x80dc7784,0x8963723c,0x145157b1,0x5c97dbaf }, + { 0x4bc4503e,0x97e74434,0x85a6b370,0x0fb1cb31,0xcd205d4b,0x3e8df2be, + 0xf8f765da,0x497dd1bc,0x6c988a1a,0x92ef95c7,0x64dc4cfa,0x3f924baa } }, + /* 132 */ + { { 0x7268b448,0x6bf1b8dd,0xefd79b94,0xd4c28ba1,0xe4e3551f,0x2fa1f8c8, + 0x5c9187a9,0x769e3ad4,0x40326c0d,0x28843b4d,0x50d5d669,0xfefc8094 }, + { 0x90339366,0x30c85bfd,0x5ccf6c3a,0x4eeb56f1,0x28ccd1dc,0x0e72b149, + 0xf2ce978e,0x73ee85b5,0x3165bb23,0xcdeb2bf3,0x4e410abf,0x8106c923 } }, + /* 133 */ + { { 0x7d02f4ee,0xc8df0161,0x18e21225,0x8a781547,0x6acf9e40,0x4ea895eb, + 0x6e5a633d,0x8b000cb5,0x7e981ffb,0xf31d86d5,0x4475bc32,0xf5c8029c }, + { 0x1b568973,0x764561ce,0xa62996ec,0x2f809b81,0xda085408,0x9e513d64, + 0xe61ce309,0xc27d815d,0x272999e0,0x0da6ff99,0xfead73f7,0xbd284779 } }, + /* 134 */ + { { 0x9b1cdf2b,0x6033c2f9,0xbc5fa151,0x2a99cf06,0x12177b3b,0x7d27d259, + 0xc4485483,0xb1f15273,0x102e2297,0x5fd57d81,0xc7f6acb7,0x3d43e017 }, + { 0x3a70eb28,0x41a8bb0b,0x3e80b06b,0x67de2d8e,0x70c28de5,0x09245a41, + 0xa7b26023,0xad7dbcb1,0x2cbc6c1e,0x70b08a35,0x9b33041f,0xb504fb66 } }, + /* 135 */ + { { 0xf97a27c2,0xa8e85ab5,0xc10a011b,0x6ac5ec8b,0xffbcf161,0x55745533, + 0x65790a60,0x01780e85,0x99ee75b0,0xe451bf85,0x39c29881,0x8907a63b }, + { 0x260189ed,0x76d46738,0x47bd35cb,0x284a4436,0x20cab61e,0xd74e8c40, + 0x416cf20a,0x6264bf8c,0x5fd820ce,0xfa5a6c95,0xf24bb5fc,0xfa7154d0 } }, + /* 136 */ + { { 0x9b3f5034,0x18482cec,0xcd9e68fd,0x962d445a,0x95746f23,0x266fb1d6, + 0x58c94a4b,0xc66ade5a,0xed68a5b6,0xdbbda826,0x7ab0d6ae,0x05664a4d }, + { 0x025e32fc,0xbcd4fe51,0xa96df252,0x61a5aebf,0x31592a31,0xd88a07e2, + 0x98905517,0x5d9d94de,0x5fd440e7,0x96bb4010,0xe807db4c,0x1b0c47a2 } }, + /* 137 */ + { { 0x08223878,0x5c2a6ac8,0xe65a5558,0xba08c269,0x9bbc27fd,0xd22b1b9b, + 0x72b9607d,0x919171bf,0xe588dc58,0x9ab455f9,0x23662d93,0x6d54916e }, + { 0x3b1de0c1,0x8da8e938,0x804f278f,0xa84d186a,0xd3461695,0xbf4988cc, + 0xe10eb0cb,0xf5eae3be,0xbf2a66ed,0x1ff8b68f,0xc305b570,0xa68daf67 } }, + /* 138 */ + { { 0x44b2e045,0xc1004cff,0x4b1c05d4,0x91b5e136,0x88a48a07,0x53ae4090, + 0xea11bb1a,0x73fb2995,0x3d93a4ea,0x32048570,0x3bfc8a5f,0xcce45de8 }, + { 0xc2b3106e,0xaff4a97e,0xb6848b4f,0x9069c630,0xed76241c,0xeda837a6, + 0x6cc3f6cf,0x8a0daf13,0x3da018a8,0x199d049d,0xd9093ba3,0xf867c6b1 } }, + /* 139 */ + { { 0x56527296,0xe4d42a56,0xce71178d,0xae26c73d,0x6c251664,0x70a0adac, + 0x5dc0ae1d,0x813483ae,0xdaab2daf,0x7574eacd,0xc2d55f4f,0xc56b52dc }, + { 0x95f32923,0x872bc167,0x5bdd2a89,0x4be17581,0xa7699f00,0x9b57f1e7, + 0x3ac2de02,0x5fcd9c72,0x92377739,0x83af3ba1,0xfc50b97f,0xa64d4e2b } }, + /* 140 */ + { { 0x0e552b40,0x2172dae2,0xd34d52e8,0x62f49725,0x07958f98,0x7930ee40, + 0x751fdd74,0x56da2a90,0xf53e48c3,0xf1192834,0x8e53c343,0x34d2ac26 }, + { 0x13111286,0x1073c218,0xda9d9827,0x201dac14,0xee95d378,0xec2c29db, + 0x1f3ee0b1,0x9316f119,0x544ce71c,0x7890c9f0,0x27612127,0xd77138af } }, + /* 141 */ + { { 0x3b4ad1cd,0x78045e6d,0x4aa49bc1,0xcd86b94e,0xfd677a16,0x57e51f1d, + 0xfa613697,0xd9290935,0x34f4d893,0x7a3f9593,0x5d5fcf9b,0x8c9c248b }, + { 0x6f70d4e9,0x9f23a482,0x63190ae9,0x17273454,0x5b081a48,0x4bdd7c13, + 0x28d65271,0x1e2de389,0xe5841d1f,0x0bbaaa25,0x746772e5,0xc4c18a79 } }, + /* 142 */ + { { 0x593375ac,0x10ee2681,0x7dd5e113,0x4f3288be,0x240f3538,0x9a97b2fb, + 0x1de6b1e2,0xfa11089f,0x1351bc58,0x516da562,0x2dfa85b5,0x573b6119 }, + { 0x6cba7df5,0x89e96683,0x8c28ab40,0xf299be15,0xad43fcbf,0xe91c9348, + 0x9a1cefb3,0xe9bbc7cc,0x738b2775,0xc8add876,0x775eaa01,0x6e3b1f2e } }, + /* 143 */ + { { 0xb677788b,0x0365a888,0x3fd6173c,0x634ae8c4,0x9e498dbe,0x30498761, + 0xc8f779ab,0x08c43e6d,0x4c09aca9,0x068ae384,0x2018d170,0x2380c70b }, + { 0xa297c5ec,0xcf77fbc3,0xca457948,0xdacbc853,0x336bec7e,0x3690de04, + 0x14eec461,0x26bbac64,0x1f713abf,0xd1c23c7e,0xe6fd569e,0xf08bbfcd } }, + /* 144 */ + { { 0x84770ee3,0x5f8163f4,0x744a1706,0x0e0c7f94,0xe1b2d46d,0x9c8f05f7, + 0xd01fd99a,0x417eafe7,0x11440e5b,0x2ba15df5,0x91a6fbcf,0xdc5c552a }, + { 0xa270f721,0x86271d74,0xa004485b,0x32c0a075,0x8defa075,0x9d1a87e3, + 0xbf0d20fe,0xb590a7ac,0x8feda1f5,0x430c41c2,0x58f6ec24,0x454d2879 } }, + /* 145 */ + { { 0x7c525435,0x52b7a635,0x37c4bdbc,0x3d9ef57f,0xdffcc475,0x2bb93e9e, + 0x7710f3be,0xf7b8ba98,0x21b727de,0x42ee86da,0x2e490d01,0x55ac3f19 }, + { 0xc0c1c390,0x487e3a6e,0x446cde7b,0x036fb345,0x496ae951,0x089eb276, + 0x71ed1234,0xedfed4d9,0x900f0b46,0x661b0dd5,0x8582f0d3,0x11bd6f1b } }, + /* 146 */ + { { 0x076bc9d1,0x5cf9350f,0xcf3cd2c3,0x15d903be,0x25af031c,0x21cfc8c2, + 0x8b1cc657,0xe0ad3248,0x70014e87,0xdd9fb963,0x297f1658,0xf0f3a5a1 }, + { 0xf1f703aa,0xbb908fba,0x2f6760ba,0x2f9cc420,0x66a38b51,0x00ceec66, + 0x05d645da,0x4deda330,0xf7de3394,0xb9cf5c72,0x1ad4c906,0xaeef6502 } }, + /* 147 */ + { { 0x7a19045d,0x0583c8b1,0xd052824c,0xae7c3102,0xff6cfa58,0x2a234979, + 0x62c733c0,0xfe9dffc9,0x9c0c4b09,0x3a7fa250,0x4fe21805,0x516437bb }, + { 0xc2a23ddb,0x9454e3d5,0x289c104e,0x0726d887,0x4fd15243,0x8977d918, + 0x6d7790ba,0xc559e73f,0x465af85f,0x8fd3e87d,0x5feee46b,0xa2615c74 } }, + /* 148 */ + { { 0x4335167d,0xc8d607a8,0xe0f5c887,0x8b42d804,0x398d11f9,0x5f9f13df, + 0x20740c67,0x5aaa5087,0xa3d9234b,0x83da9a6a,0x2a54bad1,0xbd3a5c4e }, + { 0x2db0f658,0xdd13914c,0x5a3f373a,0x29dcb66e,0x5245a72b,0xbfd62df5, + 0x91e40847,0x19d18023,0xb136b1ae,0xd9df74db,0x3f93bc5b,0x72a06b6b } }, + /* 149 */ + { { 0xad19d96f,0x6da19ec3,0xfb2a4099,0xb342daa4,0x662271ea,0x0e61633a, + 0xce8c054b,0x3bcece81,0x8bd62dc6,0x7cc8e061,0xee578d8b,0xae189e19 }, + { 0xdced1eed,0x73e7a25d,0x7875d3ab,0xc1257f0a,0x1cfef026,0x2cb2d5a2, + 0xb1fdf61c,0xd98ef39b,0x24e83e6c,0xcd8e6f69,0xc7b7088b,0xd71e7076 } }, + /* 150 */ + { { 0x9d4245bf,0x33936830,0x2ac2953b,0x22d96217,0x56c3c3cd,0xb3bf5a82, + 0x0d0699e8,0x50c9be91,0x8f366459,0xec094463,0x513b7c35,0x6c056dba }, + { 0x045ab0e3,0x687a6a83,0x445c9295,0x8d40b57f,0xa16f5954,0x0f345048, + 0x3d8f0a87,0x64b5c639,0x9f71c5e2,0x106353a2,0x874f0dd4,0xdd58b475 } }, + /* 151 */ + { { 0x62230c72,0x67ec084f,0x481385e3,0xf14f6cca,0x4cda7774,0xf58bb407, + 0xaa2dbb6b,0xe15011b1,0x0c035ab1,0xd488369d,0x8245f2fd,0xef83c24a }, + { 0x9fdc2538,0xfb57328f,0x191fe46a,0x79808293,0x32ede548,0xe28f5c44, + 0xea1a022c,0x1b3cda99,0x3df2ec7f,0x39e639b7,0x760e9a18,0x77b6272b } }, + /* 152 */ + { { 0xa65d56d5,0x2b1d51bd,0x7ea696e0,0x3a9b71f9,0x9904f4c4,0x95250ecc, + 0xe75774b7,0x8bc4d6eb,0xeaeeb9aa,0x0e343f8a,0x930e04cb,0xc473c1d1 }, + { 0x064cd8ae,0x282321b1,0x5562221c,0xf4b4371e,0xd1bf1221,0xc1cc81ec, + 0xe2c8082f,0xa52a07a9,0xba64a958,0x350d8e59,0x6fb32c9a,0x29e4f3de } }, + /* 153 */ + { { 0xba89aaa5,0x0aa9d56c,0xc4c6059e,0xf0208ac0,0xbd6ddca4,0x7400d9c6, + 0xf2c2f74a,0xb384e475,0xb1562dd3,0x4c1061fc,0x2e153b8d,0x3924e248 }, + { 0x849808ab,0xf38b8d98,0xa491aa36,0x29bf3260,0x88220ede,0x85159ada, + 0xbe5bc422,0x8b47915b,0xd7300967,0xa934d72e,0x2e515d0d,0xc4f30398 } }, + /* 154 */ + { { 0x1b1de38b,0xe3e9ee42,0x42636760,0xa124e25a,0x90165b1a,0x90bf73c0, + 0x146434c5,0x21802a34,0x2e1fa109,0x54aa83f2,0xed9c51e9,0x1d4bd03c }, + { 0x798751e6,0xc2d96a38,0x8c3507f5,0xed27235f,0xc8c24f88,0xb5fb80e2, + 0xd37f4f78,0xf873eefa,0xf224ba96,0x7229fd74,0x9edd7149,0x9dcd9199 } }, + /* 155 */ + { { 0x4e94f22a,0xee9f81a6,0xf71ec341,0xe5609892,0xa998284e,0x6c818ddd, + 0x3b54b098,0x9fd47295,0x0e8a7cc9,0x47a6ac03,0xb207a382,0xde684e5e }, + { 0x2b6b956b,0x4bdd1ecd,0xf01b3583,0x09084414,0x55233b14,0xe2f80b32, + 0xef5ebc5e,0x5a0fec54,0xbf8b29a2,0x74cf25e6,0x7f29e014,0x1c757fa0 } }, + /* 156 */ + { { 0xeb0fdfe4,0x1bcb5c4a,0xf0899367,0xd7c649b3,0x05bc083b,0xaef68e3f, + 0xa78aa607,0x57a06e46,0x21223a44,0xa2136ecc,0x52f5a50b,0x89bd6484 }, + { 0x4455f15a,0x724411b9,0x08a9c0fd,0x23dfa970,0x6db63bef,0x7b0da4d1, + 0xfb162443,0x6f8a7ec1,0xe98284fb,0xc1ac9cee,0x33566022,0x085a582b } }, + /* 157 */ + { { 0xec1f138a,0x15cb61f9,0x668f0c28,0x11c9a230,0xdf93f38f,0xac829729, + 0x4048848d,0xcef25698,0x2bba8fbf,0x3f686da0,0x111c619a,0xed5fea78 }, + { 0xd6d1c833,0x9b4f73bc,0x86e7bf80,0x50951606,0x042b1d51,0xa2a73508, + 0x5fb89ec2,0x9ef6ea49,0x5ef8b892,0xf1008ce9,0x9ae8568b,0x78a7e684 } }, + /* 158 */ + { { 0x10470cd8,0x3fe83a7c,0xf86df000,0x92734682,0xda9409b5,0xb5dac06b, + 0x94939c5f,0x1e7a9660,0x5cc116dc,0xdec6c150,0x66bac8cc,0x1a52b408 }, + { 0x6e864045,0x5303a365,0x9139efc1,0x45eae72a,0x6f31d54f,0x83bec646, + 0x6e958a6d,0x2fb4a86f,0x4ff44030,0x6760718e,0xe91ae0df,0x008117e3 } }, + /* 159 */ + { { 0x384310a2,0x5d5833ba,0x1fd6c9fc,0xbdfb4edc,0x849c4fb8,0xb9a4f102, + 0x581c1e1f,0xe5fb239a,0xd0a9746d,0xba44b2e7,0x3bd942b9,0x78f7b768 }, + { 0xc87607ae,0x076c8ca1,0xd5caaa7e,0x82b23c2e,0x2763e461,0x6a581f39, + 0x3886df11,0xca8a5e4a,0x264e7f22,0xc87e90cf,0x215cfcfc,0x04f74870 } }, + /* 160 */ + { { 0x141d161c,0x5285d116,0x93c4ed17,0x67cd2e0e,0x7c36187e,0x12c62a64, + 0xed2584ca,0xf5329539,0x42fbbd69,0xc4c777c4,0x1bdfc50a,0x107de776 }, + { 0xe96beebd,0x9976dcc5,0xa865a151,0xbe2aff95,0x9d8872af,0x0e0a9da1, + 0xa63c17cc,0x5e357a3d,0xe15cc67c,0xd31fdfd8,0x7970c6d8,0xc44bbefd } }, + /* 161 */ + { { 0x4c0c62f1,0x703f83e2,0x4e195572,0x9b1e28ee,0xfe26cced,0x6a82858b, + 0xc43638fa,0xd381c84b,0xa5ba43d8,0x94f72867,0x10b82743,0x3b4a783d }, + { 0x7576451e,0xee1ad7b5,0x14b6b5c8,0xc3d0b597,0xfcacc1b8,0x3dc30954, + 0x472c9d7b,0x55df110e,0x02f8a328,0x97c86ed7,0x88dc098f,0xd0433413 } }, + /* 162 */ + { { 0x2ca8f2fe,0x1a60d152,0x491bd41f,0x61640948,0x58dfe035,0x6dae29a5, + 0x278e4863,0x9a615bea,0x9ad7c8e5,0xbbdb4477,0x2ceac2fc,0x1c706630 }, + { 0x99699b4b,0x5e2b54c6,0x239e17e8,0xb509ca6d,0xea063a82,0x728165fe, + 0xb6a22e02,0x6b5e609d,0xb26ee1df,0x12813905,0x439491fa,0x07b9f722 } }, + /* 163 */ + { { 0x48ff4e49,0x1592ec14,0x6d644129,0x3e4e9f17,0x1156acc0,0x7acf8288, + 0xbb092b0b,0x5aa34ba8,0x7d38393d,0xcd0f9022,0xea4f8187,0x416724dd }, + { 0xc0139e73,0x3c4e641c,0x91e4d87d,0xe0fe46cf,0xcab61f8a,0xedb3c792, + 0xd3868753,0x4cb46de4,0x20f1098a,0xe449c21d,0xf5b8ea6e,0x5e5fd059 } }, + /* 164 */ + { { 0x75856031,0x7fcadd46,0xeaf2fbd0,0x89c7a4cd,0x7a87c480,0x1af523ce, + 0x61d9ae90,0xe5fc1095,0xbcdb95f5,0x3fb5864f,0xbb5b2c7d,0xbeb5188e }, + { 0x3ae65825,0x3d1563c3,0x0e57d641,0x116854c4,0x1942ebd3,0x11f73d34, + 0xc06955b3,0x24dc5904,0x995a0a62,0x8a0d4c83,0x5d577b7d,0xfb26b86d } }, + /* 165 */ + { { 0xc686ae17,0xc53108e7,0xd1c1da56,0x9090d739,0x9aec50ae,0x4583b013, + 0xa49a6ab2,0xdd9a088b,0xf382f850,0x28192eea,0xf5fe910e,0xcc8df756 }, + { 0x9cab7630,0x877823a3,0xfb8e7fc1,0x64984a9a,0x364bfc16,0x5448ef9c, + 0xc44e2a9a,0xbbb4f871,0x435c95e9,0x901a41ab,0xaaa50a06,0xc6c23e5f } }, + /* 166 */ + { { 0x9034d8dd,0xb78016c1,0x0b13e79b,0x856bb44b,0xb3241a05,0x85c6409a, + 0x2d78ed21,0x8d2fe19a,0x726eddf2,0xdcc7c26d,0x25104f04,0x3ccaff5f }, + { 0x6b21f843,0x397d7edc,0xe975de4c,0xda88e4dd,0x4f5ab69e,0x5273d396, + 0x9aae6cc0,0x537680e3,0x3e6f9461,0xf749cce5,0x957bffd3,0x021ddbd9 } }, + /* 167 */ + { { 0x777233cf,0x7b64585f,0x0942a6f0,0xfe6771f6,0xdfe6eef0,0x636aba7a, + 0x86038029,0x63bbeb56,0xde8fcf36,0xacee5842,0xd4a20524,0x48d9aa99 }, + { 0x0da5e57a,0xcff7a74c,0xe549d6c9,0xc232593c,0xf0f2287b,0x68504bcc, + 0xbc8360b5,0x6d7d098d,0x5b402f41,0xeac5f149,0xb87d1bf1,0x61936f11 } }, + /* 168 */ + { { 0xb8153a9d,0xaa9da167,0x9e83ecf0,0xa49fe3ac,0x1b661384,0x14c18f8e, + 0x38434de1,0x61c24dab,0x283dae96,0x3d973c3a,0x82754fc9,0xc99baa01 }, + { 0x4c26b1e3,0x477d198f,0xa7516202,0x12e8e186,0x362addfa,0x386e52f6, + 0xc3962853,0x31e8f695,0x6aaedb60,0xdec2af13,0x29cf74ac,0xfcfdb4c6 } }, + /* 169 */ + { { 0xcca40298,0x6b3ee958,0xf2f5d195,0xc3878153,0xed2eae5b,0x0c565630, + 0x3a697cf2,0xd089b37e,0xad5029ea,0xc2ed2ac7,0x0f0dda6a,0x7e5cdfad }, + { 0xd9b86202,0xf98426df,0x4335e054,0xed1960b1,0x3f14639e,0x1fdb0246, + 0x0db6c670,0x17f709c3,0x773421e1,0xbfc687ae,0x26c1a8ac,0x13fefc4a } }, + /* 170 */ + { { 0x7ffa0a5f,0xe361a198,0xc63fe109,0xf4b26102,0x6c74e111,0x264acbc5, + 0x77abebaf,0x4af445fa,0x24cddb75,0x448c4fdd,0x44506eea,0x0b13157d }, + { 0x72e9993d,0x22a6b159,0x85e5ecbe,0x2c3c57e4,0xfd83e1a1,0xa673560b, + 0xc3b8c83b,0x6be23f82,0x40bbe38e,0x40b13a96,0xad17399b,0x66eea033 } }, + /* 171 */ + { { 0xb4c6c693,0x49fc6e95,0x36af7d38,0xefc735de,0x35fe42fc,0xe053343d, + 0x6a9ab7c3,0xf0aa427c,0x4a0fcb24,0xc79f0436,0x93ebbc50,0x16287243 }, + { 0x16927e1e,0x5c3d6bd0,0x673b984c,0x40158ed2,0x4cd48b9a,0xa7f86fc8, + 0x60ea282d,0x1643eda6,0xe2a1beed,0x45b393ea,0x19571a94,0x664c839e } }, + /* 172 */ + { { 0x27eeaf94,0x57745750,0xea99e1e7,0x2875c925,0x5086adea,0xc127e7ba, + 0x86fe424f,0x765252a0,0x2b6c0281,0x1143cc6c,0xd671312d,0xc9bb2989 }, + { 0x51acb0a5,0x880c337c,0xd3c60f78,0xa3710915,0x9262b6ed,0x496113c0, + 0x9ce48182,0x5d25d9f8,0xb3813586,0x53b6ad72,0x4c0e159c,0x0ea3bebc } }, + /* 173 */ + { { 0xc5e49bea,0xcaba450a,0x7c05da59,0x684e5415,0xde7ac36c,0xa2e9cab9, + 0x2e6f957b,0x4ca79b5f,0x09b817b1,0xef7b0247,0x7d89df0f,0xeb304990 }, + { 0x46fe5096,0x508f7307,0x2e04eaaf,0x695810e8,0x3512f76c,0x88ef1bd9, + 0x3ebca06b,0x77661351,0xccf158b7,0xf7d4863a,0x94ee57da,0xb2a81e44 } }, + /* 174 */ + { { 0x6d53e6ba,0xff288e5b,0x14484ea2,0xa90de1a9,0xed33c8ec,0x2fadb60c, + 0x28b66a40,0x579d6ef3,0xec24372d,0x4f2dd6dd,0x1d66ec7d,0xe9e33fc9 }, + { 0x039eab6e,0x110899d2,0x3e97bb5e,0xa31a667a,0xcfdce68e,0x6200166d, + 0x5137d54b,0xbe83ebae,0x4800acdf,0x085f7d87,0x0c6f8c86,0xcf4ab133 } }, + /* 175 */ + { { 0x931e08fb,0x03f65845,0x1506e2c0,0x6438551e,0x9c36961f,0x5791f0dc, + 0xe3dcc916,0x68107b29,0xf495d2ca,0x83242374,0x6ee5895b,0xd8cfb663 }, + { 0xa0349b1b,0x525e0f16,0x4a0fab86,0x33cd2c6c,0x2af8dda9,0x46c12ee8, + 0x71e97ad3,0x7cc424ba,0x37621eb0,0x69766ddf,0xa5f0d390,0x95565f56 } }, + /* 176 */ + { { 0x1a0f5e94,0xe0e7bbf2,0x1d82d327,0xf771e115,0xceb111fa,0x10033e3d, + 0xd3426638,0xd269744d,0x00d01ef6,0xbdf2d9da,0xa049ceaf,0x1cb80c71 }, + { 0x9e21c677,0x17f18328,0x19c8f98b,0x6452af05,0x80b67997,0x35b9c5f7, + 0x40f8f3d4,0x5c2e1cbe,0x66d667ca,0x43f91656,0xcf9d6e79,0x9faaa059 } }, + /* 177 */ + { { 0x0a078fe6,0x8ad24618,0x464fd1dd,0xf6cc73e6,0xc3e37448,0x4d2ce34d, + 0xe3271b5f,0x624950c5,0xefc5af72,0x62910f5e,0xaa132bc6,0x8b585bf8 }, + { 0xa839327f,0x11723985,0x4aac252f,0x34e2d27d,0x6296cc4e,0x402f59ef, + 0x47053de9,0x00ae055c,0x28b4f09b,0xfc22a972,0xfa0c180e,0xa9e86264 } }, + /* 178 */ + { { 0xbc310ecc,0x0b7b6224,0x67fa14ed,0x8a1a74f1,0x7214395c,0x87dd0960, + 0xf5c91128,0xdf1b3d09,0x86b264a8,0x39ff23c6,0x3e58d4c5,0xdc2d49d0 }, + { 0xa9d6f501,0x2152b7d3,0xc04094f7,0xf4c32e24,0xd938990f,0xc6366596, + 0x94fb207f,0x084d078f,0x328594cb,0xfd99f1d7,0xcb2d96b3,0x36defa64 } }, + /* 179 */ + { { 0x13ed7cbe,0x4619b781,0x9784bd0e,0x95e50015,0x2c7705fe,0x2a32251c, + 0x5f0dd083,0xa376af99,0x0361a45b,0x55425c6c,0x1f291e7b,0x812d2cef }, + { 0x5fd94972,0xccf581a0,0xe56dc383,0x26e20e39,0x63dbfbf0,0x0093685d, + 0x36b8c575,0x1fc164cc,0x390ef5e7,0xb9c5ab81,0x26908c66,0x40086beb } }, + /* 180 */ + { { 0x37e3c115,0xe5e54f79,0xc1445a8a,0x69b8ee8c,0xb7659709,0x79aedff2, + 0x1b46fbe6,0xe288e163,0xd18d7bb7,0xdb4844f0,0x48aa6424,0xe0ea23d0 }, + { 0xf3d80a73,0x714c0e4e,0x3bd64f98,0x87a0aa9e,0x2ec63080,0x8844b8a8, + 0x255d81a3,0xe0ac9c30,0x455397fc,0x86151237,0x2f820155,0x0b979464 } }, + /* 181 */ + { { 0x4ae03080,0x127a255a,0x580a89fb,0x232306b4,0x6416f539,0x04e8cd6a, + 0x13b02a0e,0xaeb70dee,0x4c09684a,0xa3038cf8,0x28e433ee,0xa710ec3c }, + { 0x681b1f7d,0x77a72567,0x2fc28170,0x86fbce95,0xf5735ac8,0xd3408683, + 0x6bd68e93,0x3a324e2a,0xc027d155,0x7ec74353,0xd4427177,0xab60354c } }, + /* 182 */ + { { 0xef4c209d,0x32a5342a,0x08d62704,0x2ba75274,0xc825d5fe,0x4bb4af6f, + 0xd28e7ff1,0x1c3919ce,0xde0340f6,0x1dfc2fdc,0x29f33ba9,0xc6580baf }, + { 0x41d442cb,0xae121e75,0x3a4724e4,0x4c7727fd,0x524f3474,0xe556d6a4, + 0x785642a2,0x87e13cc7,0xa17845fd,0x182efbb1,0x4e144857,0xdcec0cf1 } }, + /* 183 */ + { { 0xe9539819,0x1cb89541,0x9d94dbf1,0xc8cb3b4f,0x417da578,0x1d353f63, + 0x8053a09e,0xb7a697fb,0xc35d8b78,0x8d841731,0xb656a7a9,0x85748d6f }, + { 0xc1859c5d,0x1fd03947,0x535d22a2,0x6ce965c1,0x0ca3aadc,0x1966a13e, + 0x4fb14eff,0x9802e41d,0x76dd3fcd,0xa9048cbb,0xe9455bba,0x89b182b5 } }, + /* 184 */ + { { 0x43360710,0xd777ad6a,0x55e9936b,0x841287ef,0x04a21b24,0xbaf5c670, + 0x35ad86f1,0xf2c0725f,0xc707e72e,0x338fa650,0xd8883e52,0x2bf8ed2e }, + { 0xb56e0d6a,0xb0212cf4,0x6843290c,0x50537e12,0x98b3dc6f,0xd8b184a1, + 0x0210b722,0xd2be9a35,0x559781ee,0x407406db,0x0bc18534,0x5a78d591 } }, + /* 185 */ + { { 0xd748b02c,0x4d57aa2a,0xa12b3b95,0xbe5b3451,0x64711258,0xadca7a45, + 0x322153db,0x597e091a,0x32eb1eab,0xf3271006,0x2873f301,0xbd9adcba }, + { 0x38543f7f,0xd1dc79d1,0x921b1fef,0x00022092,0x1e5df8ed,0x86db3ef5, + 0x9e6b944a,0x888cae04,0x791a32b4,0x71bd29ec,0xa6d1c13e,0xd3516206 } }, + /* 186 */ + { { 0x55924f43,0x2ef6b952,0x4f9de8d5,0xd2f401ae,0xadc68042,0xfc73e8d7, + 0x0d9d1bb4,0x627ea70c,0xbbf35679,0xc3bb3e3e,0xd882dee4,0x7e8a254a }, + { 0xb5924407,0x08906f50,0xa1ad444a,0xf14a0e61,0x65f3738e,0xaa0efa21, + 0xae71f161,0xd60c7dd6,0xf175894d,0x9e8390fa,0x149f4c00,0xd115cd20 } }, + /* 187 */ + { { 0xa52abf77,0x2f2e2c1d,0x54232568,0xc2a0dca5,0x54966dcc,0xed423ea2, + 0xcd0dd039,0xe48c93c7,0x176405c7,0x1e54a225,0x70d58f2e,0x1efb5b16 }, + { 0x94fb1471,0xa751f9d9,0x67d2941d,0xfdb31e1f,0x53733698,0xa6c74eb2, + 0x89a0f64a,0xd3155d11,0xa4b8d2b6,0x4414cfe4,0xf7a8e9e3,0x8d5a4be8 } }, + /* 188 */ + { { 0x52669e98,0x5c96b4d4,0x8fd42a03,0x4547f922,0xd285174e,0xcf5c1319, + 0x064bffa0,0x805cd1ae,0x246d27e7,0x50e8bc4f,0xd5781e11,0xf89ef98f }, + { 0xdee0b63f,0xb4ff95f6,0x222663a4,0xad850047,0x4d23ce9c,0x02691860, + 0x50019f59,0x3e5309ce,0x69a508ae,0x27e6f722,0x267ba52c,0xe9376652 } }, + /* 189 */ + { { 0xc0368708,0xa04d289c,0x5e306e1d,0xc458872f,0x33112fea,0x76fa23de, + 0x6efde42e,0x718e3974,0x1d206091,0xf0c98cdc,0x14a71987,0x5fa3ca62 }, + { 0xdcaa9f2a,0xeee8188b,0x589a860d,0x312cc732,0xc63aeb1f,0xf9808dd6, + 0x4ea62b53,0x70fd43db,0x890b6e97,0x2c2bfe34,0xfa426aa6,0x105f863c } }, + /* 190 */ + { { 0xb38059ad,0x0b29795d,0x90647ea0,0x5686b77e,0xdb473a3e,0xeff0470e, + 0xf9b6d1e2,0x278d2340,0xbd594ec7,0xebbff95b,0xd3a7f23d,0xf4b72334 }, + { 0xa5a83f0b,0x2a285980,0x9716a8b3,0x0786c41a,0x22511812,0x138901bd, + 0xe2fede6e,0xd1b55221,0xdf4eb590,0x0806e264,0x762e462e,0x6c4c897e } }, + /* 191 */ + { { 0xb4b41d9d,0xd10b905f,0x4523a65b,0x826ca466,0xb699fa37,0x535bbd13, + 0x73bc8f90,0x5b9933d7,0xcd2118ad,0x9332d61f,0xd4a65fd0,0x158c693e }, + { 0xe6806e63,0x4ddfb2a8,0xb5de651b,0xe31ed3ec,0x819bc69a,0xf9460e51, + 0x2c76b1f8,0x6229c0d6,0x901970a3,0xbb78f231,0x9cee72b8,0x31f3820f } }, + /* 192 */ + { { 0xc09e1c72,0xe931caf2,0x12990cf4,0x0715f298,0x943262d8,0x33aad81d, + 0x73048d3f,0x5d292b7a,0xdc7415f6,0xb152aaa4,0x0fd19587,0xc3d10fd9 }, + { 0x75ddadd0,0xf76b35c5,0x1e7b694c,0x9f5f4a51,0xc0663025,0x2f1ab7eb, + 0x920260b0,0x01c9cc87,0x05d39da6,0xc4b1f61a,0xeb4a9c4e,0x6dcd76c4 } }, + /* 193 */ + { { 0xfdc83f01,0x0ba0916f,0x9553e4f9,0x354c8b44,0xffc5e622,0xa6cc511a, + 0xe95be787,0xb954726a,0x75b41a62,0xcb048115,0xebfde989,0xfa2ae6cd }, + { 0x0f24659a,0x6376bbc7,0x4c289c43,0x13a999fd,0xec9abd8b,0xc7134184, + 0xa789ab04,0x28c02bf6,0xd3e526ec,0xff841ebc,0x640893a8,0x442b191e } }, + /* 194 */ + { { 0xfa2b6e20,0x4cac6c62,0xf6d69861,0x97f29e9b,0xbc96d12d,0x228ab1db, + 0x5e8e108d,0x6eb91327,0x40771245,0xd4b3d4d1,0xca8a803a,0x61b20623 }, + { 0xa6a560b1,0x2c2f3b41,0x3859fcf4,0x879e1d40,0x024dbfc3,0x7cdb5145, + 0x3bfa5315,0x55d08f15,0xaa93823a,0x2f57d773,0xc6a2c9a2,0xa97f259c } }, + /* 195 */ + { { 0xe58edbbb,0xc306317b,0x79dfdf13,0x25ade51c,0x16d83dd6,0x6b5beaf1, + 0x1dd8f925,0xe8038a44,0xb2a87b6b,0x7f00143c,0xf5b438de,0xa885d00d }, + { 0xcf9e48bd,0xe9f76790,0xa5162768,0xf0bdf9f0,0xad7b57cb,0x0436709f, + 0xf7c15db7,0x7e151c12,0x5d90ee3b,0x3514f022,0x2c361a8d,0x2e84e803 } }, + /* 196 */ + { { 0x563ec8d8,0x2277607d,0xe3934cb7,0xa661811f,0xf58fd5de,0x3ca72e7a, + 0x62294c6a,0x7989da04,0xf6bbefe9,0x88b3708b,0x53ed7c82,0x0d524cf7 }, + { 0x2f30c073,0x69f699ca,0x9dc1dcf3,0xf0fa264b,0x05f0aaf6,0x44ca4568, + 0xd19b9baf,0x0f5b23c7,0xeabd1107,0x39193f41,0x2a7c9b83,0x9e3e10ad } }, + /* 197 */ + { { 0xd4ae972f,0xa90824f0,0xc6e846e7,0x43eef02b,0x29d2160a,0x7e460612, + 0xfe604e91,0x29a178ac,0x4eb184b2,0x23056f04,0xeb54cdf4,0x4fcad55f }, + { 0xae728d15,0xa0ff96f3,0xc6a00331,0x8a2680c6,0x7ee52556,0x5f84cae0, + 0xc5a65dad,0x5e462c3a,0xe2d23f4f,0x5d2b81df,0xc5b1eb07,0x6e47301b } }, + /* 198 */ + { { 0xaf8219b9,0x77411d68,0x51b1907a,0xcb883ce6,0x101383b5,0x25c87e57, + 0x982f970d,0x9c7d9859,0x118305d2,0xaa6abca5,0x9013a5db,0x725fed2f }, + { 0xababd109,0x487cdbaf,0x87586528,0xc0f8cf56,0x8ad58254,0xa02591e6, + 0xdebbd526,0xc071b1d1,0x961e7e31,0x927dfe8b,0x9263dfe1,0x55f895f9 } }, + /* 199 */ + { { 0xb175645b,0xf899b00d,0xb65b4b92,0x51f3a627,0xb67399ef,0xa2f3ac8d, + 0xe400bc20,0xe717867f,0x1967b952,0x42cc9020,0x3ecd1de1,0x3d596751 }, + { 0xdb979775,0xd41ebcde,0x6a2e7e88,0x99ba61bc,0x321504f2,0x039149a5, + 0x27ba2fad,0xe7dc2314,0xb57d8368,0x9f556308,0x57da80a7,0x2b6d16c9 } }, + /* 200 */ + { { 0x279ad982,0x84af5e76,0x9c8b81a6,0x9bb4c92d,0x0e698e67,0xd79ad44e, + 0x265fc167,0xe8be9048,0x0c3a4ccc,0xf135f7e6,0xb8863a33,0xa0a10d38 }, + { 0xd386efd9,0xe197247c,0xb52346c2,0x0eefd3f9,0x78607bc8,0xc22415f9, + 0x508674ce,0xa2a8f862,0xc8c9d607,0xa72ad09e,0x50fa764f,0xcd9f0ede } }, + /* 201 */ + { { 0xd1a46d4d,0x063391c7,0x9eb01693,0x2df51c11,0x849e83de,0xc5849800, + 0x8ad08382,0x48fd09aa,0xaa742736,0xa405d873,0xe1f9600c,0xee49e61e }, + { 0x48c76f73,0xd76676be,0x01274b2a,0xd9c100f6,0x83f8718d,0x110bb67c, + 0x02fc0d73,0xec85a420,0x744656ad,0xc0449e1e,0x37d9939b,0x28ce7376 } }, + /* 202 */ + { { 0x44544ac7,0x97e9af72,0xba010426,0xf2c658d5,0xfb3adfbd,0x732dec39, + 0xa2df0b07,0xd12faf91,0x2171e208,0x8ac26725,0x5b24fa54,0xf820cdc8 }, + { 0x94f4cf77,0x307a6eea,0x944a33c6,0x18c783d2,0x0b741ac5,0x4b939d4c, + 0x3ffbb6e4,0x1d7acd15,0x7a255e44,0x06a24858,0xce336d50,0x14fbc494 } }, + /* 203 */ + { { 0x51584e3c,0x9b920c0c,0xf7e54027,0xc7733c59,0x88422bbe,0xe24ce139, + 0x523bd6ab,0x11ada812,0xb88e6def,0xde068800,0xfe8c582d,0x7b872671 }, + { 0x7de53510,0x4e746f28,0xf7971968,0x492f8b99,0x7d928ac2,0x1ec80bc7, + 0x432eb1b5,0xb3913e48,0x32028f6e,0xad084866,0x8fc2f38b,0x122bb835 } }, + /* 204 */ + { { 0x3b0b29c3,0x0a9f3b1e,0x4fa44151,0x837b6432,0x17b28ea7,0xb9905c92, + 0x98451750,0xf39bc937,0xce8b6da1,0xcd383c24,0x010620b2,0x299f57db }, + { 0x58afdce3,0x7b6ac396,0x3d05ef47,0xa15206b3,0xb9bb02ff,0xa0ae37e2, + 0x9db3964c,0x107760ab,0x67954bea,0xe29de9a0,0x431c3f82,0x446a1ad8 } }, + /* 205 */ + { { 0x5c6b8195,0xc6fecea0,0xf49e71b9,0xd744a7c5,0x177a7ae7,0xa8e96acc, + 0x358773a7,0x1a05746c,0x37567369,0xa4162146,0x87d1c971,0xaa0217f7 }, + { 0x77fd3226,0x61e9d158,0xe4f600be,0x0f6f2304,0x7a6dff07,0xa9c4cebc, + 0x09f12a24,0xd15afa01,0x8c863ee9,0x2bbadb22,0xe5eb8c78,0xa28290e4 } }, + /* 206 */ + { { 0x3e9de330,0x55b87fa0,0x195c145b,0x12b26066,0xa920bef0,0xe08536e0, + 0x4d195adc,0x7bff6f2c,0x945f4187,0x7f319e9d,0xf892ce47,0xf9848863 }, + { 0x4fe37657,0xd0efc1d3,0x5cf0e45a,0x3c58de82,0x8b0ccbbe,0x626ad21a, + 0xaf952fc5,0xd2a31208,0xeb437357,0x81791995,0x98e95d4f,0x5f19d30f } }, + /* 207 */ + { { 0x0e6865bb,0x72e83d9a,0xf63456a6,0x22f5af3b,0x463c8d9e,0x409e9c73, + 0xdfe6970e,0x40e9e578,0x711b91ca,0x876b6efa,0x942625a3,0x895512cf }, + { 0xcb4e462b,0x84c8eda8,0x4412e7c8,0x84c0154a,0xceb7b71f,0x04325db1, + 0x66f70877,0x1537dde3,0x1992b9ac,0xf3a09399,0xd498ae77,0xa7316606 } }, + /* 208 */ + { { 0xcad260f5,0x13990d2f,0xeec0e8c0,0x76c3be29,0x0f7bd7d5,0x7dc5bee0, + 0xefebda4b,0x9be167d2,0x9122b87e,0xcce3dde6,0x82b5415c,0x75a28b09 }, + { 0xe84607a6,0xf6810bcd,0x6f4dbf0d,0xc6d58128,0x1b4dafeb,0xfead577d, + 0x066b28eb,0x9bc440b2,0x8b17e84b,0x53f1da97,0xcda9a575,0x0459504b } }, + /* 209 */ + { { 0x329e5836,0x13e39a02,0xf717269d,0x2c9e7d51,0xf26c963b,0xc5ac58d6, + 0x79967bf5,0x3b0c6c43,0x55908d9d,0x60bbea3f,0xf07c9ad1,0xd84811e7 }, + { 0x5bd20e4a,0xfe7609a7,0x0a70baa8,0xe4325dd2,0xb3600386,0x3711f370, + 0xd0924302,0x97f9562f,0x4acc4436,0x040dc0c3,0xde79cdd4,0xfd6d725c } }, + /* 210 */ + { { 0xcf13eafb,0xb3efd0e3,0x5aa0ae5f,0x21009cbb,0x79022279,0xe480c553, + 0xb2fc9a6d,0x755cf334,0x07096ae7,0x8564a5bf,0xbd238139,0xddd649d0 }, + { 0x8a045041,0xd0de10b1,0xc957d572,0x6e05b413,0x4e0fb25c,0x5c5ff806, + 0x641162fb,0xd933179b,0xe57439f9,0x42d48485,0x8a8d72aa,0x70c5bd0a } }, + /* 211 */ + { { 0x97bdf646,0xa7671738,0xab329f7c,0xaa1485b4,0xf8f25fdf,0xce3e11d6, + 0xc6221824,0x76a3fc7e,0xf3924740,0x045f281f,0x96d13a9a,0x24557d4e }, + { 0xdd4c27cd,0x875c804b,0x0f5c7fea,0x11c5f0f4,0xdc55ff7e,0xac8c880b, + 0x1103f101,0x2acddec5,0xf99faa89,0x38341a21,0xce9d6b57,0xc7b67a2c } }, + /* 212 */ + { { 0x8e357586,0x9a0d724f,0xdf648da0,0x1d7f4ff5,0xfdee62a5,0x9c3e6c9b, + 0x0389b372,0x0499cef0,0x98eab879,0xe904050d,0x6c051617,0xe8eef1b6 }, + { 0xc37e3ca9,0xebf5bfeb,0xa4e0b91d,0x7c5e946d,0x2c4bea28,0x79097314, + 0xee67b2b7,0x81f6c109,0xdafc5ede,0xaf237d9b,0x2abb04c7,0xd2e60201 } }, + /* 213 */ + { { 0x8a4f57bf,0x6156060c,0xff11182a,0xf9758696,0x6296ef00,0x8336773c, + 0xff666899,0x9c054bce,0x719cd11c,0xd6a11611,0xdbe1acfa,0x9824a641 }, + { 0xba89fd01,0x0b7b7a5f,0x889f79d8,0xf8d3b809,0xf578285c,0xc5e1ea08, + 0xae6d8288,0x7ac74536,0x7521ef5f,0x5d37a200,0xb260a25d,0x5ecc4184 } }, + /* 214 */ + { { 0xa708c8d3,0xddcebb19,0xc63f81ec,0xe63ed04f,0x11873f95,0xd045f5a0, + 0x79f276d5,0x3b5ad544,0x425ae5b3,0x81272a3d,0x10ce1605,0x8bfeb501 }, + { 0x888228bf,0x4233809c,0xb2aff7df,0x4bd82acf,0x0cbd4a7f,0x9c68f180, + 0x6b44323d,0xfcd77124,0x891db957,0x60c0fcf6,0x04da8f7f,0xcfbb4d89 } }, + /* 215 */ + { { 0x3b26139a,0x9a6a5df9,0xb2cc7eb8,0x3e076a83,0x5a964bcd,0x47a8e82d, + 0xb9278d6b,0x8a4e2a39,0xe4443549,0x93506c98,0xf1e0d566,0x06497a8f }, + { 0x2b1efa05,0x3dee8d99,0x45393e33,0x2da63ca8,0xcf0579ad,0xa4af7277, + 0x3236d8ea,0xaf4b4639,0x32b617f5,0x6ccad95b,0xb88bb124,0xce76d8b8 } }, + /* 216 */ + { { 0x083843dc,0x63d2537a,0x1e4153b4,0x89eb3514,0xea9afc94,0x5175ebc4, + 0x8ed1aed7,0x7a652580,0xd85e8297,0x67295611,0xb584b73d,0x8dd2d68b }, + { 0x0133c3a4,0x237139e6,0x4bd278ea,0x9de838ab,0xc062fcd9,0xe829b072, + 0x63ba8706,0x70730d4f,0xd3cd05ec,0x6080483f,0x0c85f84d,0x872ab5b8 } }, + /* 217 */ + { { 0x999d4d49,0xfc0776d3,0xec3f45e7,0xa3eb59de,0x0dae1fc1,0xbc990e44, + 0xa15371ff,0x33596b1e,0x9bc7ab25,0xd447dcb2,0x35979582,0xcd5b63e9 }, + { 0x77d1ff11,0xae3366fa,0xedee6903,0x59f28f05,0xa4433bf2,0x6f43fed1, + 0xdf9ce00e,0x15409c9b,0xaca9c5dc,0x21b5cded,0x82d7bdb4,0xf9f33595 } }, + /* 218 */ + { { 0x9422c792,0x95944378,0xc958b8bf,0x239ea923,0xdf076541,0x4b61a247, + 0xbb9fc544,0x4d29ce85,0x0b424559,0x9a692a67,0x0e486900,0x6e0ca5a0 }, + { 0x85b3bece,0x6b79a782,0xc61f9892,0x41f35e39,0xae747f82,0xff82099a, + 0xd0ca59d6,0x58c8ae3f,0x99406b5f,0x4ac930e2,0x9df24243,0x2ce04eb9 } }, + /* 219 */ + { { 0x1ac37b82,0x4366b994,0x25b04d83,0xff0c728d,0x19c47b7c,0x1f551361, + 0xbeff13e7,0xdbf2d5ed,0xe12a683d,0xf78efd51,0x989cf9c4,0x82cd85b9 }, + { 0xe0cb5d37,0xe23c6db6,0x72ee1a15,0x818aeebd,0x28771b14,0x8212aafd, + 0x1def817d,0x7bc221d9,0x9445c51f,0xdac403a2,0x12c3746b,0x711b0517 } }, + /* 220 */ + { { 0x5ea99ecc,0x0ed9ed48,0xb8cab5e1,0xf799500d,0xb570cbdc,0xa8ec87dc, + 0xd35dfaec,0x52cfb2c2,0x6e4d80a4,0x8d31fae2,0xdcdeabe5,0xe6a37dc9 }, + { 0x1deca452,0x5d365a34,0x0d68b44e,0x09a5f8a5,0xa60744b1,0x59238ea5, + 0xbb4249e9,0xf2fedc0d,0xa909b2e3,0xe395c74e,0x39388250,0xe156d1a5 } }, + /* 221 */ + { { 0x47181ae9,0xd796b3d0,0x44197808,0xbaf44ba8,0x34cf3fac,0xe6933094, + 0xc3bd5c46,0x41aa6ade,0xeed947c6,0x4fda75d8,0x9ea5a525,0xacd9d412 }, + { 0xd430301b,0x65cc55a3,0x7b52ea49,0x3c9a5bcf,0x159507f0,0x22d319cf, + 0xde74a8dd,0x2ee0b9b5,0x877ac2b6,0x20c26a1e,0x92e7c314,0x387d73da } }, + /* 222 */ + { { 0x8cd3fdac,0x13c4833e,0x332e5b8e,0x76fcd473,0xe2fe1fd3,0xff671b4b, + 0x5d98d8ec,0x4d734e8b,0x514bbc11,0xb1ead3c6,0x7b390494,0xd14ca858 }, + { 0x5d2d37e9,0x95a443af,0x00464622,0x73c6ea73,0x15755044,0xa44aeb4b, + 0xfab58fee,0xba3f8575,0xdc680a6f,0x9779dbc9,0x7b37ddfc,0xe1ee5f5a } }, + /* 223 */ + { { 0x12d29f46,0xcd0b4648,0x0ed53137,0x93295b0b,0x80bef6c9,0xbfe26094, + 0x54248b00,0xa6565788,0x80e7f9c4,0x69c43fca,0xbe141ea1,0x2190837b }, + { 0xa1b26cfb,0x875e159a,0x7affe852,0x90ca9f87,0x92ca598e,0x15e6550d, + 0x1938ad11,0xe3e0945d,0x366ef937,0xef7636bb,0xb39869e5,0xb6034d0b } }, + /* 224 */ + { { 0x26d8356e,0x4d255e30,0xd314626f,0xf83666ed,0xd0c8ed64,0x421ddf61, + 0x26677b61,0x96e473c5,0x9e9b18b3,0xdad4af7e,0xa9393f75,0xfceffd4a }, + { 0x11c731d5,0x843138a1,0xb2f141d9,0x05bcb3a1,0x617b7671,0x20e1fa95, + 0x88ccec7b,0xbefce812,0x90f1b568,0x582073dc,0x1f055cb7,0xf572261a } }, + /* 225 */ + { { 0x36973088,0xf3148277,0x86a9f980,0xc008e708,0xe046c261,0x1b795947, + 0xca76bca0,0xdf1e6a7d,0x71acddf0,0xabafd886,0x1364d8f4,0xff7054d9 }, + { 0xe2260594,0x2cf63547,0xd73b277e,0x468a5372,0xef9bd35e,0xc7419e24, + 0x24043cc3,0x2b4a1c20,0x890b39cd,0xa28f047a,0x46f9a2e3,0xdca2cea1 } }, + /* 226 */ + { { 0x53277538,0xab788736,0xcf697738,0xa734e225,0x6b22e2c1,0x66ee1d1e, + 0xebe1d212,0x2c615389,0x02bb0766,0xf36cad40,0x3e64f207,0x120885c3 }, + { 0x90fbfec2,0x59e77d56,0xd7a574ae,0xf9e781aa,0x5d045e53,0x801410b0, + 0xa91b5f0e,0xd3b5f0aa,0x7fbb3521,0xb3d1df00,0xc72bee9a,0x11c4b33e } }, + /* 227 */ + { { 0x83c3a7f3,0xd32b9832,0x88d8a354,0x8083abcf,0x50f4ec5a,0xdeb16404, + 0x641e2907,0x18d747f0,0xf1bbf03e,0x4e8978ae,0x88a0cd89,0x932447dc }, + { 0xcf3d5897,0x561e0feb,0x13600e6d,0xfc3a682f,0xd16a6b73,0xc78b9d73, + 0xd29bf580,0xe713fede,0x08d69e5c,0x0a225223,0x1ff7fda4,0x3a924a57 } }, + /* 228 */ + { { 0xb4093bee,0xfb64554c,0xa58c6ec0,0xa6d65a25,0x43d0ed37,0x4126994d, + 0x55152d44,0xa5689a51,0x284caa8d,0xb8e5ea8c,0xd1f25538,0x33f05d4f }, + { 0x1b615d6e,0xe0fdfe09,0x705507da,0x2ded7e8f,0x17bbcc80,0xdd5631e5, + 0x267fd11f,0x4f87453e,0xff89d62d,0xc6da723f,0xe3cda21d,0x55cbcae2 } }, + /* 229 */ + { { 0x6b4e84f3,0x336bc94e,0x4ef72c35,0x72863031,0xeeb57f99,0x6d85fdee, + 0xa42ece1b,0x7f4e3272,0x36f0320a,0x7f86cbb5,0x923331e6,0xf09b6a2b }, + { 0x56778435,0x21d3ecf1,0x8323b2d2,0x2977ba99,0x1704bc0f,0x6a1b57fb, + 0x389f048a,0xd777cf8b,0xac6b42cd,0x9ce2174f,0x09e6c55a,0x404e2bff } }, + /* 230 */ + { { 0x204c5ddb,0x9b9b135e,0x3eff550e,0x9dbfe044,0xec3be0f6,0x35eab4bf, + 0x0a43e56f,0x8b4c3f0d,0x0e73f9b3,0x4c1c6673,0x2c78c905,0x92ed38bd }, + { 0xa386e27c,0xc7003f6a,0xaced8507,0xb9c4f46f,0x59df5464,0xea024ec8, + 0x429572ea,0x4af96152,0xe1fc1194,0x279cd5e2,0x281e358c,0xaa376a03 } }, + /* 231 */ + { { 0x3cdbc95c,0x07859223,0xef2e337a,0xaae1aa6a,0x472a8544,0xc040108d, + 0x8d037b7d,0x80c853e6,0x8c7eee24,0xd221315c,0x8ee47752,0x195d3856 }, + { 0xdacd7fbe,0xd4b1ba03,0xd3e0c52b,0x4b5ac61e,0x6aab7b52,0x68d3c052, + 0x660e3fea,0xf0d7248c,0x3145efb4,0xafdb3f89,0x8f40936d,0xa73fd9a3 } }, + /* 232 */ + { { 0xbb1b17ce,0x891b9ef3,0xc6127f31,0x14023667,0x305521fd,0x12b2e58d, + 0xe3508088,0x3a47e449,0xff751507,0xe49fc84b,0x5310d16e,0x4023f722 }, + { 0xb73399fa,0xa608e5ed,0xd532aa3e,0xf12632d8,0x845e8415,0x13a2758e, + 0x1fc2d861,0xae4b6f85,0x339d02f2,0x3879f5b1,0x80d99ebd,0x446d22a6 } }, + /* 233 */ + { { 0x4be164f1,0x0f502302,0x88b81920,0x8d09d2d6,0x984aceff,0x514056f1, + 0x75e9e80d,0xa5c4ddf0,0xdf496a93,0x38cb47e6,0x38df6bf7,0x899e1d6b }, + { 0xb59eb2a6,0x69e87e88,0x9b47f38b,0x280d9d63,0x3654e955,0x599411ea, + 0x969aa581,0xcf8dd4fd,0x530742a7,0xff5c2baf,0x1a373085,0xa4391536 } }, + /* 234 */ + { { 0xa8a4bdd2,0x6ace72a3,0xb68ef702,0xc656cdd1,0x90c4dad8,0xd4a33e7e, + 0x9d951c50,0x4aece08a,0x085d68e6,0xea8005ae,0x6f7502b8,0xfdd7a7d7 }, + { 0x98d6fa45,0xce6fb0a6,0x1104eb8c,0x228f8672,0xda09d7dc,0xd23d8787, + 0x2ae93065,0x5521428b,0xea56c366,0x95faba3d,0x0a88aca5,0xedbe5039 } }, + /* 235 */ + { { 0xbfb26c82,0xd64da0ad,0x952c2f9c,0xe5d70b3c,0xf7e77f68,0xf5e8f365, + 0x08f2d695,0x7234e002,0xd12e7be6,0xfaf900ee,0x4acf734e,0x27dc6934 }, + { 0xc260a46a,0x80e4ff5e,0x2dc31c28,0x7da5ebce,0xca69f552,0x485c5d73, + 0x69cc84c2,0xcdfb6b29,0xed6d4eca,0x031c5afe,0x22247637,0xc7bbf4c8 } }, + /* 236 */ + { { 0x49fe01b2,0x9d5b72c7,0x793a91b8,0x34785186,0xcf460438,0xa3ba3c54, + 0x3ab21b6f,0x73e8e43d,0xbe57b8ab,0x50cde8e0,0xdd204264,0x6488b3a7 }, + { 0xdddc4582,0xa9e398b3,0x5bec46fe,0x1698c1a9,0x156d3843,0x7f1446ef, + 0x770329a2,0x3fd25dd8,0x2c710668,0x05b1221a,0xa72ee6cf,0x65b2dc2a } }, + /* 237 */ + { { 0xcd021d63,0x21a885f7,0xfea61f08,0x3f344b15,0xc5cf73e6,0xad5ba6dd, + 0x227a8b23,0x154d0d8f,0xdc559311,0x9b74373c,0x98620fa1,0x4feab715 }, + { 0x7d9ec924,0x5098938e,0x6d47e550,0x84d54a5e,0x1b617506,0x1a2d1bdc, + 0x615868a4,0x99fe1782,0x3005a924,0x171da780,0x7d8f79b6,0xa70bf5ed } }, + /* 238 */ + { { 0xfe2216c5,0x0bc1250d,0x7601b351,0x2c37e250,0xd6f06b7e,0xb6300175, + 0x8bfeb9b7,0x4dde8ca1,0xb82f843d,0x4f210432,0xb1ac0afd,0x8d70e2f9 }, + { 0xaae91abb,0x25c73b78,0x863028f2,0x0230dca3,0xe5cf30b7,0x8b923ecf, + 0x5506f265,0xed754ec2,0x729a5e39,0x8e41b88c,0xbabf889b,0xee67cec2 } }, + /* 239 */ + { { 0x1be46c65,0xe183acf5,0xe7565d7a,0x9789538f,0xd9627b4e,0x87873391, + 0x9f1d9187,0xbf4ac4c1,0x4691f5c8,0x5db99f63,0x74a1fb98,0xa68df803 }, + { 0xbf92b5fa,0x3c448ed1,0x3e0bdc32,0xa098c841,0x79bf016c,0x8e74cd55, + 0x115e244d,0x5df0d09c,0x3410b66e,0x9418ad01,0x17a02130,0x8b6124cb } }, + /* 240 */ + { { 0xc26e3392,0x425ec3af,0xa1722e00,0xc07f8470,0xe2356b43,0xdcc28190, + 0xb1ef59a6,0x4ed97dff,0xc63028c1,0xc22b3ad1,0x68c18988,0x070723c2 }, + { 0x4cf49e7d,0x70da302f,0x3f12a522,0xc5e87c93,0x18594148,0x74acdd1d, + 0xca74124c,0xad5f73ab,0xd69fd478,0xe72e4a3e,0x7b117cc3,0x61593868 } }, + /* 241 */ + { { 0xa9aa0486,0x7b7b9577,0xa063d557,0x6e41fb35,0xda9047d7,0xb017d5c7, + 0x68a87ba9,0x8c748280,0xdf08ad93,0xab45fa5c,0x4c288a28,0xcd9fb217 }, + { 0x5747843d,0x59544642,0xa56111e3,0x34d64c6c,0x4bfce8d5,0x12e47ea1, + 0x6169267f,0x17740e05,0xeed03fb5,0x5c49438e,0x4fc3f513,0x9da30add } }, + /* 242 */ + { { 0xccfa5200,0xc4e85282,0x6a19b13d,0x2707608f,0xf5726e2f,0xdcb9a53d, + 0xe9427de5,0x612407c9,0xd54d582a,0x3e5a17e1,0x655ae118,0xb99877de }, + { 0x015254de,0x6f0e972b,0xf0a6f7c5,0x92a56db1,0xa656f8b2,0xd297e4e1, + 0xad981983,0x99fe0052,0x07cfed84,0xd3652d2f,0x843c1738,0xc784352e } }, + /* 243 */ + { { 0x7e9b2d8a,0x6ee90af0,0x57cf1964,0xac8d7018,0x71f28efc,0xf6ed9031, + 0x6812b20e,0x7f70d5a9,0xf1c61eee,0x27b557f4,0xc6263758,0xf1c9bd57 }, + { 0x2a1a6194,0x5cf7d014,0x1890ab84,0xdd614e0b,0x0e93c2a6,0x3ef9de10, + 0xe0cd91c5,0xf98cf575,0x14befc32,0x504ec0c6,0x6279d68c,0xd0513a66 } }, + /* 244 */ + { { 0xa859fb6a,0xa8eadbad,0xdb283666,0xcf8346e7,0x3e22e355,0x7b35e61a, + 0x99639c6b,0x293ece2c,0x56f241c8,0xfa0162e2,0xbf7a1dda,0xd2e6c7b9 }, + { 0x40075e63,0xd0de6253,0xf9ec8286,0x2405aa61,0x8fe45494,0x2237830a, + 0x364e9c8c,0x4fd01ac7,0x904ba750,0x4d9c3d21,0xaf1b520b,0xd589be14 } }, + /* 245 */ + { { 0x4662e53b,0x13576a4f,0xf9077676,0x35ec2f51,0x97c0af97,0x66297d13, + 0x9e598b58,0xed3201fe,0x5e70f604,0x49bc752a,0xbb12d951,0xb54af535 }, + { 0x212c1c76,0x36ea4c2b,0xeb250dfd,0x18f5bbc7,0x9a0a1a46,0xa0d466cc, + 0xdac2d917,0x52564da4,0x8e95fab5,0x206559f4,0x9ca67a33,0x7487c190 } }, + /* 246 */ + { { 0xdde98e9c,0x75abfe37,0x2a411199,0x99b90b26,0xdcdb1f7c,0x1b410996, + 0x8b3b5675,0xab346f11,0xf1f8ae1e,0x04852193,0x6b8b98c1,0x1ec4d227 }, + { 0x45452baa,0xba3bc926,0xacc4a572,0x387d1858,0xe51f171e,0x9478eff6, + 0x931e1c00,0xf357077d,0xe54c8ca8,0xffee77cd,0x551dc9a4,0xfb4892ff } }, + /* 247 */ + { { 0x2db8dff8,0x5b1bdad0,0x5a2285a2,0xd462f4fd,0xda00b461,0x1d6aad8e, + 0x41306d1b,0x43fbefcf,0x6a13fe19,0x428e86f3,0x17f89404,0xc8b2f118 }, + { 0xf0d51afb,0x762528aa,0x549b1d06,0xa3e2fea4,0xea3ddf66,0x86fad8f2, + 0x4fbdd206,0x0d9ccc4b,0xc189ff5a,0xcde97d4c,0x199f19a6,0xc36793d6 } }, + /* 248 */ + { { 0x51b85197,0xea38909b,0xb4c92895,0xffb17dd0,0x1ddb3f3f,0x0eb0878b, + 0xc57cf0f2,0xb05d28ff,0x1abd57e2,0xd8bde2e7,0xc40c1b20,0x7f2be28d }, + { 0x299a2d48,0x6554dca2,0x8377982d,0x5130ba2e,0x1071971a,0x8863205f, + 0x7cf2825d,0x15ee6282,0x03748f2b,0xd4b6c57f,0x430385a0,0xa9e3f4da } }, + /* 249 */ + { { 0x83fbc9c6,0x33eb7cec,0x4541777e,0x24a311c7,0x4f0767fc,0xc81377f7, + 0x4ab702da,0x12adae36,0x2a779696,0xb7fcb6db,0x01cea6ad,0x4a6fb284 }, + { 0xcdfc73de,0x5e8b1d2a,0x1b02fd32,0xd0efae8d,0xd81d8519,0x3f99c190, + 0xfc808971,0x3c18f7fa,0x51b7ae7b,0x41f713e7,0xf07fc3f8,0x0a4b3435 } }, + /* 250 */ + { { 0x019b7d2e,0x7dda3c4c,0xd4dc4b89,0x631c8d1a,0x1cdb313c,0x5489cd6e, + 0x4c07bb06,0xd44aed10,0x75f000d1,0x8f97e13a,0xdda5df4d,0x0e9ee64f }, + { 0x3e346910,0xeaa99f3b,0xfa294ad7,0x622f6921,0x0d0b2fe9,0x22aaa20d, + 0x1e5881ba,0x4fed2f99,0xc1571802,0x9af3b2d6,0xdc7ee17c,0x919e67a8 } }, + /* 251 */ + { { 0x76250533,0xc724fe4c,0x7d817ef8,0x8a2080e5,0x172c9751,0xa2afb0f4, + 0x17c0702e,0x9b10cdeb,0xc9b7e3e9,0xbf3975e3,0x1cd0cdc5,0x206117df }, + { 0xbe05ebd5,0xfb049e61,0x16c782c0,0xeb0bb55c,0xab7fed09,0x13a331b8, + 0x632863f0,0xf6c58b1d,0x4d3b6195,0x6264ef6e,0x9a53f116,0x92c51b63 } }, + /* 252 */ + { { 0x288b364d,0xa57c7bc8,0x7b41e5c4,0x4a562e08,0x698a9a11,0x699d21c6, + 0xf3f849b9,0xa4ed9581,0x9eb726ba,0xa223eef3,0xcc2884f9,0x13159c23 }, + { 0x3a3f4963,0x73931e58,0x0ada6a81,0x96500389,0x5ab2950b,0x3ee8a1c6, + 0x775fab52,0xeedf4949,0x4f2671b6,0x63d652e1,0x3c4e2f55,0xfed4491c } }, + /* 253 */ + { { 0xf4eb453e,0x335eadc3,0xcadd1a5b,0x5ff74b63,0x5d84a91a,0x6933d0d7, + 0xb49ba337,0x9ca3eeb9,0xc04c15b8,0x1f6facce,0xdc09a7e4,0x4ef19326 }, + { 0x3dca3233,0x53d2d324,0xa2259d4b,0x0ee40590,0x5546f002,0x18c22edb, + 0x09ea6b71,0x92429801,0xb0e91e61,0xaada0add,0x99963c50,0x5fe53ef4 } }, + /* 254 */ + { { 0x90c28c65,0x372dd06b,0x119ce47d,0x1765242c,0x6b22fc82,0xc041fb80, + 0xb0a7ccc1,0x667edf07,0x1261bece,0xc79599e7,0x19cff22a,0xbc69d9ba }, + { 0x13c06819,0x009d77cd,0xe282b79d,0x635a66ae,0x225b1be8,0x4edac4a6, + 0x524008f9,0x57d4f4e4,0xb056af84,0xee299ac5,0x3a0bc386,0xcc38444c } }, + /* 255 */ + { { 0xcd4c2356,0x490643b1,0x750547be,0x740a4851,0xd4944c04,0x643eaf29, + 0x299a98a0,0xba572479,0xee05fdf9,0x48b29f16,0x089b2d7b,0x33fb4f61 }, + { 0xa950f955,0x86704902,0xfedc3ddf,0x97e1034d,0x05fbb6a2,0x211320b6, + 0x432299bb,0x23d7b93f,0x8590e4a3,0x1fe1a057,0xf58c0ce6,0x8e1d0586 } }, +}; + +/* 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. + * 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_12(sp_point_384* r, const sp_digit* k, + int map, void* heap) +{ + return sp_384_ecc_mulmod_stripe_12(r, &p384_base, p384_table, + k, map, heap); +} + +#endif + +/* Multiply the base point of P384 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_384(mp_int* km, ecc_point* r, int map, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 p; + sp_digit kd[12]; +#endif + sp_point_384* point; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_384_point_new_12(heap, p, point); +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 12, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + } +#else + k = kd; +#endif + if (err == MP_OKAY) { + sp_384_from_mp(k, 12, km); + + err = sp_384_ecc_mulmod_base_12(point, k, map, heap); + } + if (err == MP_OKAY) { + err = sp_384_point_to_ecc_point_12(point, r); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + 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. + * Implementation is constant time. + * + * a Number to check. + * returns 1 if the number is zero and 0 otherwise. + */ +static int sp_384_iszero_12(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]) == 0; +} + +#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN || HAVE_ECC_SIGN || HAVE_ECC_VERIFY */ +/* Add 1 to a. (a = a + 1) + * + * a A single precision integer. + */ +SP_NOINLINE static void sp_384_add_one_12(sp_digit* a) +{ + __asm__ __volatile__ ( + "mov r2, #1\n\t" + "ldr r1, [%[a], #0]\n\t" + "add r1, r2\n\t" + "mov r2, #0\n\t" + "str r1, [%[a], #0]\n\t" + "ldr r1, [%[a], #4]\n\t" + "adc r1, r2\n\t" + "str r1, [%[a], #4]\n\t" + "ldr r1, [%[a], #8]\n\t" + "adc r1, r2\n\t" + "str r1, [%[a], #8]\n\t" + "ldr r1, [%[a], #12]\n\t" + "adc r1, r2\n\t" + "str r1, [%[a], #12]\n\t" + "ldr r1, [%[a], #16]\n\t" + "adc r1, r2\n\t" + "str r1, [%[a], #16]\n\t" + "ldr r1, [%[a], #20]\n\t" + "adc r1, r2\n\t" + "str r1, [%[a], #20]\n\t" + "ldr r1, [%[a], #24]\n\t" + "adc r1, r2\n\t" + "str r1, [%[a], #24]\n\t" + "ldr r1, [%[a], #28]\n\t" + "adc r1, r2\n\t" + "str r1, [%[a], #28]\n\t" + "ldr r1, [%[a], #32]\n\t" + "adc r1, r2\n\t" + "str r1, [%[a], #32]\n\t" + "ldr r1, [%[a], #36]\n\t" + "adc r1, r2\n\t" + "str r1, [%[a], #36]\n\t" + "ldr r1, [%[a], #40]\n\t" + "adc r1, r2\n\t" + "str r1, [%[a], #40]\n\t" + "ldr r1, [%[a], #44]\n\t" + "adc r1, r2\n\t" + "str r1, [%[a], #44]\n\t" + : + : [a] "r" (a) + : "memory", "r1", "r2" + ); +} + +/* 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_384_from_bin(sp_digit* r, int size, const byte* a, int n) +{ + int i, 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; + } +} + +/* Generates a scalar that is in the range 1..order-1. + * + * rng Random number generator. + * k Scalar value. + * returns RNG failures, MEMORY_E when memory allocation fails and + * MP_OKAY on success. + */ +static int sp_384_ecc_gen_k_12(WC_RNG* rng, sp_digit* k) +{ + int err; + byte buf[48]; + + do { + err = wc_RNG_GenerateBlock(rng, buf, sizeof(buf)); + if (err == 0) { + sp_384_from_bin(k, 12, buf, (int)sizeof(buf)); + if (sp_384_cmp_12(k, p384_order2) < 0) { + sp_384_add_one_12(k); + break; + } + } + } + while (err == 0); + + return err; +} + +/* Makes a random EC key pair. + * + * rng Random number generator. + * priv Generated private value. + * pub Generated public point. + * heap Heap to use for allocation. + * returns ECC_INF_E when the point does not have the correct order, RNG + * failures, MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_make_key_384(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 p; + sp_digit kd[12]; +#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN + sp_point_384 inf; +#endif +#endif + sp_point_384* point; + sp_digit* k = NULL; +#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN + sp_point_384* infinity; +#endif + int err; + + (void)heap; + + err = sp_384_point_new_12(heap, p, point); +#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN + if (err == MP_OKAY) { + err = sp_384_point_new_12(heap, inf, infinity); + } +#endif +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 12, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + } +#else + k = kd; +#endif + + if (err == MP_OKAY) { + err = sp_384_ecc_gen_k_12(rng, k); + } + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_base_12(point, k, 1, NULL); + } + +#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_12(infinity, point, p384_order, 1, NULL); + } + if (err == MP_OKAY) { + if ((sp_384_iszero_12(point->x) == 0) || (sp_384_iszero_12(point->y) == 0)) { + err = ECC_INF_E; + } + } +#endif + + if (err == MP_OKAY) { + err = sp_384_to_mp(k, priv); + } + if (err == MP_OKAY) { + err = sp_384_point_to_ecc_point_12(point, pub); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif +#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN + sp_384_point_free_12(infinity, 1, heap); +#endif + sp_384_point_free_12(point, 1, heap); + + return err; +} + +#ifdef HAVE_ECC_DHE +/* Write r as big endian to byte array. + * Fixed length number of bytes written: 48 + * + * r A single precision integer. + * a Byte array. + */ +static void sp_384_to_bin(sp_digit* r, byte* a) +{ + int i, j, s = 0, b; + + j = 384 / 8 - 1; + a[j] = 0; + for (i=0; i<12 && j>=0; i++) { + b = 0; + /* lint allow cast of mismatch sp_digit and int */ + a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ + if (j < 0) { + break; + } + while (b < 32) { + a[j--] = r[i] >> b; b += 8; + if (j < 0) { + break; + } + } + s = 8 - (b - 32); + if (j >= 0) { + a[j] = 0; + } + if (s != 0) { + j++; + } + } +} + +/* Multiply the point by the scalar and serialize the X ordinate. + * The number is 0 padded to maximum size on output. + * + * priv Scalar to multiply the point by. + * pub Point to multiply. + * out Buffer to hold X ordinate. + * outLen On entry, size of the buffer in bytes. + * On exit, length of data in buffer in bytes. + * heap Heap to use for allocation. + * 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, + word32* outLen, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 p; + sp_digit kd[12]; +#endif + sp_point_384* point = NULL; + sp_digit* k = NULL; + int err = MP_OKAY; + + if (*outLen < 48U) { + err = BUFFER_E; + } + + if (err == MP_OKAY) { + err = sp_384_point_new_12(heap, p, point); + } +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 12, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) + err = MEMORY_E; + } +#else + k = kd; +#endif + + if (err == MP_OKAY) { + sp_384_from_mp(k, 12, priv); + sp_384_point_from_ecc_point_12(point, pub); + err = sp_384_ecc_mulmod_12(point, point, k, 1, heap); + } + if (err == MP_OKAY) { + sp_384_to_bin(point->x, out); + *outLen = 48; + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_12(point, 0, heap); + + return err; +} +#endif /* HAVE_ECC_DHE */ + +#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) +#endif +#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) +#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_384_sub_in_place_12(sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + __asm__ __volatile__ ( + "mov r7, %[a]\n\t" + "add r7, #48\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; +} + +#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_in_place_12(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" + "sbc %[c], %[c]\n\t" + : [c] "+r" (c), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r3", "r4", "r5", "r6" + ); + + 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_384_mul_d_12(sp_digit* r, const sp_digit* a, + sp_digit b) +{ + __asm__ __volatile__ ( + "mov r6, #48\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_384_word_12(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_384_mask_12(sp_digit* r, const sp_digit* a, sp_digit m) +{ +#ifdef WOLFSSL_SP_SMALL + int i; + + for (i=0; i<12; 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; + r[8] = a[8] & m; + r[9] = a[9] & m; + r[10] = a[10] & m; + r[11] = a[11] & m; +#endif +} + +/* 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 Nmber 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_384_div_12(const sp_digit* a, const sp_digit* d, sp_digit* m, + sp_digit* r) +{ + sp_digit t1[24], t2[13]; + sp_digit div, r1; + int i; + + (void)m; + + div = d[11]; + XMEMCPY(t1, a, sizeof(*t1) * 2 * 12); + for (i=11; i>=0; i--) { + r1 = div_384_word_12(t1[12 + i], t1[12 + i - 1], div); + + sp_384_mul_d_12(t2, d, r1); + t1[12 + i] += sp_384_sub_in_place_12(&t1[i], t2); + t1[12 + i] -= t2[12]; + sp_384_mask_12(t2, d, t1[12 + i]); + t1[12 + i] += sp_384_add_12(&t1[i], &t1[i], t2); + sp_384_mask_12(t2, d, t1[12 + i]); + t1[12 + i] += sp_384_add_12(&t1[i], &t1[i], t2); + } + + r1 = sp_384_cmp_12(t1, d) >= 0; + sp_384_cond_sub_12(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_384_mod_12(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + return sp_384_div_12(a, m, NULL, r); +} + +#endif +#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) +#ifdef WOLFSSL_SP_SMALL +/* Order-2 for the P384 curve. */ +static const uint32_t p384_order_minus_2[12] = { + 0xccc52971U,0xecec196aU,0x48b0a77aU,0x581a0db2U,0xf4372ddfU,0xc7634d81U, + 0xffffffffU,0xffffffffU,0xffffffffU,0xffffffffU,0xffffffffU,0xffffffffU +}; +#else +/* 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 */ + +/* Multiply two number mod the order of P384 curve. (r = a * b mod order) + * + * r Result of the multiplication. + * a First operand of the multiplication. + * b Second operand of the multiplication. + */ +static void sp_384_mont_mul_order_12(sp_digit* r, const sp_digit* a, const sp_digit* b) +{ + sp_384_mul_12(r, a, b); + sp_384_mont_reduce_order_12(r, p384_order, p384_mp_order); +} + +/* Square number mod the order of P384 curve. (r = a * a mod order) + * + * r Result of the squaring. + * a Number to square. + */ +static void sp_384_mont_sqr_order_12(sp_digit* r, const sp_digit* a) +{ + sp_384_sqr_12(r, a); + sp_384_mont_reduce_order_12(r, p384_order, p384_mp_order); +} + +#ifndef WOLFSSL_SP_SMALL +/* Square number mod the order of P384 curve a number of times. + * (r = a ^ n mod order) + * + * r Result of the squaring. + * a Number to square. + */ +static void sp_384_mont_sqr_n_order_12(sp_digit* r, const sp_digit* a, int n) +{ + int i; + + sp_384_mont_sqr_order_12(r, a); + for (i=1; i=0; i--) { + sp_384_mont_sqr_order_12(t, t); + if ((p384_order_minus_2[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { + sp_384_mont_mul_order_12(t, t, a); + } + } + XMEMCPY(r, t, sizeof(sp_digit) * 12U); +#else + sp_digit* t = td; + sp_digit* t2 = td + 2 * 12; + sp_digit* t3 = td + 4 * 12; + int i; + + /* t = a^2 */ + sp_384_mont_sqr_order_12(t, a); + /* t = a^3 = t * a */ + sp_384_mont_mul_order_12(t, t, a); + /* t2= a^c = t ^ 2 ^ 2 */ + sp_384_mont_sqr_n_order_12(t2, t, 2); + /* t = a^f = t2 * t */ + sp_384_mont_mul_order_12(t, t2, t); + /* t2= a^f0 = t ^ 2 ^ 4 */ + sp_384_mont_sqr_n_order_12(t2, t, 4); + /* t = a^ff = t2 * t */ + sp_384_mont_mul_order_12(t, t2, t); + /* t2= a^ff00 = t ^ 2 ^ 8 */ + sp_384_mont_sqr_n_order_12(t2, t, 8); + /* t3= a^ffff = t2 * t */ + sp_384_mont_mul_order_12(t3, t2, t); + /* t2= a^ffff0000 = t3 ^ 2 ^ 16 */ + sp_384_mont_sqr_n_order_12(t2, t3, 16); + /* t = a^ffffffff = t2 * t3 */ + sp_384_mont_mul_order_12(t, t2, t3); + /* t2= a^ffffffff0000 = t ^ 2 ^ 16 */ + sp_384_mont_sqr_n_order_12(t2, t, 16); + /* t = a^ffffffffffff = t2 * t3 */ + sp_384_mont_mul_order_12(t, t2, t3); + /* t2= a^ffffffffffff000000000000 = t ^ 2 ^ 48 */ + sp_384_mont_sqr_n_order_12(t2, t, 48); + /* t= a^fffffffffffffffffffffffff = t2 * t */ + sp_384_mont_mul_order_12(t, t2, t); + /* t2= a^ffffffffffffffffffffffff000000000000000000000000 */ + sp_384_mont_sqr_n_order_12(t2, t, 96); + /* t2= a^ffffffffffffffffffffffffffffffffffffffffffffffff = t2 * t */ + 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) { + sp_384_mont_mul_order_12(t2, t2, a); + } + } + sp_384_mont_sqr_order_12(t2, t2); + sp_384_mont_mul_order_12(r, t2, a); +#endif /* WOLFSSL_SP_SMALL */ +} + +#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 + +/* Sign the hash using the private key. + * e = [hash, 384 bits] from binary + * r = (k.G)->x mod order + * s = (r * x + e) / k mod order + * The hash is truncated to the first 384 bits. + * + * hash Hash to sign. + * hashLen Length of the hash data. + * rng Random number generator. + * priv Private part of key - scalar. + * 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. + */ +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) +{ +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_digit* d = NULL; +#else + sp_digit ed[2*12]; + sp_digit xd[2*12]; + sp_digit kd[2*12]; + sp_digit rd[2*12]; + sp_digit td[3 * 2*12]; + sp_point_384 p; +#endif + sp_digit* e = NULL; + sp_digit* x = NULL; + sp_digit* k = NULL; + 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 i; + + (void)heap; + + err = sp_384_point_new_12(heap, p, point); +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7 * 2 * 12, heap, + DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + e = d + 0 * 12; + x = d + 2 * 12; + k = d + 4 * 12; + r = d + 6 * 12; + tmp = d + 8 * 12; +#else + e = ed; + x = xd; + k = kd; + r = rd; + tmp = td; +#endif + s = e; + kInv = k; + + if (hashLen > 48U) { + hashLen = 48U; + } + + sp_384_from_bin(e, 12, hash, (int)hashLen); + } + + 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); + } + else { + sp_384_from_mp(k, 12, km); + mp_zero(km); + } + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_base_12(point, k, 1, NULL); + } + + if (err == MP_OKAY) { + /* r = point->x mod order */ + XMEMCPY(r, point->x, sizeof(sp_digit) * 12U); + sp_384_norm_12(r); + c = sp_384_cmp_12(r, p384_order); + 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); + 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); + + /* Check that signature is usable. */ + if (sp_384_iszero_12(s) == 0) { + break; + } + } + } + + if (i == 0) { + err = RNG_FAILURE_E; + } + + if (err == MP_OKAY) { + err = sp_384_to_mp(r, rm); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(s, sm); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (d != NULL) { + XMEMSET(d, 0, sizeof(sp_digit) * 8 * 12); + XFREE(d, heap, DYNAMIC_TYPE_ECC); + } +#else + XMEMSET(e, 0, sizeof(sp_digit) * 2U * 12U); + 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); + + return err; +} +#endif /* HAVE_ECC_SIGN */ + +#ifdef HAVE_ECC_VERIFY +/* Verify the signature values with the hash and public key. + * e = Truncate(hash, 384) + * u1 = e/s mod order + * u2 = r/s mod order + * r == (u1.G + u2.Q)->x mod order + * Optimization: Leave point in projective form. + * (x, y, 1) == (x' / z'*z', y' / z'*z'*z', z' / z') + * (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' + * The hash is truncated to the first 384 bits. + * + * hash Hash to sign. + * hashLen Length of the hash data. + * rng Random number generator. + * priv Private part of key - scalar. + * 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. + */ +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) +{ +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_digit* d = NULL; +#else + sp_digit u1d[2*12]; + sp_digit u2d[2*12]; + sp_digit sd[2*12]; + sp_digit tmpd[2*12 * 5]; + sp_point_384 p1d; + sp_point_384 p2d; +#endif + sp_digit* u1 = NULL; + sp_digit* u2 = NULL; + sp_digit* s = NULL; + sp_digit* tmp = NULL; + sp_point_384* p1; + sp_point_384* p2 = NULL; + sp_digit carry; + int32_t c; + int err; + + err = sp_384_point_new_12(heap, p1d, p1); + if (err == MP_OKAY) { + err = sp_384_point_new_12(heap, p2d, p2); + } +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 12, heap, + DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + u1 = d + 0 * 12; + u2 = d + 2 * 12; + s = d + 4 * 12; + tmp = d + 6 * 12; +#else + u1 = u1d; + u2 = u2d; + s = sd; + tmp = tmpd; +#endif + + if (hashLen > 48U) { + hashLen = 48U; + } + + sp_384_from_bin(u1, 12, hash, (int)hashLen); + sp_384_from_mp(u2, 12, r); + sp_384_from_mp(s, 12, sm); + sp_384_from_mp(p2->x, 12, pX); + sp_384_from_mp(p2->y, 12, pY); + sp_384_from_mp(p2->z, 12, pZ); + + { + 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); + { + 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); + } + + err = sp_384_ecc_mulmod_base_12(p1, u1, 0, heap); + } + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_12(p2, p2, u2, 0, heap); + } + + 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); + err = sp_384_mod_mul_norm_12(u2, u2, p384_mod); + } + + if (err == MP_OKAY) { + /* u1 = r.z'.z' mod prime */ + sp_384_mont_sqr_12(p1->z, p1->z, p384_mod, p384_mp_mod); + 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) { + /* Reload r and add order. */ + sp_384_from_mp(u2, 12, r); + carry = sp_384_add_12(u2, u2, p384_order); + /* Carry means result is greater than mod and is not valid. */ + if (carry == 0) { + sp_384_norm_12(u2); + + /* 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 defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (d != NULL) + XFREE(d, heap, DYNAMIC_TYPE_ECC); +#endif + sp_384_point_free_12(p1, 0, heap); + sp_384_point_free_12(p2, 0, heap); + + return err; +} +#endif /* HAVE_ECC_VERIFY */ + +#ifdef HAVE_ECC_CHECK_KEY +/* 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_384_ecc_is_point_12(sp_point_384* point, void* heap) +{ +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_digit* d = NULL; +#else + sp_digit t1d[2*12]; + sp_digit t2d[2*12]; +#endif + sp_digit* t1; + sp_digit* t2; + int err = MP_OKAY; + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 12 * 4, heap, DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + t1 = d + 0 * 12; + t2 = d + 2 * 12; +#else + (void)heap; + + t1 = t1d; + t2 = t2d; +#endif + + sp_384_sqr_12(t1, point->y); + (void)sp_384_mod_12(t1, t1, p384_mod); + sp_384_sqr_12(t2, point->x); + (void)sp_384_mod_12(t2, t2, p384_mod); + sp_384_mul_12(t2, t2, point->x); + (void)sp_384_mod_12(t2, t2, p384_mod); + (void)sp_384_sub_12(t2, p384_mod, t2); + sp_384_mont_add_12(t1, t1, t2, p384_mod); + + sp_384_mont_add_12(t1, t1, point->x, p384_mod); + sp_384_mont_add_12(t1, t1, point->x, p384_mod); + sp_384_mont_add_12(t1, t1, point->x, p384_mod); + + if (sp_384_cmp_12(t1, p384_b) != 0) { + err = MP_VAL; + } + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + 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_384(mp_int* pX, mp_int* pY) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 pubd; +#endif + sp_point_384* pub; + byte one[1] = { 1 }; + int err; + + err = sp_384_point_new_12(NULL, pubd, pub); + if (err == MP_OKAY) { + sp_384_from_mp(pub->x, 12, pX); + sp_384_from_mp(pub->y, 12, pY); + sp_384_from_bin(pub->z, 12, one, (int)sizeof(one)); + + err = sp_384_ecc_is_point_12(pub, NULL); + } + + sp_384_point_free_12(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_384(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_digit privd[12]; + sp_point_384 pubd; + sp_point_384 pd; +#endif + sp_digit* priv = NULL; + sp_point_384* pub; + sp_point_384* p = NULL; + byte one[1] = { 1 }; + int err; + + err = sp_384_point_new_12(heap, pubd, pub); + if (err == MP_OKAY) { + err = sp_384_point_new_12(heap, pd, p); + } +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + priv = (sp_digit*)XMALLOC(sizeof(sp_digit) * 12, heap, + DYNAMIC_TYPE_ECC); + if (priv == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if !(defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) + priv = privd; +#endif + + sp_384_from_mp(pub->x, 12, pX); + sp_384_from_mp(pub->y, 12, pY); + sp_384_from_bin(pub->z, 12, one, (int)sizeof(one)); + sp_384_from_mp(priv, 12, privm); + + /* Check point at infinitiy. */ + if ((sp_384_iszero_12(pub->x) != 0) && + (sp_384_iszero_12(pub->y) != 0)) { + err = ECC_INF_E; + } + } + + 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; + } + } + + if (err == MP_OKAY) { + /* Check point is on curve */ + err = sp_384_ecc_is_point_12(pub, heap); + } + + if (err == MP_OKAY) { + /* Point * order = infinity */ + err = sp_384_ecc_mulmod_12(p, pub, p384_order, 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; + } + } + + if (err == MP_OKAY) { + /* Base * private = point */ + err = sp_384_ecc_mulmod_base_12(p, priv, 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; + } + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (priv != NULL) { + XFREE(priv, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_12(p, 0, heap); + sp_384_point_free_12(pub, 0, heap); + + return err; +} +#endif +#ifdef WOLFSSL_PUBLIC_ECC_ADD_DBL +/* Add two projective EC points together. + * (pX, pY, pZ) + (qX, qY, qZ) = (rX, rY, rZ) + * + * pX First EC point's X ordinate. + * pY First EC point's Y ordinate. + * pZ First EC point's Z ordinate. + * qX Second EC point's X ordinate. + * qY Second EC point's Y ordinate. + * qZ Second EC point's Z ordinate. + * rX Resultant EC point's X ordinate. + * rY Resultant EC point's Y ordinate. + * rZ Resultant EC point's Z ordinate. + * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise. + */ +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) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_digit tmpd[2 * 12 * 5]; + sp_point_384 pd; + sp_point_384 qd; +#endif + sp_digit* tmp; + sp_point_384* p; + sp_point_384* q = NULL; + int err; + + err = sp_384_point_new_12(NULL, pd, p); + if (err == MP_OKAY) { + err = sp_384_point_new_12(NULL, qd, q); + } +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 12 * 5, NULL, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) { + err = MEMORY_E; + } + } +#else + tmp = tmpd; +#endif + + if (err == MP_OKAY) { + sp_384_from_mp(p->x, 12, pX); + sp_384_from_mp(p->y, 12, pY); + sp_384_from_mp(p->z, 12, pZ); + sp_384_from_mp(q->x, 12, qX); + sp_384_from_mp(q->y, 12, qY); + sp_384_from_mp(q->z, 12, qZ); + + sp_384_proj_point_add_12(p, p, q, tmp); + } + + if (err == MP_OKAY) { + err = sp_384_to_mp(p->x, rX); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->y, rY); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->z, rZ); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (tmp != NULL) { + XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_12(q, 0, NULL); + sp_384_point_free_12(p, 0, NULL); + + return err; +} + +/* Double a projective EC point. + * (pX, pY, pZ) + (pX, pY, pZ) = (rX, rY, rZ) + * + * pX EC point's X ordinate. + * pY EC point's Y ordinate. + * pZ EC point's Z ordinate. + * rX Resultant EC point's X ordinate. + * rY Resultant EC point's Y ordinate. + * rZ Resultant EC point's Z ordinate. + * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise. + */ +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) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_digit tmpd[2 * 12 * 2]; + sp_point_384 pd; +#endif + sp_digit* tmp; + sp_point_384* p; + int err; + + err = sp_384_point_new_12(NULL, pd, p); +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 12 * 2, NULL, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) { + err = MEMORY_E; + } + } +#else + tmp = tmpd; +#endif + + if (err == MP_OKAY) { + sp_384_from_mp(p->x, 12, pX); + sp_384_from_mp(p->y, 12, pY); + sp_384_from_mp(p->z, 12, pZ); + + sp_384_proj_point_dbl_12(p, p, tmp); + } + + if (err == MP_OKAY) { + err = sp_384_to_mp(p->x, rX); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->y, rY); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->z, rZ); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (tmp != NULL) { + XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_12(p, 0, NULL); + + return err; +} + +/* Map a projective EC point to affine in place. + * pZ will be one. + * + * pX EC point's X ordinate. + * pY EC point's Y ordinate. + * pZ EC point's Z ordinate. + * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise. + */ +int sp_ecc_map_384(mp_int* pX, mp_int* pY, mp_int* pZ) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_digit tmpd[2 * 12 * 6]; + sp_point_384 pd; +#endif + sp_digit* tmp; + sp_point_384* p; + int err; + + err = sp_384_point_new_12(NULL, pd, p); +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 12 * 6, NULL, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) { + err = MEMORY_E; + } + } +#else + tmp = tmpd; +#endif + if (err == MP_OKAY) { + sp_384_from_mp(p->x, 12, pX); + sp_384_from_mp(p->y, 12, pY); + sp_384_from_mp(p->z, 12, pZ); + + sp_384_map_12(p, p, tmp); + } + + if (err == MP_OKAY) { + err = sp_384_to_mp(p->x, pX); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->y, pY); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->z, pZ); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (tmp != NULL) { + XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_12(p, 0, NULL); + + return err; +} +#endif /* WOLFSSL_PUBLIC_ECC_ADD_DBL */ +#ifdef HAVE_COMP_KEY +/* Find the square root of a number mod the prime of the curve. + * + * y The number to operate on and the result. + * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise. + */ +static int sp_384_mont_sqrt_12(sp_digit* y) +{ +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_digit* d; +#else + sp_digit t1d[2 * 12]; + sp_digit t2d[2 * 12]; + sp_digit t3d[2 * 12]; + sp_digit t4d[2 * 12]; + sp_digit t5d[2 * 12]; +#endif + sp_digit* t1; + sp_digit* t2; + sp_digit* t3; + sp_digit* t4; + sp_digit* t5; + int err = MP_OKAY; + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 5 * 2 * 12, NULL, DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + t1 = d + 0 * 12; + t2 = d + 2 * 12; + t3 = d + 4 * 12; + t4 = d + 6 * 12; + t5 = d + 8 * 12; +#else + t1 = t1d; + t2 = t2d; + t3 = t3d; + t4 = t4d; + t5 = t5d; +#endif + + { + /* t2 = y ^ 0x2 */ + sp_384_mont_sqr_12(t2, y, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x3 */ + sp_384_mont_mul_12(t1, t2, y, p384_mod, p384_mp_mod); + /* t5 = y ^ 0xc */ + sp_384_mont_sqr_n_12(t5, t1, 2, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xf */ + sp_384_mont_mul_12(t1, t1, t5, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x1e */ + sp_384_mont_sqr_12(t2, t1, p384_mod, p384_mp_mod); + /* t3 = y ^ 0x1f */ + sp_384_mont_mul_12(t3, t2, y, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3e0 */ + sp_384_mont_sqr_n_12(t2, t3, 5, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x3ff */ + sp_384_mont_mul_12(t1, t3, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x7fe0 */ + sp_384_mont_sqr_n_12(t2, t1, 5, p384_mod, p384_mp_mod); + /* t3 = y ^ 0x7fff */ + sp_384_mont_mul_12(t3, t3, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3fff800 */ + sp_384_mont_sqr_n_12(t2, t3, 15, p384_mod, p384_mp_mod); + /* t4 = y ^ 0x3ffffff */ + sp_384_mont_mul_12(t4, t3, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0xffffffc000000 */ + sp_384_mont_sqr_n_12(t2, t4, 30, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xfffffffffffff */ + sp_384_mont_mul_12(t1, t4, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0xfffffffffffffff000000000000000 */ + sp_384_mont_sqr_n_12(t2, t1, 60, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xffffffffffffffffffffffffffffff */ + sp_384_mont_mul_12(t1, t1, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0xffffffffffffffffffffffffffffff000000000000000000000000000000 */ + sp_384_mont_sqr_n_12(t2, t1, 120, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */ + sp_384_mont_mul_12(t1, t1, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000 */ + sp_384_mont_sqr_n_12(t2, t1, 15, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */ + sp_384_mont_mul_12(t1, t3, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000 */ + sp_384_mont_sqr_n_12(t2, t1, 31, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffff */ + sp_384_mont_mul_12(t1, t4, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffff0 */ + sp_384_mont_sqr_n_12(t2, t1, 4, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffc */ + sp_384_mont_mul_12(t1, t5, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000 */ + sp_384_mont_sqr_n_12(t2, t1, 62, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000001 */ + sp_384_mont_mul_12(t1, y, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffc00000000000000040000000 */ + sp_384_mont_sqr_n_12(y, t1, 30, p384_mod, p384_mp_mod); + } + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (d != NULL) { + XFREE(d, NULL, DYNAMIC_TYPE_ECC); + } +#endif + + return err; +} + + +/* Uncompress the point given the X ordinate. + * + * xm X ordinate. + * odd Whether the Y ordinate is odd. + * ym Calculated Y ordinate. + * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise. + */ +int sp_ecc_uncompress_384(mp_int* xm, int odd, mp_int* ym) +{ +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_digit* d; +#else + sp_digit xd[2 * 12]; + sp_digit yd[2 * 12]; +#endif + sp_digit* x = NULL; + sp_digit* y = NULL; + int err = MP_OKAY; + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4 * 12, NULL, DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + x = d + 0 * 12; + y = d + 2 * 12; +#else + x = xd; + y = yd; +#endif + + sp_384_from_mp(x, 12, xm); + err = sp_384_mod_mul_norm_12(x, x, p384_mod); + } + if (err == MP_OKAY) { + /* y = x^3 */ + { + sp_384_mont_sqr_12(y, x, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(y, y, x, p384_mod, p384_mp_mod); + } + /* y = x^3 - 3x */ + sp_384_mont_sub_12(y, y, x, p384_mod); + sp_384_mont_sub_12(y, y, x, p384_mod); + sp_384_mont_sub_12(y, y, x, p384_mod); + /* y = x^3 - 3x + b */ + err = sp_384_mod_mul_norm_12(x, p384_b, p384_mod); + } + if (err == MP_OKAY) { + sp_384_mont_add_12(y, y, x, p384_mod); + /* y = sqrt(x^3 - 3x + b) */ + err = sp_384_mont_sqrt_12(y); + } + if (err == MP_OKAY) { + XMEMSET(y + 12, 0, 12U * sizeof(sp_digit)); + sp_384_mont_reduce_12(y, p384_mod, p384_mp_mod); + if ((((word32)y[0] ^ (word32)odd) & 1U) != 0U) { + sp_384_mont_sub_12(y, p384_mod, y, p384_mod); + } + + err = sp_384_to_mp(y, ym); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (d != NULL) { + XFREE(d, NULL, DYNAMIC_TYPE_ECC); + } +#endif + + return err; +} +#endif +#endif /* WOLFSSL_SP_384 */ #endif /* WOLFSSL_HAVE_SP_ECC */ #endif /* WOLFSSL_SP_ARM_THUMB_ASM */ #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 956ec5362..d86d5a0b1 100644 --- a/wolfcrypt/src/sp_c32.c +++ b/wolfcrypt/src/sp_c32.c @@ -1896,7 +1896,7 @@ static int sp_2048_mod_exp_45(sp_digit* r, const sp_digit* a, const sp_digit* e, #ifdef WOLFSSL_SP_SMALL sp_digit* td; sp_digit* t[3]; - sp_digit* norm = NULL; + sp_digit* norm; sp_digit mp = 1; sp_digit n; int i; @@ -2828,7 +2828,7 @@ static int sp_2048_mod_exp_90(sp_digit* r, const sp_digit* a, const sp_digit* e, #ifdef WOLFSSL_SP_SMALL sp_digit* td; sp_digit* t[3]; - sp_digit* norm = NULL; + sp_digit* norm; sp_digit mp = 1; sp_digit n; int i; @@ -3226,7 +3226,7 @@ int sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm, #else e[0] = (sp_digit)em->dp[0]; if (em->used > 1) { - e[0] |= ((sp_int_digit)em->dp[1]) << DIGIT_BIT; + e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT; } #endif if (e[0] == 0) { @@ -3327,7 +3327,7 @@ int sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm, #else e[0] = (sp_digit)em->dp[0]; if (em->used > 1) { - e[0] |= ((sp_int_digit)em->dp[1]) << DIGIT_BIT; + e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT; } #endif if (e[0] == 0) { @@ -3799,13 +3799,13 @@ 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 b[180], e[90], m[90]; + sp_digit bd[180], ed[90], md[90]; #else sp_digit* d = NULL; +#endif sp_digit* b; sp_digit* e; sp_digit* m; -#endif sp_digit* r; int err = MP_OKAY; int expBits = mp_count_bits(exp); @@ -3832,16 +3832,20 @@ int sp_ModExp_2048(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) if (d == NULL) err = MEMORY_E; } -#endif if (err == MP_OKAY) { -#ifdef WOLFSSL_SMALL_STACK b = d; e = b + 90 * 2; m = e + 90; -#endif r = b; + } +#else + r = b = bd; + e = ed; + m = md; +#endif + if (err == MP_OKAY) { sp_2048_from_mp(b, 90, base); sp_2048_from_mp(e, 90, exp); sp_2048_from_mp(m, 90, mod); @@ -4077,13 +4081,13 @@ SP_NOINLINE static void sp_2048_lshift_90(sp_digit* r, sp_digit* a, byte n) static int sp_2048_mod_exp_2_90(sp_digit* r, const sp_digit* e, int bits, const sp_digit* m) { #ifndef WOLFSSL_SMALL_STACK - sp_digit norm[180]; - sp_digit tmp[91]; + sp_digit nd[180]; + sp_digit td[91]; #else sp_digit* td; +#endif sp_digit* norm; sp_digit* tmp; -#endif sp_digit mp = 1; sp_digit n, o; int i; @@ -4102,6 +4106,11 @@ static int sp_2048_mod_exp_2_90(sp_digit* r, const sp_digit* e, int bits, const #ifdef WOLFSSL_SMALL_STACK norm = td; tmp = td + 180; + XMEMSET(td, 0, sizeof(sp_digit) * 271); +#else + norm = nd; + tmp = td; + XMEMSET(td, 0, sizeof(td)); #endif sp_2048_mont_setup(m, &mp); @@ -4407,13 +4416,13 @@ 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 b[90], e[45], m[45]; + sp_digit bd[90], ed[45], md[45]; #else sp_digit* d = NULL; +#endif sp_digit* b; sp_digit* e; sp_digit* m; -#endif sp_digit* r; int err = MP_OKAY; int expBits = mp_count_bits(exp); @@ -4440,16 +4449,20 @@ int sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) if (d == NULL) err = MEMORY_E; } -#endif if (err == MP_OKAY) { -#ifdef WOLFSSL_SMALL_STACK b = d; e = b + 45 * 2; m = e + 45; -#endif r = b; + } +#else + r = b = bd; + e = ed; + m = md; +#endif + if (err == MP_OKAY) { sp_2048_from_mp(b, 45, base); sp_2048_from_mp(e, 45, exp); sp_2048_from_mp(m, 45, mod); @@ -5720,7 +5733,7 @@ static int sp_3072_mod_exp_67(sp_digit* r, const sp_digit* a, const sp_digit* e, #ifdef WOLFSSL_SP_SMALL sp_digit* td; sp_digit* t[3]; - sp_digit* norm = NULL; + sp_digit* norm; sp_digit mp = 1; sp_digit n; int i; @@ -6688,7 +6701,7 @@ static int sp_3072_mod_exp_134(sp_digit* r, const sp_digit* a, const sp_digit* e #ifdef WOLFSSL_SP_SMALL sp_digit* td; sp_digit* t[3]; - sp_digit* norm = NULL; + sp_digit* norm; sp_digit mp = 1; sp_digit n; int i; @@ -7084,7 +7097,7 @@ int sp_RsaPublic_3072(const byte* in, word32 inLen, mp_int* em, mp_int* mm, #else e[0] = (sp_digit)em->dp[0]; if (em->used > 1) { - e[0] |= ((sp_int_digit)em->dp[1]) << DIGIT_BIT; + e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT; } #endif if (e[0] == 0) { @@ -7185,7 +7198,7 @@ int sp_RsaPublic_3072(const byte* in, word32 inLen, mp_int* em, mp_int* mm, #else e[0] = (sp_digit)em->dp[0]; if (em->used > 1) { - e[0] |= ((sp_int_digit)em->dp[1]) << DIGIT_BIT; + e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT; } #endif if (e[0] == 0) { @@ -7657,13 +7670,13 @@ 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 b[268], e[134], m[134]; + sp_digit bd[268], ed[134], md[134]; #else sp_digit* d = NULL; +#endif sp_digit* b; sp_digit* e; sp_digit* m; -#endif sp_digit* r; int err = MP_OKAY; int expBits = mp_count_bits(exp); @@ -7690,16 +7703,20 @@ int sp_ModExp_3072(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) if (d == NULL) err = MEMORY_E; } -#endif if (err == MP_OKAY) { -#ifdef WOLFSSL_SMALL_STACK b = d; e = b + 134 * 2; m = e + 134; -#endif r = b; + } +#else + r = b = bd; + e = ed; + m = md; +#endif + if (err == MP_OKAY) { sp_3072_from_mp(b, 134, base); sp_3072_from_mp(e, 134, exp); sp_3072_from_mp(m, 134, mod); @@ -8023,13 +8040,13 @@ SP_NOINLINE static void sp_3072_lshift_134(sp_digit* r, sp_digit* a, byte n) static int sp_3072_mod_exp_2_134(sp_digit* r, const sp_digit* e, int bits, const sp_digit* m) { #ifndef WOLFSSL_SMALL_STACK - sp_digit norm[268]; - sp_digit tmp[135]; + sp_digit nd[268]; + sp_digit td[135]; #else sp_digit* td; +#endif sp_digit* norm; sp_digit* tmp; -#endif sp_digit mp = 1; sp_digit n, o; int i; @@ -8048,6 +8065,11 @@ static int sp_3072_mod_exp_2_134(sp_digit* r, const sp_digit* e, int bits, const #ifdef WOLFSSL_SMALL_STACK norm = td; tmp = td + 268; + XMEMSET(td, 0, sizeof(sp_digit) * 403); +#else + norm = nd; + tmp = td; + XMEMSET(td, 0, sizeof(td)); #endif sp_3072_mont_setup(m, &mp); @@ -8353,13 +8375,13 @@ 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 b[134], e[67], m[67]; + sp_digit bd[134], ed[67], md[67]; #else sp_digit* d = NULL; +#endif sp_digit* b; sp_digit* e; sp_digit* m; -#endif sp_digit* r; int err = MP_OKAY; int expBits = mp_count_bits(exp); @@ -8386,16 +8408,20 @@ int sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) if (d == NULL) err = MEMORY_E; } -#endif if (err == MP_OKAY) { -#ifdef WOLFSSL_SMALL_STACK b = d; e = b + 67 * 2; m = e + 67; -#endif r = b; + } +#else + r = b = bd; + e = ed; + m = md; +#endif + if (err == MP_OKAY) { sp_3072_from_mp(b, 67, base); sp_3072_from_mp(e, 67, exp); sp_3072_from_mp(m, 67, mod); @@ -8971,6 +8997,7 @@ SP_NOINLINE static void sp_4096_sqr_196(sp_digit* r, const sp_digit* a) #endif /* WOLFSSL_SP_SMALL */ #if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) +#if defined(WOLFSSL_HAVE_SP_RSA) && !defined(SP_RSA_PRIVATE_EXP_D) #ifdef WOLFSSL_SP_SMALL /* Add b to a into r. (r = a + b) * @@ -9082,6 +9109,7 @@ 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 */ /* Caclulate the bottom digit of -1/a mod 2^n. @@ -9159,6 +9187,7 @@ SP_NOINLINE static void sp_4096_mul_d_196(sp_digit* r, const sp_digit* a, } #if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) +#if defined(WOLFSSL_HAVE_SP_RSA) && !defined(SP_RSA_PRIVATE_EXP_D) /* 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. * @@ -9762,7 +9791,7 @@ static int sp_4096_mod_exp_98(sp_digit* r, const sp_digit* a, const sp_digit* e, #ifdef WOLFSSL_SP_SMALL sp_digit* td; sp_digit* t[3]; - sp_digit* norm = NULL; + sp_digit* norm; sp_digit mp = 1; sp_digit n; int i; @@ -10058,6 +10087,7 @@ 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 */ /* r = 2^n mod m where n is the number of bits to reduce by. @@ -10706,7 +10736,7 @@ static int sp_4096_mod_exp_196(sp_digit* r, const sp_digit* a, const sp_digit* e #ifdef WOLFSSL_SP_SMALL sp_digit* td; sp_digit* t[3]; - sp_digit* norm = NULL; + sp_digit* norm; sp_digit mp = 1; sp_digit n; int i; @@ -11101,7 +11131,7 @@ int sp_RsaPublic_4096(const byte* in, word32 inLen, mp_int* em, mp_int* mm, #else e[0] = (sp_digit)em->dp[0]; if (em->used > 1) { - e[0] |= ((sp_int_digit)em->dp[1]) << DIGIT_BIT; + e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT; } #endif if (e[0] == 0) { @@ -11202,7 +11232,7 @@ int sp_RsaPublic_4096(const byte* in, word32 inLen, mp_int* em, mp_int* mm, #else e[0] = (sp_digit)em->dp[0]; if (em->used > 1) { - e[0] |= ((sp_int_digit)em->dp[1]) << DIGIT_BIT; + e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT; } #endif if (e[0] == 0) { @@ -11674,13 +11704,13 @@ 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 b[392], e[196], m[196]; + sp_digit bd[392], ed[196], md[196]; #else sp_digit* d = NULL; +#endif sp_digit* b; sp_digit* e; sp_digit* m; -#endif sp_digit* r; int err = MP_OKAY; int expBits = mp_count_bits(exp); @@ -11707,16 +11737,20 @@ int sp_ModExp_4096(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) if (d == NULL) err = MEMORY_E; } -#endif if (err == MP_OKAY) { -#ifdef WOLFSSL_SMALL_STACK b = d; e = b + 196 * 2; m = e + 196; -#endif r = b; + } +#else + r = b = bd; + e = ed; + m = md; +#endif + if (err == MP_OKAY) { sp_4096_from_mp(b, 196, base); sp_4096_from_mp(e, 196, exp); sp_4096_from_mp(m, 196, mod); @@ -12164,13 +12198,13 @@ SP_NOINLINE static void sp_4096_lshift_196(sp_digit* r, sp_digit* a, byte n) static int sp_4096_mod_exp_2_196(sp_digit* r, const sp_digit* e, int bits, const sp_digit* m) { #ifndef WOLFSSL_SMALL_STACK - sp_digit norm[392]; - sp_digit tmp[197]; + sp_digit nd[392]; + sp_digit td[197]; #else sp_digit* td; +#endif sp_digit* norm; sp_digit* tmp; -#endif sp_digit mp = 1; sp_digit n, o; int i; @@ -12189,6 +12223,11 @@ static int sp_4096_mod_exp_2_196(sp_digit* r, const sp_digit* e, int bits, const #ifdef WOLFSSL_SMALL_STACK norm = td; tmp = td + 392; + XMEMSET(td, 0, sizeof(sp_digit) * 589); +#else + norm = nd; + tmp = td; + XMEMSET(td, 0, sizeof(td)); #endif sp_4096_mont_setup(m, &mp); @@ -12435,12 +12474,12 @@ int sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen, #ifndef WOLFSSL_SP_NO_256 /* Point structure to use. */ -typedef struct sp_point { +typedef struct sp_point_256 { sp_digit x[2 * 10]; sp_digit y[2 * 10]; sp_digit z[2 * 10]; int infinity; -} sp_point; +} sp_point_256; /* The modulus (prime) of the curve P256. */ static const sp_digit p256_mod[10] = { @@ -12479,21 +12518,24 @@ static const sp_digit p256_norm_order[10] = { static const sp_digit p256_mp_order = 0x200bc4f; #endif /* The base point of curve P256. */ -static const sp_point p256_base = { +static const sp_point_256 p256_base = { /* X ordinate */ { 0x098c296,0x04e5176,0x33a0f4a,0x204b7ac,0x277037d,0x0e9103c,0x3ce6e56, - 0x1091fe2,0x1f2e12c,0x01ac5f4, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + 0x1091fe2,0x1f2e12c,0x01ac5f4, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L }, /* Y ordinate */ { 0x3bf51f5,0x1901a0d,0x1ececbb,0x15dacc5,0x22bce33,0x303e785,0x27eb4a7, - 0x1fe6e3b,0x2e2fe1a,0x013f8d0, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + 0x1fe6e3b,0x2e2fe1a,0x013f8d0, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L }, /* Z ordinate */ { 0x0000001,0x0000000,0x0000000,0x0000000,0x0000000,0x0000000,0x0000000, - 0x0000000,0x0000000,0x0000000, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + 0x0000000,0x0000000,0x0000000, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L }, /* infinity */ 0 @@ -12505,34 +12547,32 @@ static const sp_digit p256_b[10] = { }; #endif -static int sp_ecc_point_new_ex(void* heap, sp_point* sp, sp_point** p) +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) + (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; } - else { - #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - *p = (sp_point*)XMALLOC(sizeof(sp_point), heap, DYNAMIC_TYPE_ECC); - (void)sp; - #else - *p = sp; - (void)heap; - #endif - } return ret; } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) /* Allocate memory for point and return error. */ -#define sp_ecc_point_new(heap, sp, p) sp_ecc_point_new_ex((heap), NULL, &(p)) +#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_ecc_point_new(heap, sp, p) sp_ecc_point_new_ex((heap), &(sp), &(p)) +#define sp_256_point_new_10(heap, sp, p) sp_256_point_new_ex_10((heap), &(sp), &(p)) #endif -static void sp_ecc_point_free(sp_point* p, int clear, void* heap) +static void sp_256_point_free_10(sp_point_256* p, int clear, void* heap) { #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) /* If valid pointer then clear point data if requested and free data. */ @@ -12576,7 +12616,7 @@ static int sp_256_mod_mul_norm_10(sp_digit* r, const sp_digit* a, const sp_digit #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) td = (int64_t*)XMALLOC(sizeof(int64_t) * 2 * 8, NULL, DYNAMIC_TYPE_ECC); if (td == NULL) { - err = MEMORY_E; + return MEMORY_E; } #endif @@ -12589,91 +12629,91 @@ static int sp_256_mod_mul_norm_10(sp_digit* r, const sp_digit* a, const sp_digit a32 = a32d; #endif - a32[0] = (sp_int_digit)a[0]; - a32[0] |= (sp_int_digit)a[1] << 26U; + a32[0] = a[0]; + a32[0] |= a[1] << 26U; a32[0] &= 0xffffffffL; a32[1] = (sp_digit)(a[1] >> 6); - a32[1] |= (sp_int_digit)a[2] << 20U; + a32[1] |= a[2] << 20U; a32[1] &= 0xffffffffL; a32[2] = (sp_digit)(a[2] >> 12); - a32[2] |= (sp_int_digit)a[3] << 14U; + a32[2] |= a[3] << 14U; a32[2] &= 0xffffffffL; a32[3] = (sp_digit)(a[3] >> 18); - a32[3] |= (sp_int_digit)a[4] << 8U; + a32[3] |= a[4] << 8U; a32[3] &= 0xffffffffL; a32[4] = (sp_digit)(a[4] >> 24); - a32[4] |= (sp_int_digit)a[5] << 2U; - a32[4] |= (sp_int_digit)a[6] << 28U; + a32[4] |= a[5] << 2U; + a32[4] |= a[6] << 28U; a32[4] &= 0xffffffffL; a32[5] = (sp_digit)(a[6] >> 4); - a32[5] |= (sp_int_digit)a[7] << 22U; + a32[5] |= a[7] << 22U; a32[5] &= 0xffffffffL; a32[6] = (sp_digit)(a[7] >> 10); - a32[6] |= (sp_int_digit)a[8] << 16U; + a32[6] |= a[8] << 16U; a32[6] &= 0xffffffffL; a32[7] = (sp_digit)(a[8] >> 16); - a32[7] |= (sp_int_digit)a[9] << 10U; + 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]; + 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]; + 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]; + 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]; + 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]; + 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]; + 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]; + 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[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; + 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_int_digit)t[1] << 6U; + r[1] |= t[1] << 6U; r[1] &= 0x3ffffffL; r[2] = (sp_digit)(t[1] >> 20U); - r[2] |= (sp_int_digit)t[2] << 12U; + r[2] |= t[2] << 12U; r[2] &= 0x3ffffffL; r[3] = (sp_digit)(t[2] >> 14U); - r[3] |= (sp_int_digit)t[3] << 18U; + r[3] |= t[3] << 18U; r[3] &= 0x3ffffffL; r[4] = (sp_digit)(t[3] >> 8U); - r[4] |= (sp_int_digit)t[4] << 24U; + r[4] |= t[4] << 24U; r[4] &= 0x3ffffffL; r[5] = (sp_digit)(t[4] >> 2U) & 0x3ffffffL; r[6] = (sp_digit)(t[4] >> 28U); - r[6] |= (sp_int_digit)t[5] << 4U; + r[6] |= t[5] << 4U; r[6] &= 0x3ffffffL; r[7] = (sp_digit)(t[5] >> 22U); - r[7] |= (sp_int_digit)t[6] << 10U; + r[7] |= t[6] << 10U; r[7] &= 0x3ffffffL; r[8] = (sp_digit)(t[6] >> 16U); - r[8] |= (sp_int_digit)t[7] << 16U; + r[8] |= t[7] << 16U; r[8] &= 0x3ffffffL; r[9] = (sp_digit)(t[7] >> 10U); } @@ -12769,12 +12809,12 @@ static void sp_256_from_mp(sp_digit* r, int size, const mp_int* a) #endif } -/* Convert a point of type ecc_point to type sp_point. +/* Convert a point of type ecc_point to type sp_point_256. * - * p Point of type sp_point (result). + * 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* p, const ecc_point* pm) +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)); @@ -12849,14 +12889,14 @@ static int sp_256_to_mp(const sp_digit* a, mp_int* r) return err; } -/* Convert a point of type sp_point to type ecc_point. +/* Convert a point of type sp_point_256 to type ecc_point. * - * p Point of type sp_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* p, ecc_point* pm) +static int sp_256_point_to_ecc_point_10(const sp_point_256* p, ecc_point* pm) { int err; @@ -12871,232 +12911,6 @@ static int sp_256_point_to_ecc_point_10(const sp_point* p, ecc_point* pm) 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_256_cmp_10(const sp_digit* a, const sp_digit* b) -{ - sp_digit r = 0; -#ifdef WOLFSSL_SP_SMALL - int i; - - for (i=9; i>=0; i--) { - r |= (a[i] - b[i]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); - } -#else - r |= (a[ 9] - b[ 9]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); - r |= (a[ 8] - b[ 8]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); - r |= (a[ 7] - b[ 7]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); - r |= (a[ 6] - b[ 6]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); - r |= (a[ 5] - b[ 5]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); - r |= (a[ 4] - b[ 4]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); - r |= (a[ 3] - b[ 3]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); - r |= (a[ 2] - b[ 2]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); - r |= (a[ 1] - b[ 1]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); - r |= (a[ 0] - b[ 0]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); -#endif /* WOLFSSL_SP_SMALL */ - - return r; -} - -/* Normalize the values in each word to 26. - * - * a Array of sp_digit to normalize. - */ -static void sp_256_norm_10(sp_digit* a) -{ -#ifdef WOLFSSL_SP_SMALL - int i; - for (i = 0; i < 9; i++) { - a[i+1] += a[i] >> 26; - a[i] &= 0x3ffffff; - } -#else - a[1] += a[0] >> 26; a[0] &= 0x3ffffff; - a[2] += a[1] >> 26; a[1] &= 0x3ffffff; - a[3] += a[2] >> 26; a[2] &= 0x3ffffff; - a[4] += a[3] >> 26; a[3] &= 0x3ffffff; - a[5] += a[4] >> 26; a[4] &= 0x3ffffff; - a[6] += a[5] >> 26; a[5] &= 0x3ffffff; - a[7] += a[6] >> 26; a[6] &= 0x3ffffff; - a[8] += a[7] >> 26; a[7] &= 0x3ffffff; - a[9] += a[8] >> 26; a[8] &= 0x3ffffff; -#endif -} - -/* 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_256_cond_sub_10(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 < 10; i++) { - r[i] = a[i] - (b[i] & m); - } -#else - r[ 0] = a[ 0] - (b[ 0] & m); - r[ 1] = a[ 1] - (b[ 1] & m); - r[ 2] = a[ 2] - (b[ 2] & m); - r[ 3] = a[ 3] - (b[ 3] & m); - r[ 4] = a[ 4] - (b[ 4] & m); - r[ 5] = a[ 5] - (b[ 5] & m); - r[ 6] = a[ 6] - (b[ 6] & m); - r[ 7] = a[ 7] - (b[ 7] & m); - r[ 8] = a[ 8] - (b[ 8] & m); - r[ 9] = a[ 9] - (b[ 9] & m); -#endif /* WOLFSSL_SP_SMALL */ -} - -#define sp_256_mont_reduce_order_10 sp_256_mont_reduce_10 - -/* 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_256_mul_add_10(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 < 10; i++) { - t += (tb * a[i]) + r[i]; - r[i] = t & 0x3ffffff; - t >>= 26; - } - r[10] += t; -#else - int64_t tb = b; - int64_t t[10]; - - t[ 0] = tb * a[ 0]; - t[ 1] = tb * a[ 1]; - t[ 2] = tb * a[ 2]; - t[ 3] = tb * a[ 3]; - t[ 4] = tb * a[ 4]; - t[ 5] = tb * a[ 5]; - t[ 6] = tb * a[ 6]; - t[ 7] = tb * a[ 7]; - t[ 8] = tb * a[ 8]; - t[ 9] = tb * a[ 9]; - r[ 0] += (sp_digit)(t[ 0] & 0x3ffffff); - r[ 1] += (sp_digit)((t[ 0] >> 26) + (t[ 1] & 0x3ffffff)); - r[ 2] += (sp_digit)((t[ 1] >> 26) + (t[ 2] & 0x3ffffff)); - r[ 3] += (sp_digit)((t[ 2] >> 26) + (t[ 3] & 0x3ffffff)); - r[ 4] += (sp_digit)((t[ 3] >> 26) + (t[ 4] & 0x3ffffff)); - r[ 5] += (sp_digit)((t[ 4] >> 26) + (t[ 5] & 0x3ffffff)); - r[ 6] += (sp_digit)((t[ 5] >> 26) + (t[ 6] & 0x3ffffff)); - r[ 7] += (sp_digit)((t[ 6] >> 26) + (t[ 7] & 0x3ffffff)); - r[ 8] += (sp_digit)((t[ 7] >> 26) + (t[ 8] & 0x3ffffff)); - r[ 9] += (sp_digit)((t[ 8] >> 26) + (t[ 9] & 0x3ffffff)); - r[10] += t[ 9] >> 26; -#endif /* WOLFSSL_SP_SMALL */ -} - -/* Shift the result in the high 256 bits down to the bottom. - * - * r A single precision number. - * a A single precision number. - */ -static void sp_256_mont_shift_10(sp_digit* r, const sp_digit* a) -{ -#ifdef WOLFSSL_SP_SMALL - int i; - sp_digit n, s; - - s = a[10]; - n = a[9] >> 22; - for (i = 0; i < 9; i++) { - n += (s & 0x3ffffff) << 4; - r[i] = n & 0x3ffffff; - n >>= 26; - s = a[11 + i] + (s >> 26); - } - n += s << 4; - r[9] = n; -#else - sp_digit n, s; - - s = a[10]; n = a[9] >> 22; - n += (s & 0x3ffffff) << 4; r[ 0] = n & 0x3ffffff; - n >>= 26; s = a[11] + (s >> 26); - n += (s & 0x3ffffff) << 4; r[ 1] = n & 0x3ffffff; - n >>= 26; s = a[12] + (s >> 26); - n += (s & 0x3ffffff) << 4; r[ 2] = n & 0x3ffffff; - n >>= 26; s = a[13] + (s >> 26); - n += (s & 0x3ffffff) << 4; r[ 3] = n & 0x3ffffff; - n >>= 26; s = a[14] + (s >> 26); - n += (s & 0x3ffffff) << 4; r[ 4] = n & 0x3ffffff; - n >>= 26; s = a[15] + (s >> 26); - n += (s & 0x3ffffff) << 4; r[ 5] = n & 0x3ffffff; - n >>= 26; s = a[16] + (s >> 26); - n += (s & 0x3ffffff) << 4; r[ 6] = n & 0x3ffffff; - n >>= 26; s = a[17] + (s >> 26); - n += (s & 0x3ffffff) << 4; r[ 7] = n & 0x3ffffff; - n >>= 26; s = a[18] + (s >> 26); - n += (s & 0x3ffffff) << 4; r[ 8] = n & 0x3ffffff; - n >>= 26; s = a[19] + (s >> 26); - n += s << 4; r[ 9] = n; -#endif /* WOLFSSL_SP_SMALL */ - XMEMSET(&r[10], 0, sizeof(*r) * 10U); -} - -/* 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. - */ -static void sp_256_mont_reduce_10(sp_digit* a, const sp_digit* m, sp_digit mp) -{ - int i; - sp_digit mu; - - if (mp != 1) { - for (i=0; i<9; i++) { - mu = (a[i] * mp) & 0x3ffffff; - sp_256_mul_add_10(a+i, m, mu); - a[i+1] += a[i] >> 26; - } - mu = (a[i] * mp) & 0x3fffffL; - sp_256_mul_add_10(a+i, m, mu); - a[i+1] += a[i] >> 26; - a[i] &= 0x3ffffff; - } - else { - for (i=0; i<9; i++) { - mu = a[i] & 0x3ffffff; - sp_256_mul_add_10(a+i, p256_mod, mu); - a[i+1] += a[i] >> 26; - } - mu = a[i] & 0x3fffffL; - sp_256_mul_add_10(a+i, p256_mod, mu); - a[i+1] += a[i] >> 26; - a[i] &= 0x3ffffff; - } - - sp_256_mont_shift_10(a, a); - sp_256_cond_sub_10(a, a, m, 0 - (((a[9] >> 22) > 0) ? - (sp_digit)1 : (sp_digit)0)); - sp_256_norm_10(a); -} - #ifdef WOLFSSL_SP_SMALL /* Multiply a and b into r. (r = a * b) * @@ -13266,6 +13080,232 @@ SP_NOINLINE static void sp_256_mul_10(sp_digit* r, const sp_digit* a, } #endif /* WOLFSSL_SP_SMALL */ +#define sp_256_mont_reduce_order_10 sp_256_mont_reduce_10 + +/* 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_256_cmp_10(const sp_digit* a, const sp_digit* b) +{ + sp_digit r = 0; +#ifdef WOLFSSL_SP_SMALL + int i; + + for (i=9; i>=0; i--) { + r |= (a[i] - b[i]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + } +#else + r |= (a[ 9] - b[ 9]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[ 8] - b[ 8]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[ 7] - b[ 7]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[ 6] - b[ 6]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[ 5] - b[ 5]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[ 4] - b[ 4]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[ 3] - b[ 3]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[ 2] - b[ 2]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[ 1] - b[ 1]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[ 0] - b[ 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_256_cond_sub_10(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 < 10; i++) { + r[i] = a[i] - (b[i] & m); + } +#else + r[ 0] = a[ 0] - (b[ 0] & m); + r[ 1] = a[ 1] - (b[ 1] & m); + r[ 2] = a[ 2] - (b[ 2] & m); + r[ 3] = a[ 3] - (b[ 3] & m); + r[ 4] = a[ 4] - (b[ 4] & m); + r[ 5] = a[ 5] - (b[ 5] & m); + r[ 6] = a[ 6] - (b[ 6] & m); + r[ 7] = a[ 7] - (b[ 7] & m); + r[ 8] = a[ 8] - (b[ 8] & m); + r[ 9] = a[ 9] - (b[ 9] & 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_256_mul_add_10(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 < 10; i++) { + t += (tb * a[i]) + r[i]; + r[i] = t & 0x3ffffff; + t >>= 26; + } + r[10] += t; +#else + int64_t tb = b; + int64_t t[10]; + + t[ 0] = tb * a[ 0]; + t[ 1] = tb * a[ 1]; + t[ 2] = tb * a[ 2]; + t[ 3] = tb * a[ 3]; + t[ 4] = tb * a[ 4]; + t[ 5] = tb * a[ 5]; + t[ 6] = tb * a[ 6]; + t[ 7] = tb * a[ 7]; + t[ 8] = tb * a[ 8]; + t[ 9] = tb * a[ 9]; + r[ 0] += (sp_digit)(t[ 0] & 0x3ffffff); + r[ 1] += (sp_digit)((t[ 0] >> 26) + (t[ 1] & 0x3ffffff)); + r[ 2] += (sp_digit)((t[ 1] >> 26) + (t[ 2] & 0x3ffffff)); + r[ 3] += (sp_digit)((t[ 2] >> 26) + (t[ 3] & 0x3ffffff)); + r[ 4] += (sp_digit)((t[ 3] >> 26) + (t[ 4] & 0x3ffffff)); + r[ 5] += (sp_digit)((t[ 4] >> 26) + (t[ 5] & 0x3ffffff)); + r[ 6] += (sp_digit)((t[ 5] >> 26) + (t[ 6] & 0x3ffffff)); + r[ 7] += (sp_digit)((t[ 6] >> 26) + (t[ 7] & 0x3ffffff)); + r[ 8] += (sp_digit)((t[ 7] >> 26) + (t[ 8] & 0x3ffffff)); + r[ 9] += (sp_digit)((t[ 8] >> 26) + (t[ 9] & 0x3ffffff)); + r[10] += t[ 9] >> 26; +#endif /* WOLFSSL_SP_SMALL */ +} + +/* Normalize the values in each word to 26. + * + * a Array of sp_digit to normalize. + */ +static void sp_256_norm_10(sp_digit* a) +{ +#ifdef WOLFSSL_SP_SMALL + int i; + for (i = 0; i < 9; i++) { + a[i+1] += a[i] >> 26; + a[i] &= 0x3ffffff; + } +#else + a[1] += a[0] >> 26; a[0] &= 0x3ffffff; + a[2] += a[1] >> 26; a[1] &= 0x3ffffff; + a[3] += a[2] >> 26; a[2] &= 0x3ffffff; + a[4] += a[3] >> 26; a[3] &= 0x3ffffff; + a[5] += a[4] >> 26; a[4] &= 0x3ffffff; + a[6] += a[5] >> 26; a[5] &= 0x3ffffff; + a[7] += a[6] >> 26; a[6] &= 0x3ffffff; + a[8] += a[7] >> 26; a[7] &= 0x3ffffff; + a[9] += a[8] >> 26; a[8] &= 0x3ffffff; +#endif +} + +/* Shift the result in the high 256 bits down to the bottom. + * + * r A single precision number. + * a A single precision number. + */ +static void sp_256_mont_shift_10(sp_digit* r, const sp_digit* a) +{ +#ifdef WOLFSSL_SP_SMALL + int i; + sp_digit n, s; + + s = a[10]; + n = a[9] >> 22; + for (i = 0; i < 9; i++) { + n += (s & 0x3ffffff) << 4; + r[i] = n & 0x3ffffff; + n >>= 26; + s = a[11 + i] + (s >> 26); + } + n += s << 4; + r[9] = n; +#else + sp_digit n, s; + + s = a[10]; n = a[9] >> 22; + n += (s & 0x3ffffff) << 4; r[ 0] = n & 0x3ffffff; + n >>= 26; s = a[11] + (s >> 26); + n += (s & 0x3ffffff) << 4; r[ 1] = n & 0x3ffffff; + n >>= 26; s = a[12] + (s >> 26); + n += (s & 0x3ffffff) << 4; r[ 2] = n & 0x3ffffff; + n >>= 26; s = a[13] + (s >> 26); + n += (s & 0x3ffffff) << 4; r[ 3] = n & 0x3ffffff; + n >>= 26; s = a[14] + (s >> 26); + n += (s & 0x3ffffff) << 4; r[ 4] = n & 0x3ffffff; + n >>= 26; s = a[15] + (s >> 26); + n += (s & 0x3ffffff) << 4; r[ 5] = n & 0x3ffffff; + n >>= 26; s = a[16] + (s >> 26); + n += (s & 0x3ffffff) << 4; r[ 6] = n & 0x3ffffff; + n >>= 26; s = a[17] + (s >> 26); + n += (s & 0x3ffffff) << 4; r[ 7] = n & 0x3ffffff; + n >>= 26; s = a[18] + (s >> 26); + n += (s & 0x3ffffff) << 4; r[ 8] = n & 0x3ffffff; + n >>= 26; s = a[19] + (s >> 26); + n += s << 4; r[ 9] = n; +#endif /* WOLFSSL_SP_SMALL */ + XMEMSET(&r[10], 0, sizeof(*r) * 10U); +} + +/* 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. + */ +static void sp_256_mont_reduce_10(sp_digit* a, const sp_digit* m, sp_digit mp) +{ + int i; + sp_digit mu; + + if (mp != 1) { + for (i=0; i<9; i++) { + mu = (a[i] * mp) & 0x3ffffff; + sp_256_mul_add_10(a+i, m, mu); + a[i+1] += a[i] >> 26; + } + mu = (a[i] * mp) & 0x3fffffL; + sp_256_mul_add_10(a+i, m, mu); + a[i+1] += a[i] >> 26; + a[i] &= 0x3ffffff; + } + else { + for (i=0; i<9; i++) { + mu = a[i] & 0x3ffffff; + sp_256_mul_add_10(a+i, p256_mod, mu); + a[i+1] += a[i] >> 26; + } + mu = a[i] & 0x3fffffL; + sp_256_mul_add_10(a+i, p256_mod, mu); + a[i+1] += a[i] >> 26; + a[i] &= 0x3ffffff; + } + + sp_256_mont_shift_10(a, a); + sp_256_cond_sub_10(a, a, m, 0 - (((a[9] >> 22) > 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_256_norm_10(a); +} + /* Multiply two Montogmery form numbers mod the modulus (prime). * (r = a * b mod m) * @@ -13441,7 +13481,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 */ #ifdef WOLFSSL_SP_SMALL /* Mod-2 for the P256 curve. */ -static const uint32_t p256_mod_2[8] = { +static const uint32_t p256_mod_minus_2[8] = { 0xfffffffdU,0xffffffffU,0xffffffffU,0x00000000U,0x00000000U,0x00000000U, 0x00000001U,0xffffffffU }; @@ -13463,61 +13503,56 @@ static void sp_256_mont_inv_10(sp_digit* r, const sp_digit* a, sp_digit* td) XMEMCPY(t, a, sizeof(sp_digit) * 10); for (i=254; i>=0; i--) { sp_256_mont_sqr_10(t, t, p256_mod, p256_mp_mod); - if (p256_mod_2[i / 32] & ((sp_digit)1 << (i % 32))) + if (p256_mod_minus_2[i / 32] & ((sp_digit)1 << (i % 32))) sp_256_mont_mul_10(t, t, a, p256_mod, p256_mp_mod); } XMEMCPY(r, t, sizeof(sp_digit) * 10); #else - sp_digit* t = td; + sp_digit* t1 = td; sp_digit* t2 = td + 2 * 10; sp_digit* t3 = td + 4 * 10; - - /* t = a^2 */ - sp_256_mont_sqr_10(t, a, p256_mod, p256_mp_mod); - /* t = a^3 = t * a */ - sp_256_mont_mul_10(t, t, a, p256_mod, p256_mp_mod); - /* t2= a^c = t ^ 2 ^ 2 */ - sp_256_mont_sqr_n_10(t2, t, 2, p256_mod, p256_mp_mod); - /* t3= a^d = t2 * a */ - sp_256_mont_mul_10(t3, t2, a, p256_mod, p256_mp_mod); - /* t = a^f = t2 * t */ - sp_256_mont_mul_10(t, t2, t, p256_mod, p256_mp_mod); - /* t2= a^f0 = t ^ 2 ^ 4 */ - sp_256_mont_sqr_n_10(t2, t, 4, p256_mod, p256_mp_mod); - /* t3= a^fd = t2 * t3 */ - sp_256_mont_mul_10(t3, t2, t3, p256_mod, p256_mp_mod); - /* t = a^ff = t2 * t */ - sp_256_mont_mul_10(t, t2, t, p256_mod, p256_mp_mod); - /* t2= a^ff00 = t ^ 2 ^ 8 */ - sp_256_mont_sqr_n_10(t2, t, 8, p256_mod, p256_mp_mod); - /* t3= a^fffd = t2 * t3 */ - sp_256_mont_mul_10(t3, t2, t3, p256_mod, p256_mp_mod); - /* t = a^ffff = t2 * t */ - sp_256_mont_mul_10(t, t2, t, p256_mod, p256_mp_mod); - /* t2= a^ffff0000 = t ^ 2 ^ 16 */ - sp_256_mont_sqr_n_10(t2, t, 16, p256_mod, p256_mp_mod); - /* t3= a^fffffffd = t2 * t3 */ - sp_256_mont_mul_10(t3, t2, t3, p256_mod, p256_mp_mod); - /* t = a^ffffffff = t2 * t */ - sp_256_mont_mul_10(t, t2, t, p256_mod, p256_mp_mod); - /* t = a^ffffffff00000000 = t ^ 2 ^ 32 */ - sp_256_mont_sqr_n_10(t2, t, 32, p256_mod, p256_mp_mod); - /* t2= a^ffffffffffffffff = t2 * t */ - sp_256_mont_mul_10(t, t2, t, p256_mod, p256_mp_mod); - /* t2= a^ffffffff00000001 = t2 * a */ - sp_256_mont_mul_10(t2, t2, a, p256_mod, p256_mp_mod); - /* t2= a^ffffffff000000010000000000000000000000000000000000000000 - * = t2 ^ 2 ^ 160 */ - sp_256_mont_sqr_n_10(t2, t2, 160, p256_mod, p256_mp_mod); - /* t2= a^ffffffff00000001000000000000000000000000ffffffffffffffff - * = t2 * t */ - sp_256_mont_mul_10(t2, t2, t, p256_mod, p256_mp_mod); - /* t2= a^ffffffff00000001000000000000000000000000ffffffffffffffff00000000 - * = t2 ^ 2 ^ 32 */ - sp_256_mont_sqr_n_10(t2, t2, 32, p256_mod, p256_mp_mod); - /* r = a^ffffffff00000001000000000000000000000000fffffffffffffffffffffffd - * = t2 * t3 */ - sp_256_mont_mul_10(r, t2, t3, p256_mod, p256_mp_mod); + /* 0x2 */ + sp_256_mont_sqr_10(t1, a, p256_mod, p256_mp_mod); + /* 0x3 */ + sp_256_mont_mul_10(t2, t1, a, p256_mod, p256_mp_mod); + /* 0xc */ + sp_256_mont_sqr_n_10(t1, t2, 2, p256_mod, p256_mp_mod); + /* 0xd */ + sp_256_mont_mul_10(t3, t1, a, p256_mod, p256_mp_mod); + /* 0xf */ + sp_256_mont_mul_10(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xf0 */ + sp_256_mont_sqr_n_10(t1, t2, 4, p256_mod, p256_mp_mod); + /* 0xfd */ + sp_256_mont_mul_10(t3, t3, t1, p256_mod, p256_mp_mod); + /* 0xff */ + sp_256_mont_mul_10(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xff00 */ + sp_256_mont_sqr_n_10(t1, t2, 8, p256_mod, p256_mp_mod); + /* 0xfffd */ + sp_256_mont_mul_10(t3, t3, t1, p256_mod, p256_mp_mod); + /* 0xffff */ + sp_256_mont_mul_10(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xffff0000 */ + sp_256_mont_sqr_n_10(t1, t2, 16, p256_mod, p256_mp_mod); + /* 0xfffffffd */ + sp_256_mont_mul_10(t3, t3, t1, p256_mod, p256_mp_mod); + /* 0xffffffff */ + sp_256_mont_mul_10(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xffffffff00000000 */ + sp_256_mont_sqr_n_10(t1, t2, 32, p256_mod, p256_mp_mod); + /* 0xffffffffffffffff */ + sp_256_mont_mul_10(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xffffffff00000001 */ + sp_256_mont_mul_10(r, t1, a, p256_mod, p256_mp_mod); + /* 0xffffffff000000010000000000000000000000000000000000000000 */ + sp_256_mont_sqr_n_10(r, r, 160, p256_mod, p256_mp_mod); + /* 0xffffffff00000001000000000000000000000000ffffffffffffffff */ + sp_256_mont_mul_10(r, r, t2, p256_mod, p256_mp_mod); + /* 0xffffffff00000001000000000000000000000000ffffffffffffffff00000000 */ + sp_256_mont_sqr_n_10(r, r, 32, p256_mod, p256_mp_mod); + /* 0xffffffff00000001000000000000000000000000fffffffffffffffffffffffd */ + sp_256_mont_mul_10(r, r, t3, p256_mod, p256_mp_mod); #endif /* WOLFSSL_SP_SMALL */ } @@ -13527,7 +13562,7 @@ 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* r, const sp_point* 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; @@ -13795,9 +13830,9 @@ static void sp_256_div2_10(sp_digit* r, const sp_digit* a, const sp_digit* m) * p Point to double. * t Temporary ordinate data. */ -static void sp_256_proj_point_dbl_10(sp_point* r, const sp_point* p, sp_digit* t) +static void sp_256_proj_point_dbl_10(sp_point_256* r, const sp_point_256* p, sp_digit* t) { - sp_point* rp[2]; + sp_point_256* rp[2]; sp_digit* t1 = t; sp_digit* t2 = t + 2*10; sp_digit* x; @@ -13809,8 +13844,8 @@ static void sp_256_proj_point_dbl_10(sp_point* r, const sp_point* p, sp_digit* t rp[0] = r; /*lint allow cast to different type of pointer*/ - rp[1] = (sp_point*)t; /*lint !e9087 !e740*/ - XMEMSET(rp[1], 0, sizeof(sp_point)); + rp[1] = (sp_point_256*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_256)); x = rp[p->infinity]->x; y = rp[p->infinity]->y; z = rp[p->infinity]->z; @@ -13888,11 +13923,11 @@ static int sp_256_cmp_equal_10(const sp_digit* a, const sp_digit* b) * q Second point to add. * t Temporary ordinate data. */ -static void sp_256_proj_point_add_10(sp_point* r, const sp_point* p, const sp_point* q, +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* ap[2]; - sp_point* rp[2]; + const sp_point_256* ap[2]; + sp_point_256* rp[2]; sp_digit* t1 = t; sp_digit* t2 = t + 2*10; sp_digit* t3 = t + 4*10; @@ -13905,7 +13940,7 @@ static void sp_256_proj_point_add_10(sp_point* r, const sp_point* p, const sp_po /* Ensure only the first point is the same as the result. */ if (q == r) { - const sp_point* a = p; + const sp_point_256* a = p; p = q; q = a; } @@ -13921,8 +13956,8 @@ static void sp_256_proj_point_add_10(sp_point* r, const sp_point* p, const sp_po rp[0] = r; /*lint allow cast to different type of pointer*/ - rp[1] = (sp_point*)t; /*lint !e9087 !e740*/ - XMEMSET(rp[1], 0, sizeof(sp_point)); + rp[1] = (sp_point_256*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_256)); x = rp[p->infinity | q->infinity]->x; y = rp[p->infinity | q->infinity]->y; z = rp[p->infinity | q->infinity]->z; @@ -13986,11 +14021,11 @@ static void sp_256_proj_point_add_10(sp_point* r, const sp_point* p, const sp_po * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_10(sp_point* r, const sp_point* g, const sp_digit* k, +static int sp_256_ecc_mulmod_10(sp_point_256* r, const sp_point_256* g, const sp_digit* k, int map, void* heap) { - sp_point* td; - sp_point* t[3]; + sp_point_256* td; + sp_point_256* t[3]; sp_digit* tmp; sp_digit n; int i; @@ -13999,7 +14034,7 @@ static int sp_256_ecc_mulmod_10(sp_point* r, const sp_point* g, const sp_digit* (void)heap; - td = (sp_point*)XMALLOC(sizeof(sp_point) * 3, heap, DYNAMIC_TYPE_ECC); + td = (sp_point_256*)XMALLOC(sizeof(sp_point_256) * 3, heap, DYNAMIC_TYPE_ECC); if (td == NULL) err = MEMORY_E; tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 10 * 5, heap, @@ -14044,18 +14079,18 @@ static int sp_256_ecc_mulmod_10(sp_point* r, const sp_point* g, const sp_digit* XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + ((size_t)t[1] & addr_mask[y])), - sizeof(sp_point)); + sizeof(sp_point_256)); sp_256_proj_point_dbl_10(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)); + sizeof(sp_point_256)); } if (map != 0) { sp_256_map_10(r, t[0], tmp); } else { - XMEMCPY(r, t[0], sizeof(sp_point)); + XMEMCPY(r, t[0], sizeof(sp_point_256)); } } @@ -14064,7 +14099,7 @@ static int sp_256_ecc_mulmod_10(sp_point* r, const sp_point* g, const sp_digit* XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); } if (td != NULL) { - XMEMSET(td, 0, sizeof(sp_point) * 3); + XMEMSET(td, 0, sizeof(sp_point_256) * 3); XFREE(td, NULL, DYNAMIC_TYPE_ECC); } @@ -14082,14 +14117,14 @@ static int sp_256_ecc_mulmod_10(sp_point* r, const sp_point* g, const sp_digit* * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_10(sp_point* r, const sp_point* g, const sp_digit* k, +static int sp_256_ecc_mulmod_10(sp_point_256* r, const sp_point_256* g, const sp_digit* k, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point td[3]; + sp_point_256 td[3]; sp_digit tmpd[2 * 10 * 5]; #endif - sp_point* t; + sp_point_256* t; sp_digit* tmp; sp_digit n; int i; @@ -14099,8 +14134,8 @@ static int sp_256_ecc_mulmod_10(sp_point* r, const sp_point* g, const sp_digit* (void)heap; #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - sp_point td[3]; - t = (sp_point*)XMALLOC(sizeof(*td) * 3, heap, DYNAMIC_TYPE_ECC); + sp_point_256 td[3]; + t = (sp_point_256*)XMALLOC(sizeof(*td) * 3, heap, DYNAMIC_TYPE_ECC); if (t == NULL) err = MEMORY_E; tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 10 * 5, heap, @@ -14157,7 +14192,7 @@ static int sp_256_ecc_mulmod_10(sp_point* r, const sp_point* g, const sp_digit* sp_256_map_10(r, &t[0], tmp); } else { - XMEMCPY(r, &t[0], sizeof(sp_point)); + XMEMCPY(r, &t[0], sizeof(sp_point_256)); } } @@ -14167,7 +14202,7 @@ static int sp_256_ecc_mulmod_10(sp_point* r, const sp_point* g, const sp_digit* XFREE(tmp, heap, DYNAMIC_TYPE_ECC); } if (t != NULL) { - XMEMSET(t, 0, sizeof(sp_point) * 3); + XMEMSET(t, 0, sizeof(sp_point_256) * 3); XFREE(t, heap, DYNAMIC_TYPE_ECC); } #else @@ -14180,10 +14215,10 @@ static int sp_256_ecc_mulmod_10(sp_point* r, const sp_point* g, const sp_digit* #else /* A table entry for pre-computed points. */ -typedef struct sp_table_entry { +typedef struct sp_table_entry_256 { sp_digit x[10]; sp_digit y[10]; -} sp_table_entry; +} sp_table_entry_256; /* Multiply the point by the scalar and return the result. * If map is true then convert result to affine coordinates. @@ -14195,16 +14230,16 @@ typedef struct sp_table_entry { * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_fast_10(sp_point* r, const sp_point* g, const sp_digit* k, +static int sp_256_ecc_mulmod_fast_10(sp_point_256* r, const sp_point_256* g, const sp_digit* k, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point td[16]; - sp_point rtd; + sp_point_256 td[16]; + sp_point_256 rtd; sp_digit tmpd[2 * 10 * 5]; #endif - sp_point* t; - sp_point* rt; + sp_point_256* t; + sp_point_256* rt; sp_digit* tmp; sp_digit n; int i; @@ -14213,9 +14248,9 @@ static int sp_256_ecc_mulmod_fast_10(sp_point* r, const sp_point* g, const sp_di (void)heap; - err = sp_ecc_point_new(heap, rtd, rt); + err = sp_256_point_new_10(heap, rtd, rt); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - t = (sp_point*)XMALLOC(sizeof(sp_point) * 16, heap, DYNAMIC_TYPE_ECC); + t = (sp_point_256*)XMALLOC(sizeof(sp_point_256) * 16, heap, DYNAMIC_TYPE_ECC); if (t == NULL) err = MEMORY_E; tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 10 * 5, heap, @@ -14269,7 +14304,7 @@ static int sp_256_ecc_mulmod_fast_10(sp_point* r, const sp_point* g, const sp_di n = k[i+1] << 6; c = 18; y = n >> 24; - XMEMCPY(rt, &t[y], sizeof(sp_point)); + XMEMCPY(rt, &t[y], sizeof(sp_point_256)); n <<= 8; for (; i>=0 || c>=4; ) { if (c < 4) { @@ -14292,7 +14327,7 @@ static int sp_256_ecc_mulmod_fast_10(sp_point* r, const sp_point* g, const sp_di sp_256_map_10(r, rt, tmp); } else { - XMEMCPY(r, rt, sizeof(sp_point)); + XMEMCPY(r, rt, sizeof(sp_point_256)); } } @@ -14302,14 +14337,14 @@ static int sp_256_ecc_mulmod_fast_10(sp_point* r, const sp_point* g, const sp_di XFREE(tmp, heap, DYNAMIC_TYPE_ECC); } if (t != NULL) { - XMEMSET(t, 0, sizeof(sp_point) * 16); + XMEMSET(t, 0, sizeof(sp_point_256) * 16); XFREE(t, heap, DYNAMIC_TYPE_ECC); } #else ForceZero(tmpd, sizeof(tmpd)); ForceZero(td, sizeof(td)); #endif - sp_ecc_point_free(rt, 1, heap); + sp_256_point_free_10(rt, 1, heap); return err; } @@ -14322,10 +14357,10 @@ static int sp_256_ecc_mulmod_fast_10(sp_point* r, const sp_point* g, const sp_di * n Number of times to double * t Temporary ordinate data. */ -static void sp_256_proj_point_dbl_n_10(sp_point* r, const sp_point* p, int n, +static void sp_256_proj_point_dbl_n_10(sp_point_256* r, const sp_point_256* p, int n, sp_digit* t) { - sp_point* rp[2]; + sp_point_256* rp[2]; sp_digit* w = t; sp_digit* a = t + 2*10; sp_digit* b = t + 4*10; @@ -14339,8 +14374,8 @@ static void sp_256_proj_point_dbl_n_10(sp_point* r, const sp_point* p, int n, rp[0] = r; /*lint allow cast to different type of pointer*/ - rp[1] = (sp_point*)t; /*lint !e9087 !e740*/ - XMEMSET(rp[1], 0, sizeof(sp_point)); + rp[1] = (sp_point_256*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_256)); x = rp[p->infinity]->x; y = rp[p->infinity]->y; z = rp[p->infinity]->z; @@ -14402,11 +14437,11 @@ static void sp_256_proj_point_dbl_n_10(sp_point* r, const sp_point* p, int n, * q Second point to add. * t Temporary ordinate data. */ -static void sp_256_proj_point_add_qz1_10(sp_point* r, const sp_point* p, - const sp_point* q, sp_digit* t) +static void sp_256_proj_point_add_qz1_10(sp_point_256* r, const sp_point_256* p, + const sp_point_256* q, sp_digit* t) { - const sp_point* ap[2]; - sp_point* rp[2]; + const sp_point_256* ap[2]; + sp_point_256* rp[2]; sp_digit* t1 = t; sp_digit* t2 = t + 2*10; sp_digit* t3 = t + 4*10; @@ -14428,8 +14463,8 @@ static void sp_256_proj_point_add_qz1_10(sp_point* r, const sp_point* p, rp[0] = r; /*lint allow cast to different type of pointer*/ - rp[1] = (sp_point*)t; /*lint !e9087 !e740*/ - XMEMSET(rp[1], 0, sizeof(sp_point)); + rp[1] = (sp_point_256*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_256)); x = rp[p->infinity | q->infinity]->x; y = rp[p->infinity | q->infinity]->y; z = rp[p->infinity | q->infinity]->z; @@ -14482,7 +14517,7 @@ static void sp_256_proj_point_add_qz1_10(sp_point* r, const sp_point* p, * a Point to convert. * t Temporary data. */ -static void sp_256_proj_to_affine_10(sp_point* a, sp_digit* t) +static void sp_256_proj_to_affine_10(sp_point_256* a, sp_digit* t) { sp_digit* t1 = t; sp_digit* t2 = t + 2 * 10; @@ -14505,26 +14540,26 @@ static void sp_256_proj_to_affine_10(sp_point* a, sp_digit* t) * tmp Temporary data. * heap Heap to use for allocation. */ -static int sp_256_gen_stripe_table_10(const sp_point* a, - sp_table_entry* table, sp_digit* tmp, void* heap) +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) - sp_point td, s1d, s2d; + sp_point_256 td, s1d, s2d; #endif - sp_point* t; - sp_point* s1 = NULL; - sp_point* s2 = NULL; + sp_point_256* t; + sp_point_256* s1 = NULL; + sp_point_256* s2 = NULL; int i, j; int err; (void)heap; - err = sp_ecc_point_new(heap, td, t); + err = sp_256_point_new_10(heap, td, t); if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, s1d, s1); + err = sp_256_point_new_10(heap, s1d, s1); } if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, s2d, s2); + err = sp_256_point_new_10(heap, s2d, s2); } if (err == MP_OKAY) { @@ -14546,7 +14581,7 @@ static int sp_256_gen_stripe_table_10(const sp_point* a, s2->infinity = 0; /* table[0] = {0, 0, infinity} */ - XMEMSET(&table[0], 0, sizeof(sp_table_entry)); + XMEMSET(&table[0], 0, sizeof(sp_table_entry_256)); /* 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)); @@ -14572,9 +14607,9 @@ static int sp_256_gen_stripe_table_10(const sp_point* a, } } - sp_ecc_point_free(s2, 0, heap); - sp_ecc_point_free(s1, 0, heap); - sp_ecc_point_free( t, 0, heap); + sp_256_point_free_10(s2, 0, heap); + sp_256_point_free_10(s1, 0, heap); + sp_256_point_free_10( t, 0, heap); return err; } @@ -14589,16 +14624,16 @@ static int sp_256_gen_stripe_table_10(const sp_point* a, * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_stripe_10(sp_point* r, const sp_point* g, - const sp_table_entry* table, const sp_digit* k, int map, void* heap) +static int sp_256_ecc_mulmod_stripe_10(sp_point_256* r, const sp_point_256* g, + const sp_table_entry_256* table, const sp_digit* k, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point rtd; - sp_point pd; + sp_point_256 rtd; + sp_point_256 pd; sp_digit td[2 * 10 * 5]; #endif - sp_point* rt; - sp_point* p = NULL; + sp_point_256* rt; + sp_point_256* p = NULL; sp_digit* t; int i, j; int y, x; @@ -14607,9 +14642,10 @@ static int sp_256_ecc_mulmod_stripe_10(sp_point* r, const sp_point* g, (void)g; (void)heap; - err = sp_ecc_point_new(heap, rtd, rt); + + err = sp_256_point_new_10(heap, rtd, rt); if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, pd, p); + err = sp_256_point_new_10(heap, pd, p); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 10 * 5, heap, @@ -14649,7 +14685,7 @@ static int sp_256_ecc_mulmod_stripe_10(sp_point* r, const sp_point* g, sp_256_map_10(r, rt, t); } else { - XMEMCPY(r, rt, sizeof(sp_point)); + XMEMCPY(r, rt, sizeof(sp_point_256)); } } @@ -14658,8 +14694,8 @@ static int sp_256_ecc_mulmod_stripe_10(sp_point* r, const sp_point* g, XFREE(t, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(p, 0, heap); - sp_ecc_point_free(rt, 0, heap); + sp_256_point_free_10(p, 0, heap); + sp_256_point_free_10(rt, 0, heap); return err; } @@ -14669,43 +14705,43 @@ static int sp_256_ecc_mulmod_stripe_10(sp_point* r, const sp_point* g, #define FP_ENTRIES 16 #endif -typedef struct sp_cache_t { +typedef struct sp_cache_256_t { sp_digit x[10]; sp_digit y[10]; - sp_table_entry table[256]; + sp_table_entry_256 table[256]; uint32_t cnt; int set; -} sp_cache_t; +} sp_cache_256_t; -static THREAD_LS_T sp_cache_t sp_cache[FP_ENTRIES]; -static THREAD_LS_T int sp_cache_last = -1; -static THREAD_LS_T int sp_cache_inited = 0; +static THREAD_LS_T sp_cache_256_t sp_cache_256[FP_ENTRIES]; +static THREAD_LS_T int sp_cache_256_last = -1; +static THREAD_LS_T int sp_cache_256_inited = 0; #ifndef HAVE_THREAD_LS - static volatile int initCacheMutex = 0; - static wolfSSL_Mutex sp_cache_lock; + static volatile int initCacheMutex_256 = 0; + static wolfSSL_Mutex sp_cache_256_lock; #endif -static void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache) +static void sp_ecc_get_cache_256(const sp_point_256* g, sp_cache_256_t** cache) { int i, j; uint32_t least; - if (sp_cache_inited == 0) { + if (sp_cache_256_inited == 0) { for (i=0; ix, sp_cache[i].x) & - sp_256_cmp_equal_10(g->y, sp_cache[i].y)) { - sp_cache[i].cnt++; + if (sp_256_cmp_equal_10(g->x, sp_cache_256[i].x) & + sp_256_cmp_equal_10(g->y, sp_cache_256[i].y)) { + sp_cache_256[i].cnt++; break; } } @@ -14713,32 +14749,32 @@ static void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache) /* No match. */ if (i == FP_ENTRIES) { /* Find empty entry. */ - i = (sp_cache_last + 1) % FP_ENTRIES; - for (; i != sp_cache_last; i=(i+1)%FP_ENTRIES) { - if (!sp_cache[i].set) { + i = (sp_cache_256_last + 1) % FP_ENTRIES; + for (; i != sp_cache_256_last; i=(i+1)%FP_ENTRIES) { + if (!sp_cache_256[i].set) { break; } } /* Evict least used. */ - if (i == sp_cache_last) { - least = sp_cache[0].cnt; + if (i == sp_cache_256_last) { + least = sp_cache_256[0].cnt; for (j=1; jx, sizeof(sp_cache[i].x)); - XMEMCPY(sp_cache[i].y, g->y, sizeof(sp_cache[i].y)); - sp_cache[i].set = 1; - sp_cache[i].cnt = 1; + XMEMCPY(sp_cache_256[i].x, g->x, sizeof(sp_cache_256[i].x)); + XMEMCPY(sp_cache_256[i].y, g->y, sizeof(sp_cache_256[i].y)); + sp_cache_256[i].set = 1; + sp_cache_256[i].cnt = 1; } - *cache = &sp_cache[i]; - sp_cache_last = i; + *cache = &sp_cache_256[i]; + sp_cache_256_last = i; } #endif /* FP_ECC */ @@ -14752,32 +14788,32 @@ static void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache) * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_10(sp_point* r, const sp_point* g, const sp_digit* k, +static int sp_256_ecc_mulmod_10(sp_point_256* r, const sp_point_256* g, const sp_digit* k, int map, void* heap) { #ifndef FP_ECC return sp_256_ecc_mulmod_fast_10(r, g, k, map, heap); #else sp_digit tmp[2 * 10 * 5]; - sp_cache_t* cache; + sp_cache_256_t* cache; int err = MP_OKAY; #ifndef HAVE_THREAD_LS - if (initCacheMutex == 0) { - wc_InitMutex(&sp_cache_lock); - initCacheMutex = 1; + if (initCacheMutex_256 == 0) { + wc_InitMutex(&sp_cache_256_lock); + initCacheMutex_256 = 1; } - if (wc_LockMutex(&sp_cache_lock) != 0) + if (wc_LockMutex(&sp_cache_256_lock) != 0) err = BAD_MUTEX_E; #endif /* HAVE_THREAD_LS */ if (err == MP_OKAY) { - sp_ecc_get_cache(g, &cache); + sp_ecc_get_cache_256(g, &cache); if (cache->cnt == 2) sp_256_gen_stripe_table_10(g, cache->table, tmp, heap); #ifndef HAVE_THREAD_LS - wc_UnLockMutex(&sp_cache_lock); + wc_UnLockMutex(&sp_cache_256_lock); #endif /* HAVE_THREAD_LS */ if (cache->cnt < 2) { @@ -14808,15 +14844,14 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point p; - sp_digit k[10]; -#else - sp_digit* k = NULL; + sp_point_256 p; + sp_digit kd[10]; #endif - sp_point* point; - int err; + sp_point_256* point; + sp_digit* k = NULL; + int err = MP_OKAY; - err = sp_ecc_point_new(heap, p, point); + err = sp_256_point_new_10(heap, p, point); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 10, heap, @@ -14824,6 +14859,8 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, if (k == NULL) err = MEMORY_E; } +#else + k = kd; #endif if (err == MP_OKAY) { sp_256_from_mp(k, 10, km); @@ -14840,7 +14877,7 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, XFREE(k, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(point, 0, heap); + sp_256_point_free_10(point, 0, heap); return err; } @@ -14855,7 +14892,7 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_base_10(sp_point* r, const sp_digit* k, +static int sp_256_ecc_mulmod_base_10(sp_point_256* r, const sp_digit* k, int map, void* heap) { /* No pre-computed values. */ @@ -14863,7 +14900,7 @@ static int sp_256_ecc_mulmod_base_10(sp_point* r, const sp_digit* k, } #else -static const sp_table_entry p256_table[256] = { +static const sp_table_entry_256 p256_table[256] = { /* 0 */ { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, @@ -16153,7 +16190,7 @@ static const sp_table_entry p256_table[256] = { * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_base_10(sp_point* r, const sp_digit* k, +static int sp_256_ecc_mulmod_base_10(sp_point_256* r, const sp_digit* k, int map, void* heap) { return sp_256_ecc_mulmod_stripe_10(r, &p256_base, p256_table, @@ -16174,15 +16211,14 @@ static int sp_256_ecc_mulmod_base_10(sp_point* r, const sp_digit* k, int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point p; - sp_digit k[10]; -#else - sp_digit* k = NULL; + sp_point_256 p; + sp_digit kd[10]; #endif - sp_point* point; - int err; + sp_point_256* point; + sp_digit* k = NULL; + int err = MP_OKAY; - err = sp_ecc_point_new(heap, p, point); + err = sp_256_point_new_10(heap, p, point); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 10, heap, @@ -16191,6 +16227,8 @@ int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) err = MEMORY_E; } } +#else + k = kd; #endif if (err == MP_OKAY) { sp_256_from_mp(k, 10, km); @@ -16206,7 +16244,7 @@ int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) XFREE(k, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(point, 0, heap); + sp_256_point_free_10(point, 0, heap); return err; } @@ -16310,26 +16348,25 @@ static int sp_256_ecc_gen_k_10(WC_RNG* rng, sp_digit* k) int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point p; - sp_digit k[10]; + sp_point_256 p; + sp_digit kd[10]; #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN - sp_point inf; + sp_point_256 inf; #endif -#else +#endif + sp_point_256* point; sp_digit* k = NULL; -#endif - sp_point* point; #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN - sp_point* infinity; + sp_point_256* infinity; #endif int err; (void)heap; - err = sp_ecc_point_new(heap, p, point); + err = sp_256_point_new_10(heap, p, point); #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, inf, infinity); + err = sp_256_point_new_10(heap, inf, infinity); } #endif #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) @@ -16340,6 +16377,8 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) err = MEMORY_E; } } +#else + k = kd; #endif if (err == MP_OKAY) { @@ -16373,9 +16412,9 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) } #endif #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN - sp_ecc_point_free(infinity, 1, heap); + sp_256_point_free_10(infinity, 1, heap); #endif - sp_ecc_point_free(point, 1, heap); + sp_256_point_free_10(point, 1, heap); return err; } @@ -16436,12 +16475,11 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, word32* outLen, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point p; - sp_digit k[10]; -#else - sp_digit* k = NULL; + sp_point_256 p; + sp_digit kd[10]; #endif - sp_point* point = NULL; + sp_point_256* point = NULL; + sp_digit* k = NULL; int err = MP_OKAY; if (*outLen < 32U) { @@ -16449,7 +16487,7 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, } if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, p, point); + err = sp_256_point_new_10(heap, p, point); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { @@ -16458,6 +16496,8 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, if (k == NULL) err = MEMORY_E; } +#else + k = kd; #endif if (err == MP_OKAY) { @@ -16475,7 +16515,7 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, XFREE(k, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(point, 0, heap); + sp_256_point_free_10(point, 0, heap); return err; } @@ -16697,7 +16737,7 @@ static int sp_256_mod_10(sp_digit* r, const sp_digit* a, const sp_digit* m) #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) #ifdef WOLFSSL_SP_SMALL /* Order-2 for the P256 curve. */ -static const uint32_t p256_order_2[8] = { +static const uint32_t p256_order_minus_2[8] = { 0xfc63254fU,0xf3b9cac2U,0xa7179e84U,0xbce6faadU,0xffffffffU,0xffffffffU, 0x00000000U,0xffffffffU }; @@ -16766,7 +16806,7 @@ static void sp_256_mont_inv_order_10(sp_digit* r, const sp_digit* a, XMEMCPY(t, a, sizeof(sp_digit) * 10); for (i=254; i>=0; i--) { sp_256_mont_sqr_order_10(t, t); - if ((p256_order_2[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { + if ((p256_order_minus_2[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { sp_256_mont_mul_order_10(t, t, a); } } @@ -16882,24 +16922,24 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_digit kd[2*10]; sp_digit rd[2*10]; sp_digit td[3 * 2*10]; - sp_point p; + sp_point_256 p; #endif sp_digit* e = NULL; sp_digit* x = NULL; sp_digit* k = NULL; sp_digit* r = NULL; sp_digit* tmp = NULL; - sp_point* point = NULL; + sp_point_256* point = NULL; sp_digit carry; sp_digit* s = NULL; sp_digit* kInv = NULL; - int err; + int err = MP_OKAY; int32_t c; int i; (void)heap; - err = sp_ecc_point_new(heap, p, point); + err = sp_256_point_new_10(heap, p, point); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7 * 2 * 10, heap, @@ -17015,7 +17055,7 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, XMEMSET(r, 0, sizeof(sp_digit) * 2U * 10U); XMEMSET(tmp, 0, sizeof(sp_digit) * 3U * 2U * 10U); #endif - sp_ecc_point_free(point, 1, heap); + sp_256_point_free_10(point, 1, heap); return err; } @@ -17052,22 +17092,22 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, sp_digit u2d[2*10]; sp_digit sd[2*10]; sp_digit tmpd[2*10 * 5]; - sp_point p1d; - sp_point p2d; + sp_point_256 p1d; + sp_point_256 p2d; #endif sp_digit* u1 = NULL; sp_digit* u2 = NULL; sp_digit* s = NULL; sp_digit* tmp = NULL; - sp_point* p1; - sp_point* p2 = NULL; + sp_point_256* p1; + sp_point_256* p2 = NULL; sp_digit carry; int32_t c; int err; - err = sp_ecc_point_new(heap, p1d, p1); + err = sp_256_point_new_10(heap, p1d, p1); if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, p2d, p2); + err = sp_256_point_new_10(heap, p2d, p2); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { @@ -17185,8 +17225,8 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, if (d != NULL) XFREE(d, heap, DYNAMIC_TYPE_ECC); #endif - sp_ecc_point_free(p1, 0, heap); - sp_ecc_point_free(p2, 0, heap); + sp_256_point_free_10(p1, 0, heap); + sp_256_point_free_10(p2, 0, heap); return err; } @@ -17200,10 +17240,10 @@ 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* point, void* heap) +static int sp_256_ecc_is_point_10(sp_point_256* point, void* heap) { #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - sp_digit* d; + sp_digit* d = NULL; #else sp_digit t1d[2*10]; sp_digit t2d[2*10]; @@ -17267,13 +17307,13 @@ static int sp_256_ecc_is_point_10(sp_point* point, void* heap) int sp_ecc_is_point_256(mp_int* pX, mp_int* pY) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point pubd; + sp_point_256 pubd; #endif - sp_point* pub; + sp_point_256* pub; byte one[1] = { 1 }; int err; - err = sp_ecc_point_new(NULL, pubd, pub); + err = sp_256_point_new_10(NULL, pubd, pub); if (err == MP_OKAY) { sp_256_from_mp(pub->x, 10, pX); sp_256_from_mp(pub->y, 10, pY); @@ -17282,7 +17322,7 @@ int sp_ecc_is_point_256(mp_int* pX, mp_int* pY) err = sp_256_ecc_is_point_10(pub, NULL); } - sp_ecc_point_free(pub, 0, NULL); + sp_256_point_free_10(pub, 0, NULL); return err; } @@ -17302,18 +17342,18 @@ int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_digit privd[10]; - sp_point pubd; - sp_point pd; + sp_point_256 pubd; + sp_point_256 pd; #endif sp_digit* priv = NULL; - sp_point* pub; - sp_point* p = NULL; + sp_point_256* pub; + sp_point_256* p = NULL; byte one[1] = { 1 }; int err; - err = sp_ecc_point_new(heap, pubd, pub); + err = sp_256_point_new_10(heap, pubd, pub); if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, pd, p); + err = sp_256_point_new_10(heap, pd, p); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { @@ -17384,8 +17424,8 @@ int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) XFREE(priv, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(p, 0, heap); - sp_ecc_point_free(pub, 0, heap); + sp_256_point_free_10(p, 0, heap); + sp_256_point_free_10(pub, 0, heap); return err; } @@ -17411,17 +17451,17 @@ int sp_ecc_proj_add_point_256(mp_int* pX, mp_int* pY, mp_int* pZ, { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_digit tmpd[2 * 10 * 5]; - sp_point pd; - sp_point qd; + sp_point_256 pd; + sp_point_256 qd; #endif sp_digit* tmp; - sp_point* p; - sp_point* q = NULL; + sp_point_256* p; + sp_point_256* q = NULL; int err; - err = sp_ecc_point_new(NULL, pd, p); + err = sp_256_point_new_10(NULL, pd, p); if (err == MP_OKAY) { - err = sp_ecc_point_new(NULL, qd, q); + err = sp_256_point_new_10(NULL, qd, q); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { @@ -17461,8 +17501,8 @@ int sp_ecc_proj_add_point_256(mp_int* pX, mp_int* pY, mp_int* pZ, XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(q, 0, NULL); - sp_ecc_point_free(p, 0, NULL); + sp_256_point_free_10(q, 0, NULL); + sp_256_point_free_10(p, 0, NULL); return err; } @@ -17483,13 +17523,13 @@ int sp_ecc_proj_dbl_point_256(mp_int* pX, mp_int* pY, mp_int* pZ, { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_digit tmpd[2 * 10 * 2]; - sp_point pd; + sp_point_256 pd; #endif sp_digit* tmp; - sp_point* p; + sp_point_256* p; int err; - err = sp_ecc_point_new(NULL, pd, p); + err = sp_256_point_new_10(NULL, pd, p); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 10 * 2, NULL, @@ -17525,7 +17565,7 @@ int sp_ecc_proj_dbl_point_256(mp_int* pX, mp_int* pY, mp_int* pZ, XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(p, 0, NULL); + sp_256_point_free_10(p, 0, NULL); return err; } @@ -17542,13 +17582,13 @@ int sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_digit tmpd[2 * 10 * 4]; - sp_point pd; + sp_point_256 pd; #endif sp_digit* tmp; - sp_point* p; + sp_point_256* p; int err; - err = sp_ecc_point_new(NULL, pd, p); + err = sp_256_point_new_10(NULL, pd, p); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 10 * 4, NULL, @@ -17583,7 +17623,7 @@ int sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ) XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(p, 0, NULL); + sp_256_point_free_10(p, 0, NULL); return err; } @@ -17664,6 +17704,7 @@ static int sp_256_mont_sqrt_10(sp_digit* y) return err; } + /* Uncompress the point given the X ordinate. * * xm X ordinate. @@ -17740,6 +17781,6153 @@ int sp_ecc_uncompress_256(mp_int* xm, int odd, mp_int* ym) } #endif #endif /* !WOLFSSL_SP_NO_256 */ +#ifdef WOLFSSL_SP_384 + +/* Point structure to use. */ +typedef struct sp_point_384 { + sp_digit x[2 * 15]; + sp_digit y[2 * 15]; + sp_digit z[2 * 15]; + 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 + +}; +/* 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 + +}; +/* The Montogmery multiplier for modulus of the curve P384. */ +static sp_digit p384_mp_mod = 0x000001; +#if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \ + defined(HAVE_ECC_VERIFY) +/* 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 + +}; +#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 + +}; +#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 + +}; +#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 = 0x8fdc45; +#endif +/* The base point of curve P384. */ +static const sp_point_384 p384_base = { + /* X ordinate */ + { + 0x2760ab7,0x1178e1c,0x296c3a5,0x176fd54,0x05502f2,0x0950a8e,0x3741e08, + 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, + + 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, + + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + }, + /* infinity */ + 0 +}; +#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 + +}; +#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) + (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) +/* 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) +/* 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) + 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) + 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) + 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] |= t[1] << 6U; + r[1] &= 0x3ffffffL; + r[2] = (sp_digit)(t[1] >> 20U); + r[2] |= t[2] << 12U; + r[2] &= 0x3ffffffL; + r[3] = (sp_digit)(t[2] >> 14U); + r[3] |= t[3] << 18U; + r[3] &= 0x3ffffffL; + r[4] = (sp_digit)(t[3] >> 8U); + r[4] |= t[4] << 24U; + r[4] &= 0x3ffffffL; + r[5] = (sp_digit)(t[4] >> 2U) & 0x3ffffffL; + r[6] = (sp_digit)(t[4] >> 28U); + r[6] |= t[5] << 4U; + r[6] &= 0x3ffffffL; + r[7] = (sp_digit)(t[5] >> 22U); + r[7] |= t[6] << 10U; + r[7] &= 0x3ffffffL; + r[8] = (sp_digit)(t[6] >> 16U); + r[8] |= t[7] << 16U; + r[8] &= 0x3ffffffL; + r[9] = (sp_digit)(t[7] >> 10U); + r[9] |= t[8] << 22U; + r[9] &= 0x3ffffffL; + r[10] = (sp_digit)(t[8] >> 4U) & 0x3ffffffL; + r[11] = (sp_digit)(t[8] >> 30U); + r[11] |= t[9] << 2U; + r[11] &= 0x3ffffffL; + r[12] = (sp_digit)(t[9] >> 24U); + r[12] |= t[10] << 8U; + r[12] &= 0x3ffffffL; + r[13] = (sp_digit)(t[10] >> 18U); + r[13] |= t[11] << 14U; + r[13] &= 0x3ffffffL; + r[14] = (sp_digit)(t[11] >> 12U); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + 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] |= a[i] << s; + r->dp[j] &= (1L << DIGIT_BIT) - 1; + s = DIGIT_BIT - s; + r->dp[++j] = 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] = 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) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static void sp_384_mul_15(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + int i, j, k; + int64_t c; + + c = ((int64_t)a[14]) * b[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) { + break; + } + if (j < 0) { + continue; + } + + c += ((int64_t)a[i]) * b[j]; + } + r[k + 2] += c >> 52; + r[k + 1] = (c >> 26) & 0x3ffffff; + c = (c & 0x3ffffff) << 26; + } + r[0] = (sp_digit)(c >> 26); +} + +#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_384_mul_15(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[ 0]) * b[ 7] + + ((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)a[ 7]) * b[ 0]; + int64_t t8 = ((int64_t)a[ 0]) * b[ 8] + + ((int64_t)a[ 1]) * b[ 7] + + ((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)a[ 7]) * b[ 1] + + ((int64_t)a[ 8]) * b[ 0]; + int64_t t9 = ((int64_t)a[ 0]) * b[ 9] + + ((int64_t)a[ 1]) * b[ 8] + + ((int64_t)a[ 2]) * b[ 7] + + ((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)a[ 7]) * b[ 2] + + ((int64_t)a[ 8]) * b[ 1] + + ((int64_t)a[ 9]) * b[ 0]; + int64_t t10 = ((int64_t)a[ 0]) * b[10] + + ((int64_t)a[ 1]) * b[ 9] + + ((int64_t)a[ 2]) * b[ 8] + + ((int64_t)a[ 3]) * b[ 7] + + ((int64_t)a[ 4]) * b[ 6] + + ((int64_t)a[ 5]) * b[ 5] + + ((int64_t)a[ 6]) * b[ 4] + + ((int64_t)a[ 7]) * b[ 3] + + ((int64_t)a[ 8]) * b[ 2] + + ((int64_t)a[ 9]) * b[ 1] + + ((int64_t)a[10]) * b[ 0]; + int64_t t11 = ((int64_t)a[ 0]) * b[11] + + ((int64_t)a[ 1]) * b[10] + + ((int64_t)a[ 2]) * b[ 9] + + ((int64_t)a[ 3]) * b[ 8] + + ((int64_t)a[ 4]) * b[ 7] + + ((int64_t)a[ 5]) * b[ 6] + + ((int64_t)a[ 6]) * b[ 5] + + ((int64_t)a[ 7]) * b[ 4] + + ((int64_t)a[ 8]) * b[ 3] + + ((int64_t)a[ 9]) * b[ 2] + + ((int64_t)a[10]) * b[ 1] + + ((int64_t)a[11]) * b[ 0]; + int64_t t12 = ((int64_t)a[ 0]) * b[12] + + ((int64_t)a[ 1]) * b[11] + + ((int64_t)a[ 2]) * b[10] + + ((int64_t)a[ 3]) * b[ 9] + + ((int64_t)a[ 4]) * b[ 8] + + ((int64_t)a[ 5]) * b[ 7] + + ((int64_t)a[ 6]) * b[ 6] + + ((int64_t)a[ 7]) * b[ 5] + + ((int64_t)a[ 8]) * b[ 4] + + ((int64_t)a[ 9]) * b[ 3] + + ((int64_t)a[10]) * b[ 2] + + ((int64_t)a[11]) * b[ 1] + + ((int64_t)a[12]) * b[ 0]; + int64_t t13 = ((int64_t)a[ 0]) * b[13] + + ((int64_t)a[ 1]) * b[12] + + ((int64_t)a[ 2]) * b[11] + + ((int64_t)a[ 3]) * b[10] + + ((int64_t)a[ 4]) * b[ 9] + + ((int64_t)a[ 5]) * b[ 8] + + ((int64_t)a[ 6]) * b[ 7] + + ((int64_t)a[ 7]) * b[ 6] + + ((int64_t)a[ 8]) * b[ 5] + + ((int64_t)a[ 9]) * b[ 4] + + ((int64_t)a[10]) * b[ 3] + + ((int64_t)a[11]) * b[ 2] + + ((int64_t)a[12]) * b[ 1] + + ((int64_t)a[13]) * b[ 0]; + int64_t t14 = ((int64_t)a[ 0]) * b[14] + + ((int64_t)a[ 1]) * b[13] + + ((int64_t)a[ 2]) * b[12] + + ((int64_t)a[ 3]) * b[11] + + ((int64_t)a[ 4]) * b[10] + + ((int64_t)a[ 5]) * b[ 9] + + ((int64_t)a[ 6]) * b[ 8] + + ((int64_t)a[ 7]) * b[ 7] + + ((int64_t)a[ 8]) * b[ 6] + + ((int64_t)a[ 9]) * b[ 5] + + ((int64_t)a[10]) * b[ 4] + + ((int64_t)a[11]) * b[ 3] + + ((int64_t)a[12]) * b[ 2] + + ((int64_t)a[13]) * b[ 1] + + ((int64_t)a[14]) * b[ 0]; + int64_t t15 = ((int64_t)a[ 1]) * b[14] + + ((int64_t)a[ 2]) * b[13] + + ((int64_t)a[ 3]) * b[12] + + ((int64_t)a[ 4]) * b[11] + + ((int64_t)a[ 5]) * b[10] + + ((int64_t)a[ 6]) * b[ 9] + + ((int64_t)a[ 7]) * b[ 8] + + ((int64_t)a[ 8]) * b[ 7] + + ((int64_t)a[ 9]) * b[ 6] + + ((int64_t)a[10]) * b[ 5] + + ((int64_t)a[11]) * b[ 4] + + ((int64_t)a[12]) * b[ 3] + + ((int64_t)a[13]) * b[ 2] + + ((int64_t)a[14]) * b[ 1]; + int64_t t16 = ((int64_t)a[ 2]) * b[14] + + ((int64_t)a[ 3]) * b[13] + + ((int64_t)a[ 4]) * b[12] + + ((int64_t)a[ 5]) * b[11] + + ((int64_t)a[ 6]) * b[10] + + ((int64_t)a[ 7]) * b[ 9] + + ((int64_t)a[ 8]) * b[ 8] + + ((int64_t)a[ 9]) * b[ 7] + + ((int64_t)a[10]) * b[ 6] + + ((int64_t)a[11]) * b[ 5] + + ((int64_t)a[12]) * b[ 4] + + ((int64_t)a[13]) * b[ 3] + + ((int64_t)a[14]) * b[ 2]; + int64_t t17 = ((int64_t)a[ 3]) * b[14] + + ((int64_t)a[ 4]) * b[13] + + ((int64_t)a[ 5]) * b[12] + + ((int64_t)a[ 6]) * b[11] + + ((int64_t)a[ 7]) * b[10] + + ((int64_t)a[ 8]) * b[ 9] + + ((int64_t)a[ 9]) * b[ 8] + + ((int64_t)a[10]) * b[ 7] + + ((int64_t)a[11]) * b[ 6] + + ((int64_t)a[12]) * b[ 5] + + ((int64_t)a[13]) * b[ 4] + + ((int64_t)a[14]) * b[ 3]; + int64_t t18 = ((int64_t)a[ 4]) * b[14] + + ((int64_t)a[ 5]) * b[13] + + ((int64_t)a[ 6]) * b[12] + + ((int64_t)a[ 7]) * b[11] + + ((int64_t)a[ 8]) * b[10] + + ((int64_t)a[ 9]) * b[ 9] + + ((int64_t)a[10]) * b[ 8] + + ((int64_t)a[11]) * b[ 7] + + ((int64_t)a[12]) * b[ 6] + + ((int64_t)a[13]) * b[ 5] + + ((int64_t)a[14]) * b[ 4]; + int64_t t19 = ((int64_t)a[ 5]) * b[14] + + ((int64_t)a[ 6]) * b[13] + + ((int64_t)a[ 7]) * b[12] + + ((int64_t)a[ 8]) * b[11] + + ((int64_t)a[ 9]) * b[10] + + ((int64_t)a[10]) * b[ 9] + + ((int64_t)a[11]) * b[ 8] + + ((int64_t)a[12]) * b[ 7] + + ((int64_t)a[13]) * b[ 6] + + ((int64_t)a[14]) * b[ 5]; + int64_t t20 = ((int64_t)a[ 6]) * b[14] + + ((int64_t)a[ 7]) * b[13] + + ((int64_t)a[ 8]) * b[12] + + ((int64_t)a[ 9]) * b[11] + + ((int64_t)a[10]) * b[10] + + ((int64_t)a[11]) * b[ 9] + + ((int64_t)a[12]) * b[ 8] + + ((int64_t)a[13]) * b[ 7] + + ((int64_t)a[14]) * b[ 6]; + int64_t t21 = ((int64_t)a[ 7]) * b[14] + + ((int64_t)a[ 8]) * b[13] + + ((int64_t)a[ 9]) * b[12] + + ((int64_t)a[10]) * b[11] + + ((int64_t)a[11]) * b[10] + + ((int64_t)a[12]) * b[ 9] + + ((int64_t)a[13]) * b[ 8] + + ((int64_t)a[14]) * b[ 7]; + int64_t t22 = ((int64_t)a[ 8]) * b[14] + + ((int64_t)a[ 9]) * b[13] + + ((int64_t)a[10]) * b[12] + + ((int64_t)a[11]) * b[11] + + ((int64_t)a[12]) * b[10] + + ((int64_t)a[13]) * b[ 9] + + ((int64_t)a[14]) * b[ 8]; + int64_t t23 = ((int64_t)a[ 9]) * b[14] + + ((int64_t)a[10]) * b[13] + + ((int64_t)a[11]) * b[12] + + ((int64_t)a[12]) * b[11] + + ((int64_t)a[13]) * b[10] + + ((int64_t)a[14]) * b[ 9]; + int64_t t24 = ((int64_t)a[10]) * b[14] + + ((int64_t)a[11]) * b[13] + + ((int64_t)a[12]) * b[12] + + ((int64_t)a[13]) * b[11] + + ((int64_t)a[14]) * b[10]; + int64_t t25 = ((int64_t)a[11]) * b[14] + + ((int64_t)a[12]) * b[13] + + ((int64_t)a[13]) * b[12] + + ((int64_t)a[14]) * b[11]; + int64_t t26 = ((int64_t)a[12]) * b[14] + + ((int64_t)a[13]) * b[13] + + ((int64_t)a[14]) * b[12]; + int64_t t27 = ((int64_t)a[13]) * b[14] + + ((int64_t)a[14]) * b[13]; + int64_t t28 = ((int64_t)a[14]) * b[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 */ +#define sp_384_mont_reduce_order_15 sp_384_mont_reduce_15 + +/* 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_384_cmp_15(const sp_digit* a, const sp_digit* b) +{ + sp_digit r = 0; +#ifdef WOLFSSL_SP_SMALL + int i; + + for (i=14; i>=0; i--) { + r |= (a[i] - b[i]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + } +#else + r |= (a[14] - b[14]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[13] - b[13]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[12] - b[12]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[11] - b[11]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[10] - b[10]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[ 9] - b[ 9]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[ 8] - b[ 8]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[ 7] - b[ 7]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[ 6] - b[ 6]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[ 5] - b[ 5]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[ 4] - b[ 4]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[ 3] - b[ 3]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[ 2] - b[ 2]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[ 1] - b[ 1]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[ 0] - b[ 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_384_cond_sub_15(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 < 15; i++) { + r[i] = a[i] - (b[i] & m); + } +#else + r[ 0] = a[ 0] - (b[ 0] & m); + r[ 1] = a[ 1] - (b[ 1] & m); + r[ 2] = a[ 2] - (b[ 2] & m); + r[ 3] = a[ 3] - (b[ 3] & m); + r[ 4] = a[ 4] - (b[ 4] & m); + r[ 5] = a[ 5] - (b[ 5] & m); + r[ 6] = a[ 6] - (b[ 6] & m); + r[ 7] = a[ 7] - (b[ 7] & m); + r[ 8] = a[ 8] - (b[ 8] & m); + r[ 9] = a[ 9] - (b[ 9] & m); + r[10] = a[10] - (b[10] & m); + r[11] = a[11] - (b[11] & m); + r[12] = a[12] - (b[12] & m); + r[13] = a[13] - (b[13] & m); + r[14] = a[14] - (b[14] & 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_384_mul_add_15(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 < 15; i++) { + t += (tb * a[i]) + r[i]; + r[i] = t & 0x3ffffff; + t >>= 26; + } + r[15] += t; +#else + int64_t tb = b; + int64_t t[15]; + + t[ 0] = tb * a[ 0]; + t[ 1] = tb * a[ 1]; + t[ 2] = tb * a[ 2]; + t[ 3] = tb * a[ 3]; + t[ 4] = tb * a[ 4]; + t[ 5] = tb * a[ 5]; + t[ 6] = tb * a[ 6]; + t[ 7] = tb * a[ 7]; + t[ 8] = tb * a[ 8]; + t[ 9] = tb * a[ 9]; + t[10] = tb * a[10]; + t[11] = tb * a[11]; + t[12] = tb * a[12]; + t[13] = tb * a[13]; + t[14] = tb * a[14]; + r[ 0] += (sp_digit)(t[ 0] & 0x3ffffff); + r[ 1] += (sp_digit)((t[ 0] >> 26) + (t[ 1] & 0x3ffffff)); + r[ 2] += (sp_digit)((t[ 1] >> 26) + (t[ 2] & 0x3ffffff)); + r[ 3] += (sp_digit)((t[ 2] >> 26) + (t[ 3] & 0x3ffffff)); + r[ 4] += (sp_digit)((t[ 3] >> 26) + (t[ 4] & 0x3ffffff)); + r[ 5] += (sp_digit)((t[ 4] >> 26) + (t[ 5] & 0x3ffffff)); + r[ 6] += (sp_digit)((t[ 5] >> 26) + (t[ 6] & 0x3ffffff)); + r[ 7] += (sp_digit)((t[ 6] >> 26) + (t[ 7] & 0x3ffffff)); + r[ 8] += (sp_digit)((t[ 7] >> 26) + (t[ 8] & 0x3ffffff)); + r[ 9] += (sp_digit)((t[ 8] >> 26) + (t[ 9] & 0x3ffffff)); + r[10] += (sp_digit)((t[ 9] >> 26) + (t[10] & 0x3ffffff)); + r[11] += (sp_digit)((t[10] >> 26) + (t[11] & 0x3ffffff)); + r[12] += (sp_digit)((t[11] >> 26) + (t[12] & 0x3ffffff)); + r[13] += (sp_digit)((t[12] >> 26) + (t[13] & 0x3ffffff)); + r[14] += (sp_digit)((t[13] >> 26) + (t[14] & 0x3ffffff)); + r[15] += t[14] >> 26; +#endif /* WOLFSSL_SP_SMALL */ +} + +/* Normalize the values in each word to 26. + * + * a Array of sp_digit to normalize. + */ +static void sp_384_norm_15(sp_digit* a) +{ +#ifdef WOLFSSL_SP_SMALL + int i; + for (i = 0; i < 14; i++) { + a[i+1] += a[i] >> 26; + a[i] &= 0x3ffffff; + } +#else + a[1] += a[0] >> 26; a[0] &= 0x3ffffff; + a[2] += a[1] >> 26; a[1] &= 0x3ffffff; + a[3] += a[2] >> 26; a[2] &= 0x3ffffff; + a[4] += a[3] >> 26; a[3] &= 0x3ffffff; + a[5] += a[4] >> 26; a[4] &= 0x3ffffff; + a[6] += a[5] >> 26; a[5] &= 0x3ffffff; + a[7] += a[6] >> 26; a[6] &= 0x3ffffff; + a[8] += a[7] >> 26; a[7] &= 0x3ffffff; + a[9] += a[8] >> 26; a[8] &= 0x3ffffff; + a[10] += a[9] >> 26; a[9] &= 0x3ffffff; + a[11] += a[10] >> 26; a[10] &= 0x3ffffff; + a[12] += a[11] >> 26; a[11] &= 0x3ffffff; + a[13] += a[12] >> 26; a[12] &= 0x3ffffff; + a[14] += a[13] >> 26; a[13] &= 0x3ffffff; +#endif +} + +/* Shift the result in the high 384 bits down to the bottom. + * + * r A single precision number. + * a A single precision number. + */ +static void sp_384_mont_shift_15(sp_digit* r, const sp_digit* a) +{ +#ifdef WOLFSSL_SP_SMALL + int i; + int64_t n = a[14] >> 20; + n += ((int64_t)a[15]) << 6; + + for (i = 0; i < 14; i++) { + r[i] = n & 0x3ffffff; + n >>= 26; + n += ((int64_t)a[16 + i]) << 6; + } + r[14] = (sp_digit)n; +#else + int64_t n = a[14] >> 20; + n += ((int64_t)a[15]) << 6; + r[ 0] = n & 0x3ffffff; n >>= 26; n += ((int64_t)a[16]) << 6; + r[ 1] = n & 0x3ffffff; n >>= 26; n += ((int64_t)a[17]) << 6; + r[ 2] = n & 0x3ffffff; n >>= 26; n += ((int64_t)a[18]) << 6; + r[ 3] = n & 0x3ffffff; n >>= 26; n += ((int64_t)a[19]) << 6; + r[ 4] = n & 0x3ffffff; n >>= 26; n += ((int64_t)a[20]) << 6; + r[ 5] = n & 0x3ffffff; n >>= 26; n += ((int64_t)a[21]) << 6; + r[ 6] = n & 0x3ffffff; n >>= 26; n += ((int64_t)a[22]) << 6; + r[ 7] = n & 0x3ffffff; n >>= 26; n += ((int64_t)a[23]) << 6; + r[ 8] = n & 0x3ffffff; n >>= 26; n += ((int64_t)a[24]) << 6; + r[ 9] = n & 0x3ffffff; n >>= 26; n += ((int64_t)a[25]) << 6; + r[10] = n & 0x3ffffff; n >>= 26; n += ((int64_t)a[26]) << 6; + r[11] = n & 0x3ffffff; n >>= 26; n += ((int64_t)a[27]) << 6; + r[12] = n & 0x3ffffff; n >>= 26; n += ((int64_t)a[28]) << 6; + r[13] = n & 0x3ffffff; n >>= 26; n += ((int64_t)a[29]) << 6; + r[14] = (sp_digit)n; +#endif /* WOLFSSL_SP_SMALL */ + XMEMSET(&r[15], 0, sizeof(*r) * 15U); +} + +/* 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. + */ +static void sp_384_mont_reduce_15(sp_digit* a, const sp_digit* m, sp_digit mp) +{ + int i; + sp_digit mu; + + sp_384_norm_15(a + 15); + + for (i=0; i<14; i++) { + mu = (a[i] * mp) & 0x3ffffff; + sp_384_mul_add_15(a+i, m, mu); + a[i+1] += a[i] >> 26; + } + mu = (a[i] * mp) & 0xfffffL; + 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)); + sp_384_norm_15(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_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] += c >> 52; + r[k + 1] = (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. + * a Number to square in Montogmery form. + * 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) +{ + sp_384_sqr_15(r, a); + sp_384_mont_reduce_15(r, m, mp); +} + +#if !defined(WOLFSSL_SP_SMALL) || defined(HAVE_COMP_KEY) +/* Square the Montgomery form number a number of times. (r = a ^ n mod m) + * + * r Result of squaring. + * a Number to square in Montogmery form. + * n Number of times to square. + * m Modulus (prime). + * mp Montogmery mulitplier. + */ +static void sp_384_mont_sqr_n_15(sp_digit* r, const sp_digit* a, int n, + const sp_digit* m, sp_digit mp) +{ + sp_384_mont_sqr_15(r, a, m, mp); + for (; n > 1; n--) { + sp_384_mont_sqr_15(r, r, m, mp); + } +} + +#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] = { + 0xfffffffdU,0x00000000U,0x00000000U,0xffffffffU,0xfffffffeU,0xffffffffU, + 0xffffffffU,0xffffffffU,0xffffffffU,0xffffffffU,0xffffffffU,0xffffffffU +}; +#endif /* !WOLFSSL_SP_SMALL */ + +/* Invert the number, in Montgomery form, modulo the modulus (prime) of the + * P384 curve. (r = 1 / a mod m) + * + * r Inverse result. + * a Number to invert. + * td Temporary data. + */ +static void sp_384_mont_inv_15(sp_digit* r, const sp_digit* a, sp_digit* td) +{ +#ifdef WOLFSSL_SP_SMALL + sp_digit* t = td; + int i; + + XMEMCPY(t, a, sizeof(sp_digit) * 15); + for (i=382; i>=0; i--) { + sp_384_mont_sqr_15(t, t, p384_mod, p384_mp_mod); + if (p384_mod_minus_2[i / 32] & ((sp_digit)1 << (i % 32))) + sp_384_mont_mul_15(t, t, a, p384_mod, p384_mp_mod); + } + XMEMCPY(r, t, sizeof(sp_digit) * 15); +#else + sp_digit* t1 = td; + sp_digit* t2 = td + 2 * 15; + sp_digit* t3 = td + 4 * 15; + sp_digit* t4 = td + 6 * 15; + sp_digit* t5 = td + 8 * 15; + + /* 0x2 */ + sp_384_mont_sqr_15(t1, a, p384_mod, p384_mp_mod); + /* 0x3 */ + sp_384_mont_mul_15(t5, t1, a, p384_mod, p384_mp_mod); + /* 0xc */ + sp_384_mont_sqr_n_15(t1, t5, 2, p384_mod, p384_mp_mod); + /* 0xf */ + sp_384_mont_mul_15(t2, t5, t1, p384_mod, p384_mp_mod); + /* 0x1e */ + sp_384_mont_sqr_15(t1, t2, p384_mod, p384_mp_mod); + /* 0x1f */ + sp_384_mont_mul_15(t4, t1, a, p384_mod, p384_mp_mod); + /* 0x3e0 */ + sp_384_mont_sqr_n_15(t1, t4, 5, p384_mod, p384_mp_mod); + /* 0x3ff */ + sp_384_mont_mul_15(t2, t4, t1, p384_mod, p384_mp_mod); + /* 0x7fe0 */ + sp_384_mont_sqr_n_15(t1, t2, 5, p384_mod, p384_mp_mod); + /* 0x7fff */ + sp_384_mont_mul_15(t4, t4, t1, p384_mod, p384_mp_mod); + /* 0x3fff8000 */ + sp_384_mont_sqr_n_15(t1, t4, 15, p384_mod, p384_mp_mod); + /* 0x3fffffff */ + sp_384_mont_mul_15(t2, t4, t1, p384_mod, p384_mp_mod); + /* 0xfffffffc */ + sp_384_mont_sqr_n_15(t3, t2, 2, p384_mod, p384_mp_mod); + /* 0xfffffffd */ + sp_384_mont_mul_15(r, t3, a, p384_mod, p384_mp_mod); + /* 0xffffffff */ + sp_384_mont_mul_15(t3, t5, t3, p384_mod, p384_mp_mod); + /* 0xfffffffc0000000 */ + sp_384_mont_sqr_n_15(t1, t2, 30, p384_mod, p384_mp_mod); + /* 0xfffffffffffffff */ + sp_384_mont_mul_15(t2, t2, t1, p384_mod, p384_mp_mod); + /* 0xfffffffffffffff000000000000000 */ + sp_384_mont_sqr_n_15(t1, t2, 60, p384_mod, p384_mp_mod); + /* 0xffffffffffffffffffffffffffffff */ + sp_384_mont_mul_15(t2, t2, t1, p384_mod, p384_mp_mod); + /* 0xffffffffffffffffffffffffffffff000000000000000000000000000000 */ + sp_384_mont_sqr_n_15(t1, t2, 120, p384_mod, p384_mp_mod); + /* 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */ + sp_384_mont_mul_15(t2, t2, t1, p384_mod, p384_mp_mod); + /* 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000 */ + sp_384_mont_sqr_n_15(t1, t2, 15, p384_mod, p384_mp_mod); + /* 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */ + sp_384_mont_mul_15(t2, t4, t1, p384_mod, p384_mp_mod); + /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00000000 */ + sp_384_mont_sqr_n_15(t1, t2, 33, p384_mod, p384_mp_mod); + /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff */ + sp_384_mont_mul_15(t2, t3, t1, p384_mod, p384_mp_mod); + /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff000000000000000000000000 */ + sp_384_mont_sqr_n_15(t1, t2, 96, p384_mod, p384_mp_mod); + /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffd */ + sp_384_mont_mul_15(r, r, t1, p384_mod, p384_mp_mod); + +#endif /* WOLFSSL_SP_SMALL */ +} + +/* 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_15(sp_point_384* r, const sp_point_384* p, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2*15; + int32_t n; + + sp_384_mont_inv_15(t1, p->z, t + 2*15); + + sp_384_mont_sqr_15(t2, t1, p384_mod, p384_mp_mod); + sp_384_mont_mul_15(t1, t2, t1, p384_mod, p384_mp_mod); + + /* x /= z^2 */ + sp_384_mont_mul_15(r->x, p->x, t2, p384_mod, p384_mp_mod); + XMEMSET(r->x + 15, 0, sizeof(r->x) / 2U); + sp_384_mont_reduce_15(r->x, p384_mod, p384_mp_mod); + /* Reduce x to less than modulus */ + n = sp_384_cmp_15(r->x, p384_mod); + sp_384_cond_sub_15(r->x, r->x, p384_mod, 0 - ((n >= 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_384_norm_15(r->x); + + /* y /= z^3 */ + sp_384_mont_mul_15(r->y, p->y, t1, p384_mod, p384_mp_mod); + XMEMSET(r->y + 15, 0, sizeof(r->y) / 2U); + sp_384_mont_reduce_15(r->y, p384_mod, p384_mp_mod); + /* Reduce y to less than modulus */ + n = sp_384_cmp_15(r->y, p384_mod); + sp_384_cond_sub_15(r->y, r->y, p384_mod, 0 - ((n >= 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_384_norm_15(r->y); + + XMEMSET(r->z, 0, sizeof(r->z)); + r->z[0] = 1; + +} + +#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. + * a First number to add in Montogmery form. + * b Second number to add in Montogmery form. + * m Modulus (prime). + */ +static void sp_384_mont_add_15(sp_digit* r, const sp_digit* a, const sp_digit* b, + const sp_digit* m) +{ + (void)sp_384_add_15(r, a, b); + sp_384_norm_15(r); + sp_384_cond_sub_15(r, r, m, 0 - (((r[14] >> 20) > 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_384_norm_15(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_384_mont_dbl_15(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + (void)sp_384_add_15(r, a, a); + sp_384_norm_15(r); + sp_384_cond_sub_15(r, r, m, 0 - (((r[14] >> 20) > 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_384_norm_15(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_384_mont_tpl_15(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + (void)sp_384_add_15(r, a, a); + sp_384_norm_15(r); + sp_384_cond_sub_15(r, r, m, 0 - (((r[14] >> 20) > 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_384_norm_15(r); + (void)sp_384_add_15(r, r, a); + sp_384_norm_15(r); + sp_384_cond_sub_15(r, r, m, 0 - (((r[14] >> 20) > 0) ? + (sp_digit)1 : (sp_digit)0)); + 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. + * + * 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_384_cond_add_15(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 < 15; i++) { + r[i] = a[i] + (b[i] & m); + } +#else + r[ 0] = a[ 0] + (b[ 0] & m); + r[ 1] = a[ 1] + (b[ 1] & m); + r[ 2] = a[ 2] + (b[ 2] & m); + r[ 3] = a[ 3] + (b[ 3] & m); + r[ 4] = a[ 4] + (b[ 4] & m); + r[ 5] = a[ 5] + (b[ 5] & m); + r[ 6] = a[ 6] + (b[ 6] & m); + r[ 7] = a[ 7] + (b[ 7] & m); + r[ 8] = a[ 8] + (b[ 8] & m); + r[ 9] = a[ 9] + (b[ 9] & m); + r[10] = a[10] + (b[10] & m); + r[11] = a[11] + (b[11] & m); + r[12] = a[12] + (b[12] & m); + r[13] = a[13] + (b[13] & m); + r[14] = a[14] + (b[14] & m); +#endif /* WOLFSSL_SP_SMALL */ +} + +/* 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_384_mont_sub_15(sp_digit* r, const sp_digit* a, const sp_digit* b, + const sp_digit* m) +{ + (void)sp_384_sub_15(r, a, b); + sp_384_cond_add_15(r, r, m, r[14] >> 20); + sp_384_norm_15(r); +} + +/* Shift number left one bit. + * Bottom bit is lost. + * + * r Result of shift. + * a Number to shift. + */ +SP_NOINLINE static void sp_384_rshift1_15(sp_digit* r, 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; + } +#else + r[0] = ((a[0] >> 1) | (a[1] << 25)) & 0x3ffffff; + r[1] = ((a[1] >> 1) | (a[2] << 25)) & 0x3ffffff; + r[2] = ((a[2] >> 1) | (a[3] << 25)) & 0x3ffffff; + r[3] = ((a[3] >> 1) | (a[4] << 25)) & 0x3ffffff; + r[4] = ((a[4] >> 1) | (a[5] << 25)) & 0x3ffffff; + r[5] = ((a[5] >> 1) | (a[6] << 25)) & 0x3ffffff; + r[6] = ((a[6] >> 1) | (a[7] << 25)) & 0x3ffffff; + r[7] = ((a[7] >> 1) | (a[8] << 25)) & 0x3ffffff; + r[8] = ((a[8] >> 1) | (a[9] << 25)) & 0x3ffffff; + r[9] = ((a[9] >> 1) | (a[10] << 25)) & 0x3ffffff; + r[10] = ((a[10] >> 1) | (a[11] << 25)) & 0x3ffffff; + r[11] = ((a[11] >> 1) | (a[12] << 25)) & 0x3ffffff; + r[12] = ((a[12] >> 1) | (a[13] << 25)) & 0x3ffffff; + r[13] = ((a[13] >> 1) | (a[14] << 25)) & 0x3ffffff; +#endif + r[14] = a[14] >> 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_384_div2_15(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + sp_384_cond_add_15(r, a, m, 0 - (a[0] & 1)); + sp_384_norm_15(r); + sp_384_rshift1_15(r, r); +} + +/* Double the Montgomery form projective point p. + * + * r Result of doubling point. + * p Point to double. + * t Temporary ordinate data. + */ +static void sp_384_proj_point_dbl_15(sp_point_384* r, const sp_point_384* p, sp_digit* t) +{ + sp_point_384* rp[2]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*15; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + /* When infinity don't double point passed in - constant time. */ + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_384*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_384)); + x = rp[p->infinity]->x; + y = rp[p->infinity]->y; + z = rp[p->infinity]->z; + /* Put point to double into result - good for infinity. */ + if (r != p) { + for (i=0; i<15; i++) { + r->x[i] = p->x[i]; + } + for (i=0; i<15; i++) { + r->y[i] = p->y[i]; + } + for (i=0; i<15; i++) { + r->z[i] = p->z[i]; + } + r->infinity = p->infinity; + } + + /* T1 = Z * Z */ + sp_384_mont_sqr_15(t1, z, p384_mod, p384_mp_mod); + /* Z = Y * Z */ + sp_384_mont_mul_15(z, y, z, p384_mod, p384_mp_mod); + /* Z = 2Z */ + sp_384_mont_dbl_15(z, z, p384_mod); + /* T2 = X - T1 */ + sp_384_mont_sub_15(t2, x, t1, p384_mod); + /* T1 = X + T1 */ + sp_384_mont_add_15(t1, x, t1, p384_mod); + /* T2 = T1 * T2 */ + sp_384_mont_mul_15(t2, t1, t2, p384_mod, p384_mp_mod); + /* T1 = 3T2 */ + sp_384_mont_tpl_15(t1, t2, p384_mod); + /* Y = 2Y */ + sp_384_mont_dbl_15(y, y, p384_mod); + /* Y = Y * Y */ + sp_384_mont_sqr_15(y, y, p384_mod, p384_mp_mod); + /* T2 = Y * Y */ + sp_384_mont_sqr_15(t2, y, p384_mod, p384_mp_mod); + /* T2 = T2/2 */ + sp_384_div2_15(t2, t2, p384_mod); + /* Y = Y * X */ + sp_384_mont_mul_15(y, y, x, p384_mod, p384_mp_mod); + /* X = T1 * T1 */ + sp_384_mont_mul_15(x, t1, t1, p384_mod, p384_mp_mod); + /* X = X - Y */ + sp_384_mont_sub_15(x, x, y, p384_mod); + /* X = X - Y */ + sp_384_mont_sub_15(x, x, y, p384_mod); + /* Y = Y - X */ + sp_384_mont_sub_15(y, y, x, p384_mod); + /* Y = Y * T1 */ + sp_384_mont_mul_15(y, y, t1, p384_mod, p384_mp_mod); + /* Y = Y - T2 */ + sp_384_mont_sub_15(y, y, t2, p384_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_384_cmp_equal_15(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])) == 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. + */ +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]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*15; + sp_digit* t3 = t + 4*15; + sp_digit* t4 = t + 6*15; + sp_digit* t5 = t + 8*15; + 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_384* a = p; + p = q; + q = a; + } + + /* Check double */ + (void)sp_384_sub_15(t1, p384_mod, q->y); + sp_384_norm_15(t1); + if ((sp_384_cmp_equal_15(p->x, q->x) & sp_384_cmp_equal_15(p->z, q->z) & + (sp_384_cmp_equal_15(p->y, q->y) | sp_384_cmp_equal_15(p->y, t1))) != 0) { + sp_384_proj_point_dbl_15(r, p, t); + } + else { + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_384*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_384)); + 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<15; i++) { + r->x[i] = ap[p->infinity]->x[i]; + } + for (i=0; i<15; i++) { + r->y[i] = ap[p->infinity]->y[i]; + } + for (i=0; i<15; i++) { + r->z[i] = ap[p->infinity]->z[i]; + } + r->infinity = ap[p->infinity]->infinity; + + /* U1 = X1*Z2^2 */ + sp_384_mont_sqr_15(t1, q->z, p384_mod, p384_mp_mod); + sp_384_mont_mul_15(t3, t1, q->z, p384_mod, p384_mp_mod); + sp_384_mont_mul_15(t1, t1, x, p384_mod, p384_mp_mod); + /* U2 = X2*Z1^2 */ + sp_384_mont_sqr_15(t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_15(t4, t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_15(t2, t2, q->x, p384_mod, p384_mp_mod); + /* S1 = Y1*Z2^3 */ + sp_384_mont_mul_15(t3, t3, y, p384_mod, p384_mp_mod); + /* S2 = Y2*Z1^3 */ + sp_384_mont_mul_15(t4, t4, q->y, p384_mod, p384_mp_mod); + /* H = U2 - U1 */ + sp_384_mont_sub_15(t2, t2, t1, p384_mod); + /* R = S2 - S1 */ + sp_384_mont_sub_15(t4, t4, t3, p384_mod); + /* Z3 = H*Z1*Z2 */ + sp_384_mont_mul_15(z, z, q->z, p384_mod, p384_mp_mod); + sp_384_mont_mul_15(z, z, t2, p384_mod, p384_mp_mod); + /* X3 = R^2 - H^3 - 2*U1*H^2 */ + sp_384_mont_sqr_15(x, t4, p384_mod, p384_mp_mod); + sp_384_mont_sqr_15(t5, t2, p384_mod, p384_mp_mod); + sp_384_mont_mul_15(y, t1, t5, p384_mod, p384_mp_mod); + sp_384_mont_mul_15(t5, t5, t2, p384_mod, p384_mp_mod); + sp_384_mont_sub_15(x, x, t5, p384_mod); + sp_384_mont_dbl_15(t1, y, p384_mod); + sp_384_mont_sub_15(x, x, t1, p384_mod); + /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */ + sp_384_mont_sub_15(y, y, x, p384_mod); + sp_384_mont_mul_15(y, y, t4, p384_mod, p384_mp_mod); + sp_384_mont_mul_15(t5, t5, t3, p384_mod, p384_mp_mod); + sp_384_mont_sub_15(y, y, t5, p384_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. + * + * r Resulting point. + * g Point to multiply. + * 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_384_ecc_mulmod_15(sp_point_384* r, const sp_point_384* g, const sp_digit* k, + int map, void* heap) +{ + sp_point_384* td; + sp_point_384* t[3]; + sp_digit* tmp; + sp_digit n; + int i; + int c, y; + int err = MP_OKAY; + + (void)heap; + + td = (sp_point_384*)XMALLOC(sizeof(sp_point_384) * 3, heap, DYNAMIC_TYPE_ECC); + if (td == NULL) + err = MEMORY_E; + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 15 * 6, heap, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) + err = MEMORY_E; + + if (err == MP_OKAY) { + XMEMSET(td, 0, sizeof(*td) * 3); + + t[0] = &td[0]; + t[1] = &td[1]; + t[2] = &td[2]; + + /* t[0] = {0, 0, 1} * norm */ + t[0]->infinity = 1; + /* t[1] = {g->x, g->y, g->z} * norm */ + err = sp_384_mod_mul_norm_15(t[1]->x, g->x, p384_mod); + } + if (err == MP_OKAY) + err = sp_384_mod_mul_norm_15(t[1]->y, g->y, p384_mod); + if (err == MP_OKAY) + err = sp_384_mod_mul_norm_15(t[1]->z, g->z, p384_mod); + + if (err == MP_OKAY) { + i = 14; + c = 20; + n = k[i--] << (26 - c); + for (; ; c--) { + if (c == 0) { + if (i == -1) + break; + + n = k[i--]; + c = 26; + } + + y = (n >> 25) & 1; + n <<= 1; + + sp_384_proj_point_add_15(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_384)); + sp_384_proj_point_dbl_15(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_384)); + } + + if (map != 0) { + sp_384_map_15(r, t[0], tmp); + } + else { + XMEMCPY(r, t[0], sizeof(sp_point_384)); + } + } + + if (tmp != NULL) { + XMEMSET(tmp, 0, sizeof(sp_digit) * 2 * 15 * 6); + XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); + } + if (td != NULL) { + XMEMSET(td, 0, sizeof(sp_point_384) * 3); + XFREE(td, NULL, DYNAMIC_TYPE_ECC); + } + + return err; +} + +#elif defined(WOLFSSL_SP_CACHE_RESISTANT) +/* Multiply the point 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. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_ecc_mulmod_15(sp_point_384* r, const sp_point_384* g, const sp_digit* k, + int map, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 td[3]; + sp_digit tmpd[2 * 15 * 6]; +#endif + sp_point_384* t; + sp_digit* tmp; + sp_digit n; + int i; + int c, y; + int err = MP_OKAY; + + (void)heap; + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_point_384 td[3]; + t = (sp_point_384*)XMALLOC(sizeof(*td) * 3, heap, DYNAMIC_TYPE_ECC); + if (t == NULL) + err = MEMORY_E; + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 15 * 6, heap, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) + err = MEMORY_E; +#else + t = td; + tmp = tmpd; +#endif + + if (err == MP_OKAY) { + t[0] = &td[0]; + t[1] = &td[1]; + t[2] = &td[2]; + + /* 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_384_mod_mul_norm_15(t[1].x, g->x, p384_mod); + } + if (err == MP_OKAY) + err = sp_384_mod_mul_norm_15(t[1].y, g->y, p384_mod); + if (err == MP_OKAY) + err = sp_384_mod_mul_norm_15(t[1].z, g->z, p384_mod); + + if (err == MP_OKAY) { + i = 14; + c = 20; + n = k[i--] << (26 - c); + for (; ; c--) { + if (c == 0) { + if (i == -1) + break; + + n = k[i--]; + c = 26; + } + + y = (n >> 25) & 1; + n <<= 1; + + sp_384_proj_point_add_15(&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(t[2])); + sp_384_proj_point_dbl_15(&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(t[2])); + } + + if (map != 0) { + sp_384_map_15(r, &t[0], tmp); + } + else { + XMEMCPY(r, &t[0], sizeof(sp_point_384)); + } + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (tmp != NULL) { + XMEMSET(tmp, 0, sizeof(sp_digit) * 2 * 15 * 6); + XFREE(tmp, heap, DYNAMIC_TYPE_ECC); + } + if (t != NULL) { + XMEMSET(t, 0, sizeof(sp_point_384) * 3); + XFREE(t, heap, DYNAMIC_TYPE_ECC); + } +#else + ForceZero(tmpd, sizeof(tmpd)); + ForceZero(td, sizeof(td)); +#endif + + return err; +} + +#else +/* A table entry for pre-computed points. */ +typedef struct sp_table_entry_384 { + sp_digit x[15]; + sp_digit y[15]; +} sp_table_entry_384; + +/* Multiply the point 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. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_ecc_mulmod_fast_15(sp_point_384* r, const sp_point_384* g, const sp_digit* k, + int map, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 td[16]; + sp_point_384 rtd; + sp_digit tmpd[2 * 15 * 6]; +#endif + sp_point_384* t; + sp_point_384* rt; + sp_digit* tmp; + sp_digit n; + int i; + int c, y; + int err; + + (void)heap; + + err = sp_384_point_new_15(heap, rtd, rt); +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + t = (sp_point_384*)XMALLOC(sizeof(sp_point_384) * 16, heap, DYNAMIC_TYPE_ECC); + if (t == NULL) + err = MEMORY_E; + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 15 * 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 */ + (void)sp_384_mod_mul_norm_15(t[1].x, g->x, p384_mod); + (void)sp_384_mod_mul_norm_15(t[1].y, g->y, p384_mod); + (void)sp_384_mod_mul_norm_15(t[1].z, g->z, p384_mod); + t[1].infinity = 0; + sp_384_proj_point_dbl_15(&t[ 2], &t[ 1], tmp); + t[ 2].infinity = 0; + sp_384_proj_point_add_15(&t[ 3], &t[ 2], &t[ 1], tmp); + t[ 3].infinity = 0; + sp_384_proj_point_dbl_15(&t[ 4], &t[ 2], tmp); + t[ 4].infinity = 0; + sp_384_proj_point_add_15(&t[ 5], &t[ 3], &t[ 2], tmp); + t[ 5].infinity = 0; + sp_384_proj_point_dbl_15(&t[ 6], &t[ 3], tmp); + t[ 6].infinity = 0; + sp_384_proj_point_add_15(&t[ 7], &t[ 4], &t[ 3], tmp); + t[ 7].infinity = 0; + sp_384_proj_point_dbl_15(&t[ 8], &t[ 4], tmp); + t[ 8].infinity = 0; + sp_384_proj_point_add_15(&t[ 9], &t[ 5], &t[ 4], tmp); + t[ 9].infinity = 0; + sp_384_proj_point_dbl_15(&t[10], &t[ 5], tmp); + t[10].infinity = 0; + sp_384_proj_point_add_15(&t[11], &t[ 6], &t[ 5], tmp); + t[11].infinity = 0; + sp_384_proj_point_dbl_15(&t[12], &t[ 6], tmp); + t[12].infinity = 0; + sp_384_proj_point_add_15(&t[13], &t[ 7], &t[ 6], tmp); + t[13].infinity = 0; + sp_384_proj_point_dbl_15(&t[14], &t[ 7], tmp); + t[14].infinity = 0; + sp_384_proj_point_add_15(&t[15], &t[ 8], &t[ 7], tmp); + t[15].infinity = 0; + + i = 13; + n = k[i+1] << 6; + c = 16; + y = n >> 22; + XMEMCPY(rt, &t[y], sizeof(sp_point_384)); + n <<= 10; + for (; i>=0 || c>=4; ) { + if (c < 4) { + n |= k[i--] << (6 - c); + c += 26; + } + y = (n >> 28) & 0xf; + n <<= 4; + c -= 4; + + sp_384_proj_point_dbl_15(rt, rt, tmp); + sp_384_proj_point_dbl_15(rt, rt, tmp); + sp_384_proj_point_dbl_15(rt, rt, tmp); + sp_384_proj_point_dbl_15(rt, rt, tmp); + + sp_384_proj_point_add_15(rt, rt, &t[y], tmp); + } + + if (map != 0) { + sp_384_map_15(r, rt, tmp); + } + else { + XMEMCPY(r, rt, sizeof(sp_point_384)); + } + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (tmp != NULL) { + XMEMSET(tmp, 0, sizeof(sp_digit) * 2 * 15 * 6); + XFREE(tmp, heap, DYNAMIC_TYPE_ECC); + } + if (t != NULL) { + XMEMSET(t, 0, sizeof(sp_point_384) * 16); + XFREE(t, heap, DYNAMIC_TYPE_ECC); + } +#else + ForceZero(tmpd, sizeof(tmpd)); + ForceZero(td, sizeof(td)); +#endif + sp_384_point_free_15(rt, 1, heap); + + return err; +} + +#ifdef FP_ECC +/* 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_384_proj_point_dbl_n_15(sp_point_384* r, const sp_point_384* p, int n, + sp_digit* t) +{ + sp_point_384* rp[2]; + sp_digit* w = t; + sp_digit* a = t + 2*15; + sp_digit* b = t + 4*15; + sp_digit* t1 = t + 6*15; + sp_digit* t2 = t + 8*15; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_384*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_384)); + x = rp[p->infinity]->x; + y = rp[p->infinity]->y; + z = rp[p->infinity]->z; + if (r != p) { + for (i=0; i<15; i++) { + r->x[i] = p->x[i]; + } + for (i=0; i<15; i++) { + r->y[i] = p->y[i]; + } + for (i=0; i<15; i++) { + r->z[i] = p->z[i]; + } + r->infinity = p->infinity; + } + + /* Y = 2*Y */ + sp_384_mont_dbl_15(y, y, p384_mod); + /* 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); + while (n-- > 0) { + /* 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); + sp_384_mont_tpl_15(a, t1, p384_mod); + /* 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 = A^2 - 2B */ + sp_384_mont_sqr_15(x, a, p384_mod, p384_mp_mod); + sp_384_mont_dbl_15(t1, b, p384_mod); + sp_384_mont_sub_15(x, x, t1, p384_mod); + /* Z = Z*Y */ + sp_384_mont_mul_15(z, z, y, p384_mod, p384_mp_mod); + /* t2 = Y^4 */ + sp_384_mont_sqr_15(t2, t2, p384_mod, p384_mp_mod); + if (n != 0) { + /* W = W*Y^4 */ + sp_384_mont_mul_15(w, w, t2, p384_mod, p384_mp_mod); + } + /* y = 2*A*(B - X) - Y^4 */ + sp_384_mont_sub_15(y, b, x, p384_mod); + sp_384_mont_mul_15(y, y, a, p384_mod, p384_mp_mod); + sp_384_mont_dbl_15(y, y, p384_mod); + sp_384_mont_sub_15(y, y, t2, p384_mod); + } + /* Y = Y/2 */ + sp_384_div2_15(y, y, p384_mod); +} + +#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_384_proj_point_add_qz1_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]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*15; + sp_digit* t3 = t + 4*15; + sp_digit* t4 = t + 6*15; + sp_digit* t5 = t + 8*15; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + /* Check double */ + (void)sp_384_sub_15(t1, p384_mod, q->y); + sp_384_norm_15(t1); + if ((sp_384_cmp_equal_15(p->x, q->x) & sp_384_cmp_equal_15(p->z, q->z) & + (sp_384_cmp_equal_15(p->y, q->y) | sp_384_cmp_equal_15(p->y, t1))) != 0) { + sp_384_proj_point_dbl_15(r, p, t); + } + else { + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_384*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_384)); + 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<15; i++) { + r->x[i] = ap[p->infinity]->x[i]; + } + for (i=0; i<15; i++) { + r->y[i] = ap[p->infinity]->y[i]; + } + for (i=0; i<15; i++) { + r->z[i] = ap[p->infinity]->z[i]; + } + r->infinity = ap[p->infinity]->infinity; + + /* U2 = X2*Z1^2 */ + sp_384_mont_sqr_15(t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_15(t4, t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_15(t2, t2, q->x, p384_mod, p384_mp_mod); + /* S2 = Y2*Z1^3 */ + sp_384_mont_mul_15(t4, t4, q->y, p384_mod, p384_mp_mod); + /* H = U2 - X1 */ + sp_384_mont_sub_15(t2, t2, x, p384_mod); + /* R = S2 - Y1 */ + sp_384_mont_sub_15(t4, t4, y, p384_mod); + /* Z3 = H*Z1 */ + sp_384_mont_mul_15(z, z, t2, p384_mod, p384_mp_mod); + /* X3 = R^2 - H^3 - 2*X1*H^2 */ + sp_384_mont_sqr_15(t1, t4, p384_mod, p384_mp_mod); + sp_384_mont_sqr_15(t5, t2, p384_mod, p384_mp_mod); + sp_384_mont_mul_15(t3, x, t5, p384_mod, p384_mp_mod); + sp_384_mont_mul_15(t5, t5, t2, p384_mod, p384_mp_mod); + sp_384_mont_sub_15(x, t1, t5, p384_mod); + sp_384_mont_dbl_15(t1, t3, p384_mod); + sp_384_mont_sub_15(x, x, t1, p384_mod); + /* Y3 = R*(X1*H^2 - X3) - Y1*H^3 */ + sp_384_mont_sub_15(t3, t3, x, p384_mod); + sp_384_mont_mul_15(t3, t3, t4, p384_mod, p384_mp_mod); + sp_384_mont_mul_15(t5, t5, y, p384_mod, p384_mp_mod); + sp_384_mont_sub_15(y, t3, t5, p384_mod); + } +} + +#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_15(sp_point_384* a, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 15; + sp_digit* tmp = t + 4 * 15; + + sp_384_mont_inv_15(t1, a->z, tmp); + + sp_384_mont_sqr_15(t2, t1, p384_mod, p384_mp_mod); + sp_384_mont_mul_15(t1, t2, t1, p384_mod, p384_mp_mod); + + sp_384_mont_mul_15(a->x, a->x, t2, p384_mod, p384_mp_mod); + sp_384_mont_mul_15(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. + * + * 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_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) + sp_point_384 td, s1d, s2d; +#endif + sp_point_384* t; + sp_point_384* s1 = NULL; + sp_point_384* s2 = NULL; + int i, j; + int err; + + (void)heap; + + err = sp_384_point_new_15(heap, td, t); + if (err == MP_OKAY) { + err = sp_384_point_new_15(heap, s1d, s1); + } + if (err == MP_OKAY) { + err = sp_384_point_new_15(heap, s2d, s2); + } + + if (err == MP_OKAY) { + err = sp_384_mod_mul_norm_15(t->x, a->x, p384_mod); + } + if (err == MP_OKAY) { + err = sp_384_mod_mul_norm_15(t->y, a->y, p384_mod); + } + if (err == MP_OKAY) { + err = sp_384_mod_mul_norm_15(t->z, a->z, p384_mod); + } + if (err == MP_OKAY) { + t->infinity = 0; + sp_384_proj_to_affine_15(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_15(t, t, 48, tmp); + sp_384_proj_to_affine_15(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_15(t, s1, s2, tmp); + sp_384_proj_to_affine_15(t, tmp); + XMEMCPY(table[j].x, t->x, sizeof(table->x)); + XMEMCPY(table[j].y, t->y, sizeof(table->y)); + } + } + } + + sp_384_point_free_15(s2, 0, heap); + sp_384_point_free_15(s1, 0, heap); + sp_384_point_free_15( t, 0, heap); + + return err; +} + +#endif /* FP_ECC */ +/* Multiply the point 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_384_ecc_mulmod_stripe_15(sp_point_384* r, const sp_point_384* g, + const sp_table_entry_384* table, const sp_digit* k, int map, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 rtd; + sp_point_384 pd; + sp_digit td[2 * 15 * 6]; +#endif + sp_point_384* rt; + sp_point_384* p = NULL; + sp_digit* t; + int i, j; + int y, x; + int err; + + (void)g; + (void)heap; + + + err = sp_384_point_new_15(heap, rtd, rt); + if (err == MP_OKAY) { + err = sp_384_point_new_15(heap, pd, p); + } +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 15 * 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; + for (j=0,x=47; j<8; j++,x+=48) { + y |= ((k[x / 26] >> (x % 26)) & 1) << j; + } + 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; + for (j=0,x=i; j<8; j++,x+=48) { + y |= ((k[x / 26] >> (x % 26)) & 1) << j; + } + + sp_384_proj_point_dbl_15(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_384_proj_point_add_qz1_15(rt, rt, p, t); + } + + if (map != 0) { + sp_384_map_15(r, rt, t); + } + else { + XMEMCPY(r, rt, sizeof(sp_point_384)); + } + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (t != NULL) { + XFREE(t, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_15(p, 0, heap); + sp_384_point_free_15(rt, 0, heap); + + return err; +} + +#ifdef FP_ECC +#ifndef FP_ENTRIES + #define FP_ENTRIES 16 +#endif + +typedef struct sp_cache_384_t { + sp_digit x[15]; + sp_digit y[15]; + sp_table_entry_384 table[256]; + uint32_t cnt; + int set; +} sp_cache_384_t; + +static THREAD_LS_T sp_cache_384_t sp_cache_384[FP_ENTRIES]; +static THREAD_LS_T int sp_cache_384_last = -1; +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 + +static void sp_ecc_get_cache_384(const sp_point_384* g, sp_cache_384_t** cache) +{ + int i, j; + uint32_t least; + + if (sp_cache_384_inited == 0) { + for (i=0; ix, sp_cache_384[i].x) & + sp_384_cmp_equal_15(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. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_ecc_mulmod_15(sp_point_384* r, const sp_point_384* g, const sp_digit* k, + int map, void* heap) +{ +#ifndef FP_ECC + return sp_384_ecc_mulmod_fast_15(r, g, k, map, heap); +#else + sp_digit tmp[2 * 15 * 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_15(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_fast_15(r, g, k, map, heap); + } + else { + err = sp_384_ecc_mulmod_stripe_15(r, g, cache->table, k, + map, 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_384(mp_int* km, ecc_point* gm, ecc_point* r, int map, + void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 p; + sp_digit kd[15]; +#endif + sp_point_384* point; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_384_point_new_15(heap, p, point); +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 15, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) + err = MEMORY_E; + } +#else + k = kd; +#endif + if (err == MP_OKAY) { + sp_384_from_mp(k, 15, km); + sp_384_point_from_ecc_point_15(point, gm); + + err = sp_384_ecc_mulmod_15(point, point, k, map, heap); + } + if (err == MP_OKAY) { + err = sp_384_point_to_ecc_point_15(point, r); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + 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. + * + * 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_384_ecc_mulmod_base_15(sp_point_384* r, const sp_digit* k, + int map, void* heap) +{ + /* No pre-computed values. */ + return sp_384_ecc_mulmod_15(r, &p384_base, k, map, heap); +} + +#else +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 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 */ + { { 0x1c0b528,0x01d5992,0x0e383dd,0x38a835b,0x220e378,0x106d35b, + 0x1c3afc5,0x03bfe1e,0x28459a3,0x2d91521,0x214ede2,0x0bfdc8d, + 0x2151381,0x3708a67,0x004d3aa }, + { 0x303a4fe,0x10f6b52,0x29ac230,0x2fdeed2,0x0a1bfa8,0x3a0ec14, + 0x2de7562,0x3ff662e,0x21968f4,0x031b0d4,0x3969a84,0x2000898, + 0x1c5e9dd,0x2f09685,0x002b78a } }, + /* 2 */ + { { 0x30c535b,0x191d4ca,0x2296298,0x14dc141,0x090dd69,0x05aae6b, + 0x0cd6b42,0x35da80e,0x3b7be12,0x2cf7e6d,0x1f347bd,0x3d365e1, + 0x1448913,0x32704fa,0x00222c5 }, + { 0x280dc64,0x39e5bc9,0x24175f8,0x2dd60d4,0x0120e7c,0x041d02e, + 0x0b5d8ad,0x37b9895,0x2fb5337,0x1f0e2e3,0x14f0224,0x2230b86, + 0x1bc4cf6,0x17cdb09,0x007b5c7 } }, + /* 3 */ + { { 0x2dffea5,0x28f30e7,0x29fce26,0x070df5f,0x235bbfd,0x2f78fbd, + 0x27700d9,0x23d6bc3,0x3471a53,0x0c0e03a,0x05bf9eb,0x276a2ec, + 0x20c3e2e,0x31cc691,0x00dbb93 }, + { 0x126b605,0x2e8983d,0x153737d,0x23bf5e1,0x295d497,0x35ca812, + 0x2d793ae,0x16c6893,0x3777600,0x089a520,0x1e681f8,0x3d55ee6, + 0x154ef99,0x155f592,0x00ae5f9 } }, + /* 4 */ + { { 0x26feef9,0x20315fc,0x1240244,0x250e838,0x3c31a26,0x1cf8af1, + 0x1002c32,0x3b531cd,0x1c53ef1,0x22310ba,0x3f4948e,0x22eafd9, + 0x3863202,0x3d0e2a5,0x006a502 }, + { 0x34536fe,0x04e91ad,0x30ebf5f,0x2af62a7,0x01d218b,0x1c8c9da, + 0x336bcc3,0x23060c3,0x331576e,0x1b14c5e,0x1bbcb76,0x0755e9a, + 0x3d4dcef,0x24c2cf8,0x00917c4 } }, + /* 5 */ + { { 0x349ddd0,0x09b8bb8,0x0250114,0x3e66cbf,0x29f117e,0x3005d29, + 0x36b480e,0x2119bfc,0x2761845,0x253d2f7,0x0580604,0x0bb6db4, + 0x3ca922f,0x1744677,0x008adc7 }, + { 0x3d5a7ce,0x27425ed,0x11e9a61,0x3968d10,0x3874275,0x3692d3b, + 0x03e0470,0x0763d50,0x3d97790,0x3cbaeab,0x2747170,0x18faf3a, + 0x180365e,0x2511fe7,0x0012a36 } }, + /* 6 */ + { { 0x3c52870,0x2701e93,0x296128f,0x120694e,0x1ce0b37,0x3860a36, + 0x10fa180,0x0896b55,0x2f76adb,0x22892ae,0x2e58a34,0x07b4295, + 0x2cb62d1,0x079a522,0x00f3d81 }, + { 0x061ed22,0x2375dd3,0x3c9d861,0x3e602d1,0x10bb747,0x39ae156, + 0x3f796fd,0x087a48a,0x06d680a,0x37f7f47,0x2af2c9d,0x36c55dc, + 0x10f3dc0,0x279b07a,0x00a0937 } }, + /* 7 */ + { { 0x085c629,0x319bbf8,0x089a386,0x184256f,0x15fc2a4,0x00fd2d0, + 0x13d6312,0x363d44d,0x32b7e4b,0x25f2865,0x27df8ce,0x1dce02a, + 0x24ea3b0,0x0e27b9f,0x00d8a90 }, + { 0x3b14461,0x1d371f9,0x0f781bc,0x0503271,0x0dc2cb0,0x13bc284, + 0x34b3a68,0x1ff894a,0x25d2032,0x16f79ba,0x260f961,0x07b10d5, + 0x18173b7,0x2812e2b,0x00eede5 } }, + /* 8 */ + { { 0x13b9a2d,0x132ece2,0x0c5d558,0x02c0214,0x1820c66,0x37cb50f, + 0x26d8267,0x3a00504,0x3f00109,0x33756ee,0x38172f1,0x2e4bb8c, + 0x030d985,0x3e4fcc5,0x00609d4 }, + { 0x2daf9d6,0x16681fa,0x1fb01e0,0x1b03c49,0x370e653,0x183c839, + 0x2207515,0x0ea6b58,0x1ae7aaf,0x3a96522,0x24bae14,0x1c38bd9, + 0x082497b,0x1c05db4,0x000dd03 } }, + /* 9 */ + { { 0x110521f,0x04efa21,0x0c174cc,0x2a7dc93,0x387315b,0x14f7098, + 0x1d83bb3,0x2495ed2,0x2fe0c27,0x1e2d9df,0x093c953,0x0287073, + 0x02c9951,0x336291c,0x0033e30 }, + { 0x208353f,0x3f22748,0x2b2bf0f,0x2373b50,0x10170fa,0x1b8a97d, + 0x0851ed2,0x0b25824,0x055ecb5,0x12049d9,0x3fe1adf,0x11b1385, + 0x28eab06,0x11fac21,0x00513f0 } }, + /* 10 */ + { { 0x35bdf53,0x1847d37,0x1a6dc07,0x29d62c4,0x045d331,0x313b8e5, + 0x165daf1,0x1e34562,0x3e75a58,0x16ea2fa,0x02dd302,0x3302862, + 0x3eb8bae,0x2266a48,0x00cf2a3 }, + { 0x24fd048,0x324a074,0x025df98,0x1662eec,0x3841bfb,0x26ae754, + 0x1df8cec,0x0113ae3,0x0b67fef,0x094e293,0x2323666,0x0ab087c, + 0x2f06509,0x0e142d9,0x00a919d } }, + /* 11 */ + { { 0x1d480d8,0x00ed021,0x3a7d3db,0x1e46ca1,0x28cd9f4,0x2a3ceeb, + 0x24dc754,0x0624a3c,0x0003db4,0x1520bae,0x1c56e0f,0x2fe7ace, + 0x1dc6f38,0x0c826a4,0x008b977 }, + { 0x209cfc2,0x2c16c9c,0x1b70a31,0x21416cb,0x34c49bf,0x186549e, + 0x062498d,0x146e959,0x0391fac,0x08ff944,0x2b4b834,0x013d57a, + 0x2eabffb,0x0370131,0x00c07c1 } }, + /* 12 */ + { { 0x332f048,0x0bf9336,0x16dfad2,0x2451d7b,0x35f23bf,0x299adb2, + 0x0ce0c0a,0x0170294,0x289f034,0x2b7d89e,0x395e2d6,0x1d20df7, + 0x2e64e36,0x16dae90,0x00081c9 }, + { 0x31d6ceb,0x0f80db9,0x0271eba,0x33db1ac,0x1b45bcc,0x1a11c07, + 0x347e630,0x148fd9e,0x142e712,0x3183e3e,0x1cd47ad,0x108d1c9, + 0x09cbb82,0x35e61d9,0x0083027 } }, + /* 13 */ + { { 0x215b0b8,0x0a7a98d,0x2c41b39,0x3f69536,0x0b41441,0x16da8da, + 0x15d556b,0x3c17a26,0x129167e,0x3ea0351,0x2d25a27,0x2f2d285, + 0x15b68f6,0x2931ef5,0x00210d6 }, + { 0x1351130,0x012aec9,0x37ebf38,0x26640f8,0x01d2df6,0x2130972, + 0x201efc0,0x23a457c,0x087a1c6,0x14c68a3,0x163f62a,0x36b494d, + 0x015d481,0x39c35b1,0x005dd6d } }, + /* 14 */ + { { 0x06612ce,0x11c3f61,0x199729f,0x3b36863,0x2986f3e,0x3cd2be1, + 0x04c1612,0x2be2dae,0x00846dd,0x3d7bc29,0x249e795,0x1016803, + 0x37a3714,0x2c5aa8b,0x005f491 }, + { 0x341b38d,0x01eb936,0x3caac7f,0x27863ef,0x1ef7d11,0x1110ec6, + 0x18e0761,0x26498e8,0x01a79a1,0x390d5a1,0x22226fb,0x3d2a473, + 0x0872191,0x1230f32,0x00dc772 } }, + /* 15 */ + { { 0x0b1ec9d,0x03fc6b9,0x3706d57,0x03b9fbb,0x221d23e,0x2867821, + 0x1e40f4c,0x2c9c0f3,0x3c4cd4b,0x31f5948,0x3f13aa6,0x307c1b2, + 0x04b6016,0x116b453,0x005aa72 }, + { 0x0b74de8,0x20519d1,0x134e37f,0x05d882a,0x1839e7a,0x3a2c6a8, + 0x0d14e8d,0x1d78bdd,0x251f30d,0x3a1e27e,0x081c261,0x2c9014b, + 0x165ee09,0x19e0cf1,0x00654e2 } }, + /* 16 */ + { { 0x39fbe67,0x081778b,0x0e44378,0x20dfdca,0x1c4afcb,0x20b803c, + 0x0ec06c6,0x1508f6f,0x1c3114d,0x3bca851,0x3a52463,0x07661d1, + 0x17b0aa0,0x16c5f5c,0x00fc093 }, + { 0x0d01f95,0x0ef13f5,0x2d34965,0x2a25582,0x39aa83e,0x3e38fcf, + 0x3943dca,0x385bbdd,0x210e86f,0x3dc1dd2,0x3f9ffdc,0x18b9bc6, + 0x345c96b,0x0e79621,0x008a72f } }, + /* 17 */ + { { 0x341c342,0x3793688,0x042273a,0x153a9c1,0x3dd326e,0x1d073bc, + 0x2c7d983,0x05524cd,0x00d59e6,0x347abe8,0x3d9a3ef,0x0fb624a, + 0x2c7e4cd,0x09b3171,0x0003faf }, + { 0x045f8ac,0x38bf3cc,0x1e73087,0x0c85d3c,0x314a655,0x382be69, + 0x384f28f,0x24d6cb3,0x2842cdc,0x1777f5e,0x2929c89,0x03c45ed, + 0x3cfcc4c,0x0b59322,0x0035657 } }, + /* 18 */ + { { 0x18c1bba,0x2eb005f,0x33d57ec,0x30e42c3,0x36058f9,0x1865f43, + 0x2116e3f,0x2c4a2bb,0x0684033,0x0f1375c,0x0209b98,0x2136e9b, + 0x1bc4af0,0x0b3e0c7,0x0097c7c }, + { 0x16010e8,0x398777e,0x2a172f4,0x0814a7e,0x0d97e4e,0x274dfc8, + 0x2666606,0x1b5c93b,0x1ed3d36,0x3f3304e,0x13488e0,0x02dbb88, + 0x2d53369,0x3717ce9,0x007cad1 } }, + /* 19 */ + { { 0x257a41f,0x2a6a076,0x39b6660,0x04bb000,0x1e74a04,0x3876b45, + 0x343c6b5,0x0753108,0x3f54668,0x24a13cf,0x23749e8,0x0421fc5, + 0x32f13b5,0x0f31be7,0x00070f2 }, + { 0x1186e14,0x0847697,0x0dff542,0x0dff76c,0x084748f,0x2c7d060, + 0x23aab4d,0x0b43906,0x27ba640,0x1497b59,0x02f5835,0x0a492a4, + 0x0a6892f,0x39f3e91,0x005844e } }, + /* 20 */ + { { 0x33b236f,0x02181cf,0x21dafab,0x0760788,0x019e9d4,0x249ed0a, + 0x36571e3,0x3c7dbcf,0x1337550,0x010d22a,0x285e62f,0x19ee65a, + 0x052bf71,0x1d65fd5,0x0062d43 }, + { 0x2955926,0x3fae7bc,0x0353d85,0x07db7de,0x1440a56,0x328dad6, + 0x1668ec9,0x28058e2,0x1a1a22d,0x1014afc,0x3609325,0x3effdcb, + 0x209f3bd,0x3ca3888,0x0094e50 } }, + /* 21 */ + { { 0x062e8af,0x0b96ccc,0x136990b,0x1d7a28f,0x1a85723,0x0076dec, + 0x21b00b2,0x06a88ff,0x2f0ee65,0x1fa49b7,0x39b10ad,0x10b26fa, + 0x0be7465,0x026e8bf,0x00098e3 }, + { 0x3f1d63f,0x37bacff,0x1374779,0x02882ff,0x323d0e8,0x1da3de5, + 0x12bb3b8,0x0a15a11,0x34d1f95,0x2b3dd6e,0x29ea3fa,0x39ad000, + 0x33a538f,0x390204d,0x0012bd3 } }, + /* 22 */ + { { 0x04cbba5,0x0de0344,0x1d4cc02,0x11fe8d7,0x36207e7,0x32a6da8, + 0x0239281,0x1ec40d7,0x3e89798,0x213fc66,0x0022eee,0x11daefe, + 0x3e74db8,0x28534ee,0x00aa0a4 }, + { 0x07d4543,0x250cc46,0x206620f,0x1c1e7db,0x1321538,0x31fa0b8, + 0x30f74ea,0x01aae0e,0x3a2828f,0x3e9dd22,0x026ef35,0x3c0a62b, + 0x27dbdc5,0x01c23a6,0x000f0c5 } }, + /* 23 */ + { { 0x2f029dd,0x3091337,0x21b80c5,0x21e1419,0x13dabc6,0x3847660, + 0x12b865f,0x36eb666,0x38f6274,0x0ba6006,0x098da24,0x1398c64, + 0x13d08e5,0x246a469,0x009929a }, + { 0x1285887,0x3ff5c8d,0x010237b,0x097c506,0x0bc7594,0x34b9b88, + 0x00cc35f,0x0bb964a,0x00cfbc4,0x29cd718,0x0837619,0x2b4a192, + 0x0c57bb7,0x08c69de,0x00a3627 } }, + /* 24 */ + { { 0x1361ed8,0x266d724,0x366cae7,0x1d5b18c,0x247d71b,0x2c9969a, + 0x0dd5211,0x1edd153,0x25998d7,0x0380856,0x3ab29db,0x09366de, + 0x1e53644,0x2b31ff6,0x008b0ff }, + { 0x3b5d9ef,0x217448d,0x174746d,0x18afea4,0x15b106d,0x3e66e8b, + 0x0479f85,0x13793b4,0x1231d10,0x3c39bce,0x25e8983,0x2a13210, + 0x05a7083,0x382be04,0x00a9507 } }, + /* 25 */ + { { 0x0cf381c,0x1a29b85,0x31ccf6c,0x2f708b8,0x3af9d27,0x2a29732, + 0x168d4da,0x393488d,0x2c0e338,0x3f90c7b,0x0f52ad1,0x2a0a3fa, + 0x2cd80f1,0x15e7a1a,0x00db6a0 }, + { 0x107832a,0x159cb91,0x1289288,0x17e21f9,0x073fc27,0x1584342, + 0x3802780,0x3d6c197,0x154075f,0x16366d1,0x09f712b,0x23a3ec4, + 0x29cf23a,0x3218baf,0x0039f0a } }, + /* 26 */ + { { 0x052edf5,0x2afde13,0x2e53d8f,0x3969626,0x3dcd737,0x1e46ac5, + 0x118bf0d,0x01b2652,0x156bcff,0x16d7ef6,0x1ca46d4,0x34c0cbb, + 0x3e486f6,0x1f85068,0x002cdff }, + { 0x1f47ec8,0x12cee98,0x0608667,0x18fbbe1,0x08a8821,0x31a1fe4, + 0x17c7054,0x3c89e89,0x2edf6cd,0x1b8c32c,0x3f6ea84,0x1319329, + 0x3cd3c2c,0x05f331a,0x00186fa } }, + /* 27 */ + { { 0x1fcb91e,0x0fd4d87,0x358a48a,0x04d91b4,0x083595e,0x044a1e6, + 0x15827b9,0x1d5eaf4,0x2b82187,0x08f3984,0x21bd737,0x0c54285, + 0x2f56887,0x14c2d98,0x00f4684 }, + { 0x01896f6,0x0e542d0,0x2090883,0x269dfcf,0x1e11cb8,0x239fd29, + 0x312cac4,0x19dfacb,0x369f606,0x0cc4f75,0x16579f9,0x33c22cc, + 0x0f22bfd,0x3b251ae,0x006429c } }, + /* 28 */ + { { 0x375f9a4,0x137552e,0x3570498,0x2e4a74e,0x24aef06,0x35b9307, + 0x384ca23,0x3bcd6d7,0x011b083,0x3c93187,0x392ca9f,0x129ce48, + 0x0a800ce,0x145d9cc,0x00865d6 }, + { 0x22b4a2b,0x37f9d9c,0x3e0eca3,0x3e5ec20,0x112c04b,0x2e1ae29, + 0x3ce5b51,0x0f83200,0x32d6a7e,0x10ff1d8,0x081adbe,0x265c30b, + 0x216b1c8,0x0eb4483,0x003cbcd } }, + /* 29 */ + { { 0x030ce93,0x2d331fb,0x20a2fbf,0x1f6dc9c,0x010ed6c,0x1ed5540, + 0x275bf74,0x3df0fb1,0x103333f,0x0241c96,0x1075bfc,0x30e5cf9, + 0x0f31bc7,0x32c01eb,0x00b049e }, + { 0x358839c,0x1dbabd3,0x1e4fb40,0x36a8ac1,0x2101896,0x2d0319b, + 0x2033b0a,0x192e8fd,0x2ebc8d8,0x2867ba7,0x07bf6d2,0x1b3c555, + 0x2477deb,0x198fe09,0x008e5a9 } }, + /* 30 */ + { { 0x3fbd5e1,0x18bf77d,0x2b1d69e,0x151da44,0x338ecfe,0x0768efe, + 0x1a3d56d,0x3c35211,0x10e1c86,0x2012525,0x3bc36ce,0x32b6fe4, + 0x0c8d183,0x15c93f3,0x0041fce }, + { 0x332c144,0x24e70a0,0x246e05f,0x22c21c7,0x2b17f24,0x1ba2bfd, + 0x0534e26,0x318a4f6,0x1dc3b85,0x0c741bc,0x23131b7,0x01a8cba, + 0x364e5db,0x21362cf,0x00f2951 } }, + /* 31 */ + { { 0x2ddc103,0x14ffdcd,0x206fd96,0x0de57bd,0x025f43e,0x381b73a, + 0x2301fcf,0x3bafc27,0x34130b6,0x0216bc8,0x0ff56b2,0x2c4ad4c, + 0x23c6b79,0x1267fa6,0x009b4fb }, + { 0x1d27ac2,0x13e2494,0x1389015,0x38d5b29,0x2d33167,0x3f01969, + 0x28ec1fa,0x1b26de0,0x2587f74,0x1c25668,0x0c44f83,0x23c6f8c, + 0x32fdbb1,0x045f104,0x00a7946 } }, + /* 32 */ + { { 0x23c647b,0x09addd7,0x1348c04,0x0e633c1,0x1bfcbd9,0x1cb034f, + 0x1312e31,0x11cdcc7,0x1e6ee75,0x057d27f,0x2da7ee6,0x154c3c1, + 0x3a5fb89,0x2c2ba2c,0x00cf281 }, + { 0x1b8a543,0x125cd50,0x1d30fd1,0x29cc203,0x341a625,0x14e4233, + 0x3aae076,0x289e38a,0x036ba02,0x230f405,0x3b21b8f,0x34088b9, + 0x01297a0,0x03a75fb,0x00fdc27 } }, + /* 33 */ + { { 0x07f41d6,0x1cf032f,0x1641008,0x0f86deb,0x3d97611,0x0e110fe, + 0x136ff42,0x0b914a9,0x0e241e6,0x180c340,0x1f545fc,0x0ba619d, + 0x1208c53,0x04223a4,0x00cd033 }, + { 0x397612c,0x0132665,0x34e2d1a,0x00bba99,0x1d4393e,0x065d0a8, + 0x2fa69ee,0x1643b55,0x08085f0,0x3774aad,0x08a2243,0x33bf149, + 0x03f41a5,0x1ed950e,0x0048cc6 } }, + /* 34 */ + { { 0x014ab48,0x010c3bf,0x2a744e5,0x13c99c1,0x2195b7f,0x32207fd, + 0x28a228c,0x004f4bf,0x0e2d945,0x2ec6e5a,0x0b92162,0x1aa95e5, + 0x2754a93,0x1adcd93,0x004fb76 }, + { 0x1e1ff7f,0x24ef28c,0x269113f,0x32b393c,0x2696eb5,0x0ac2780, + 0x354bf8a,0x0ffe3fd,0x09ce58e,0x0163c4f,0x1678c0b,0x15cd1bc, + 0x292b3b7,0x036ea19,0x00d5420 } }, + /* 35 */ + { { 0x1da1265,0x0c2ef5b,0x18dd9a0,0x3f3a25c,0x0f7b4f3,0x0d8196e, + 0x24931f9,0x090729a,0x1875f72,0x1ef39cb,0x2577585,0x2ed472d, + 0x136756c,0x20553a6,0x00c7161 }, + { 0x2e32189,0x283de4b,0x00b2e81,0x0989df7,0x3ef2fab,0x1c7d1a7, + 0x24f6feb,0x3e16679,0x233dfda,0x06d1233,0x3e6b5df,0x1707132, + 0x05f7b3f,0x2c00779,0x00fb8df } }, + /* 36 */ + { { 0x15bb921,0x117e9d3,0x267ec73,0x2f934ad,0x25c7e04,0x20b5e8f, + 0x2d3a802,0x2ca911f,0x3f87e47,0x39709dd,0x08488e2,0x2cec400, + 0x35b4589,0x1f0acba,0x009aad7 }, + { 0x2ac34ae,0x06f29f6,0x3326d68,0x3949abe,0x02452e4,0x0687b85, + 0x0879244,0x1eb7832,0x0d4c240,0x31d0ec1,0x3c17a2a,0x17a666f, + 0x01a06cb,0x3e0929c,0x004dca2 } }, + /* 37 */ + { { 0x127bc1a,0x0c72984,0x13be68e,0x26c5fab,0x1a3edd5,0x097d685, + 0x36b645e,0x385799e,0x394a420,0x39d8885,0x0b1e872,0x13f60ed, + 0x2ce1b79,0x3c0ecb7,0x007cab3 }, + { 0x29b3586,0x26fc572,0x0bd7711,0x0913494,0x0a55459,0x31af3c9, + 0x3633eac,0x3e2105c,0x0c2b1b6,0x0e6f4c2,0x047d38c,0x2b81bd5, + 0x1fe1c3b,0x04d7cd0,0x0054dcc } }, + /* 38 */ + { { 0x03caf0d,0x0d66365,0x313356d,0x2a4897f,0x2ce044e,0x18feb7a, + 0x1f6a7c5,0x3709e7b,0x14473e8,0x2d8cbae,0x3190dca,0x12d19f8, + 0x31e3181,0x3cc5b6e,0x002d4f4 }, + { 0x143b7ca,0x2604728,0x39508d6,0x0cb79f3,0x24ec1ac,0x1ed7fa0, + 0x3ab5fd3,0x3c76488,0x2e49390,0x03a0985,0x3580461,0x3fd2c81, + 0x308f0ab,0x38561d6,0x0011b9b } }, + /* 39 */ + { { 0x3be682c,0x0c68f4e,0x32dd4ae,0x099d3bb,0x0bc7c5d,0x311f750, + 0x2fd10a3,0x2e7864a,0x23bc14a,0x13b1f82,0x32e495e,0x1b0f746, + 0x3cd856a,0x17a4c26,0x00085ee }, + { 0x02e67fd,0x06a4223,0x2af2f38,0x2038987,0x132083a,0x1b7bb85, + 0x0d6a499,0x131e43f,0x3035e52,0x278ee3e,0x1d5b08b,0x30d8364, + 0x2719f8d,0x0b21fc9,0x003a06e } }, + /* 40 */ + { { 0x237cac0,0x27d6a1c,0x27945cd,0x2750d61,0x293f0b5,0x253db13, + 0x04a764e,0x20b4d0e,0x12bb627,0x160c13b,0x0de0601,0x236e2cf, + 0x2190f0b,0x354d76f,0x004336d }, + { 0x2ab473a,0x10d54e4,0x1046574,0x1d6f97b,0x0031c72,0x06426a9, + 0x38678c2,0x0b76cf9,0x04f9920,0x152adf8,0x2977e63,0x1234819, + 0x198be26,0x061024c,0x00d427d } }, + /* 41 */ + { { 0x39b5a31,0x2123d43,0x362a822,0x1a2eab6,0x0bb0034,0x0d5d567, + 0x3a04723,0x3a10c8c,0x08079ae,0x0d27bda,0x2eb9e1e,0x2619e82, + 0x39a55a8,0x0c6c7db,0x00c1519 }, + { 0x174251e,0x13ac2eb,0x295ed26,0x18d2afc,0x037b9b2,0x1258344, + 0x00921b0,0x1f702d8,0x1bc4da7,0x1c3794f,0x12b1869,0x366eacf, + 0x16ddf01,0x31ebdc5,0x00ad54e } }, + /* 42 */ + { { 0x1efdc58,0x1370d5e,0x0ddb8e7,0x1a53fda,0x1456bd3,0x0c825a9, + 0x0e74ccd,0x20f41c9,0x3423867,0x139073f,0x3c70d8a,0x131fc85, + 0x219a2a0,0x34bf986,0x0041199 }, + { 0x1c05dd2,0x268f80a,0x3da9d38,0x1af9f8f,0x0535f2a,0x30ad37e, + 0x2cf72d7,0x14a509b,0x1f4fe74,0x259e09d,0x1d23f51,0x0672732, + 0x08fc463,0x00b6201,0x001e05a } }, + /* 43 */ + { { 0x0d5ffe8,0x3238bb5,0x17f275c,0x25b6fa8,0x2f8bb48,0x3b8f2d2, + 0x059790c,0x18594d4,0x285a47c,0x3d301bb,0x12935d2,0x23ffc96, + 0x3d7c7f9,0x15c8cbf,0x0034c4a }, + { 0x20376a2,0x05201ba,0x1e02c4b,0x1413c45,0x02ea5e7,0x39575f0, + 0x2d76e21,0x113694c,0x011f310,0x0da3725,0x31b7799,0x1cb9195, + 0x0cfd592,0x22ee4ea,0x00adaa3 } }, + /* 44 */ + { { 0x14ed72a,0x031c49f,0x39a34bf,0x192e87d,0x0da0e92,0x130e7a9, + 0x00258bf,0x144e123,0x2d82a71,0x0294e53,0x3f06c66,0x3d4473a, + 0x037cd4a,0x3bbfb17,0x00fcebc }, + { 0x39ae8c1,0x2dd6a9d,0x206ef23,0x332b479,0x2deff59,0x09d5720, + 0x3526fd2,0x33bf7cf,0x344bb32,0x359316a,0x115bdef,0x1b8468a, + 0x3813ea9,0x11a8450,0x00ab197 } }, + /* 45 */ + { { 0x0837d7d,0x1e1617b,0x0ba443c,0x2f2e3b8,0x2ca5b6f,0x176ed7b, + 0x2924d9d,0x07294d3,0x104bb4f,0x1cfd3e8,0x398640f,0x1162dc8, + 0x007ea15,0x2aa75fd,0x004231f }, + { 0x16e6896,0x01987be,0x0f9d53e,0x1a740ec,0x1554e4c,0x31e1634, + 0x3cb07b9,0x013eb53,0x39352cb,0x1dfa549,0x0974e7f,0x17c55d2, + 0x157c85f,0x1561adb,0x002e3fa } }, + /* 46 */ + { { 0x29951a8,0x35200da,0x2ad042c,0x22109e4,0x3a8b15b,0x2eca69c, + 0x28bcf9a,0x0cfa063,0x0924099,0x12ff668,0x2fb88dc,0x028d653, + 0x2445876,0x218d01c,0x0014418 }, + { 0x1caedc7,0x295bba6,0x01c9162,0x3364744,0x28fb12e,0x24c80b6, + 0x2719673,0x35e5ba9,0x04aa4cc,0x206ab23,0x1cf185a,0x2c140d8, + 0x1095a7d,0x1b3633f,0x000c9f8 } }, + /* 47 */ + { { 0x0b2a556,0x0a051c4,0x30b29a7,0x190c9ed,0x3767ca9,0x38de66d, + 0x2d9e125,0x3aca813,0x2dc22a3,0x319e074,0x0d9450a,0x3445bac, + 0x3e08a5b,0x07f29fa,0x00eccac }, + { 0x02d6e94,0x21113f7,0x321bde6,0x0a4d7b3,0x03621f4,0x2780e8b, + 0x22d5432,0x1fc2853,0x0d57d3e,0x254f90b,0x33ed00b,0x289b025, + 0x12272bb,0x30e715f,0x0000297 } }, + /* 48 */ + { { 0x0243a7d,0x2aac42e,0x0c5b3aa,0x0fa3e96,0x06eeef9,0x2b9fdd9, + 0x26fca39,0x0134fe1,0x22661ab,0x1990416,0x03945d6,0x15e3628, + 0x3848ca3,0x0f91e46,0x00b08cd }, + { 0x16d2411,0x3717e1d,0x128c45e,0x3669d54,0x0d4a790,0x2797da8, + 0x0f09634,0x2faab0b,0x27df649,0x3b19b49,0x0467039,0x39b65a2, + 0x3816f3c,0x31ad0bd,0x0050046 } }, + /* 49 */ + { { 0x2425043,0x3858099,0x389092a,0x3f7c236,0x11ff66a,0x3c58b39, + 0x2f5a7f8,0x1663ce1,0x2a0fcf5,0x38634b7,0x1a8ca18,0x0dcace8, + 0x0e6f778,0x03ae334,0x00df0d2 }, + { 0x1bb4045,0x357875d,0x14b77ed,0x33ae5b6,0x2252a47,0x31899dd, + 0x3293582,0x040c6f6,0x14340dd,0x3614f0e,0x3d5f47f,0x326fb3d, + 0x0044a9d,0x00beeb9,0x0027c23 } }, + /* 50 */ + { { 0x32d49ce,0x34822a3,0x30a22d1,0x00858b7,0x10d91aa,0x2681fd9, + 0x1cce870,0x2404a71,0x38b8433,0x377c1c8,0x019442c,0x0a38b21, + 0x22aba50,0x0d61c81,0x002dcbd }, + { 0x0680967,0x2f0f2f9,0x172cb5f,0x1167e4b,0x12a7bc6,0x05b0da7, + 0x2c76e11,0x3a36201,0x37a3177,0x1d71419,0x0569df5,0x0dce7ad, + 0x3f40b75,0x3bd8db0,0x002d481 } }, + /* 51 */ + { { 0x2a1103e,0x34e7f7f,0x1b171a2,0x24a57e0,0x2eaae55,0x166c992, + 0x10aa18f,0x0bb836f,0x01acb59,0x0e430e7,0x1750cca,0x18be036, + 0x3cc6cdf,0x0a0f7e5,0x00da4d8 }, + { 0x2201067,0x374d187,0x1f6b0a6,0x165a7ec,0x31531f8,0x3580487, + 0x15e5521,0x0724522,0x2b04c04,0x202c86a,0x3cc1ccf,0x225b11a, + 0x1bde79d,0x0eccc50,0x00d24da } }, + /* 52 */ + { { 0x3b0a354,0x2814dd4,0x1cd8575,0x3d031b7,0x0392ff2,0x1855ee5, + 0x0e8cff5,0x203442e,0x3bd3b1b,0x141cf95,0x3fedee1,0x1d783c0, + 0x26f192a,0x0392aa3,0x0075238 }, + { 0x158ffe9,0x3889f19,0x14151f4,0x06067b1,0x13a3486,0x1e65c21, + 0x382d5ef,0x1ab0aac,0x2ffddc4,0x3179b7a,0x3c8d094,0x05101e3, + 0x237c6e5,0x3947d83,0x00f674f } }, + /* 53 */ + { { 0x363408f,0x21eb96b,0x27376fb,0x2a735d6,0x1a39c36,0x3d31863, + 0x33313fc,0x32235e0,0x082f034,0x23ef351,0x39b3528,0x1a69d84, + 0x1d9c944,0x07159ad,0x0077a71 }, + { 0x04f8d65,0x25771e5,0x2ba84a6,0x194586a,0x1e6da5f,0x118059a, + 0x14e9c32,0x1d24619,0x3f528ae,0x22f22e4,0x0f5580d,0x0747a0e, + 0x32cc85f,0x286b3a8,0x008ccf9 } }, + /* 54 */ + { { 0x196fee2,0x2c4431c,0x094528a,0x18e1d32,0x175799d,0x26bb6b7, + 0x2293482,0x23fd289,0x07b2be8,0x1a5c533,0x158d60d,0x04a4f3f, + 0x164e9f7,0x32ccca9,0x00da6b6 }, + { 0x1d821c2,0x3f76c4f,0x323df43,0x17e4374,0x0f2f278,0x121227e, + 0x2464190,0x19d2644,0x326d24c,0x3185983,0x0803c15,0x0767a33, + 0x1c4c996,0x0563eab,0x00631c6 } }, + /* 55 */ + { { 0x1752366,0x0baf83f,0x288bacf,0x0384e6f,0x2b93c34,0x3c805e7, + 0x3664850,0x29e1663,0x254ff1d,0x3852080,0x0f85c16,0x1e389d9, + 0x3191352,0x3915eaa,0x00a246e }, + { 0x3763b33,0x187ad14,0x3c0d438,0x3f11702,0x1c49f03,0x35ac7a8, + 0x3f16bca,0x27266bf,0x08b6fd4,0x0f38ce4,0x37fde8c,0x147a6ff, + 0x02c5e5c,0x28e7fc5,0x00076a7 } }, + /* 56 */ + { { 0x2338d10,0x0e77fa7,0x011b046,0x1bfd0ad,0x28ee699,0x21d73bc, + 0x0461d1a,0x342ea58,0x2d695b4,0x30415ed,0x2906e0b,0x18e494a, + 0x20f8a27,0x026b870,0x002c19f }, + { 0x2f4c43d,0x3f0fc3b,0x0aa95b8,0x2a01ea1,0x3e2e1b1,0x0d74af6, + 0x0555288,0x0cb757d,0x24d2071,0x143d2bb,0x3907f67,0x3e0ce30, + 0x131f0e9,0x3724381,0x007a874 } }, + /* 57 */ + { { 0x3c27050,0x08b5165,0x0bf884b,0x3dd679c,0x3bd0b8d,0x25ce2e6, + 0x1674057,0x1f13ed3,0x1f5cd91,0x0d1fd35,0x13ce6e3,0x2671338, + 0x10f8b90,0x34e5487,0x00942bf }, + { 0x03b566d,0x23c3da9,0x37de502,0x1a486ff,0x1af6e86,0x1108cb3, + 0x36f856c,0x01a6a0f,0x179f915,0x1595a01,0x2cfecb8,0x082568b, + 0x1ba16d1,0x1abb6c0,0x00cf7f0 } }, + /* 58 */ + { { 0x2f96c80,0x1b8f123,0x209c0f5,0x2ccf76d,0x1d521f2,0x3705143, + 0x2941027,0x07f88af,0x07102a9,0x38b4868,0x1efa37d,0x1bdd3e8, + 0x028a12e,0x02e055b,0x009a9a9 }, + { 0x1c7dfcb,0x3aa7aa7,0x1d62c54,0x3f0b0b0,0x3c74e66,0x274f819, + 0x23f9674,0x0e2b67c,0x24654dd,0x0c71f0e,0x1946cee,0x0016211, + 0x0045dc7,0x0da1173,0x0089856 } }, + /* 59 */ + { { 0x0e73946,0x29f353f,0x056329d,0x2d48c5a,0x28f697d,0x2ea4bb1, + 0x235e9cc,0x34faa38,0x15f9f91,0x3557519,0x2a50a6c,0x1a27c8e, + 0x2a1a0f3,0x3098879,0x00dcf21 }, + { 0x1b818bf,0x2f20b98,0x2243cff,0x25b691e,0x3c74a2f,0x2f06833, + 0x0e980a8,0x32db48d,0x2b57929,0x33cd7f5,0x2fe17d6,0x11a384b, + 0x2dafb81,0x2b9562c,0x00ddea6 } }, + /* 60 */ + { { 0x2787b2e,0x37a21df,0x310d294,0x07ce6a4,0x1258acc,0x3050997, + 0x19714aa,0x122824b,0x11c708b,0x0462d56,0x21abbf7,0x331aec3, + 0x307b927,0x3e8d5a0,0x00c0581 }, + { 0x24d4d58,0x3d628fc,0x23279e0,0x2e38338,0x2febe9b,0x346f9c0, + 0x3d6a419,0x3264e47,0x245faca,0x3669f62,0x1e50d66,0x3028232, + 0x18201ab,0x0bdc192,0x0002c34 } }, + /* 61 */ + { { 0x17bdbc2,0x1c501c5,0x1605ccd,0x31ab438,0x372fa89,0x24a8057, + 0x13da2bb,0x3f95ac7,0x3cda0a3,0x1e2b679,0x24f0673,0x03b72f4, + 0x35be616,0x2ccd849,0x0079d4d }, + { 0x33497c4,0x0c7f657,0x2fb0d3d,0x3b81064,0x38cafea,0x0e942bc, + 0x3ca7451,0x2ab9784,0x1678c85,0x3c62098,0x1eb556f,0x01b3aa2, + 0x149f3ce,0x2656f6d,0x002eef1 } }, + /* 62 */ + { { 0x0596edc,0x1f4fad4,0x03a28ed,0x18a4149,0x3aa3593,0x12db40a, + 0x12c2c2a,0x3b1a288,0x327c4fb,0x35847f5,0x384f733,0x02e3fde, + 0x1af0e8a,0x2e417c3,0x00d85a6 }, + { 0x0091cf7,0x2267d75,0x276860e,0x19cbbfc,0x04fef2b,0x030ce59, + 0x3195cb1,0x1aa3f07,0x3699362,0x2a09d74,0x0d6c840,0x1e413d0, + 0x28acdc7,0x1ff5ea1,0x0088d8b } }, + /* 63 */ + { { 0x3d98425,0x08dc8de,0x154e85f,0x24b1c2c,0x2d44639,0x19a1e8b, + 0x300ee29,0x053f72e,0x3f7c832,0x12417f6,0x1359368,0x0674a4c, + 0x1218e20,0x0e4fbd4,0x000428c }, + { 0x01e909a,0x1d88fe6,0x12da40c,0x215ef86,0x2925133,0x004241f, + 0x3e480f4,0x2d16523,0x07c3120,0x3375e86,0x21fd8f3,0x35dc0b6, + 0x0efc5c9,0x14ef8d6,0x0066e47 } }, + /* 64 */ + { { 0x2973cf4,0x34d3845,0x34f7070,0x22df93c,0x120aee0,0x3ae2b4a, + 0x1af9b95,0x177689a,0x036a6a4,0x0377828,0x23df41e,0x22d4a39, + 0x0df2aa1,0x06ca898,0x0003cc7 }, + { 0x06b1dd7,0x19dc2a8,0x35d324a,0x0467499,0x25bfa9c,0x1a1110c, + 0x01e2a19,0x1b3c1cf,0x18d131a,0x10d9815,0x2ee7945,0x0a2720c, + 0x0ddcdb0,0x2c071b6,0x00a6aef } }, + /* 65 */ + { { 0x1ab5245,0x1192d00,0x13ffba1,0x1b71236,0x09b8d0b,0x0eb49cb, + 0x1867dc9,0x371de4e,0x05eae9f,0x36faf82,0x094ea8b,0x2b9440e, + 0x022e173,0x2268e6b,0x00740fc }, + { 0x0e23b23,0x22c28ca,0x04d05e2,0x0bb84c4,0x1235272,0x0289903, + 0x267a18b,0x0df0fd1,0x32e49bb,0x2ab1d29,0x281e183,0x3dcd3c3, + 0x1c0eb79,0x2db0ff6,0x00bffe5 } }, + /* 66 */ + { { 0x2a2123f,0x0d63d71,0x1f6db1a,0x257f8a3,0x1927b2d,0x06674be, + 0x302753f,0x20b7225,0x14c1a3f,0x0429cdd,0x377affe,0x0f40a75, + 0x2d34d06,0x05fb6b9,0x0054398 }, + { 0x38b83c4,0x1e7bbda,0x1682f79,0x0527651,0x2615cb2,0x1795fab, + 0x0e4facc,0x11f763c,0x1b81130,0x2010ae2,0x13f3650,0x20d5b72, + 0x1f32f88,0x34617f4,0x00bf008 } }, + /* 67 */ + { { 0x28068db,0x0aa8913,0x1a47801,0x10695ca,0x1c72cc6,0x0fc1a47, + 0x33df2c4,0x0517cf0,0x3471d92,0x1be815c,0x397f794,0x3f03cbe, + 0x121bfae,0x172cbe0,0x00813d7 }, + { 0x383bba6,0x04f1c90,0x0b3f056,0x1c29089,0x2a924ce,0x3c85e69, + 0x1cecbe5,0x0ad8796,0x0aa79f6,0x25e38ba,0x13ad807,0x30b30ed, + 0x0fa963a,0x35c763d,0x0055518 } }, + /* 68 */ + { { 0x0623f3b,0x3ca4880,0x2bff03c,0x0457ca7,0x3095c71,0x02a9a08, + 0x1722478,0x302c10b,0x3a17458,0x001131e,0x0959ec2,0x18bdfbc, + 0x2929fca,0x2adfe32,0x0040ae2 }, + { 0x127b102,0x14ddeaa,0x1771b8c,0x283700c,0x2398a86,0x085a901, + 0x108f9dc,0x0cc0012,0x33a918d,0x26d08e9,0x20b9473,0x12c3fc7, + 0x1f69763,0x1c94b5a,0x00e29de } }, + /* 69 */ + { { 0x035af04,0x3450021,0x12da744,0x077fb06,0x25f255b,0x0db7150, + 0x17dc123,0x1a2a07c,0x2a7636a,0x3972430,0x3704ca1,0x0327add, + 0x3d65a96,0x3c79bec,0x009de8c }, + { 0x11d3d06,0x3fb8354,0x12c7c60,0x04fe7ad,0x0466e23,0x01ac245, + 0x3c0f5f2,0x2a935d0,0x3ac2191,0x090bd56,0x3febdbc,0x3f1f23f, + 0x0ed1cce,0x02079ba,0x00d4fa6 } }, + /* 70 */ + { { 0x0ab9645,0x10174ec,0x3711b5e,0x26357c7,0x2aeec7f,0x2170a9b, + 0x1423115,0x1a5122b,0x39e512c,0x18116b2,0x290db1c,0x041b13a, + 0x26563ae,0x0f56263,0x00b89f3 }, + { 0x3ed2ce4,0x01f365f,0x1b2043b,0x05f7605,0x1f9934e,0x2a068d2, + 0x38d4d50,0x201859d,0x2de5291,0x0a7985a,0x17e6711,0x01b6c1b, + 0x08091fa,0x33c6212,0x001da23 } }, + /* 71 */ + { { 0x2f2c4b5,0x311acd0,0x1e47821,0x3bd9816,0x1931513,0x1bd4334, + 0x30ae436,0x2c49dc0,0x2c943e7,0x010ed4d,0x1fca536,0x189633d, + 0x17abf00,0x39e5ad5,0x00e4e3e }, + { 0x0c8b22f,0x2ce4009,0x1054bb6,0x307f2fc,0x32eb5e2,0x19d24ab, + 0x3b18c95,0x0e55e4d,0x2e4acf5,0x1bc250c,0x1dbf3a5,0x17d6a74, + 0x087cf58,0x07f6f82,0x00f8675 } }, + /* 72 */ + { { 0x110e0b2,0x0e672e7,0x11b7157,0x1598371,0x01c0d59,0x3d60c24, + 0x096b8a1,0x0121075,0x0268859,0x219962f,0x03213f2,0x3022adc, + 0x18de488,0x3dcdeb9,0x008d2e0 }, + { 0x06cfee6,0x26f2552,0x3c579b7,0x31fa796,0x2036a26,0x362ba5e, + 0x103601c,0x012506b,0x387ff3a,0x101a41f,0x2c7eb58,0x23d2efc, + 0x10a5a07,0x2fd5fa3,0x00e3731 } }, + /* 73 */ + { { 0x1cd0abe,0x08a0af8,0x2fa272f,0x17a1fbf,0x1d4f901,0x30e0d2f, + 0x1898066,0x273b674,0x0c1b8a2,0x3272337,0x3ee82eb,0x006e7d3, + 0x2a75606,0x0af1c81,0x0037105 }, + { 0x2f32562,0x2842491,0x1bb476f,0x1305cd4,0x1daad53,0x0d8daed, + 0x164c37b,0x138030f,0x05145d5,0x300e2a3,0x32c09e7,0x0798600, + 0x3515130,0x2b9e55c,0x009764e } }, + /* 74 */ + { { 0x3d5256a,0x06c67f2,0x3a3b879,0x3c9b284,0x04007e0,0x33c1a41, + 0x3794604,0x1d6240e,0x022b6c1,0x22c62a7,0x01d4590,0x32df5f6, + 0x368f1a1,0x2a7486e,0x006e13f }, + { 0x31e6e16,0x20f18a9,0x09ed471,0x23b861d,0x15cf0ef,0x397b502, + 0x1c7f9b2,0x05f84b2,0x2cce6e1,0x3c10bba,0x13fb5a7,0x1b52058, + 0x1feb1b8,0x03b7279,0x00ea1cf } }, + /* 75 */ + { { 0x2a4cc9b,0x15cf273,0x08f36e6,0x076bf3b,0x2541796,0x10e2dbd, + 0x0bf02aa,0x3aa2201,0x03cdcd4,0x3ee252c,0x3799571,0x3e01fa4, + 0x156e8d0,0x1fd6188,0x003466a }, + { 0x2515664,0x166b355,0x2b0b51e,0x0f28f17,0x355b0f9,0x2909e76, + 0x206b026,0x3823a12,0x179c5fa,0x0972141,0x2663a1a,0x01ee36e, + 0x3fc8dcf,0x2ef3d1b,0x0049a36 } }, + /* 76 */ + { { 0x2d93106,0x3d6b311,0x3c9ce47,0x382aa25,0x265b7ad,0x0b5f92f, + 0x0f4c941,0x32aa4df,0x380d4b2,0x0e8aba6,0x260357a,0x1f38273, + 0x0d5f95e,0x199f23b,0x0029f77 }, + { 0x0a0b1c5,0x21a3d6a,0x0ad8df6,0x33d8a5e,0x1240858,0x30000a8, + 0x3ac101d,0x2a8143d,0x1d7ffe9,0x1c74a2a,0x1b962c9,0x1261359, + 0x0c8b274,0x002cf4a,0x00a8a7c } }, + /* 77 */ + { { 0x211a338,0x22a14ab,0x16e77c5,0x3c746be,0x3a78613,0x0d5731c, + 0x1767d25,0x0b799fa,0x009792a,0x09ae8dc,0x124386b,0x183d860, + 0x176747d,0x14c4445,0x00ab09b }, + { 0x0eb9dd0,0x0121066,0x032895a,0x330541c,0x1e6c17a,0x2271b92, + 0x06da454,0x054c2bf,0x20abb21,0x0ead169,0x3d7ea93,0x2359649, + 0x242c6c5,0x3194255,0x00a3ef3 } }, + /* 78 */ + { { 0x3010879,0x1083a77,0x217989d,0x174e55d,0x29d2525,0x0e544ed, + 0x1efd50e,0x30c4e73,0x05bd5d1,0x0793bf9,0x3f7af77,0x052779c, + 0x2b06bc0,0x13d0d02,0x0055a6b }, + { 0x3eaf771,0x094947a,0x0288f13,0x0a21e35,0x22ab441,0x23816bf, + 0x15832e1,0x2d8aff3,0x348cc1f,0x2bbd4a8,0x01c4792,0x34209d3, + 0x06dc72b,0x211a1df,0x00345c5 } }, + /* 79 */ + { { 0x2a65e90,0x173ac2f,0x199cde1,0x0ac905b,0x00987f7,0x3618f7b, + 0x1b578df,0x0d5e113,0x34bac6a,0x27d85ed,0x1b48e99,0x18af5eb, + 0x1a1be9e,0x3987aac,0x00877ca }, + { 0x2358610,0x3776a8e,0x2b0723a,0x344c978,0x22fc4d6,0x1615d53, + 0x3198f51,0x2d61225,0x12cb392,0x07dd061,0x355f7de,0x09e0132, + 0x0efae99,0x13b46aa,0x00e9e6c } }, + /* 80 */ + { { 0x0683186,0x36d8e66,0x0ea9867,0x0937731,0x1fb5cf4,0x13c39ef, + 0x1a7ffed,0x27dfb32,0x31c7a77,0x09f15fd,0x16b25ef,0x1dd01e7, + 0x0168090,0x240ed02,0x0090eae }, + { 0x2e1fceb,0x2ab9783,0x1a1fdf2,0x093a1b0,0x33ff1da,0x2864fb7, + 0x3587d6c,0x275aa03,0x123dc9b,0x0e95a55,0x0592030,0x2102402, + 0x1bdef7b,0x37f2e9b,0x001efa4 } }, + /* 81 */ + { { 0x0540015,0x20e3e78,0x37dcfbd,0x11b0e41,0x02c3239,0x3586449, + 0x1fb9e6a,0x0baa22c,0x00c0ca6,0x3e58491,0x2dbe00f,0x366d4b0, + 0x176439a,0x2a86b86,0x00f52ab }, + { 0x0ac32ad,0x226250b,0x0f91d0e,0x1098aa6,0x3dfb79e,0x1dbd572, + 0x052ecf2,0x0f84995,0x0d27ad2,0x036c6b0,0x1e4986f,0x2317dab, + 0x2327df6,0x0dee0b3,0x00389ac } }, + /* 82 */ + { { 0x0e60f5b,0x0622d3e,0x2ada511,0x05522a8,0x27fe670,0x206af28, + 0x333cb83,0x3f25f6c,0x19ddaf3,0x0ec579b,0x36aabc0,0x093dbac, + 0x348b44b,0x277dca9,0x00c5978 }, + { 0x1cf5279,0x32e294a,0x1a6c26f,0x3f006b6,0x37a3c6b,0x2e2eb26, + 0x2cf88d4,0x3410619,0x1899c80,0x23d3226,0x30add14,0x2810905, + 0x01a41f0,0x11e5176,0x005a02f } }, + /* 83 */ + { { 0x1c90202,0x321df30,0x3570fa5,0x103e2b1,0x3d099d4,0x05e207d, + 0x0a5b1bd,0x0075d0a,0x3db5b25,0x2d87899,0x32e4465,0x226fc13, + 0x24cb8f8,0x3821daa,0x004da3a }, + { 0x3e66861,0x03f89b8,0x386d3ef,0x14ccc62,0x35e7729,0x11ce5b7, + 0x035fbc7,0x3f4df0f,0x29c439f,0x1144568,0x32d7037,0x312f65e, + 0x06b9dbf,0x03a9589,0x0008863 } }, + /* 84 */ + { { 0x0a9e8c9,0x1a19b6e,0x091ecd9,0x2e16ee0,0x2a11963,0x116cf34, + 0x390d530,0x194131f,0x2b580f3,0x31d569c,0x21d3751,0x3e2ce64, + 0x193de46,0x32454f0,0x004bffd }, + { 0x09554e7,0x170126e,0x2be6cd1,0x153de89,0x0353c67,0x350765c, + 0x202370b,0x1db01e5,0x30b12b1,0x3778591,0x00c8809,0x2e845d5, + 0x1fb1e56,0x170f90d,0x00e2db3 } }, + /* 85 */ + { { 0x328e33f,0x392aad8,0x36d1d71,0x0aebe04,0x1548678,0x1b55c8c, + 0x24995f8,0x2a5a01e,0x1bd1651,0x37c7c29,0x36803b6,0x3716c91, + 0x1a935a5,0x32f10b7,0x005c587 }, + { 0x2e8b4c0,0x336ccae,0x11382b6,0x22ec4cc,0x066d159,0x35fa585, + 0x23b2d25,0x3017528,0x2a674a8,0x3a4f900,0x1a7ce82,0x2b2539b, + 0x3d46545,0x0a07918,0x00eb9f8 } }, + /* 86 */ + { { 0x2cf5b9b,0x03e747f,0x166a34e,0x0afc81a,0x0a115b1,0x3aa814d, + 0x11cf3b1,0x163e556,0x3cbfb15,0x157c0a4,0x1bc703a,0x2141e90, + 0x01f811c,0x207218b,0x0092e6b }, + { 0x1af24e3,0x3af19b3,0x3c70cc9,0x335cbf3,0x068917e,0x055ee92, + 0x09a9308,0x2cac9b7,0x008b06a,0x1175097,0x36e929c,0x0be339c, + 0x0932436,0x15f18ba,0x0009f6f } }, + /* 87 */ + { { 0x29375fb,0x35ade34,0x11571c7,0x07b8d74,0x3fabd85,0x090fa91, + 0x362dcd4,0x02c3fdb,0x0608fe3,0x2477649,0x3fc6e70,0x059b7eb, + 0x1e6a708,0x1a4c220,0x00c6c4c }, + { 0x2a53fb0,0x1a3e1f5,0x11f9203,0x27e7ad3,0x038718e,0x3f5f9e4, + 0x308acda,0x0a8700f,0x34472fe,0x3420d7a,0x08076e5,0x014240e, + 0x0e7317e,0x197a98e,0x00538f7 } }, + /* 88 */ + { { 0x2663b4b,0x0927670,0x38dd0e0,0x16d1f34,0x3e700ab,0x3119567, + 0x12559d2,0x399b6c6,0x0a84bcd,0x163e7dd,0x3e2aced,0x058548c, + 0x03a5bad,0x011cf74,0x00c155c }, + { 0x3e454eb,0x2a1e64e,0x1ccd346,0x36e0edf,0x266ee94,0x2e74aaf, + 0x2d8378a,0x3cd547d,0x1d27733,0x0928e5b,0x353553c,0x26f502b, + 0x1d94341,0x2635cc7,0x00d0ead } }, + /* 89 */ + { { 0x0142408,0x382c3bb,0x3310908,0x2e50452,0x398943c,0x1d0ac75, + 0x1bf7d81,0x04bd00f,0x36b6934,0x3349c37,0x0f69e20,0x0195252, + 0x243a1c5,0x030da5f,0x00a76a9 }, + { 0x224825a,0x28ce111,0x34c2e0f,0x02e2b30,0x382e48c,0x26853ca, + 0x24bd14e,0x0200dec,0x1e24db3,0x0d3d775,0x132da0a,0x1dea79e, + 0x253dc0c,0x03c9d31,0x0020db9 } }, + /* 90 */ + { { 0x26c5fd9,0x05e6dc3,0x2eea261,0x08db260,0x2f8bec1,0x1255edf, + 0x283338d,0x3d9a91d,0x2640a72,0x03311f9,0x1bad935,0x152fda8, + 0x0e95abd,0x31abd15,0x00dfbf4 }, + { 0x107f4fa,0x29ebe9a,0x27353f7,0x3821972,0x27311fa,0x2925ab6, + 0x337ab82,0x2de6c91,0x1f115fe,0x044f909,0x21b93c2,0x3a5f142, + 0x13eb5e9,0x3ab1377,0x00b26b6 } }, + /* 91 */ + { { 0x22e5f2b,0x2ae7d4a,0x1ac481c,0x0a6fce1,0x2f93caf,0x242658e, + 0x3f35c3c,0x050f3d2,0x30074c9,0x142079c,0x0281b4c,0x295fea3, + 0x007413e,0x01726cd,0x00e4979 }, + { 0x1ab3cfb,0x1b76295,0x36adf55,0x1ad4636,0x1d444b9,0x3bd2e55, + 0x35425a5,0x1aa8cd3,0x3acecd2,0x1f769e8,0x1a655e9,0x1f6846f, + 0x24c70b5,0x3bff080,0x0002da3 } }, + /* 92 */ + { { 0x081d0d9,0x2c00d99,0x1fe2e24,0x396063f,0x03740db,0x243f680, + 0x3c1f451,0x1ff7b07,0x2803cf2,0x38ca724,0x2934f43,0x0d72d4d, + 0x0e8fe74,0x2975e21,0x002b505 }, + { 0x11adcc9,0x331a99c,0x21e16cf,0x1714c78,0x1f03432,0x2caa2a6, + 0x34a9679,0x2f7fe8b,0x0423c21,0x1a757ce,0x31b57d6,0x171e044, + 0x093b9b2,0x13602e0,0x00db534 } }, + /* 93 */ + { { 0x250a2f5,0x0b999eb,0x21d10d7,0x22b92a1,0x39b7f8d,0x0c37c72, + 0x29f70f3,0x3bf0e84,0x1d7e04f,0x07a42a9,0x272c3ae,0x1587b2f, + 0x155faff,0x10a336e,0x000d8fb }, + { 0x3663784,0x0d7dcf5,0x056ad22,0x319f8b1,0x0c05bae,0x2b6ff33, + 0x0292e42,0x0435797,0x188efb1,0x0d3f45e,0x119d49f,0x395dcd3, + 0x279fe27,0x133a13d,0x00188ac } }, + /* 94 */ + { { 0x396c53e,0x0d133e9,0x009b7ee,0x13421a0,0x1bbf607,0x1d284a5, + 0x1594f74,0x18cb47c,0x2dcac11,0x2999ddb,0x04e2fa5,0x1889e2c, + 0x0a89a18,0x33cb215,0x0052665 }, + { 0x104ab58,0x1d91920,0x3d6d7e3,0x04dc813,0x1167759,0x13a8466, + 0x0a06a54,0x103761b,0x25b1c92,0x26a8fdd,0x2474614,0x21406a4, + 0x251d75f,0x38c3734,0x007b982 } }, + /* 95 */ + { { 0x15f3060,0x3a7bf30,0x3be6e44,0x0baa1fa,0x05ad62f,0x1e54035, + 0x099d41c,0x2a744d9,0x1c0336f,0x3e99b5b,0x1afd3b1,0x2bf1255, + 0x1822bf8,0x2c93972,0x001d8cc }, + { 0x1d7584b,0x0508ade,0x20dd403,0x203a8fc,0x1c54a05,0x1611a31, + 0x037c8f9,0x1dcd4fe,0x110fbea,0x30f60bc,0x3dffe2f,0x26a1de1, + 0x0480367,0x18ec81c,0x0048eba } }, + /* 96 */ + { { 0x346e2f6,0x0435077,0x036789b,0x3e06545,0x313ab57,0x351a721, + 0x3372b91,0x15e6019,0x2fa4f6c,0x3c30656,0x272c9ac,0x10e84a8, + 0x2bdacea,0x232d9e2,0x009dadd }, + { 0x182579a,0x15b1af8,0x02d8cce,0x36cb49b,0x086feba,0x2911d17, + 0x268ee12,0x011e871,0x18698dc,0x35602b3,0x11b9ec2,0x0ade731, + 0x0f6a05a,0x1821015,0x00007da } }, + /* 97 */ + { { 0x3b00dd0,0x328d485,0x27a69e3,0x32c3a06,0x1046779,0x120b61c, + 0x19fef3d,0x0fef2e6,0x134d923,0x039bce0,0x348cd0e,0x0b0c007, + 0x066ae11,0x15d8f1b,0x00934e7 }, + { 0x33234dc,0x353f0f5,0x2fc1b44,0x18a193a,0x2fcae20,0x1afbc86, + 0x3afe252,0x17f7e10,0x107f3b7,0x2d84d54,0x394c2e6,0x19e96a9, + 0x0a37283,0x26c6152,0x003d262 } }, + /* 98 */ + { { 0x37cfaf8,0x01863d0,0x0299623,0x32c80cb,0x25b8742,0x0a4d90e, + 0x1f72472,0x13de652,0x31a0946,0x0ee0103,0x0f25414,0x2518b49, + 0x07e7604,0x1488d9b,0x00abd6b }, + { 0x1338f55,0x2ce4af5,0x1a0c119,0x3380525,0x21a80a9,0x235d4df, + 0x118ca7f,0x2dd8bcc,0x1c26bf4,0x32dc56b,0x28482b6,0x1418596, + 0x3c84d24,0x1f1a5a9,0x00d958d } }, + /* 99 */ + { { 0x1c21f31,0x22aa1ef,0x258c9ad,0x2d2018f,0x0adb3ca,0x01f75ee, + 0x186283b,0x31ad3bf,0x3621be7,0x3b1ee6d,0x015582d,0x3d61d04, + 0x2ddf32e,0x14b8a66,0x00c970c }, + { 0x2f24d66,0x00b8a88,0x100a78f,0x041d330,0x2efec1d,0x24c5b86, + 0x2a6a390,0x37526bc,0x2055849,0x3339f08,0x16bffc4,0x07f9d72, + 0x06ec09c,0x3f49ee8,0x00cad98 } }, + /* 100 */ + { { 0x248b73e,0x1b8b42d,0x285eed7,0x39473f4,0x1a9f92c,0x3b44f78, + 0x086c062,0x06a4ea3,0x34ea519,0x3c74e95,0x1ad1b8b,0x1737e2c, + 0x2cfe338,0x0a291f4,0x00bbecc }, + { 0x1cec548,0x0c9b01a,0x20b298d,0x377c902,0x24f5bc1,0x2415c8d, + 0x1a70622,0x2529090,0x1c5c682,0x283f1ba,0x2319f17,0x0120e2e, + 0x01c6f4d,0x33c67ff,0x008b612 } }, + /* 101 */ + { { 0x03830eb,0x02d4053,0x10c59bb,0x0f23b83,0x13d08f8,0x26ea4e2, + 0x2626427,0x0a45292,0x0449cbc,0x0175750,0x074c46f,0x27ae0f8, + 0x2d7d6ae,0x163dd3a,0x0063bb7 }, + { 0x2bb29e0,0x034bab1,0x341e1c4,0x21d2c0b,0x295aa2d,0x0f2c666, + 0x1891755,0x13db64a,0x2fe5158,0x337646e,0x31a1aae,0x057bee4, + 0x00f9e37,0x396d19e,0x00c1b6a } }, + /* 102 */ + { { 0x2772f41,0x34f92d0,0x39d1cde,0x174ef2d,0x03a700d,0x03fbb98, + 0x30d50e8,0x352ed10,0x1fcf5e5,0x3d113bc,0x26e358f,0x180653f, + 0x1b43cc6,0x3cc9aa4,0x00e68a2 }, + { 0x37fe4d2,0x09dd725,0x01eb584,0x171f8a9,0x278fdef,0x3e37c03, + 0x3bec02f,0x149757c,0x0cd5852,0x37d2e10,0x0e6988b,0x1c120e9, + 0x0b83708,0x38e7319,0x0039499 } }, + /* 103 */ + { { 0x08df5fe,0x177a02c,0x0362fc0,0x1f18ee8,0x00c1295,0x173c50a, + 0x379414d,0x1885ba8,0x32a54ef,0x2315644,0x39e65cf,0x357c4be, + 0x1d66333,0x09e05a5,0x0009c60 }, + { 0x1f7a2fb,0x073b518,0x2eb83ac,0x11353d7,0x1dd8384,0x0c63f2b, + 0x238c6c8,0x2a1920a,0x2e5e9f1,0x1cc56f8,0x042daf4,0x1ed5dc5, + 0x25f9e31,0x012a56a,0x0081b59 } }, + /* 104 */ + { { 0x321d232,0x2c71422,0x3a756b6,0x30230b2,0x387f3db,0x3a7c3eb, + 0x274b46a,0x201e69f,0x185bb7b,0x140da82,0x0d974a2,0x0616e42, + 0x35ec94f,0x3bc366b,0x005aa7c }, + { 0x3dcfffc,0x19a9c15,0x3225e05,0x36ae114,0x16ea311,0x0cda2aa, + 0x2a1a8d2,0x154b5cb,0x08348cd,0x17b66c8,0x080ea43,0x21e59f3, + 0x04173b9,0x31d5b04,0x00ad735 } }, + /* 105 */ + { { 0x2e76ef4,0x216acf3,0x2b93aea,0x112bc74,0x3449974,0x2b2e48f, + 0x11929be,0x2f03021,0x19051e3,0x0ac202d,0x19be68a,0x3b87619, + 0x26cdac4,0x086592c,0x00f00de }, + { 0x2e90d4d,0x3ed703c,0x2c648d7,0x29ddf67,0x000e219,0x3471247, + 0x26febd5,0x1161713,0x3541a8f,0x302038d,0x08d2af9,0x26e1b21, + 0x398514a,0x36dad99,0x002ed70 } }, + /* 106 */ + { { 0x06f25cb,0x1104596,0x370faee,0x07e83f3,0x0f7b686,0x228d43a, + 0x12cd201,0x0a1bd57,0x3e592dc,0x1e186fc,0x2226aba,0x2c63fe9, + 0x17b039a,0x1efaa61,0x00d1582 }, + { 0x2e6acef,0x07d51e4,0x3ac326c,0x322b07e,0x1422c63,0x32ff5c7, + 0x18760df,0x048928b,0x139b251,0x04d7da9,0x048d1a2,0x2a23e84, + 0x199dbba,0x2fa7afe,0x0049f1a } }, + /* 107 */ + { { 0x3492b73,0x27d3d3d,0x2b1a16f,0x07b2ce4,0x0cf28ec,0x2729bff, + 0x3130d46,0x3e96116,0x140b72e,0x14a2ea3,0x1ca066f,0x3a61f1d, + 0x022ebac,0x09192b4,0x003e399 }, + { 0x12555bb,0x0b6139d,0x239463a,0x12a70ab,0x2aaa93b,0x2254e72, + 0x00424ec,0x26a6736,0x26daa11,0x25b5ad6,0x379f262,0x140cd30, + 0x0c7d3bd,0x097bbcf,0x00899e9 } }, + /* 108 */ + { { 0x3825dc4,0x3cd946f,0x0462b7f,0x31102e7,0x30f741c,0x3313ed6, + 0x1ff5a95,0x15bf9dc,0x09b47fd,0x0f2e7a7,0x1626c0d,0x3c14f6d, + 0x14098bd,0x19d7df8,0x00a97ce }, + { 0x0934f5e,0x3f968db,0x046f68a,0x12333bf,0x26cd5e1,0x1ea2161, + 0x358570d,0x235031d,0x35edd55,0x05265e3,0x24ae00c,0x3542229, + 0x25bb2a1,0x1c83c75,0x0058f2a } }, + /* 109 */ + { { 0x24daedb,0x376928f,0x305266f,0x0499746,0x038318c,0x312efd7, + 0x1910a24,0x33450a3,0x1c478a9,0x39d8bf9,0x12cc0ae,0x397aeab, + 0x0654c08,0x095f283,0x00d2cdf }, + { 0x0b717d2,0x1f162c2,0x107a48f,0x128e1b3,0x2380718,0x39f4044, + 0x00f626a,0x05ec0c9,0x21bc439,0x200fa4d,0x20aea01,0x186a1d8, + 0x26372f2,0x1a91f87,0x0053f55 } }, + /* 110 */ + { { 0x3512a90,0x33b958b,0x29f1c84,0x0106c3a,0x224b3c0,0x09b307a, + 0x215d2de,0x3bdf43b,0x22cf0c9,0x176121d,0x1534143,0x09ba717, + 0x16b3110,0x0f73f6c,0x008f5b7 }, + { 0x2c75d95,0x26fbcb4,0x0dda1f6,0x206f819,0x28d33d5,0x1fb4d79, + 0x024c125,0x30a0630,0x1f9c309,0x0fe350d,0x1696019,0x0a54187, + 0x09541fd,0x35e3a79,0x0066618 } }, + /* 111 */ + { { 0x0e382de,0x33f5163,0x0dde571,0x3bb7a40,0x1175806,0x12ae8ed, + 0x0499653,0x3b25586,0x38ade7a,0x3fa265d,0x3f4aa97,0x3c03dbb, + 0x30c6de8,0x32d4042,0x00ae971 }, + { 0x2f788f1,0x1fbaf0e,0x3e2d182,0x3ff904f,0x0d46229,0x1d0726d, + 0x15455b4,0x093ae28,0x290f8e4,0x097c0b9,0x1ae8771,0x28480bb, + 0x04f6d40,0x3689925,0x0049b3b } }, + /* 112 */ + { { 0x35b2d69,0x31819c0,0x11b0d63,0x035afb6,0x2b50715,0x2bece6c, + 0x35f82f7,0x0ad987c,0x0011601,0x02e6f67,0x2d0a5f5,0x365e583, + 0x2f7c900,0x11449c5,0x00ed705 }, + { 0x27abdb4,0x1bbfd04,0x301c157,0x263c079,0x36850d6,0x3f21f8b, + 0x27d7493,0x0f9227e,0x06fb0ce,0x002daf3,0x37d8c1c,0x3ef87d7, + 0x19cc6f4,0x0c3809c,0x00cf752 } }, + /* 113 */ + { { 0x22d94ed,0x075b09c,0x020e676,0x084dc62,0x2d1ec3f,0x17439f1, + 0x240b702,0x33cc596,0x30ebaf3,0x0359fe0,0x393ea43,0x0ece01e, + 0x16c6963,0x03a82f2,0x0017faa }, + { 0x3866b98,0x3cd20b7,0x12d4e6b,0x3a6a76d,0x1205c1e,0x3e6ae1a, + 0x2f9bbdf,0x2e61547,0x2d175ee,0x28e18f6,0x13cf442,0x085b0ef, + 0x0e321ef,0x238fe72,0x003fb22 } }, + /* 114 */ + { { 0x360ac07,0x26dc301,0x3f4d94f,0x2ba75e6,0x1f3c9cc,0x17ff20f, + 0x0ea084c,0x30e39cf,0x143dc49,0x03bd43e,0x3c9e733,0x19e8aba, + 0x27fbaf4,0x12d913a,0x005ee53 }, + { 0x3609e7f,0x2d89c80,0x09f020c,0x1558bf7,0x3098443,0x3c515fd, + 0x1c8e580,0x16506bd,0x26cb4b2,0x1747d42,0x2ec8239,0x32c91f0, + 0x1ca3377,0x079768f,0x00a5f3e } }, + /* 115 */ + { { 0x185fa94,0x122759f,0x0e47023,0x0dcb6e7,0x10ba405,0x3b5eab4, + 0x1f7a1fa,0x32d003f,0x1739a4c,0x3295ec3,0x1b18967,0x3f3b265, + 0x34d2448,0x2dbadc9,0x00f30b5 }, + { 0x01c5338,0x2d1dcf2,0x2bd07cc,0x39a8fb5,0x2b85639,0x355bab6, + 0x1df95f1,0x01eb5f6,0x17f0a16,0x1b895b5,0x157574d,0x29fff72, + 0x3a8c46d,0x0118071,0x0065f84 } }, + /* 116 */ + { { 0x3a1e7f1,0x17432f2,0x1f648d4,0x3000ad5,0x2ef0a08,0x1f86624, + 0x1ca31b1,0x241f9dc,0x2cb4885,0x2b8610f,0x364ce16,0x1e5faf0, + 0x0b33867,0x2cb637d,0x00816d2 }, + { 0x1aa8671,0x02c394e,0x35f5e87,0x393040a,0x39f0db3,0x1c831a5, + 0x2966591,0x034a8d0,0x09e613c,0x042b532,0x018ddd6,0x3e402c9, + 0x2e20e1a,0x29cb4cd,0x00e087c } }, + /* 117 */ + { { 0x3a10079,0x20c7fea,0x3ff2222,0x1edb593,0x00dc5f8,0x3a32ccc, + 0x1479073,0x0cfed11,0x2a2702a,0x17a056a,0x1fba321,0x235acb9, + 0x149c833,0x172de7d,0x000f753 }, + { 0x2e95923,0x3b365cb,0x009f471,0x0df1b47,0x21e868b,0x199bbd3, + 0x07b8ecc,0x12ff0af,0x189808a,0x3bd5059,0x3fbc4d2,0x0fa7b88, + 0x1125bf2,0x0db0b5d,0x0043572 } }, + /* 118 */ + { { 0x29cdb1b,0x1db656e,0x391efe1,0x004be09,0x245a1ca,0x3793328, + 0x254af24,0x2f2e65d,0x10e5cc4,0x2af6fe7,0x2d97ac0,0x29f7d42, + 0x19fd6f6,0x0ac184d,0x00c5211 }, + { 0x305eae3,0x36738d3,0x2c2b696,0x00ba50e,0x3903adc,0x2122f85, + 0x0753470,0x1cf96a4,0x1702a39,0x247883c,0x2feb67e,0x2ab3071, + 0x3c6b9e1,0x30cb85a,0x002ca0a } }, + /* 119 */ + { { 0x3871eb5,0x284b93b,0x0a7affe,0x176a2fc,0x294c2f2,0x204d3aa, + 0x1e4c2a7,0x3ec4134,0x2fb0360,0x3847b45,0x05fc11b,0x0a6db6e, + 0x390fa40,0x2adfd34,0x005e9f7 }, + { 0x0646612,0x1b5cbcc,0x10d8507,0x0777687,0x3a0afed,0x1687440, + 0x0222578,0x1af34a4,0x2174e27,0x372d267,0x11246c3,0x34769c5, + 0x2044316,0x1b4d626,0x00c72d5 } }, + /* 120 */ + { { 0x2e5bb45,0x3ff1d36,0x16dcdf5,0x128986f,0x399068c,0x2a63b1e, + 0x0afa7aa,0x3a5b770,0x200f121,0x33b74bb,0x1414045,0x0f31ef8, + 0x2f50e16,0x2f38cd6,0x00b0b1b }, + { 0x1a06293,0x035e140,0x2644d44,0x1f1954b,0x2cdebab,0x31d5f91, + 0x0b8dbc8,0x38f2d23,0x3783cab,0x2a07e73,0x3123f59,0x3409846, + 0x3784ddd,0x223bbac,0x003dc7b } }, + /* 121 */ + { { 0x0741456,0x234e631,0x2121e1b,0x00980ca,0x3a9dfa9,0x098c916, + 0x3fc86d1,0x1c63072,0x3625244,0x13d0471,0x05b0fc5,0x1487550, + 0x2498596,0x11bb6ea,0x001afab }, + { 0x274b4ad,0x240aea1,0x3d12a75,0x2b56b61,0x1486b43,0x1b83426, + 0x31c7363,0x35b59ca,0x207bb6c,0x38e6243,0x19bace4,0x0a26671, + 0x35e3381,0x0c2ded4,0x00d8da4 } }, + /* 122 */ + { { 0x2b75791,0x19590b1,0x2bfb39f,0x2988601,0x0050947,0x0d8bbe1, + 0x23e3701,0x08e4432,0x2ed8c3d,0x326f182,0x332e1dd,0x12219c5, + 0x2e0779b,0x367aa63,0x0012d10 }, + { 0x251b7dc,0x0a08b4d,0x1138b6f,0x2ea02af,0x06345a5,0x1cb4f21, + 0x0332624,0x1d49d88,0x140acc5,0x2f55287,0x024447c,0x291ace9, + 0x1a4966e,0x015cbec,0x005bc41 } }, + /* 123 */ + { { 0x351cd0e,0x315e8e9,0x07d6e70,0x067ae8f,0x2190d84,0x351f556, + 0x03bee79,0x31b62c7,0x266f912,0x1b6a504,0x007a6ad,0x3a6ab31, + 0x3891112,0x3c45ba0,0x00d6ce5 }, + { 0x0e1f2ce,0x32a5edc,0x1434063,0x1ca084f,0x2a3e47c,0x137e042, + 0x16e2418,0x2069280,0x3b0dfd8,0x35a22b5,0x289bf0a,0x1f667f2, + 0x02d23a3,0x0ce688f,0x00d8e3f } }, + /* 124 */ + { { 0x10bed6f,0x14c58dd,0x0b0abdf,0x0ca0f9a,0x3808abc,0x2ec228c, + 0x2366275,0x12afa16,0x20f6b0e,0x37dca8e,0x3af0c6a,0x1c5b467, + 0x1b25ff7,0x00814de,0x0022dcc }, + { 0x1a56e11,0x02fe37e,0x3f21740,0x35d5a91,0x06cb8ba,0x29bad91, + 0x17176f7,0x2d919f2,0x0f7d1f5,0x13a3f61,0x04ddb05,0x0c82a51, + 0x286f598,0x2e8c777,0x0007071 } }, + /* 125 */ + { { 0x0f8fcb9,0x3e83966,0x170c6fd,0x3825343,0x089cec8,0x01b482a, + 0x0993971,0x3327282,0x39aba8a,0x32456fe,0x1507e01,0x1c3252d, + 0x21ffb13,0x29822a0,0x0083246 }, + { 0x23c378f,0x1cea7ef,0x1be9a82,0x224d689,0x37e5447,0x3764a75, + 0x3a49724,0x361e1b3,0x19d365b,0x3a61ffb,0x1c29a7a,0x20ab251, + 0x17ec549,0x175d777,0x004589a } }, + /* 126 */ + { { 0x15540a9,0x2ec5d2a,0x05b09fa,0x1bc058b,0x07cfb88,0x28f7b86, + 0x3e766be,0x189305e,0x01fe88e,0x23fdf69,0x0b919c3,0x02dc7ae, + 0x3f9a9ad,0x0b83cc7,0x0086a52 }, + { 0x28bc259,0x39bdca1,0x39e4bc8,0x0e0f33b,0x16130c6,0x2919955, + 0x31f4549,0x2fed027,0x30919b2,0x0a39b03,0x0ca7bb2,0x1711b24, + 0x3b67b94,0x05a136b,0x00acd87 } }, + /* 127 */ + { { 0x0c53841,0x31cb284,0x3ced090,0x06d5693,0x1c20ae0,0x0408d2b, + 0x37ebd5e,0x081900f,0x26a8589,0x0acfd0a,0x34a1472,0x2f0c302, + 0x124ccbd,0x10de328,0x00971bc }, + { 0x17ff2ff,0x27d1b54,0x147b6f7,0x38bb2ea,0x26a9c96,0x0a49448, + 0x39f2f46,0x247c579,0x3b16a4e,0x28c2a5a,0x2d4c72d,0x11f248c, + 0x1e4df11,0x047d604,0x0065bc3 } }, + /* 128 */ + { { 0x39b3239,0x1f75f44,0x3bae87c,0x139360c,0x18b5782,0x3ffc005, + 0x3c48789,0x2bc6af2,0x38b909e,0x223ff3b,0x31443a7,0x017d3bb, + 0x0bfed99,0x128b857,0x00020dd }, + { 0x306d695,0x25a7b28,0x2f60ca2,0x2b6e4f2,0x1df940c,0x1fa9b8e, + 0x37fab78,0x13f959f,0x10ff98c,0x38343b8,0x019cb91,0x11a1e6b, + 0x17ab4c6,0x1431f47,0x004b4ea } }, + /* 129 */ + { { 0x20db57e,0x102515e,0x170219e,0x2b66a32,0x1e6017c,0x2f973fe, + 0x3739e51,0x0e28b6f,0x3cda7a9,0x30d91ac,0x28350df,0x1444215, + 0x098b504,0x1bcd5b8,0x00ad3bd }, + { 0x22e3e3e,0x3aeaffb,0x26cb935,0x0091ce4,0x2fbd017,0x3a7ed6a, + 0x335b029,0x3bfc1f1,0x3852e3f,0x2b14a86,0x046b405,0x266af4c, + 0x3997191,0x33b0e40,0x00e306f } }, + /* 130 */ + { { 0x3e4712c,0x26bb208,0x18eed6d,0x1b30f06,0x27ca837,0x06faf62, + 0x1831873,0x3fbcf9b,0x3f3d88b,0x1fb55eb,0x0f44edc,0x29917bb, + 0x3151772,0x342d72e,0x00d4e63 }, + { 0x2ee0ecf,0x39e8733,0x2e8e98c,0x0cd4e0f,0x08f0126,0x1ad157a, + 0x079078a,0x23018ee,0x196c765,0x2b2f34f,0x0783336,0x075bf9c, + 0x3713672,0x098d699,0x00f21a7 } }, + /* 131 */ + { { 0x186ba11,0x22cf365,0x048019d,0x2ca2970,0x0d9e0ae,0x08c3bd7, + 0x261dbf2,0x2fc2790,0x1ee02e6,0x10256a7,0x00dc778,0x18dc8f2, + 0x157b189,0x2ebc514,0x005c97d }, + { 0x3c4503e,0x1d10d12,0x337097e,0x0c6169a,0x30fb1cb,0x3481752, + 0x0df2bec,0x19768fa,0x1bcf8f7,0x2925f74,0x2c988a1,0x3be571d, + 0x04cfa92,0x2ea9937,0x003f924 } }, + /* 132 */ + { { 0x268b448,0x06e375c,0x1b946bf,0x287bf5e,0x3d4c28b,0x138d547, + 0x21f8c8e,0x21ea4be,0x2d45c91,0x35da78e,0x00326c0,0x210ed35, + 0x1d66928,0x0251435,0x00fefc8 }, + { 0x0339366,0x216ff64,0x2c3a30c,0x3c5733d,0x04eeb56,0x2333477, + 0x32b1492,0x25e3839,0x1b5f2ce,0x0dcfba1,0x3165bb2,0x3acafcc, + 0x10abfcd,0x248d390,0x008106c } }, + /* 133 */ + { { 0x102f4ee,0x3c0585f,0x1225c8d,0x11c6388,0x08a7815,0x2b3e790, + 0x2895eb6,0x18cf53a,0x0b56e5a,0x2e2c003,0x3e981ff,0x0761b55, + 0x1bc32f3,0x0a7111d,0x00f5c80 }, + { 0x3568973,0x1587386,0x16ec764,0x20698a6,0x02f809b,0x2821502, + 0x113d64d,0x38c2679,0x15de61c,0x0309f60,0x272999e,0x29bfe64, + 0x173f70d,0x1de7fab,0x00bd284 } }, + /* 134 */ + { { 0x31cdf2b,0x0f0be66,0x2151603,0x01af17e,0x32a99cf,0x085dece, + 0x27d2591,0x1520df4,0x273c448,0x1ec7c54,0x102e229,0x355f604, + 0x2acb75f,0x005f1fd,0x003d43e }, + { 0x270eb28,0x22ec2ce,0x306b41a,0x238fa02,0x167de2d,0x030a379, + 0x245a417,0x1808c24,0x0b1a7b2,0x3ab5f6f,0x2cbc6c1,0x2c228d4, + 0x3041f70,0x2d9a6cc,0x00b504f } }, + /* 135 */ + { { 0x17a27c2,0x216ad7e,0x011ba8e,0x22f0428,0x16ac5ec,0x3ef3c58, + 0x345533f,0x0298155,0x2856579,0x0005e03,0x19ee75b,0x146fe16, + 0x29881e4,0x18ece70,0x008907a }, + { 0x20189ed,0x119ce09,0x35cb76d,0x0d91ef4,0x2284a44,0x032ad87, + 0x0e8c402,0x3c82b5d,0x38c416c,0x398992f,0x1fd820c,0x169b255, + 0x3b5fcfa,0x1343c92,0x00fa715 } }, + /* 136 */ + { { 0x33f5034,0x20b3b26,0x28fd184,0x16b3679,0x3962d44,0x15d1bc8, + 0x2fb1d69,0x1292c99,0x25a58c9,0x1b19ab7,0x2d68a5b,0x2f6a09b, + 0x0d6aedb,0x2935eac,0x0005664 }, + { 0x25e32fc,0x13f9440,0x3252bcd,0x2fea5b7,0x161a5ae,0x0564a8c, + 0x0a07e23,0x1545f62,0x0de9890,0x1d76765,0x1fd440e,0x2ed0041, + 0x3db4c96,0x1e8ba01,0x001b0c4 } }, + /* 137 */ + { { 0x0223878,0x29ab202,0x15585c2,0x1a79969,0x1ba08c2,0x2ef09ff, + 0x2b1b9b9,0x181f748,0x1bf72b9,0x224645c,0x2588dc5,0x2d157e7, + 0x22d939a,0x05b88d9,0x006d549 }, + { 0x31de0c1,0x23a4e0e,0x278f8da,0x1aa013c,0x1a84d18,0x0d185a5, + 0x0988ccd,0x2c32efd,0x3bee10e,0x37d7ab8,0x3f2a66e,0x3e2da3e, + 0x1b5701f,0x3d9f0c1,0x00a68da } }, + /* 138 */ + { { 0x0b2e045,0x0133fd1,0x05d4c10,0x0d92c70,0x391b5e1,0x2292281, + 0x2e40908,0x2ec694e,0x195ea11,0x29cfeca,0x3d93a4e,0x01215c0, + 0x08a5f32,0x37a0eff,0x00cce45 }, + { 0x2b3106e,0x12a5fb0,0x0b4faff,0x0c2da12,0x09069c6,0x35d8907, + 0x2837a6e,0x3db3fb6,0x3136cc3,0x222836b,0x3da018a,0x2741274, + 0x13ba319,0x1ac7642,0x00f867c } }, + /* 139 */ + { { 0x2527296,0x10a9595,0x178de4d,0x0f739c4,0x0ae26c7,0x3094599, + 0x20adac6,0x2b875c2,0x3ae5dc0,0x3e04d20,0x1aab2da,0x1d3ab37, + 0x15f4f75,0x0b730b5,0x00c56b5 }, + { 0x1f32923,0x2f059e5,0x2a89872,0x2056f74,0x04be175,0x1da67c0, + 0x17f1e7a,0x3780a6d,0x0723ac2,0x257f367,0x1237773,0x2bcee86, + 0x0b97f83,0x38aff14,0x00a64d4 } }, + /* 140 */ + { { 0x2552b40,0x0b6b883,0x12e8217,0x0974d35,0x062f497,0x1e563e6, + 0x30ee400,0x375d1e4,0x290751f,0x0d5b68a,0x353e48c,0x064a0d3, + 0x3c343f1,0x309a394,0x0034d2a }, + { 0x3111286,0x0f08604,0x1827107,0x0536a76,0x0201dac,0x3a574de, + 0x2c29dbe,0x382c7b0,0x1191f3e,0x324c5bc,0x144ce71,0x24327c1, + 0x1212778,0x22bc9d8,0x00d7713 } }, + /* 141 */ + { { 0x34ad1cd,0x1179b4e,0x1bc1780,0x1392a92,0x2cd86b9,0x359de85, + 0x251f1df,0x0da5d5f,0x135fa61,0x0f64a42,0x34f4d89,0x0fe564c, + 0x3cf9b7a,0x122d757,0x008c9c2 }, + { 0x370d4e9,0x0e9209b,0x0ae99f2,0x1518c64,0x0172734,0x2c20692, + 0x1d7c135,0x149c52f,0x38928d6,0x3c78b78,0x25841d1,0x2eaa897, + 0x372e50b,0x29e5d19,0x00c4c18 } }, + /* 142 */ + { { 0x13375ac,0x389a056,0x211310e,0x2f9f757,0x04f3288,0x103cd4e, + 0x17b2fb2,0x2c78a6a,0x09f1de6,0x23e8442,0x1351bc5,0x1b69588, + 0x285b551,0x0464b7e,0x00573b6 }, + { 0x0ba7df5,0x259a0db,0x2b4089e,0x05630a2,0x3f299be,0x350ff2f, + 0x1c9348a,0x3becfa4,0x3cc9a1c,0x17a6ef1,0x338b277,0x2b761d9, + 0x2aa01c8,0x3cb9dd7,0x006e3b1 } }, + /* 143 */ + { { 0x277788b,0x16a222d,0x173c036,0x310ff58,0x2634ae8,0x392636f, + 0x0987619,0x1e6acc1,0x26dc8f7,0x242310f,0x0c09aca,0x22b8e11, + 0x0d17006,0x1c2c806,0x002380c }, + { 0x297c5ec,0x1fef0e8,0x3948cf7,0x14f2915,0x2dacbc8,0x0dafb1f, + 0x10de043,0x31184da,0x06414ee,0x3c9aeeb,0x1f713ab,0x308f1f8, + 0x1569ed1,0x3f379bf,0x00f08bb } }, + /* 144 */ + { { 0x0770ee3,0x058fd21,0x17065f8,0x251d128,0x10e0c7f,0x06cb51b, + 0x0f05f7e,0x3666a72,0x3e7d01f,0x2d05fab,0x11440e5,0x28577d4, + 0x2fbcf2b,0x14aa469,0x00dc5c5 }, + { 0x270f721,0x1c75d28,0x085b862,0x1d68011,0x132c0a0,0x37be81d, + 0x1a87e38,0x083fa74,0x3acbf0d,0x16d6429,0x0feda1f,0x031070a, + 0x2ec2443,0x21e563d,0x00454d2 } }, + /* 145 */ + { { 0x0525435,0x1e98d5f,0x3dbc52b,0x1fcdf12,0x13d9ef5,0x3ff311d, + 0x393e9ed,0x3cef8ae,0x2987710,0x3bdee2e,0x21b727d,0x3ba1b68, + 0x10d0142,0x3c64b92,0x0055ac3 }, + { 0x0c1c390,0x38e9bb0,0x1e7b487,0x11511b3,0x1036fb3,0x25aba54, + 0x1eb2764,0x048d022,0x0d971ed,0x1bb7fb5,0x100f0b4,0x06c3756, + 0x2f0d366,0x3c6e160,0x0011bd6 } }, + /* 146 */ + { { 0x36bc9d1,0x24d43c1,0x12c35cf,0x2fb3cf3,0x015d903,0x16bc0c7, + 0x0fc8c22,0x3195c87,0x2488b1c,0x1f82b4c,0x30014e8,0x27ee58d, + 0x31658dd,0x1684a5f,0x00f0f3a }, + { 0x1f703aa,0x023eebc,0x20babb9,0x080bd9d,0x12f9cc4,0x1a8e2d4, + 0x0eec666,0x1176803,0x33005d6,0x1137b68,0x37de339,0x33d71cb, + 0x0c906b9,0x14086b5,0x00aeef6 } }, + /* 147 */ + { { 0x219045d,0x0f22c5e,0x024c058,0x00b414a,0x0ae7c31,0x3db3e96, + 0x234979f,0x0cf00a8,0x3c962c7,0x27fa77f,0x1c0c4b0,0x1fe8942, + 0x218053a,0x1eed3f8,0x0051643 }, + { 0x2a23ddb,0x138f570,0x104e945,0x21ca270,0x30726d8,0x3f45490, + 0x37d9184,0x242ea25,0x33f6d77,0x3f15679,0x065af85,0x34fa1f5, + 0x2e46b8f,0x31d17fb,0x00a2615 } }, + /* 148 */ + { { 0x335167d,0x181ea10,0x0887c8d,0x01383d7,0x18b42d8,0x263447e, + 0x1f13df3,0x0319d7e,0x0872074,0x2d6aa94,0x23d9234,0x36a69aa, + 0x0bad183,0x3138a95,0x00bd3a5 }, + { 0x1b0f658,0x0e4530b,0x373add1,0x1b968fc,0x329dcb6,0x09169ca, + 0x162df55,0x0211eff,0x02391e4,0x3867460,0x3136b1a,0x37dd36e, + 0x3bc5bd9,0x2dacfe4,0x0072a06 } }, + /* 149 */ + { { 0x119d96f,0x067b0eb,0x00996da,0x293eca9,0x2b342da,0x1889c7a, + 0x21633a6,0x0152c39,0x281ce8c,0x18ef3b3,0x0bd62dc,0x3238186, + 0x38d8b7c,0x3867b95,0x00ae189 }, + { 0x0ed1eed,0x1e89777,0x13ab73e,0x029e1d7,0x2c1257f,0x33fbc09, + 0x32d5a21,0x3d870b2,0x39bb1fd,0x33663bc,0x24e83e6,0x239bda4, + 0x3088bcd,0x01db1ed,0x00d71e7 } }, + /* 150 */ + { { 0x14245bf,0x0da0c27,0x153b339,0x05cab0a,0x122d962,0x1b0f0f3, + 0x3f5a825,0x267a2ce,0x2910d06,0x254326f,0x0f36645,0x025118e, + 0x37c35ec,0x36e944e,0x006c056 }, + { 0x05ab0e3,0x29aa0c1,0x1295687,0x1fd1172,0x08d40b5,0x05bd655, + 0x345048a,0x02a1c3c,0x2393d8f,0x0992d71,0x1f71c5e,0x18d4e8a, + 0x30dd410,0x11d61d3,0x00dd58b } }, + /* 151 */ + { { 0x2230c72,0x30213d8,0x05e367e,0x329204e,0x0f14f6c,0x3369ddd, + 0x0bb4074,0x2edafd6,0x1b1aa2d,0x0785404,0x0c035ab,0x220da74, + 0x1f2fdd4,0x092a091,0x00ef83c }, + { 0x3dc2538,0x1cca3e7,0x246afb5,0x24c647f,0x0798082,0x0bb7952, + 0x0f5c443,0x008b38a,0x299ea1a,0x3c6cf36,0x3df2ec7,0x398e6dc, + 0x29a1839,0x1cadd83,0x0077b62 } }, + /* 152 */ + { { 0x25d56d5,0x3546f69,0x16e02b1,0x3e5fa9a,0x03a9b71,0x2413d31, + 0x250ecc9,0x1d2de54,0x2ebe757,0x2a2f135,0x2aeeb9a,0x0d0fe2b, + 0x204cb0e,0x07464c3,0x00c473c }, + { 0x24cd8ae,0x0c86c41,0x221c282,0x0795588,0x1f4b437,0x06fc488, + 0x0c81ecd,0x020bf07,0x3a9e2c8,0x2294a81,0x3a64a95,0x0363966, + 0x32c9a35,0x0f79bec,0x0029e4f } }, + /* 153 */ + { { 0x289aaa5,0x2755b2e,0x059e0aa,0x3031318,0x0f0208a,0x35b7729, + 0x00d9c6b,0x3dd29d0,0x075f2c2,0x0ece139,0x31562dd,0x04187f2, + 0x13b8d4c,0x0920b85,0x003924e }, + { 0x09808ab,0x2e36621,0x2a36f38,0x1829246,0x229bf32,0x20883b7, + 0x159ada8,0x3108a14,0x15bbe5b,0x1e2d1e4,0x1730096,0x0d35cbb, + 0x15d0da9,0x0e60b94,0x00c4f30 } }, + /* 154 */ + { { 0x31de38b,0x27b9086,0x2760e3e,0x169098d,0x2a124e2,0x00596c6, + 0x3f73c09,0x0d31642,0x2341464,0x248600a,0x2e1fa10,0x2aa0fc8, + 0x051e954,0x00f3b67,0x001d4bd }, + { 0x18751e6,0x25a8e1e,0x07f5c2d,0x17e30d4,0x0ed2723,0x23093e2, + 0x3b80e2c,0x13de2d7,0x2fad37f,0x1be1cfb,0x3224ba9,0x0a7f5d3, + 0x1714972,0x06667b7,0x009dcd9 } }, + /* 155 */ + { { 0x294f22a,0x3e06993,0x0341ee9,0x24bdc7b,0x2e56098,0x2660a13, + 0x018ddda,0x2c261b2,0x2953b54,0x267f51c,0x0e8a7cc,0x29ab00c, + 0x3a38247,0x397ac81,0x00de684 }, + { 0x36b956b,0x347b34a,0x35834bd,0x053c06c,0x0090844,0x148cec5, + 0x380b325,0x2f17b8b,0x054ef5e,0x09683fb,0x3f8b29a,0x33c979a, + 0x1e01474,0x3e81fca,0x001c757 } }, + /* 156 */ + { { 0x30fdfe4,0x2d712ba,0x13671bc,0x2cfc226,0x3d7c649,0x16f020e, + 0x368e3f0,0x2981ebb,0x246a78a,0x115e81b,0x21223a4,0x04dbb30, + 0x1a50ba2,0x12114bd,0x0089bd6 }, + { 0x055f15a,0x1046e51,0x00fd724,0x1c022a7,0x323dfa9,0x36d8efb, + 0x0da4d16,0x0910dec,0x2c1fb16,0x2dbe29f,0x298284f,0x2b273bb, + 0x26022c1,0x20accd5,0x00085a5 } }, + /* 157 */ + { { 0x01f138a,0x2d87e7b,0x0c2815c,0x0c19a3c,0x311c9a2,0x3e4fce3, + 0x029729d,0x21236b2,0x2984048,0x3f3bc95,0x2bba8fb,0x1a1b680, + 0x0619a3f,0x29e0447,0x00ed5fe }, + { 0x2d1c833,0x3dcef35,0x3f809b4,0x01a1b9e,0x1509516,0x10ac754, + 0x2735080,0x27b0a8a,0x2495fb8,0x0a7bdba,0x1ef8b89,0x00233a5, + 0x0568bf1,0x1a126ba,0x0078a7e } }, + /* 158 */ + { { 0x0470cd8,0x20e9f04,0x30003fe,0x20be1b7,0x1927346,0x2a5026d, + 0x1ac06bd,0x2717ed7,0x2609493,0x3079ea5,0x1cc116d,0x31b0541, + 0x2c8ccde,0x10219ae,0x001a52b }, + { 0x2864045,0x0e8d95b,0x2fc1530,0x0aa44e7,0x345eae7,0x3cc7553, + 0x3ec6466,0x229b60e,0x06f6e95,0x00bed2a,0x0ff4403,0x181c639, + 0x2e0df67,0x1f8fa46,0x0000811 } }, + /* 159 */ + { { 0x04310a2,0x20cee8e,0x09fc5d5,0x3707f5b,0x0bdfb4e,0x12713ee, + 0x24f1028,0x0787ee6,0x39a581c,0x3797ec8,0x10a9746,0x112cb9f, + 0x142b9ba,0x1da0ef6,0x0078f7b }, + { 0x07607ae,0x3232872,0x2a7e076,0x0bb572a,0x182b23c,0x1d8f918, + 0x181f392,0x37c45a9,0x24a3886,0x0b2a297,0x264e7f2,0x1fa433c, + 0x0fcfcc8,0x21c0857,0x0004f74 } }, + /* 160 */ + { { 0x01d161c,0x1744585,0x2d17528,0x03a4f13,0x267cd2e,0x30d861f, + 0x062a647,0x213284b,0x139ed25,0x27d4ca5,0x02fbbd6,0x31ddf11, + 0x3c50ac4,0x1dd86f7,0x00107de }, + { 0x16beebd,0x1b7317a,0x2151997,0x256a196,0x3be2aff,0x3621cab, + 0x0a9da19,0x05f3038,0x23da63c,0x3178d5e,0x215cc67,0x07f7f63, + 0x0c6d8d3,0x3bf5e5c,0x00c44bb } }, + /* 161 */ + { { 0x00c62f1,0x3e0f893,0x1572703,0x3b93865,0x19b1e28,0x389b33b, + 0x02858bf,0x0e3e9aa,0x04bc436,0x234e072,0x25ba43d,0x3dca19e, + 0x0274394,0x20f442e,0x003b4a7 }, + { 0x176451e,0x2b5ed5d,0x35c8ee1,0x25c52da,0x0c3d0b5,0x32b306e, + 0x030954f,0x275ecf7,0x10e472c,0x21577c4,0x02f8a32,0x321bb5c, + 0x0098f97,0x104e237,0x00d0433 } }, + /* 162 */ + { { 0x0a8f2fe,0x034548b,0x141f1a6,0x121246f,0x1616409,0x237f80d, + 0x2e29a55,0x1218db6,0x3ea278e,0x1669856,0x1ad7c8e,0x36d11de, + 0x2c2fcbb,0x18c0b3a,0x001c706 }, + { 0x1699b4b,0x2d531a6,0x17e85e2,0x1b48e78,0x2b509ca,0x2818ea0, + 0x0165fee,0x0b809ca,0x09db6a2,0x3dad798,0x326ee1d,0x204e416, + 0x091fa12,0x1c890e5,0x0007b9f } }, + /* 163 */ + { { 0x0ff4e49,0x0bb0512,0x0129159,0x05db591,0x03e4e9f,0x055ab30, + 0x0f82881,0x0ac2deb,0x3a8bb09,0x356a8d2,0x3d38393,0x03e4089, + 0x38187cd,0x1377a93,0x0041672 }, + { 0x0139e73,0x3990730,0x187d3c4,0x33e4793,0x2e0fe46,0x2ad87e2, + 0x33c792c,0x21d4fb6,0x1e4d386,0x2932d1b,0x20f1098,0x1270874, + 0x0ea6ee4,0x0167d6e,0x005e5fd } }, + /* 164 */ + { { 0x1856031,0x2b7519d,0x3bd07fc,0x337abcb,0x089c7a4,0x2a1f120, + 0x3523ce7,0x2ba406b,0x09561d9,0x1797f04,0x3cdb95f,0x2d6193e, + 0x32c7d3f,0x223aed6,0x00beb51 }, + { 0x2e65825,0x158f0ce,0x16413d1,0x310395f,0x3116854,0x250baf4, + 0x373d341,0x156cc47,0x104c069,0x0893716,0x195a0a6,0x035320e, + 0x37b7d8a,0x21b5755,0x00fb26b } }, + /* 165 */ + { { 0x286ae17,0x04239f1,0x1a56c53,0x0e74707,0x29090d7,0x2bb142b, + 0x03b0139,0x1aac916,0x08ba49a,0x0376682,0x3382f85,0x064bbab, + 0x2910e28,0x1d5bd7f,0x00cc8df }, + { 0x0ab7630,0x208e8e7,0x3fc1877,0x26bee39,0x264984a,0x192ff05, + 0x08ef9c3,0x0aa6951,0x071c44e,0x26eed3e,0x035c95e,0x06906ad, + 0x10a0690,0x397eaa9,0x00c6c23 } }, + /* 166 */ + { { 0x034d8dd,0x005b064,0x279bb78,0x12c2c4f,0x1856bb4,0x0c90681, + 0x06409ab,0x3b48617,0x19a2d78,0x0a34bf8,0x326eddf,0x31f09b5, + 0x04f04dc,0x3d7c944,0x003ccaf }, + { 0x321f843,0x35fb71a,0x1e4c397,0x377a5d7,0x2da88e4,0x3d6ada7, + 0x33d3964,0x1b30149,0x0e39aae,0x054dda0,0x3e6f946,0x1273394, + 0x3ffd3f7,0x2f6655e,0x00021dd } }, + /* 167 */ + { { 0x37233cf,0x11617dd,0x26f07b6,0x3d8250a,0x0fe6771,0x3f9bbbc, + 0x2aba7ad,0x200a58d,0x3568603,0x198eefa,0x1e8fcf3,0x3b9610b, + 0x20524ac,0x2a67528,0x0048d9a }, + { 0x1a5e57a,0x1e9d303,0x16c9cff,0x0f39527,0x3c23259,0x03c8a1e, + 0x104bccf,0x182d5a1,0x18dbc83,0x05b5f42,0x1b402f4,0x317c525, + 0x11bf1ea,0x3c46e1f,0x0061936 } }, + /* 168 */ + { { 0x0153a9d,0x36859ee,0x2cf0aa9,0x2b27a0f,0x0a49fe3,0x2d984e1, + 0x018f8e1,0x1378453,0x1ab3843,0x1987093,0x283dae9,0x25cf0e8, + 0x14fc93d,0x280609d,0x00c99ba }, + { 0x026b1e3,0x34663d3,0x2202477,0x21a9d45,0x212e8e1,0x18ab77e, + 0x2e52f63,0x0a14ce1,0x295c396,0x00c7a3d,0x2aaedb6,0x30abc4d, + 0x374acde,0x1318a73,0x00fcfdb } }, + /* 169 */ + { { 0x0a40298,0x3ba5633,0x11956b3,0x14fcbd7,0x3c38781,0x34bab96, + 0x165630e,0x1f3c831,0x37e3a69,0x2b4226c,0x2d5029e,0x3b4ab1e, + 0x1da6ac2,0x3eb43c3,0x007e5cd }, + { 0x1b86202,0x109b7f6,0x2054f98,0x2c50cd7,0x2ed1960,0x3c518e7, + 0x1b02463,0x319c07f,0x1c30db6,0x045fdc2,0x373421e,0x31a1eb9, + 0x1a8acbf,0x31289b0,0x0013fef } }, + /* 170 */ + { { 0x3fa0a5f,0x068661f,0x2109e36,0x00b18ff,0x1f4b261,0x31d3844, + 0x0acbc56,0x3aebc99,0x1fa77ab,0x152bd11,0x24cddb7,0x2313f74, + 0x06eea44,0x15f5114,0x000b131 }, + { 0x2e9993d,0x1ac565c,0x2cbe22a,0x3921797,0x12c3c57,0x360f868, + 0x33560bf,0x320ee99,0x382c3b8,0x39af88f,0x00bbe38,0x2c4ea59, + 0x3399b40,0x00ceb45,0x0066eea } }, + /* 171 */ + { { 0x0c6c693,0x31ba56d,0x3d3849f,0x378dabd,0x0efc735,0x17f90bf, + 0x13343d3,0x2df0f81,0x27c6a9a,0x13c2a90,0x0a0fcb2,0x27c10d9, + 0x3bc50c7,0x090e4fa,0x0016287 }, + { 0x2927e1e,0x35af405,0x184c5c3,0x3499cee,0x240158e,0x33522e6, + 0x386fc84,0x0a0b69f,0x1a660ea,0x34590fb,0x22a1bee,0x2ce4fab, + 0x31a9445,0x0e78655,0x00664c8 } }, + /* 172 */ + { { 0x3eeaf94,0x115d409,0x21e7577,0x097aa67,0x22875c9,0x021ab7a, + 0x27e7ba5,0x1093f04,0x2a086fe,0x05d9494,0x2b6c028,0x10f31b0, + 0x1312d11,0x262759c,0x00c9bb2 }, + { 0x1acb0a5,0x30cdf14,0x0f78880,0x0574f18,0x1a37109,0x098adbb, + 0x2113c09,0x2060925,0x1f89ce4,0x1974976,0x3381358,0x2dab5ca, + 0x2159c53,0x3af1303,0x000ea3b } }, + /* 173 */ + { { 0x1e49bea,0x29142b1,0x1a59cab,0x055f017,0x0684e54,0x39eb0db, + 0x29cab9d,0x255ee8b,0x35f2e6f,0x05329e6,0x09b817b,0x1ec091c, + 0x1df0fef,0x2641f62,0x00eb304 }, + { 0x2fe5096,0x3dcc1d1,0x2aaf508,0x3a0b813,0x0695810,0x144bddb, + 0x2f1bd93,0x281ae23,0x3513ebc,0x1ddd984,0x0cf158b,0x35218eb, + 0x257daf7,0x391253b,0x00b2a81 } }, + /* 174 */ + { { 0x153e6ba,0x22396db,0x0ea2ff2,0x2a45121,0x0a90de1,0x34cf23b, + 0x2db60ce,0x1a900be,0x2f328b6,0x355e75b,0x2c24372,0x0b75b77, + 0x2ec7d4f,0x3f24759,0x00e9e33 }, + { 0x39eab6e,0x2267480,0x3b5e110,0x1e8fa5e,0x2a31a66,0x3f739a3, + 0x00166dc,0x3552d88,0x3ae5137,0x3efa0fa,0x0800acd,0x17df61d, + 0x38c8608,0x04cc31b,0x00cf4ab } }, + /* 175 */ + { { 0x31e08fb,0x1961164,0x22c003f,0x078541b,0x3643855,0x30da587, + 0x11f0dc9,0x324595e,0x329e3dc,0x29a041e,0x3495d2c,0x0908dd3, + 0x1895b83,0x198dbb9,0x00d8cfb }, + { 0x0349b1b,0x383c5a8,0x2b86525,0x1b1283e,0x133cd2c,0x2be376a, + 0x012ee82,0x1eb4d1b,0x0ba71e9,0x01f3109,0x37621eb,0x1d9b77c, + 0x0d39069,0x3d5a97c,0x0095565 } }, + /* 176 */ + { { 0x20f5e94,0x1eefc86,0x1327e0e,0x054760b,0x2f771e1,0x3ac447e, + 0x033e3dc,0x198e040,0x04dd342,0x1b49a5d,0x00d01ef,0x3cb6768, + 0x1ceafbd,0x31c6812,0x001cb80 }, + { 0x221c677,0x060ca27,0x398b17f,0x0146723,0x36452af,0x02d9e65, + 0x39c5f78,0x3cf50d6,0x0be40f8,0x2970b87,0x26d667c,0x3e45959, + 0x16e7943,0x01673e7,0x009faaa } }, + /* 177 */ + { { 0x2078fe6,0x0918602,0x11dd8ad,0x399193f,0x0f6cc73,0x0f8dd12, + 0x2ce34dc,0x06d7d34,0x0c5e327,0x0989254,0x2fc5af7,0x2443d7b, + 0x32bc662,0x2fe2a84,0x008b585 }, + { 0x039327f,0x08e616a,0x252f117,0x1f52ab0,0x234e2d2,0x0a5b313, + 0x2f59ef6,0x0f7a500,0x15c4705,0x2c02b81,0x28b4f09,0x08aa5c8, + 0x0180efc,0x0993e83,0x00a9e86 } }, + /* 178 */ + { { 0x0310ecc,0x2d8892f,0x14ed0b7,0x3c59fe8,0x08a1a74,0x0850e57, + 0x1d09607,0x044a21f,0x109f5c9,0x237c6cf,0x06b264a,0x3fc8f1a, + 0x0d4c539,0x2740f96,0x00dc2d4 }, + { 0x1d6f501,0x0adf4ea,0x14f7215,0x0930102,0x3f4c32e,0x24e2643, + 0x366596d,0x081ff18,0x38f94fb,0x2c21341,0x328594c,0x267c75c, + 0x196b3fd,0x29932cb,0x0036def } }, + /* 179 */ + { { 0x3ed7cbe,0x26de044,0x3d0e461,0x0565e12,0x295e500,0x31dc17f, + 0x32251c2,0x3420ca8,0x3995f0d,0x2e8ddab,0x0361a45,0x10971b0, + 0x11e7b55,0x33bc7ca,0x00812d2 }, + { 0x3d94972,0x1606817,0x0383ccf,0x0e795b7,0x026e20e,0x0f6fefc, + 0x13685d6,0x315d402,0x0cc36b8,0x1c7f059,0x390ef5e,0x316ae04, + 0x08c66b9,0x2fac9a4,0x0040086 } }, + /* 180 */ + { { 0x3e3c115,0x153de4d,0x1a8ae5e,0x2330511,0x169b8ee,0x1d965c2, + 0x2edff2b,0x3ef99e6,0x1631b46,0x1f8a238,0x118d7bb,0x12113c3, + 0x26424db,0x0f4122a,0x00e0ea2 }, + { 0x3d80a73,0x30393bc,0x0f98714,0x278ef59,0x087a0aa,0x3b18c20, + 0x04b8a82,0x2068e21,0x030255d,0x3382b27,0x055397f,0x05448dd, + 0x2015586,0x1190be0,0x000b979 } }, + /* 181 */ + { { 0x2e03080,0x2895692,0x09fb127,0x2d1602a,0x1232306,0x105bd4e, + 0x28cd6a6,0x0a83813,0x1ee13b0,0x2abadc3,0x0c09684,0x00e33e1, + 0x033eea3,0x30f0a39,0x00a710e }, + { 0x01b1f7d,0x1c959da,0x017077a,0x254bf0a,0x086fbce,0x15cd6b2, + 0x008683f,0x23a4f4d,0x22a6bd6,0x14e8c93,0x0027d15,0x31d0d4f, + 0x271777e,0x1533510,0x00ab603 } }, + /* 182 */ + { { 0x34c209d,0x14d0abb,0x270432a,0x1d02358,0x22ba752,0x209757f, + 0x34af6fc,0x1ffc52e,0x1ced28e,0x1870e46,0x1e0340f,0x3f0bf73, + 0x33ba91d,0x2ebca7c,0x00c6580 }, + { 0x1d442cb,0x0879d50,0x24e4ae1,0x3f4e91c,0x04c7727,0x093cd1d, + 0x16d6a45,0x10a8b95,0x0c77856,0x361f84f,0x217845f,0x0bbeec6, + 0x0485718,0x33c5385,0x00dcec0 } }, + /* 183 */ + { { 0x1539819,0x225507a,0x1bf11cb,0x13e7653,0x0c8cb3b,0x05f695e, + 0x353f634,0x2827874,0x3fb8053,0x22de9a5,0x035d8b7,0x2105cc7, + 0x2a7a98d,0x35bed95,0x0085748 }, + { 0x1859c5d,0x00e51f0,0x22a21fd,0x3054d74,0x06ce965,0x328eab7, + 0x26a13e0,0x13bfc65,0x01d4fb1,0x36600b9,0x36dd3fc,0x01232ed, + 0x15bbaa9,0x0ad7a51,0x0089b18 } }, + /* 184 */ + { { 0x3360710,0x1eb5a90,0x136bd77,0x3bd57a6,0x0841287,0x12886c9, + 0x35c6700,0x21bc6eb,0x25f35ad,0x3bcb01c,0x0707e72,0x23e9943, + 0x03e5233,0x34bb622,0x002bf8e }, + { 0x16e0d6a,0x04b3d2d,0x290cb02,0x049a10c,0x350537e,0x22cf71b, + 0x3184a19,0x2dc8b62,0x2350210,0x3b4afa6,0x159781e,0x1d01b6d, + 0x1853440,0x16442f0,0x005a78d } }, + /* 185 */ + { { 0x348b02c,0x1ea8ab5,0x3b954d5,0x14684ac,0x0be5b34,0x11c4496, + 0x0a7a456,0x14f6eb7,0x11a3221,0x2d65f82,0x32eb1ea,0x09c4018, + 0x3f301f3,0x32e8a1c,0x00bd9ad }, + { 0x0543f7f,0x31e744e,0x1fefd1d,0x24a486c,0x1000220,0x3977e3b, + 0x1b3ef51,0x2512a1b,0x2049e6b,0x122232b,0x391a32b,0x2f4a7b1, + 0x1c13e71,0x081a9b4,0x00d3516 } }, + /* 186 */ + { { 0x1924f43,0x1ae5495,0x28d52ef,0x2b93e77,0x2d2f401,0x371a010, + 0x33e8d7a,0x06ed3f1,0x30c0d9d,0x2589fa9,0x3bf3567,0x2ecf8fa, + 0x2dee4c3,0x152b620,0x007e8a2 }, + { 0x1924407,0x01bd42d,0x044a089,0x18686b5,0x2f14a0e,0x17cdce3, + 0x0efa216,0x3c586a8,0x1d6ae71,0x375831f,0x3175894,0x20e43eb, + 0x34c009e,0x3480527,0x00d115c } }, + /* 187 */ + { { 0x12abf77,0x38b0769,0x25682f2,0x295508c,0x0c2a0dc,0x1259b73, + 0x023ea25,0x340e7b5,0x3c7cd0d,0x1f92324,0x176405c,0x1528894, + 0x18f2e1e,0x2c59c35,0x001efb5 }, + { 0x0fb1471,0x07e7665,0x141da75,0x07d9f4a,0x0fdb31e,0x0dccda6, + 0x074eb25,0x3d92a9b,0x11189a0,0x1b4c557,0x24b8d2b,0x0533f92, + 0x0e9e344,0x2fa3dea,0x008d5a4 } }, + /* 188 */ + { { 0x2669e98,0x1ad3514,0x2a035c9,0x08a3f50,0x24547f9,0x0a145d3, + 0x1c1319d,0x3fe833d,0x1ae064b,0x1e01734,0x246d27e,0x3a2f13c, + 0x01e1150,0x263f55e,0x00f89ef }, + { 0x2e0b63f,0x3e57db7,0x23a4b4f,0x11c8899,0x0ad8500,0x348f3a7, + 0x2918604,0x27d6409,0x1ce5001,0x38f94c2,0x29a508a,0x39bdc89, + 0x3a52c27,0x194899e,0x00e9376 } }, + /* 189 */ + { { 0x0368708,0x34a2730,0x2e1da04,0x0bd78c1,0x2c45887,0x0c44bfa, + 0x3a23de3,0x390b9db,0x1746efd,0x05c638e,0x1d20609,0x3263370, + 0x31987f0,0x2988529,0x005fa3c }, + { 0x0aa9f2a,0x20622f7,0x060deee,0x0c9626a,0x3312cc7,0x18ebac7, + 0x008dd6c,0x0ad4fe6,0x3db4ea6,0x1dc3f50,0x090b6e9,0x0aff8d2, + 0x26aa62c,0x18f3e90,0x00105f8 } }, + /* 190 */ + { { 0x38059ad,0x25e576c,0x3ea00b2,0x1fa4191,0x25686b7,0x2d1ce8f, + 0x30470ed,0x3478bbf,0x340f9b6,0x1c9e348,0x3d594ec,0x2ffe56e, + 0x3f23deb,0x0cd34e9,0x00f4b72 }, + { 0x1a83f0b,0x2166029,0x28b32a2,0x06a5c5a,0x20786c4,0x0944604, + 0x0901bd2,0x379b84e,0x221e2fe,0x0346d54,0x1f4eb59,0x01b8993, + 0x2462e08,0x25f9d8b,0x006c4c8 } }, + /* 191 */ + { { 0x0b41d9d,0x2e417ed,0x265bd10,0x199148e,0x3826ca4,0x1a67e8d, + 0x1bbd13b,0x23e414d,0x3d773bc,0x356e64c,0x0d2118a,0x0cb587f, + 0x25fd093,0x24fb529,0x00158c6 }, + { 0x2806e63,0x3ecaa39,0x251b4dd,0x3b2d779,0x2e31ed3,0x066f1a6, + 0x060e518,0x2c7e3e5,0x0d62c76,0x0d88a70,0x101970a,0x1e3c8c6, + 0x272b8bb,0x083e73b,0x0031f38 } }, + /* 192 */ + { { 0x09e1c72,0x072bcb0,0x0cf4e93,0x2604a64,0x00715f2,0x10c98b6, + 0x2ad81d9,0x234fcce,0x37a7304,0x1974a4a,0x1c7415f,0x14aaa93, + 0x19587b1,0x3f643f4,0x00c3d10 }, + { 0x1ddadd0,0x2cd715d,0x294cf76,0x14479ed,0x19f5f4a,0x0198c09, + 0x1ab7ebc,0x182c0bc,0x0879202,0x1807273,0x05d39da,0x2c7d868, + 0x29c4ec4,0x1b13ad2,0x006dcd7 } }, + /* 193 */ + { { 0x1c83f01,0x0245bff,0x24f90ba,0x112554f,0x2354c8b,0x3f17988, + 0x0c511af,0x39e1e9b,0x26ae95b,0x0ae551c,0x35b41a6,0x0120455, + 0x1e989cb,0x1b37aff,0x00fa2ae }, + { 0x324659a,0x1aef1c3,0x1c43637,0x3f530a2,0x313a999,0x326af62, + 0x134184e,0x2ac131c,0x3f6a789,0x30a300a,0x13e526e,0x2107af3, + 0x093a8ff,0x2479902,0x00442b1 } }, + /* 194 */ + { { 0x22b6e20,0x31b18be,0x18614ca,0x26fdb5a,0x197f29e,0x325b44b, + 0x0ab1dbb,0x042348a,0x3275e8e,0x15bae44,0x0077124,0x2cf5345, + 0x2803ad4,0x188f2a2,0x0061b20 }, + { 0x2a560b1,0x3ced069,0x3cf42c2,0x100e167,0x3879e1d,0x0936ff0, + 0x1b51450,0x14c55f3,0x3153bfa,0x2957423,0x2a93823,0x15f5dce, + 0x2c9a22f,0x16731a8,0x00a97f2 } }, + /* 195 */ + { { 0x18edbbb,0x18c5ef9,0x1f13c30,0x071e77f,0x225ade5,0x1b60f75, + 0x1beaf11,0x3e495ad,0x2441dd8,0x2fa00e2,0x32a87b6,0x00050f2, + 0x038de7f,0x0037d6d,0x00a885d }, + { 0x39e48bd,0x1d9e433,0x2768e9f,0x3c29458,0x3f0bdf9,0x35ed5f2, + 0x36709fa,0x176dc10,0x012f7c1,0x2df8547,0x1d90ee3,0x053c089, + 0x21a8d35,0x200cb0d,0x002e84e } }, + /* 196 */ + { { 0x23ec8d8,0x1d81f55,0x0cb7227,0x07f8e4d,0x2a66181,0x163f577, + 0x272e7af,0x131a8f2,0x2046229,0x25e6276,0x36bbefe,0x2cdc22f, + 0x17c8288,0x33dd4fb,0x000d524 }, + { 0x330c073,0x1a6728b,0x1cf369f,0x12e7707,0x2f0fa26,0x17c2abd, + 0x0a45680,0x26ebd13,0x3c7d19b,0x1c3d6c8,0x2abd110,0x064fd07, + 0x09b8339,0x02b4a9f,0x009e3e1 } }, + /* 197 */ + { { 0x0ae972f,0x2093c35,0x06e7a90,0x0af1ba1,0x243eef0,0x2748582, + 0x0606122,0x13a45f9,0x0acfe60,0x08a685e,0x0eb184b,0x015bc11, + 0x0cdf423,0x157fad5,0x004fcad }, + { 0x2728d15,0x3e5bceb,0x0331a0f,0x31b1a80,0x28a2680,0x3b94955, + 0x04cae07,0x176b57e,0x03ac5a6,0x3d7918b,0x22d23f4,0x0ae077f, + 0x1eb075d,0x006f16c,0x006e473 } }, + /* 198 */ + { { 0x38219b9,0x0475a2b,0x107a774,0x39946c6,0x1cb883c,0x004e0ed, + 0x087e571,0x25c3497,0x059982f,0x0a71f66,0x118305d,0x1aaf294, + 0x3a5dbaa,0x34be404,0x00725fe }, + { 0x3abd109,0x336ebea,0x2528487,0x15a1d61,0x0c0f8cf,0x2b56095, + 0x2591e68,0x3549a80,0x1d1debb,0x0701c6c,0x161e7e3,0x1f7fa2e, + 0x3dfe192,0x17e6498,0x0055f89 } }, + /* 199 */ + { { 0x175645b,0x26c036c,0x0b92f89,0x09ed96d,0x351f3a6,0x19ce67b, + 0x33ac8db,0x2f0828b,0x27fe400,0x0b9c5e1,0x1967b95,0x3324080, + 0x11de142,0x1d44fb3,0x003d596 }, + { 0x3979775,0x3af37b6,0x3e88d41,0x2f1a8b9,0x299ba61,0x085413c, + 0x1149a53,0x0beb40e,0x31427ba,0x239f708,0x357d836,0x1558c22, + 0x280a79f,0x1b255f6,0x002b6d1 } }, + /* 200 */ + { { 0x39ad982,0x3d79d89,0x01a684a,0x0b6722e,0x39bb4c9,0x39a6399, + 0x1ad44e0,0x3059f5e,0x048265f,0x33a2fa4,0x0c3a4cc,0x0d7df98, + 0x23a33f1,0x34e2e21,0x00a0a10 }, + { 0x386efd9,0x1c91f34,0x06c2e19,0x3e6d48d,0x00eefd3,0x2181ef2, + 0x2415f97,0x1d33b08,0x0625086,0x1e8aa3e,0x08c9d60,0x0ab427b, + 0x2764fa7,0x3b7943e,0x00cd9f0 } }, + /* 201 */ + { { 0x1a46d4d,0x0e471f4,0x1693063,0x0467ac0,0x22df51c,0x127a0f7, + 0x0498008,0x20e0b16,0x1aa8ad0,0x1923f42,0x2a74273,0x01761ce, + 0x1600ca4,0x187b87e,0x00ee49e }, + { 0x0c76f73,0x19daf92,0x0b2ad76,0x3d8049d,0x1d9c100,0x0fe1c63, + 0x0bb67c8,0x035cc44,0x02002fc,0x37b2169,0x344656a,0x1127879, + 0x1939bc0,0x0dd8df6,0x0028ce7 } }, + /* 202 */ + { { 0x0544ac7,0x26bdc91,0x042697e,0x356e804,0x1f2c658,0x2ceb7ef, + 0x2dec39f,0x02c1dcc,0x391a2df,0x2344beb,0x2171e20,0x3099c94, + 0x0fa548a,0x37216c9,0x00f820c }, + { 0x0f4cf77,0x29bbaa5,0x33c6307,0x34a5128,0x118c783,0x2dd06b1, + 0x139d4c0,0x2db912e,0x1153ffb,0x1075eb3,0x3a255e4,0x2892161, + 0x36d5006,0x125338c,0x0014fbc } }, + /* 203 */ + { { 0x1584e3c,0x0830314,0x00279b9,0x167df95,0x2c7733c,0x2108aef, + 0x0ce1398,0x35aaf89,0x012523b,0x3c46b6a,0x388e6de,0x01a2002, + 0x0582dde,0x19c7fa3,0x007b872 }, + { 0x1e53510,0x11bca1f,0x19684e7,0x267de5c,0x2492f8b,0x364a2b0, + 0x080bc77,0x2c6d47b,0x248432e,0x3ace44f,0x32028f6,0x0212198, + 0x2f38bad,0x20d63f0,0x00122bb } }, + /* 204 */ + { { 0x30b29c3,0x3cec78e,0x01510a9,0x0c93e91,0x3837b64,0x1eca3a9, + 0x105c921,0x05d42e6,0x1379845,0x07ce6f2,0x0e8b6da,0x0e0f093, + 0x220b2cd,0x1f6c041,0x00299f5 }, + { 0x0afdce3,0x2b0e596,0x2f477b6,0x2ccf417,0x3a15206,0x26ec0bf, + 0x2e37e2b,0x2593282,0x0ab9db3,0x2841dd8,0x27954be,0x277a681, + 0x03f82e2,0x2b610c7,0x00446a1 } }, + /* 205 */ + { { 0x06b8195,0x3b3a817,0x31b9c6f,0x317d279,0x3d744a7,0x1de9eb9, + 0x296acc1,0x1ce9ea3,0x06c3587,0x246815d,0x3756736,0x0588518, + 0x1c971a4,0x1fde1f4,0x00aa021 }, + { 0x3fd3226,0x274561d,0x00be61e,0x01393d8,0x30f6f23,0x29b7fc1, + 0x04cebc7,0x0a892a7,0x20109f1,0x27456be,0x0c863ee,0x2eb6c8a, + 0x38c782b,0x039397a,0x00a2829 } }, + /* 206 */ + { { 0x29de330,0x21fe80f,0x145b55b,0x1986570,0x012b260,0x2482fbc, + 0x0536e0a,0x16b7382,0x32c4d19,0x1deffdb,0x145f418,0x0c67a76, + 0x2ce477f,0x218fe24,0x00f9848 }, + { 0x3e37657,0x3f074d3,0x245ad0e,0x20973c3,0x23c58de,0x2c332ef, + 0x2ad21a8,0x0bf1589,0x208af95,0x1f4a8c4,0x2b43735,0x1e46657, + 0x15d4f81,0x0c3e63a,0x005f19d } }, + /* 207 */ + { { 0x26865bb,0x20f6683,0x16a672e,0x0efd8d1,0x222f5af,0x18f2367, + 0x1e9c734,0x25c3902,0x178dfe6,0x2903a79,0x311b91c,0x1adbbe9, + 0x225a387,0x0b3e509,0x0089551 }, + { 0x34e462b,0x23b6a32,0x27c884c,0x129104b,0x384c015,0x3adedc7, + 0x325db1c,0x021dc10,0x1e366f7,0x3054df7,0x1992b9a,0x2824e64, + 0x0ae77f3,0x181b526,0x00a7316 } }, + /* 208 */ + { { 0x2d260f5,0x2434bf2,0x28c0139,0x0a7bb03,0x176c3be,0x3def5f5, + 0x05bee00,0x3692df7,0x3d2efeb,0x3a6f859,0x1122b87,0x38f779a, + 0x1415ccc,0x2c260ad,0x0075a28 }, + { 0x04607a6,0x042f37a,0x3f0df68,0x0a1bd36,0x3c6d581,0x2d36bfa, + 0x2d577d1,0x0a3affa,0x0b2066b,0x2e6f110,0x0b17e84,0x3c76a5e, + 0x1a57553,0x012f36a,0x0004595 } }, + /* 209 */ + { { 0x29e5836,0x0e6808c,0x269d13e,0x147dc5c,0x32c9e7d,0x09b258e, + 0x2c58d6f,0x1efd716,0x0437996,0x34ec31b,0x15908d9,0x2efa8fd, + 0x09ad160,0x079fc1f,0x00d8481 }, + { 0x3d20e4a,0x18269d6,0x3aa8fe7,0x34829c2,0x2e4325d,0x0d800e1, + 0x11f370b,0x10c08dc,0x22fd092,0x1a5fe55,0x0acc443,0x037030d, + 0x1cdd404,0x097379e,0x00fd6d7 } }, + /* 210 */ + { { 0x313eafb,0x3f438f3,0x2e5fb3e,0x2ed6a82,0x121009c,0x240889e, + 0x00c5537,0x269b792,0x334b2fc,0x1dd573c,0x07096ae,0x19296fc, + 0x3813985,0x2742f48,0x00ddd64 }, + { 0x2045041,0x3842c62,0x1572d0d,0x04f255f,0x06e05b4,0x383ec97, + 0x1ff8064,0x18bed71,0x39b6411,0x2764cc5,0x257439f,0x3521217, + 0x172aa42,0x342a2a3,0x0070c5b } }, + /* 211 */ + { { 0x3bdf646,0x1c5ce25,0x1f7ca76,0x2d2acca,0x3aa1485,0x23c97f7, + 0x3e11d6f,0x0609338,0x07ec622,0x01da8ff,0x3392474,0x17ca07f, + 0x13a9a04,0x353a5b4,0x0024557 }, + { 0x14c27cd,0x32012f7,0x3fea875,0x3d03d71,0x211c5f0,0x3157fdf, + 0x0c880bd,0x3c406b2,0x2c51103,0x24ab377,0x399faa8,0x0d06887, + 0x16b5738,0x28b33a7,0x00c7b67 } }, + /* 212 */ + { { 0x2357586,0x35c93e3,0x0da09a0,0x3d77d92,0x11d7f4f,0x37b98a9, + 0x3e6c9bf,0x2cdca70,0x2f00389,0x2412673,0x18eab87,0x0101436, + 0x11617e9,0x06d9b01,0x00e8eef }, + { 0x37e3ca9,0x16ffaf0,0x391debf,0x1b69382,0x07c5e94,0x312fa8a, + 0x0973142,0x2cadde4,0x109ee67,0x3a07db0,0x1afc5ed,0x08df66f, + 0x304c7af,0x0804aae,0x00d2e60 } }, + /* 213 */ + { { 0x24f57bf,0x1818322,0x182a615,0x25bfc44,0x0f97586,0x0a5bbc0, + 0x36773c6,0x1a2660c,0x3ceff66,0x3270152,0x319cd11,0x2845845, + 0x1acfad6,0x19076f8,0x009824a }, + { 0x289fd01,0x2de97ee,0x39d80b7,0x026227d,0x0f8d3b8,0x15e0a17, + 0x21ea08f,0x20a2317,0x136ae6d,0x3deb1d1,0x3521ef5,0x0de8801, + 0x0a25d5d,0x0612c98,0x005ecc4 } }, + /* 214 */ + { { 0x308c8d3,0x3aec669,0x01ecddc,0x13f18fe,0x1e63ed0,0x061cfe5, + 0x05f5a01,0x1db5741,0x14479f2,0x0ced6b5,0x025ae5b,0x09ca8f5, + 0x2160581,0x1404433,0x008bfeb }, + { 0x08228bf,0x0e02722,0x37df423,0x33ecabf,0x34bd82a,0x32f529f, + 0x28f1800,0x0c8f671,0x1246b44,0x1ff35dc,0x091db95,0x303f3da, + 0x28f7f60,0x3624136,0x00cfbb4 } }, + /* 215 */ + { { 0x326139a,0x2977e4e,0x3eb89a6,0x20ecb31,0x13e076a,0x2a592f3, + 0x28e82d5,0x235ad1e,0x239b927,0x262938a,0x2444354,0x141b263, + 0x0d56693,0x2a3fc78,0x0006497 }, + { 0x31efa05,0x3a3664a,0x3e333de,0x2a114e4,0x12da63c,0x3c15e6b, + 0x2f7277c,0x363aa92,0x2393236,0x16bd2d1,0x32b617f,0x32b656c, + 0x3b1246c,0x22e2e22,0x00ce76d } }, + /* 216 */ + { { 0x03843dc,0x094de82,0x13b463d,0x0507905,0x089eb35,0x2a6bf25, + 0x35ebc4e,0x2bb5d45,0x1808ed1,0x1de9949,0x185e829,0x0a55847, + 0x0b73d67,0x1a2ed61,0x008dd2d }, + { 0x133c3a4,0x04e7980,0x38ea237,0x2ad2f49,0x19de838,0x018bf36, + 0x29b072c,0x21c1ba0,0x14f63ba,0x31c1cc3,0x13cd05e,0x20120ff, + 0x1f84d60,0x16e0321,0x00872ab } }, + /* 217 */ + { { 0x19d4d49,0x1ddb4e6,0x05e7fc0,0x37bb0fd,0x1a3eb59,0x36b87f0, + 0x190e440,0x1c7fef2,0x31ea153,0x14cd65a,0x1bc7ab2,0x11f72ca, + 0x39582d4,0x0fa4d65,0x00cd5b6 }, + { 0x3d1ff11,0x0d9be9d,0x2903ae3,0x017b7b9,0x259f28f,0x110cefc, + 0x03fed1a,0x38039bd,0x09bdf9c,0x3055027,0x2ca9c5d,0x2d737b6, + 0x3bdb421,0x16560b5,0x00f9f33 } }, + /* 218 */ + { { 0x022c792,0x110de25,0x38bf959,0x08f2562,0x1239ea9,0x3c1d950, + 0x21a247d,0x315112d,0x285bb9f,0x2534a73,0x0b42455,0x1a4a99c, + 0x069009a,0x1680392,0x006e0ca }, + { 0x1b3bece,0x269e0a1,0x18926b7,0x0e7187e,0x241f35e,0x39d1fe0, + 0x02099aa,0x1675bfe,0x23fd0ca,0x3d6322b,0x19406b5,0x324c38a, + 0x242434a,0x3ae677c,0x002ce04 } }, + /* 219 */ + { { 0x2c37b82,0x1ae6506,0x0d83436,0x23496c1,0x0ff0c72,0x2711edf, + 0x1513611,0x04f9c7d,0x1edbeff,0x376fcb5,0x212a683,0x23bf547, + 0x0f9c4f7,0x16e6627,0x0082cd8 }, + { 0x0cb5d37,0x31b6db8,0x1a15e23,0x2f5cbb8,0x0818aee,0x21dc6c5, + 0x12aafd2,0x205f608,0x1d91def,0x3def088,0x1445c51,0x3100e8a, + 0x3746bda,0x145c4b0,0x00711b0 } }, + /* 220 */ + { { 0x2a99ecc,0x27b5217,0x35e10ed,0x036e32a,0x0f79950,0x15c32f7, + 0x2c87dcb,0x3ebb2a3,0x2c2d35d,0x114b3ec,0x2e4d80a,0x0c7eb89, + 0x2abe58d,0x3727737,0x00e6a37 }, + { 0x1eca452,0x1968d07,0x344e5d3,0x29435a2,0x109a5f8,0x181d12c, + 0x238ea5a,0x127a564,0x00dbb42,0x0fcbfb7,0x2909b2e,0x2571d3a, + 0x08250e3,0x0694e4e,0x00e156d } }, + /* 221 */ + { { 0x3181ae9,0x1acf411,0x3808d79,0x2a11065,0x0baf44b,0x133cfeb, + 0x1330943,0x1711b9a,0x2dec3bd,0x1906a9a,0x2ed947c,0x369d763, + 0x1a5254f,0x104a7a9,0x00acd9d }, + { 0x030301b,0x31568f5,0x2a4965c,0x33ded4b,0x03c9a5b,0x16541fc, + 0x1319cf1,0x2a3748b,0x1b5de74,0x18bb82e,0x077ac2b,0x309a87a, + 0x3c31420,0x0f6a4b9,0x00387d7 } }, + /* 222 */ + { { 0x0d3fdac,0x120cfa3,0x1b8e13c,0x1ccccb9,0x376fcd4,0x0bf87f4, + 0x271b4be,0x363b3fd,0x28b5d98,0x0535cd3,0x114bbc1,0x3ab4f19, + 0x10494b1,0x2161ece,0x00d14ca }, + { 0x12d37e9,0x110ebd7,0x062295a,0x1cc0119,0x073c6ea,0x15d5411, + 0x0aeb4b1,0x23fba91,0x175fab5,0x3ee8fe1,0x1c680a6,0x1e76f27, + 0x3ddfc97,0x3d69ecd,0x00e1ee5 } }, + /* 223 */ + { { 0x2d29f46,0x2d19204,0x3137cd0,0x02c3b54,0x193295b,0x02fbdb2, + 0x2260948,0x22c02ff,0x3885424,0x1299595,0x00e7f9c,0x310ff2a, + 0x01ea169,0x0deef85,0x0021908 }, + { 0x1b26cfb,0x38566a8,0x2852875,0x21debff,0x290ca9f,0x0b29663, + 0x26550d9,0x2b44457,0x05d1938,0x1f8f825,0x366ef93,0x1d8daec, + 0x069e5ef,0x342ece6,0x00b6034 } }, + /* 224 */ + { { 0x2d8356e,0x1578c09,0x226f4d2,0x3b74c51,0x0f83666,0x0323b59, + 0x1ddf61d,0x1ed8508,0x3c52667,0x0e5b91c,0x1e9b18b,0x352bdfa, + 0x13f75da,0x352aa4e,0x00fceff }, + { 0x1c731d5,0x04e2844,0x01d9843,0x286cbc5,0x105bcb3,0x05edd9c, + 0x21fa956,0x3b1ec83,0x01288cc,0x22fbf3a,0x10f1b56,0x081cf72, + 0x15cb758,0x18687c1,0x00f5722 } }, + /* 225 */ + { { 0x2973088,0x1209dcd,0x3980f31,0x0221aa7,0x1c008e7,0x011b098, + 0x395947e,0x2f2806d,0x27dca76,0x037c79a,0x31acddf,0x2bf6219, + 0x0d8f4ab,0x13644d9,0x00ff705 }, + { 0x2260594,0x18d51f8,0x277e2cf,0x1cb5cec,0x2468a53,0x3e6f4d7, + 0x019e24e,0x0f30f1d,0x0202404,0x34ad287,0x090b39c,0x23c11ea, + 0x1a2e3a2,0x3a851be,0x00dca2c } }, + /* 226 */ + { { 0x3277538,0x221cd94,0x3738ab7,0x0973da5,0x1a734e2,0x2c8b8b0, + 0x2e1d1e6,0x348499b,0x389ebe1,0x18b1854,0x02bb076,0x1b2b500, + 0x0f207f3,0x170cf99,0x0012088 }, + { 0x0fbfec2,0x1df55a4,0x34ae59e,0x2ab5e95,0x3f9e781,0x3411794, + 0x1410b05,0x17c3a00,0x0aaa91b,0x074ed7c,0x3fbb352,0x3477c01, + 0x3ee9ab3,0x0cfb1ca,0x0011c4b } }, + /* 227 */ + { { 0x3c3a7f3,0x2e60ca0,0x2354d32,0x33e2362,0x28083ab,0x03d3b16, + 0x3164045,0x0a41f7a,0x3f0641e,0x38635d1,0x31bbf03,0x225e2bb, + 0x0cd894e,0x1f72228,0x0093244 }, + { 0x33d5897,0x383faf3,0x0e6d561,0x0bc4d80,0x3fc3a68,0x05a9adc, + 0x0b9d73d,0x3d6031e,0x2ded29b,0x339c4ff,0x08d69e5,0x089488c, + 0x3fda40a,0x295c7fd,0x003a924 } }, + /* 228 */ + { { 0x0093bee,0x115532d,0x2ec0fb6,0x0969631,0x3a6d65a,0x0f43b4d, + 0x26994d4,0x0b51104,0x2515515,0x3695a26,0x284caa8,0x397aa30, + 0x25538b8,0x353f47c,0x0033f05 }, + { 0x3615d6e,0x37f8246,0x07dae0f,0x23dc154,0x02ded7e,0x1eef320, + 0x1631e51,0x3447f75,0x13e267f,0x353e1d1,0x3f89d62,0x369c8ff, + 0x1a21dc6,0x2b8b8f3,0x0055cbc } }, + /* 229 */ + { { 0x34e84f3,0x2f2539a,0x2c35336,0x0c53bdc,0x1728630,0x3ad5fe6, + 0x05fdeee,0x3386db6,0x272a42e,0x29fd38c,0x36f0320,0x21b2ed4, + 0x331e67f,0x28ae48c,0x00f09b6 }, + { 0x2778435,0x0fb3c55,0x32d221d,0x2660c8e,0x32977ba,0x1c12f03, + 0x1b57fb1,0x01229a8,0x38b389f,0x375ddf3,0x2c6b42c,0x3885d3e, + 0x2c55a9c,0x2ffc279,0x00404e2 } }, + /* 230 */ + { { 0x04c5ddb,0x2c4d788,0x150e9b9,0x110fbfd,0x29dbfe0,0x30ef83d, + 0x2ab4bfe,0x395bcd7,0x30d0a43,0x0e2d30f,0x0e73f9b,0x07199cc, + 0x0c9054c,0x22f4b1e,0x0092ed3 }, + { 0x386e27c,0x00fdaa8,0x0507c70,0x1beb3b6,0x0b9c4f4,0x277d519, + 0x024ec85,0x1cbaba8,0x1524295,0x112be58,0x21fc119,0x273578b, + 0x2358c27,0x280ca07,0x00aa376 } }, + /* 231 */ + { { 0x0dbc95c,0x16488cf,0x337a078,0x1abbcb8,0x0aae1aa,0x1caa151, + 0x00108d4,0x1edf701,0x3e68d03,0x1203214,0x0c7eee2,0x084c572, + 0x07752d2,0x215a3b9,0x00195d3 }, + { 0x2cd7fbe,0x06e80f6,0x052bd4b,0x07b4f83,0x24b5ac6,0x2aaded4, + 0x13c0526,0x0ffa9a3,0x08c660e,0x13c35c9,0x3145efb,0x36cfe24, + 0x0936daf,0x268e3d0,0x00a73fd } }, + /* 232 */ + { { 0x31b17ce,0x2e7bcee,0x3f31891,0x19f1849,0x1140236,0x015487f, + 0x32e58d3,0x202204a,0x049e350,0x1ce91f9,0x3f75150,0x27f212f, + 0x0d16ee4,0x1c894c4,0x004023f }, + { 0x33399fa,0x2397b6d,0x2a3ea60,0x36354ca,0x1f12632,0x117a105, + 0x22758e8,0x361844e,0x3851fc2,0x0ab92db,0x339d02f,0x1e7d6c4, + 0x19ebd38,0x0a9a036,0x00446d2 } }, + /* 233 */ + { { 0x3e164f1,0x008c092,0x19200f5,0x35a22e0,0x38d09d2,0x212b3bf, + 0x0056f19,0x3a03545,0x1f075e9,0x0e97137,0x1f496a9,0x32d1f9b, + 0x36bf738,0x35ace37,0x00899e1 }, + { 0x19eb2a6,0x21fa22d,0x338b69e,0x18e6d1f,0x1280d9d,0x1953a55, + 0x1411ea3,0x2960566,0x0fd969a,0x1f3e375,0x130742a,0x170aebd, + 0x33085ff,0x14d868d,0x00a4391 } }, + /* 234 */ + { { 0x0a4bdd2,0x39ca8ea,0x37026ac,0x346da3b,0x0c656cd,0x03136b6, + 0x233e7e9,0x0714352,0x08a9d95,0x192bb38,0x085d68e,0x20016b8, + 0x102b8ea,0x1f5dbdd,0x00fdd7a }, + { 0x0d6fa45,0x3ec29a6,0x2b8cce6,0x1c84413,0x0228f86,0x28275f7, + 0x3d8787d,0x0c19748,0x28b2ae9,0x1954850,0x2a56c36,0x3eae8f7, + 0x0aca595,0x00e42a2,0x00edbe5 } }, + /* 235 */ + { { 0x3b26c82,0x3682b6f,0x2f9cd64,0x0f254b0,0x0e5d70b,0x1f9dfda, + 0x28f365f,0x35a57d7,0x00208f2,0x19c8d38,0x112e7be,0x3e403bb, + 0x3734efa,0x24d12b3,0x0027dc6 }, + { 0x260a46a,0x13fd7b0,0x1c2880e,0x338b70c,0x27da5eb,0x29a7d54, + 0x1c5d73c,0x2130921,0x32969cc,0x2b37eda,0x2d6d4ec,0x0716bfb, + 0x0763703,0x1320889,0x00c7bbf } }, + /* 236 */ + { { 0x1fe01b2,0x2dcb1d2,0x11b89d5,0x219e4ea,0x0347851,0x3d1810e, + 0x3a3c54c,0x06dbe8e,0x03d3ab2,0x2dcfa39,0x3e57b8a,0x337a382, + 0x0426450,0x0e9f748,0x006488b }, + { 0x1dc4582,0x0e62cf7,0x06fea9e,0x2a56fb1,0x31698c1,0x15b4e10, + 0x1446ef1,0x0a689fc,0x1d87703,0x20ff497,0x2c71066,0x2c48868, + 0x2e6cf05,0x30aa9cb,0x0065b2d } }, + /* 237 */ + { { 0x1021d63,0x2217df3,0x1f0821a,0x057fa98,0x23f344b,0x173dcf9, + 0x1ba6ddc,0x22c8eb5,0x18f227a,0x0455343,0x1c55931,0x1d0dcf3, + 0x20fa19b,0x1c56618,0x004feab }, + { 0x19ec924,0x224e39f,0x2550509,0x179b51f,0x284d54a,0x2d85d41, + 0x2d1bdc1,0x1a29068,0x3826158,0x1267f85,0x3005a92,0x0769e00, + 0x379b617,0x17b5f63,0x00a70bf } }, + /* 238 */ + { { 0x22216c5,0x049437f,0x33510bc,0x141d806,0x22c37e2,0x1bc1adf, + 0x300175d,0x2e6ded8,0x0a18bfe,0x35377a3,0x382f843,0x08410ca, + 0x00afd4f,0x0be6c6b,0x008d70e }, + { 0x2e91abb,0x1cede2a,0x28f225c,0x28e18c0,0x30230dc,0x173cc2d, + 0x123ecfe,0x3c9962e,0x2c25506,0x27b5d53,0x329a5e3,0x106e231, + 0x3889b8e,0x3b0aeaf,0x00ee67c } }, + /* 239 */ + { { 0x3e46c65,0x0eb3d46,0x1d7ae18,0x23f9d59,0x2978953,0x2589ed3, + 0x073391d,0x2461e1e,0x0c19f1d,0x22fd2b1,0x0691f5c,0x2e67d8d, + 0x1fb985d,0x200dd28,0x00a68df }, + { 0x392b5fa,0x123b46f,0x1c323c4,0x104f82f,0x0a098c8,0x26fc05b, + 0x34cd557,0x0913639,0x09c115e,0x3977c34,0x3410b66,0x062b404, + 0x0213094,0x132c5e8,0x008b612 } }, + /* 240 */ + { { 0x26e3392,0x3b0ebf0,0x2e00425,0x1c285c8,0x3c07f84,0x08d5ad0, + 0x028190e,0x1669b73,0x1ffb1ef,0x053b65f,0x063028c,0x0aceb47, + 0x18988c2,0x0f09a30,0x0007072 }, + { 0x0f49e7d,0x28c0bd3,0x252270d,0x24cfc4a,0x0c5e87c,0x2165052, + 0x2cdd1d1,0x04931d2,0x3abca74,0x22b57dc,0x169fd47,0x0b928fb, + 0x17cc3e7,0x21a1ec4,0x0061593 } }, + /* 241 */ + { { 0x1aa0486,0x2e55dea,0x15577b7,0x0d6818f,0x36e41fb,0x2a411f5, + 0x17d5c7d,0x1eea6c0,0x28068a8,0x0e31d20,0x1f08ad9,0x117e973, + 0x08a28ab,0x085d30a,0x00cd9fb }, + { 0x347843d,0x1119095,0x11e3595,0x1b29584,0x134d64c,0x2ff3a35, + 0x247ea14,0x099fc4b,0x2056169,0x145dd03,0x2ed03fb,0x1250e3b, + 0x3f5135c,0x2b753f0,0x009da30 } }, + /* 242 */ + { { 0x0fa5200,0x214a0b3,0x313dc4e,0x23da866,0x3270760,0x15c9b8b, + 0x39a53df,0x1f79772,0x3c9e942,0x2984901,0x154d582,0x1685f87, + 0x2e1183e,0x1f79956,0x00b9987 }, + { 0x15254de,0x3a5cac0,0x37c56f0,0x2c7c29b,0x292a56d,0x195be2c, + 0x17e4e1a,0x0660f4a,0x052ad98,0x1267f80,0x07cfed8,0x194b4bc, + 0x01738d3,0x14ba10f,0x00c7843 } }, + /* 243 */ + { { 0x29b2d8a,0x242bc1f,0x19646ee,0x0615f3c,0x0ac8d70,0x07ca3bf, + 0x2d90317,0x2c83bdb,0x1a96812,0x39fdc35,0x31c61ee,0x2d55fd3, + 0x2375827,0x355f189,0x00f1c9b }, + { 0x21a6194,0x1f4050a,0x2b845cf,0x02c6242,0x2dd614e,0x3a4f0a9, + 0x39de100,0x24714fb,0x175e0cd,0x0be633d,0x14befc3,0x13b0318, + 0x1d68c50,0x299989e,0x00d0513 } }, + /* 244 */ + { { 0x059fb6a,0x2b6eb6a,0x3666a8e,0x39f6ca0,0x1cf8346,0x388b8d5, + 0x35e61a3,0x271adec,0x22c9963,0x20a4fb3,0x16f241c,0x0058b89, + 0x21ddafa,0x1ee6fde,0x00d2e6c }, + { 0x0075e63,0x39894d0,0x0286d0d,0x187e7b2,0x02405aa,0x3f91525, + 0x37830a8,0x2723088,0x2c7364e,0x013f406,0x104ba75,0x270f486, + 0x3520b4d,0x3852bc6,0x00d589b } }, + /* 245 */ + { { 0x262e53b,0x1da93d1,0x3676135,0x147e41d,0x335ec2f,0x1f02be5, + 0x297d139,0x22d6198,0x1fe9e59,0x13b4c80,0x1e70f60,0x2f1d4a9, + 0x2d95149,0x14d6ec4,0x00b54af }, + { 0x12c1c76,0x2930ac8,0x0dfd36e,0x31fac94,0x218f5bb,0x2828691, + 0x1466cc9,0x3645e83,0x1a4dac2,0x1549593,0x0e95fab,0x19567d2, + 0x27a3320,0x0642729,0x007487c } }, + /* 246 */ + { { 0x1e98e9c,0x2ff8df7,0x119975a,0x098a904,0x099b90b,0x336c7df, + 0x010996d,0x159d46d,0x3118b3b,0x3aacd1b,0x31f8ae1,0x214864f, + 0x398c104,0x089dae2,0x001ec4d }, + { 0x1452baa,0x2f24991,0x2572ba3,0x162b312,0x2387d18,0x147c5c7, + 0x38eff6e,0x0700251,0x37d931e,0x23cd5c1,0x254c8ca,0x3b9df37, + 0x1c9a4ff,0x0bfd547,0x00fb489 } }, + /* 247 */ + { { 0x1b8dff8,0x2f6b40b,0x05a25b1,0x3f5688a,0x1d462f4,0x2802d18, + 0x2aad8ed,0x1b46c75,0x3cf4130,0x250fefb,0x2a13fe1,0x23a1bcd, + 0x0940442,0x04605fe,0x00c8b2f }, + { 0x0d51afb,0x14a2abc,0x1d06762,0x291526c,0x2a3e2fe,0x28f77d9, + 0x3ad8f2e,0x3481a1b,0x04b4fbd,0x2836733,0x0189ff5,0x3a5f533, + 0x319a6cd,0x0f58667,0x00c3679 } }, + /* 248 */ + { { 0x1b85197,0x22426d4,0x2895ea3,0x342d324,0x3ffb17d,0x376cfcf, + 0x30878b1,0x3c3c83a,0x0ffc57c,0x0ac174a,0x1abd57e,0x2f78b9c, + 0x01b20d8,0x0a37103,0x007f2be }, + { 0x19a2d48,0x137288a,0x182d655,0x0ba0dde,0x25130ba,0x01c65c6, + 0x23205f1,0x2097621,0x2827cf2,0x2c57b98,0x03748f2,0x2db15fc, + 0x385a0d4,0x13690c0,0x00a9e3f } }, + /* 249 */ + { { 0x3fbc9c6,0x2df3b20,0x377e33e,0x31d1505,0x024a311,0x3c1d9ff, + 0x1377f74,0x00b6b20,0x2364ab7,0x184ab6b,0x2a77969,0x3f2db6c, + 0x2a6adb7,0x0a10073,0x004a6fb }, + { 0x1fc73de,0x2c74ab3,0x3d325e8,0x2346c0b,0x1d0efae,0x2076146, + 0x19c190d,0x225c4fe,0x3fafc80,0x2cf063d,0x11b7ae7,0x3dc4f9d, + 0x3c3f841,0x10d7c1f,0x000a4b3 } }, + /* 250 */ + { { 0x19b7d2e,0x28f1300,0x0b897dd,0x06b5371,0x0631c8d,0x336cc4f, + 0x09cd6e1,0x2ec1952,0x1104c07,0x07512bb,0x35f000d,0x25f84e9, + 0x1df4d8f,0x193f769,0x000e9ee }, + { 0x2346910,0x267cecf,0x0ad7eaa,0x087e8a5,0x1622f69,0x342cbfa, + 0x2aa20d0,0x206e88a,0x3991e58,0x093fb4b,0x0157180,0x3cecb5b, + 0x2e17c9a,0x1ea371f,0x00919e6 } }, + /* 251 */ + { { 0x2250533,0x13f931d,0x3ef8c72,0x395f605,0x18a2080,0x1cb25d4, + 0x2fb0f41,0x1c0ba8a,0x1eb17c0,0x266c433,0x09b7e3e,0x0e5d78f, + 0x0cdc5bf,0x1f7c734,0x0020611 }, + { 0x205ebd5,0x127986f,0x02c0fb0,0x1705b1e,0x1eb0bb5,0x2dffb42, + 0x2331b8a,0x18fc04e,0x31d6328,0x17db162,0x0d3b619,0x193bdb9, + 0x3f11662,0x2d8e694,0x0092c51 } }, + /* 252 */ + { { 0x08b364d,0x31ef20a,0x25c4a57,0x021ed07,0x14a562e,0x262a684, + 0x1d21c66,0x126e5a6,0x181f3f8,0x2a93b65,0x1eb726b,0x08fbbce, + 0x084f9a2,0x308f30a,0x0013159 }, + { 0x23f4963,0x0c7960e,0x2a81739,0x2242b69,0x3965003,0x2aca542, + 0x28a1c65,0x2ad48fb,0x149775f,0x1bbb7d2,0x0f2671b,0x3594b85, + 0x22f5563,0x2470f13,0x00fed44 } }, + /* 253 */ + { { 0x0eb453e,0x3ab70fd,0x1a5b335,0x18f2b74,0x25ff74b,0x3612a46, + 0x33d0d75,0x28cdda4,0x2b9b49b,0x22728fb,0x004c15b,0x1beb33b, + 0x1a7e41f,0x0c9b702,0x004ef19 }, + { 0x1ca3233,0x0b4c90f,0x1d4b53d,0x2428896,0x20ee405,0x151bc00, + 0x022edb5,0x1adc463,0x00109ea,0x06490a6,0x30e91e6,0x3682b76, + 0x23c50aa,0x3bd2665,0x005fe53 } }, + /* 254 */ + { { 0x0c28c65,0x3741ae4,0x247d372,0x0b04673,0x2176524,0x2c8bf20, + 0x01fb806,0x3330701,0x307b0a7,0x3999fb7,0x1261bec,0x256679c, + 0x3f22ac7,0x26e8673,0x00bc69d }, + { 0x3c06819,0x35df344,0x379d009,0x2bb8a0a,0x0635a66,0x096c6fa, + 0x1ac4a62,0x023e53b,0x0e45240,0x115f53d,0x3056af8,0x0a66b16, + 0x3c386ee,0x1130e82,0x00cc384 } }, + /* 255 */ + { { 0x14c2356,0x190ec73,0x07be490,0x145d415,0x0740a48,0x1251301, + 0x3eaf29d,0x2628190,0x079299a,0x26e95c9,0x2e05fdf,0x2ca7c5b, + 0x32d7b48,0x3d84226,0x0033fb4 }, + { 0x150f955,0x01240aa,0x3ddf867,0x137fb70,0x297e103,0x17eeda8, + 0x1320b60,0x266ec84,0x13f4322,0x0c8f5ee,0x0590e4a,0x386815e, + 0x00ce61f,0x161bd63,0x008e1d0 } }, +}; + +/* 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. + * 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_15(sp_point_384* r, const sp_digit* k, + int map, void* heap) +{ + return sp_384_ecc_mulmod_stripe_15(r, &p384_base, p384_table, + k, map, heap); +} + +#endif + +/* Multiply the base point of P384 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_384(mp_int* km, ecc_point* r, int map, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 p; + sp_digit kd[15]; +#endif + sp_point_384* point; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_384_point_new_15(heap, p, point); +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 15, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + } +#else + k = kd; +#endif + if (err == MP_OKAY) { + sp_384_from_mp(k, 15, km); + + err = sp_384_ecc_mulmod_base_15(point, k, map, heap); + } + if (err == MP_OKAY) { + err = sp_384_point_to_ecc_point_15(point, r); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + 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. + * Implementation is constant time. + * + * a Number to check. + * returns 1 if the number is zero and 0 otherwise. + */ +static int sp_384_iszero_15(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]) == 0; +} + +#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN || HAVE_ECC_SIGN || HAVE_ECC_VERIFY */ +/* Add 1 to a. (a = a + 1) + * + * r A single precision integer. + * a A single precision integer. + */ +SP_NOINLINE static void sp_384_add_one_15(sp_digit* a) +{ + a[0]++; + sp_384_norm_15(a); +} + +/* 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_384_from_bin(sp_digit* r, int size, const byte* a, int n) +{ + int i, j = 0; + word32 s = 0; + + r[0] = 0; + for (i = n-1; i >= 0; i--) { + r[j] |= (((sp_digit)a[i]) << s); + if (s >= 18U) { + r[j] &= 0x3ffffff; + s = 26U - 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; + } +} + +/* Generates a scalar that is in the range 1..order-1. + * + * rng Random number generator. + * k Scalar value. + * returns RNG failures, MEMORY_E when memory allocation fails and + * MP_OKAY on success. + */ +static int sp_384_ecc_gen_k_15(WC_RNG* rng, sp_digit* k) +{ + int err; + byte buf[48]; + + do { + err = wc_RNG_GenerateBlock(rng, buf, sizeof(buf)); + if (err == 0) { + sp_384_from_bin(k, 15, buf, (int)sizeof(buf)); + if (sp_384_cmp_15(k, p384_order2) < 0) { + sp_384_add_one_15(k); + break; + } + } + } + while (err == 0); + + return err; +} + +/* Makes a random EC key pair. + * + * rng Random number generator. + * priv Generated private value. + * pub Generated public point. + * heap Heap to use for allocation. + * returns ECC_INF_E when the point does not have the correct order, RNG + * failures, MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_make_key_384(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 p; + sp_digit kd[15]; +#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN + sp_point_384 inf; +#endif +#endif + sp_point_384* point; + sp_digit* k = NULL; +#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN + sp_point_384* infinity; +#endif + int err; + + (void)heap; + + err = sp_384_point_new_15(heap, p, point); +#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN + if (err == MP_OKAY) { + err = sp_384_point_new_15(heap, inf, infinity); + } +#endif +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 15, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + } +#else + k = kd; +#endif + + if (err == MP_OKAY) { + err = sp_384_ecc_gen_k_15(rng, k); + } + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_base_15(point, k, 1, NULL); + } + +#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_15(infinity, point, p384_order, 1, NULL); + } + if (err == MP_OKAY) { + if ((sp_384_iszero_15(point->x) == 0) || (sp_384_iszero_15(point->y) == 0)) { + err = ECC_INF_E; + } + } +#endif + + if (err == MP_OKAY) { + err = sp_384_to_mp(k, priv); + } + if (err == MP_OKAY) { + err = sp_384_point_to_ecc_point_15(point, pub); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif +#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN + sp_384_point_free_15(infinity, 1, heap); +#endif + sp_384_point_free_15(point, 1, heap); + + return err; +} + +#ifdef HAVE_ECC_DHE +/* Write r as big endian to byte array. + * Fixed length number of bytes written: 48 + * + * r A single precision integer. + * a Byte array. + */ +static void sp_384_to_bin(sp_digit* r, byte* a) +{ + int i, j, s = 0, b; + + for (i=0; i<14; i++) { + r[i+1] += r[i] >> 26; + r[i] &= 0x3ffffff; + } + j = 384 / 8 - 1; + a[j] = 0; + for (i=0; i<15 && j>=0; i++) { + b = 0; + /* lint allow cast of mismatch sp_digit and int */ + a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ + if (j < 0) { + break; + } + while (b < 26) { + a[j--] = r[i] >> b; b += 8; + if (j < 0) { + break; + } + } + s = 8 - (b - 26); + if (j >= 0) { + a[j] = 0; + } + if (s != 0) { + j++; + } + } +} + +/* Multiply the point by the scalar and serialize the X ordinate. + * The number is 0 padded to maximum size on output. + * + * priv Scalar to multiply the point by. + * pub Point to multiply. + * out Buffer to hold X ordinate. + * outLen On entry, size of the buffer in bytes. + * On exit, length of data in buffer in bytes. + * heap Heap to use for allocation. + * 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, + word32* outLen, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 p; + sp_digit kd[15]; +#endif + sp_point_384* point = NULL; + sp_digit* k = NULL; + int err = MP_OKAY; + + if (*outLen < 48U) { + err = BUFFER_E; + } + + if (err == MP_OKAY) { + err = sp_384_point_new_15(heap, p, point); + } +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 15, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) + err = MEMORY_E; + } +#else + k = kd; +#endif + + if (err == MP_OKAY) { + sp_384_from_mp(k, 15, priv); + sp_384_point_from_ecc_point_15(point, pub); + err = sp_384_ecc_mulmod_15(point, point, k, 1, heap); + } + if (err == MP_OKAY) { + sp_384_to_bin(point->x, out); + *outLen = 48; + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_15(point, 0, heap); + + return err; +} +#endif /* HAVE_ECC_DHE */ + +#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) +#endif +#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) +/* 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_384_mul_d_15(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 < 15; i++) { + t += tb * a[i]; + r[i] = t & 0x3ffffff; + t >>= 26; + } + r[15] = (sp_digit)t; +#else + int64_t tb = b; + int64_t t[15]; + + t[ 0] = tb * a[ 0]; + t[ 1] = tb * a[ 1]; + t[ 2] = tb * a[ 2]; + t[ 3] = tb * a[ 3]; + t[ 4] = tb * a[ 4]; + t[ 5] = tb * a[ 5]; + t[ 6] = tb * a[ 6]; + t[ 7] = tb * a[ 7]; + t[ 8] = tb * a[ 8]; + t[ 9] = tb * a[ 9]; + t[10] = tb * a[10]; + t[11] = tb * a[11]; + t[12] = tb * a[12]; + t[13] = tb * a[13]; + t[14] = tb * a[14]; + r[ 0] = (t[ 0] & 0x3ffffff); + r[ 1] = (sp_digit)(t[ 0] >> 26) + (t[ 1] & 0x3ffffff); + r[ 2] = (sp_digit)(t[ 1] >> 26) + (t[ 2] & 0x3ffffff); + r[ 3] = (sp_digit)(t[ 2] >> 26) + (t[ 3] & 0x3ffffff); + r[ 4] = (sp_digit)(t[ 3] >> 26) + (t[ 4] & 0x3ffffff); + r[ 5] = (sp_digit)(t[ 4] >> 26) + (t[ 5] & 0x3ffffff); + r[ 6] = (sp_digit)(t[ 5] >> 26) + (t[ 6] & 0x3ffffff); + r[ 7] = (sp_digit)(t[ 6] >> 26) + (t[ 7] & 0x3ffffff); + r[ 8] = (sp_digit)(t[ 7] >> 26) + (t[ 8] & 0x3ffffff); + r[ 9] = (sp_digit)(t[ 8] >> 26) + (t[ 9] & 0x3ffffff); + r[10] = (sp_digit)(t[ 9] >> 26) + (t[10] & 0x3ffffff); + r[11] = (sp_digit)(t[10] >> 26) + (t[11] & 0x3ffffff); + r[12] = (sp_digit)(t[11] >> 26) + (t[12] & 0x3ffffff); + r[13] = (sp_digit)(t[12] >> 26) + (t[13] & 0x3ffffff); + r[14] = (sp_digit)(t[13] >> 26) + (t[14] & 0x3ffffff); + r[15] = (sp_digit)(t[14] >> 26); +#endif /* WOLFSSL_SP_SMALL */ +} + +#ifdef WOLFSSL_SP_DIV_32 +static WC_INLINE sp_digit sp_384_div_word_15(sp_digit d1, sp_digit d0, + sp_digit dv) +{ + sp_digit d, r, t; + + /* All 26 bits from d1 and top 5 bits from d0. */ + d = (d1 << 5) | (d0 >> 21); + r = d / dv; + d -= r * dv; + /* Up to 6 bits in r */ + /* Next 5 bits from d0. */ + r <<= 5; + d <<= 5; + d |= (d0 >> 16) & ((1 << 5) - 1); + t = d / dv; + d -= t * dv; + r += t; + /* Up to 11 bits in r */ + /* Next 5 bits from d0. */ + r <<= 5; + d <<= 5; + d |= (d0 >> 11) & ((1 << 5) - 1); + t = d / dv; + d -= t * dv; + r += t; + /* Up to 16 bits in r */ + /* Next 5 bits from d0. */ + r <<= 5; + d <<= 5; + d |= (d0 >> 6) & ((1 << 5) - 1); + t = d / dv; + d -= t * dv; + r += t; + /* Up to 21 bits in r */ + /* Next 5 bits from d0. */ + r <<= 5; + d <<= 5; + d |= (d0 >> 1) & ((1 << 5) - 1); + t = d / dv; + d -= t * dv; + r += t; + /* Up to 26 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. + * + * 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) +{ + int i; +#ifndef WOLFSSL_SP_DIV_32 + int64_t d1; +#endif + sp_digit dv, r1; +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_digit* td; +#else + sp_digit t1d[30], t2d[15 + 1]; +#endif + sp_digit* t1; + sp_digit* t2; + int err = MP_OKAY; + + (void)m; + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * (3 * 15 + 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) + t1 = td; + t2 = td + 2 * 15; +#else + t1 = t1d; + t2 = t2d; +#endif + + dv = d[14]; + XMEMCPY(t1, a, sizeof(*t1) * 2U * 15U); + for (i=14; i>=0; i--) { + t1[15 + i] += t1[15 + i - 1] >> 26; + t1[15 + i - 1] &= 0x3ffffff; +#ifndef WOLFSSL_SP_DIV_32 + d1 = t1[15 + i]; + d1 <<= 26; + d1 += t1[15 + i - 1]; + r1 = (sp_digit)(d1 / dv); +#else + r1 = sp_384_div_word_15(t1[15 + i], t1[15 + i - 1], dv); +#endif + + sp_384_mul_d_15(t2, d, r1); + (void)sp_384_sub_15(&t1[i], &t1[i], t2); + t1[15 + i] -= t2[15]; + t1[15 + i] += t1[15 + i - 1] >> 26; + t1[15 + i - 1] &= 0x3ffffff; + r1 = (((-t1[15 + i]) << 26) - t1[15 + i - 1]) / dv; + r1++; + sp_384_mul_d_15(t2, d, r1); + (void)sp_384_add_15(&t1[i], &t1[i], t2); + t1[15 + i] += t1[15 + i - 1] >> 26; + t1[15 + i - 1] &= 0x3ffffff; + } + t1[15 - 1] += t1[15 - 2] >> 26; + t1[15 - 2] &= 0x3ffffff; + r1 = t1[15 - 1] / dv; + + sp_384_mul_d_15(t2, d, r1); + (void)sp_384_sub_15(t1, t1, t2); + XMEMCPY(r, t1, sizeof(*r) * 2U * 15U); + for (i=0; i<13; i++) { + r[i+1] += r[i] >> 26; + r[i] &= 0x3ffffff; + } + sp_384_cond_add_15(r, r, d, 0 - ((r[14] < 0) ? + (sp_digit)1 : (sp_digit)0)); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + 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_384_mod_15(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + return sp_384_div_15(a, m, NULL, r); +} + +#endif +#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) +#ifdef WOLFSSL_SP_SMALL +/* Order-2 for the P384 curve. */ +static const uint32_t p384_order_minus_2[12] = { + 0xccc52971U,0xecec196aU,0x48b0a77aU,0x581a0db2U,0xf4372ddfU,0xc7634d81U, + 0xffffffffU,0xffffffffU,0xffffffffU,0xffffffffU,0xffffffffU,0xffffffffU +}; +#else +/* 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 */ + +/* Multiply two number mod the order of P384 curve. (r = a * b mod order) + * + * r Result of the multiplication. + * a First operand of the multiplication. + * b Second operand of the multiplication. + */ +static void sp_384_mont_mul_order_15(sp_digit* r, const sp_digit* a, const sp_digit* b) +{ + sp_384_mul_15(r, a, b); + sp_384_mont_reduce_order_15(r, p384_order, p384_mp_order); +} + +/* Square number mod the order of P384 curve. (r = a * a mod order) + * + * r Result of the squaring. + * a Number to square. + */ +static void sp_384_mont_sqr_order_15(sp_digit* r, const sp_digit* a) +{ + sp_384_sqr_15(r, a); + sp_384_mont_reduce_order_15(r, p384_order, p384_mp_order); +} + +#ifndef WOLFSSL_SP_SMALL +/* Square number mod the order of P384 curve a number of times. + * (r = a ^ n mod order) + * + * r Result of the squaring. + * a Number to square. + */ +static void sp_384_mont_sqr_n_order_15(sp_digit* r, const sp_digit* a, int n) +{ + int i; + + sp_384_mont_sqr_order_15(r, a); + for (i=1; i=0; i--) { + sp_384_mont_sqr_order_15(t, t); + if ((p384_order_minus_2[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { + sp_384_mont_mul_order_15(t, t, a); + } + } + XMEMCPY(r, t, sizeof(sp_digit) * 15U); +#else + sp_digit* t = td; + sp_digit* t2 = td + 2 * 15; + sp_digit* t3 = td + 4 * 15; + int i; + + /* t = a^2 */ + sp_384_mont_sqr_order_15(t, a); + /* t = a^3 = t * a */ + sp_384_mont_mul_order_15(t, t, a); + /* t2= a^c = t ^ 2 ^ 2 */ + sp_384_mont_sqr_n_order_15(t2, t, 2); + /* t = a^f = t2 * t */ + sp_384_mont_mul_order_15(t, t2, t); + /* t2= a^f0 = t ^ 2 ^ 4 */ + sp_384_mont_sqr_n_order_15(t2, t, 4); + /* t = a^ff = t2 * t */ + sp_384_mont_mul_order_15(t, t2, t); + /* t2= a^ff00 = t ^ 2 ^ 8 */ + sp_384_mont_sqr_n_order_15(t2, t, 8); + /* t3= a^ffff = t2 * t */ + sp_384_mont_mul_order_15(t3, t2, t); + /* t2= a^ffff0000 = t3 ^ 2 ^ 16 */ + sp_384_mont_sqr_n_order_15(t2, t3, 16); + /* t = a^ffffffff = t2 * t3 */ + sp_384_mont_mul_order_15(t, t2, t3); + /* t2= a^ffffffff0000 = t ^ 2 ^ 16 */ + sp_384_mont_sqr_n_order_15(t2, t, 16); + /* t = a^ffffffffffff = t2 * t3 */ + sp_384_mont_mul_order_15(t, t2, t3); + /* t2= a^ffffffffffff000000000000 = t ^ 2 ^ 48 */ + sp_384_mont_sqr_n_order_15(t2, t, 48); + /* t= a^fffffffffffffffffffffffff = t2 * t */ + sp_384_mont_mul_order_15(t, t2, t); + /* t2= a^ffffffffffffffffffffffff000000000000000000000000 */ + sp_384_mont_sqr_n_order_15(t2, t, 96); + /* t2= a^ffffffffffffffffffffffffffffffffffffffffffffffff = t2 * t */ + 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) { + sp_384_mont_mul_order_15(t2, t2, a); + } + } + sp_384_mont_sqr_order_15(t2, t2); + sp_384_mont_mul_order_15(r, t2, a); +#endif /* WOLFSSL_SP_SMALL */ +} + +#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 + +/* Sign the hash using the private key. + * e = [hash, 384 bits] from binary + * r = (k.G)->x mod order + * s = (r * x + e) / k mod order + * The hash is truncated to the first 384 bits. + * + * hash Hash to sign. + * hashLen Length of the hash data. + * rng Random number generator. + * priv Private part of key - scalar. + * 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. + */ +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) +{ +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_digit* d = NULL; +#else + sp_digit ed[2*15]; + sp_digit xd[2*15]; + sp_digit kd[2*15]; + sp_digit rd[2*15]; + sp_digit td[3 * 2*15]; + sp_point_384 p; +#endif + sp_digit* e = NULL; + sp_digit* x = NULL; + sp_digit* k = NULL; + 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 i; + + (void)heap; + + err = sp_384_point_new_15(heap, p, point); +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7 * 2 * 15, heap, + DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + e = d + 0 * 15; + x = d + 2 * 15; + k = d + 4 * 15; + r = d + 6 * 15; + tmp = d + 8 * 15; +#else + e = ed; + x = xd; + k = kd; + r = rd; + tmp = td; +#endif + s = e; + kInv = k; + + if (hashLen > 48U) { + hashLen = 48U; + } + + sp_384_from_bin(e, 15, hash, (int)hashLen); + } + + 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); + } + else { + sp_384_from_mp(k, 15, km); + mp_zero(km); + } + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_base_15(point, k, 1, NULL); + } + + if (err == MP_OKAY) { + /* r = point->x mod order */ + XMEMCPY(r, point->x, sizeof(sp_digit) * 15U); + sp_384_norm_15(r); + c = sp_384_cmp_15(r, p384_order); + 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); + 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); + + /* Check that signature is usable. */ + if (sp_384_iszero_15(s) == 0) { + break; + } + } + } + + if (i == 0) { + err = RNG_FAILURE_E; + } + + if (err == MP_OKAY) { + err = sp_384_to_mp(r, rm); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(s, sm); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (d != NULL) { + XMEMSET(d, 0, sizeof(sp_digit) * 8 * 15); + XFREE(d, heap, DYNAMIC_TYPE_ECC); + } +#else + XMEMSET(e, 0, sizeof(sp_digit) * 2U * 15U); + 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); + + return err; +} +#endif /* HAVE_ECC_SIGN */ + +#ifdef HAVE_ECC_VERIFY +/* Verify the signature values with the hash and public key. + * e = Truncate(hash, 384) + * u1 = e/s mod order + * u2 = r/s mod order + * r == (u1.G + u2.Q)->x mod order + * Optimization: Leave point in projective form. + * (x, y, 1) == (x' / z'*z', y' / z'*z'*z', z' / z') + * (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' + * The hash is truncated to the first 384 bits. + * + * hash Hash to sign. + * hashLen Length of the hash data. + * rng Random number generator. + * priv Private part of key - scalar. + * 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. + */ +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) +{ +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_digit* d = NULL; +#else + sp_digit u1d[2*15]; + sp_digit u2d[2*15]; + sp_digit sd[2*15]; + sp_digit tmpd[2*15 * 5]; + sp_point_384 p1d; + sp_point_384 p2d; +#endif + sp_digit* u1 = NULL; + sp_digit* u2 = NULL; + sp_digit* s = NULL; + sp_digit* tmp = NULL; + sp_point_384* p1; + sp_point_384* p2 = NULL; + sp_digit carry; + int32_t c; + int err; + + err = sp_384_point_new_15(heap, p1d, p1); + if (err == MP_OKAY) { + err = sp_384_point_new_15(heap, p2d, p2); + } +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 15, heap, + DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + u1 = d + 0 * 15; + u2 = d + 2 * 15; + s = d + 4 * 15; + tmp = d + 6 * 15; +#else + u1 = u1d; + u2 = u2d; + s = sd; + tmp = tmpd; +#endif + + if (hashLen > 48U) { + hashLen = 48U; + } + + sp_384_from_bin(u1, 15, hash, (int)hashLen); + sp_384_from_mp(u2, 15, r); + sp_384_from_mp(s, 15, sm); + sp_384_from_mp(p2->x, 15, pX); + sp_384_from_mp(p2->y, 15, pY); + sp_384_from_mp(p2->z, 15, pZ); + + { + 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); + { + 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); + } + + err = sp_384_ecc_mulmod_base_15(p1, u1, 0, heap); + } + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_15(p2, p2, u2, 0, heap); + } + + 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); + err = sp_384_mod_mul_norm_15(u2, u2, p384_mod); + } + + if (err == MP_OKAY) { + /* u1 = r.z'.z' mod prime */ + sp_384_mont_sqr_15(p1->z, p1->z, p384_mod, p384_mp_mod); + 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) { + /* Reload r and add order. */ + sp_384_from_mp(u2, 15, r); + carry = sp_384_add_15(u2, u2, p384_order); + /* Carry means result is greater than mod and is not valid. */ + if (carry == 0) { + sp_384_norm_15(u2); + + /* 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 defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (d != NULL) + XFREE(d, heap, DYNAMIC_TYPE_ECC); +#endif + sp_384_point_free_15(p1, 0, heap); + sp_384_point_free_15(p2, 0, heap); + + return err; +} +#endif /* HAVE_ECC_VERIFY */ + +#ifdef HAVE_ECC_CHECK_KEY +/* 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_384_ecc_is_point_15(sp_point_384* point, void* heap) +{ +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_digit* d = NULL; +#else + sp_digit t1d[2*15]; + sp_digit t2d[2*15]; +#endif + sp_digit* t1; + sp_digit* t2; + int err = MP_OKAY; + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 15 * 4, heap, DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + t1 = d + 0 * 15; + t2 = d + 2 * 15; +#else + (void)heap; + + t1 = t1d; + t2 = t2d; +#endif + + sp_384_sqr_15(t1, point->y); + (void)sp_384_mod_15(t1, t1, p384_mod); + sp_384_sqr_15(t2, point->x); + (void)sp_384_mod_15(t2, t2, p384_mod); + sp_384_mul_15(t2, t2, point->x); + (void)sp_384_mod_15(t2, t2, p384_mod); + (void)sp_384_sub_15(t2, p384_mod, t2); + sp_384_mont_add_15(t1, t1, t2, p384_mod); + + sp_384_mont_add_15(t1, t1, point->x, p384_mod); + sp_384_mont_add_15(t1, t1, point->x, p384_mod); + sp_384_mont_add_15(t1, t1, point->x, p384_mod); + + if (sp_384_cmp_15(t1, p384_b) != 0) { + err = MP_VAL; + } + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + 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_384(mp_int* pX, mp_int* pY) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 pubd; +#endif + sp_point_384* pub; + byte one[1] = { 1 }; + int err; + + err = sp_384_point_new_15(NULL, pubd, pub); + if (err == MP_OKAY) { + sp_384_from_mp(pub->x, 15, pX); + sp_384_from_mp(pub->y, 15, pY); + sp_384_from_bin(pub->z, 15, one, (int)sizeof(one)); + + err = sp_384_ecc_is_point_15(pub, NULL); + } + + sp_384_point_free_15(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_384(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_digit privd[15]; + sp_point_384 pubd; + sp_point_384 pd; +#endif + sp_digit* priv = NULL; + sp_point_384* pub; + sp_point_384* p = NULL; + byte one[1] = { 1 }; + int err; + + err = sp_384_point_new_15(heap, pubd, pub); + if (err == MP_OKAY) { + err = sp_384_point_new_15(heap, pd, p); + } +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + priv = (sp_digit*)XMALLOC(sizeof(sp_digit) * 15, heap, + DYNAMIC_TYPE_ECC); + if (priv == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if !(defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) + priv = privd; +#endif + + sp_384_from_mp(pub->x, 15, pX); + sp_384_from_mp(pub->y, 15, pY); + sp_384_from_bin(pub->z, 15, one, (int)sizeof(one)); + sp_384_from_mp(priv, 15, privm); + + /* Check point at infinitiy. */ + if ((sp_384_iszero_15(pub->x) != 0) && + (sp_384_iszero_15(pub->y) != 0)) { + err = ECC_INF_E; + } + } + + 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; + } + } + + if (err == MP_OKAY) { + /* Check point is on curve */ + err = sp_384_ecc_is_point_15(pub, heap); + } + + if (err == MP_OKAY) { + /* Point * order = infinity */ + err = sp_384_ecc_mulmod_15(p, pub, p384_order, 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; + } + } + + if (err == MP_OKAY) { + /* Base * private = point */ + err = sp_384_ecc_mulmod_base_15(p, priv, 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; + } + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (priv != NULL) { + XFREE(priv, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_15(p, 0, heap); + sp_384_point_free_15(pub, 0, heap); + + return err; +} +#endif +#ifdef WOLFSSL_PUBLIC_ECC_ADD_DBL +/* Add two projective EC points together. + * (pX, pY, pZ) + (qX, qY, qZ) = (rX, rY, rZ) + * + * pX First EC point's X ordinate. + * pY First EC point's Y ordinate. + * pZ First EC point's Z ordinate. + * qX Second EC point's X ordinate. + * qY Second EC point's Y ordinate. + * qZ Second EC point's Z ordinate. + * rX Resultant EC point's X ordinate. + * rY Resultant EC point's Y ordinate. + * rZ Resultant EC point's Z ordinate. + * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise. + */ +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) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_digit tmpd[2 * 15 * 5]; + sp_point_384 pd; + sp_point_384 qd; +#endif + sp_digit* tmp; + sp_point_384* p; + sp_point_384* q = NULL; + int err; + + err = sp_384_point_new_15(NULL, pd, p); + if (err == MP_OKAY) { + err = sp_384_point_new_15(NULL, qd, q); + } +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 15 * 5, NULL, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) { + err = MEMORY_E; + } + } +#else + tmp = tmpd; +#endif + + if (err == MP_OKAY) { + sp_384_from_mp(p->x, 15, pX); + sp_384_from_mp(p->y, 15, pY); + sp_384_from_mp(p->z, 15, pZ); + sp_384_from_mp(q->x, 15, qX); + sp_384_from_mp(q->y, 15, qY); + sp_384_from_mp(q->z, 15, qZ); + + sp_384_proj_point_add_15(p, p, q, tmp); + } + + if (err == MP_OKAY) { + err = sp_384_to_mp(p->x, rX); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->y, rY); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->z, rZ); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (tmp != NULL) { + XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_15(q, 0, NULL); + sp_384_point_free_15(p, 0, NULL); + + return err; +} + +/* Double a projective EC point. + * (pX, pY, pZ) + (pX, pY, pZ) = (rX, rY, rZ) + * + * pX EC point's X ordinate. + * pY EC point's Y ordinate. + * pZ EC point's Z ordinate. + * rX Resultant EC point's X ordinate. + * rY Resultant EC point's Y ordinate. + * rZ Resultant EC point's Z ordinate. + * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise. + */ +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) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_digit tmpd[2 * 15 * 2]; + sp_point_384 pd; +#endif + sp_digit* tmp; + sp_point_384* p; + int err; + + err = sp_384_point_new_15(NULL, pd, p); +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 15 * 2, NULL, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) { + err = MEMORY_E; + } + } +#else + tmp = tmpd; +#endif + + if (err == MP_OKAY) { + sp_384_from_mp(p->x, 15, pX); + sp_384_from_mp(p->y, 15, pY); + sp_384_from_mp(p->z, 15, pZ); + + sp_384_proj_point_dbl_15(p, p, tmp); + } + + if (err == MP_OKAY) { + err = sp_384_to_mp(p->x, rX); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->y, rY); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->z, rZ); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (tmp != NULL) { + XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_15(p, 0, NULL); + + return err; +} + +/* Map a projective EC point to affine in place. + * pZ will be one. + * + * pX EC point's X ordinate. + * pY EC point's Y ordinate. + * pZ EC point's Z ordinate. + * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise. + */ +int sp_ecc_map_384(mp_int* pX, mp_int* pY, mp_int* pZ) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_digit tmpd[2 * 15 * 6]; + sp_point_384 pd; +#endif + sp_digit* tmp; + sp_point_384* p; + int err; + + err = sp_384_point_new_15(NULL, pd, p); +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 15 * 6, NULL, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) { + err = MEMORY_E; + } + } +#else + tmp = tmpd; +#endif + if (err == MP_OKAY) { + sp_384_from_mp(p->x, 15, pX); + sp_384_from_mp(p->y, 15, pY); + sp_384_from_mp(p->z, 15, pZ); + + sp_384_map_15(p, p, tmp); + } + + if (err == MP_OKAY) { + err = sp_384_to_mp(p->x, pX); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->y, pY); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->z, pZ); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (tmp != NULL) { + XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_15(p, 0, NULL); + + return err; +} +#endif /* WOLFSSL_PUBLIC_ECC_ADD_DBL */ +#ifdef HAVE_COMP_KEY +/* Find the square root of a number mod the prime of the curve. + * + * y The number to operate on and the result. + * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise. + */ +static int sp_384_mont_sqrt_15(sp_digit* y) +{ +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_digit* d; +#else + sp_digit t1d[2 * 15]; + sp_digit t2d[2 * 15]; + sp_digit t3d[2 * 15]; + sp_digit t4d[2 * 15]; + sp_digit t5d[2 * 15]; +#endif + sp_digit* t1; + sp_digit* t2; + sp_digit* t3; + sp_digit* t4; + sp_digit* t5; + int err = MP_OKAY; + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 5 * 2 * 15, NULL, DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + t1 = d + 0 * 15; + t2 = d + 2 * 15; + t3 = d + 4 * 15; + t4 = d + 6 * 15; + t5 = d + 8 * 15; +#else + t1 = t1d; + t2 = t2d; + t3 = t3d; + t4 = t4d; + t5 = t5d; +#endif + + { + /* t2 = y ^ 0x2 */ + sp_384_mont_sqr_15(t2, y, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x3 */ + sp_384_mont_mul_15(t1, t2, y, p384_mod, p384_mp_mod); + /* t5 = y ^ 0xc */ + sp_384_mont_sqr_n_15(t5, t1, 2, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xf */ + sp_384_mont_mul_15(t1, t1, t5, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x1e */ + sp_384_mont_sqr_15(t2, t1, p384_mod, p384_mp_mod); + /* t3 = y ^ 0x1f */ + sp_384_mont_mul_15(t3, t2, y, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3e0 */ + sp_384_mont_sqr_n_15(t2, t3, 5, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x3ff */ + sp_384_mont_mul_15(t1, t3, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x7fe0 */ + sp_384_mont_sqr_n_15(t2, t1, 5, p384_mod, p384_mp_mod); + /* t3 = y ^ 0x7fff */ + sp_384_mont_mul_15(t3, t3, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3fff800 */ + sp_384_mont_sqr_n_15(t2, t3, 15, p384_mod, p384_mp_mod); + /* t4 = y ^ 0x3ffffff */ + sp_384_mont_mul_15(t4, t3, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0xffffffc000000 */ + sp_384_mont_sqr_n_15(t2, t4, 30, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xfffffffffffff */ + sp_384_mont_mul_15(t1, t4, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0xfffffffffffffff000000000000000 */ + sp_384_mont_sqr_n_15(t2, t1, 60, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xffffffffffffffffffffffffffffff */ + sp_384_mont_mul_15(t1, t1, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0xffffffffffffffffffffffffffffff000000000000000000000000000000 */ + sp_384_mont_sqr_n_15(t2, t1, 120, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */ + sp_384_mont_mul_15(t1, t1, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000 */ + sp_384_mont_sqr_n_15(t2, t1, 15, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */ + sp_384_mont_mul_15(t1, t3, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000 */ + sp_384_mont_sqr_n_15(t2, t1, 31, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffff */ + sp_384_mont_mul_15(t1, t4, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffff0 */ + sp_384_mont_sqr_n_15(t2, t1, 4, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffc */ + sp_384_mont_mul_15(t1, t5, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000 */ + sp_384_mont_sqr_n_15(t2, t1, 62, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000001 */ + sp_384_mont_mul_15(t1, y, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffc00000000000000040000000 */ + sp_384_mont_sqr_n_15(y, t1, 30, p384_mod, p384_mp_mod); + } + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (d != NULL) { + XFREE(d, NULL, DYNAMIC_TYPE_ECC); + } +#endif + + return err; +} + + +/* Uncompress the point given the X ordinate. + * + * xm X ordinate. + * odd Whether the Y ordinate is odd. + * ym Calculated Y ordinate. + * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise. + */ +int sp_ecc_uncompress_384(mp_int* xm, int odd, mp_int* ym) +{ +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_digit* d; +#else + sp_digit xd[2 * 15]; + sp_digit yd[2 * 15]; +#endif + sp_digit* x = NULL; + sp_digit* y = NULL; + int err = MP_OKAY; + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4 * 15, NULL, DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + x = d + 0 * 15; + y = d + 2 * 15; +#else + x = xd; + y = yd; +#endif + + sp_384_from_mp(x, 15, xm); + err = sp_384_mod_mul_norm_15(x, x, p384_mod); + } + if (err == MP_OKAY) { + /* y = x^3 */ + { + sp_384_mont_sqr_15(y, x, p384_mod, p384_mp_mod); + sp_384_mont_mul_15(y, y, x, p384_mod, p384_mp_mod); + } + /* y = x^3 - 3x */ + sp_384_mont_sub_15(y, y, x, p384_mod); + sp_384_mont_sub_15(y, y, x, p384_mod); + sp_384_mont_sub_15(y, y, x, p384_mod); + /* y = x^3 - 3x + b */ + err = sp_384_mod_mul_norm_15(x, p384_b, p384_mod); + } + if (err == MP_OKAY) { + sp_384_mont_add_15(y, y, x, p384_mod); + /* y = sqrt(x^3 - 3x + b) */ + err = sp_384_mont_sqrt_15(y); + } + if (err == MP_OKAY) { + XMEMSET(y + 15, 0, 15U * sizeof(sp_digit)); + sp_384_mont_reduce_15(y, p384_mod, p384_mp_mod); + if ((((word32)y[0] ^ (word32)odd) & 1U) != 0U) { + sp_384_mont_sub_15(y, p384_mod, y, p384_mod); + } + + err = sp_384_to_mp(y, ym); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (d != NULL) { + XFREE(d, NULL, DYNAMIC_TYPE_ECC); + } +#endif + + return err; +} +#endif +#endif /* WOLFSSL_SP_384 */ #endif /* WOLFSSL_HAVE_SP_ECC */ #endif /* SP_WORD_SIZE == 32 */ #endif /* !WOLFSSL_SP_ASM */ diff --git a/wolfcrypt/src/sp_c64.c b/wolfcrypt/src/sp_c64.c index eafa8e8cd..38ca21d62 100644 --- a/wolfcrypt/src/sp_c64.c +++ b/wolfcrypt/src/sp_c64.c @@ -1544,7 +1544,7 @@ static int sp_2048_mod_exp_18(sp_digit* r, const sp_digit* a, const sp_digit* e, #ifdef WOLFSSL_SP_SMALL sp_digit* td; sp_digit* t[3]; - sp_digit* norm = NULL; + sp_digit* norm; sp_digit mp = 1; sp_digit n; int i; @@ -2468,7 +2468,7 @@ static int sp_2048_mod_exp_36(sp_digit* r, const sp_digit* a, const sp_digit* e, #ifdef WOLFSSL_SP_SMALL sp_digit* td; sp_digit* t[3]; - sp_digit* norm = NULL; + sp_digit* norm; sp_digit mp = 1; sp_digit n; int i; @@ -2863,7 +2863,7 @@ int sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm, #else e[0] = (sp_digit)em->dp[0]; if (em->used > 1) { - e[0] |= ((sp_int_digit)em->dp[1]) << DIGIT_BIT; + e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT; } #endif if (e[0] == 0) { @@ -2964,7 +2964,7 @@ int sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm, #else e[0] = (sp_digit)em->dp[0]; if (em->used > 1) { - e[0] |= ((sp_int_digit)em->dp[1]) << DIGIT_BIT; + e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT; } #endif if (e[0] == 0) { @@ -3436,13 +3436,13 @@ 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 b[72], e[36], m[36]; + sp_digit bd[72], ed[36], md[36]; #else sp_digit* d = NULL; +#endif sp_digit* b; sp_digit* e; sp_digit* m; -#endif sp_digit* r; int err = MP_OKAY; int expBits = mp_count_bits(exp); @@ -3469,16 +3469,20 @@ int sp_ModExp_2048(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) if (d == NULL) err = MEMORY_E; } -#endif if (err == MP_OKAY) { -#ifdef WOLFSSL_SMALL_STACK b = d; e = b + 36 * 2; m = e + 36; -#endif r = b; + } +#else + r = b = bd; + e = ed; + m = md; +#endif + if (err == MP_OKAY) { sp_2048_from_mp(b, 36, base); sp_2048_from_mp(e, 36, exp); sp_2048_from_mp(m, 36, mod); @@ -3606,13 +3610,13 @@ SP_NOINLINE static void sp_2048_lshift_36(sp_digit* r, sp_digit* a, byte n) static int sp_2048_mod_exp_2_36(sp_digit* r, const sp_digit* e, int bits, const sp_digit* m) { #ifndef WOLFSSL_SMALL_STACK - sp_digit norm[72]; - sp_digit tmp[37]; + sp_digit nd[72]; + sp_digit td[37]; #else sp_digit* td; +#endif sp_digit* norm; sp_digit* tmp; -#endif sp_digit mp = 1; sp_digit n, o; int i; @@ -3631,6 +3635,11 @@ static int sp_2048_mod_exp_2_36(sp_digit* r, const sp_digit* e, int bits, const #ifdef WOLFSSL_SMALL_STACK norm = td; tmp = td + 72; + XMEMSET(td, 0, sizeof(sp_digit) * 109); +#else + norm = nd; + tmp = td; + XMEMSET(td, 0, sizeof(td)); #endif sp_2048_mont_setup(m, &mp); @@ -3937,13 +3946,13 @@ 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 b[36], e[18], m[18]; + sp_digit bd[36], ed[18], md[18]; #else sp_digit* d = NULL; +#endif sp_digit* b; sp_digit* e; sp_digit* m; -#endif sp_digit* r; int err = MP_OKAY; int expBits = mp_count_bits(exp); @@ -3970,16 +3979,20 @@ int sp_ModExp_1024(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) if (d == NULL) err = MEMORY_E; } -#endif if (err == MP_OKAY) { -#ifdef WOLFSSL_SMALL_STACK b = d; e = b + 18 * 2; m = e + 18; -#endif r = b; + } +#else + r = b = bd; + e = ed; + m = md; +#endif + if (err == MP_OKAY) { sp_2048_from_mp(b, 18, base); sp_2048_from_mp(e, 18, exp); sp_2048_from_mp(m, 18, mod); @@ -5705,7 +5718,7 @@ static int sp_3072_mod_exp_27(sp_digit* r, const sp_digit* a, const sp_digit* e, #ifdef WOLFSSL_SP_SMALL sp_digit* td; sp_digit* t[3]; - sp_digit* norm = NULL; + sp_digit* norm; sp_digit mp = 1; sp_digit n; int i; @@ -6599,7 +6612,7 @@ static int sp_3072_mod_exp_54(sp_digit* r, const sp_digit* a, const sp_digit* e, #ifdef WOLFSSL_SP_SMALL sp_digit* td; sp_digit* t[3]; - sp_digit* norm = NULL; + sp_digit* norm; sp_digit mp = 1; sp_digit n; int i; @@ -6995,7 +7008,7 @@ int sp_RsaPublic_3072(const byte* in, word32 inLen, mp_int* em, mp_int* mm, #else e[0] = (sp_digit)em->dp[0]; if (em->used > 1) { - e[0] |= ((sp_int_digit)em->dp[1]) << DIGIT_BIT; + e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT; } #endif if (e[0] == 0) { @@ -7096,7 +7109,7 @@ int sp_RsaPublic_3072(const byte* in, word32 inLen, mp_int* em, mp_int* mm, #else e[0] = (sp_digit)em->dp[0]; if (em->used > 1) { - e[0] |= ((sp_int_digit)em->dp[1]) << DIGIT_BIT; + e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT; } #endif if (e[0] == 0) { @@ -7568,13 +7581,13 @@ 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 b[108], e[54], m[54]; + sp_digit bd[108], ed[54], md[54]; #else sp_digit* d = NULL; +#endif sp_digit* b; sp_digit* e; sp_digit* m; -#endif sp_digit* r; int err = MP_OKAY; int expBits = mp_count_bits(exp); @@ -7601,16 +7614,20 @@ int sp_ModExp_3072(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) if (d == NULL) err = MEMORY_E; } -#endif if (err == MP_OKAY) { -#ifdef WOLFSSL_SMALL_STACK b = d; e = b + 54 * 2; m = e + 54; -#endif r = b; + } +#else + r = b = bd; + e = ed; + m = md; +#endif + if (err == MP_OKAY) { sp_3072_from_mp(b, 54, base); sp_3072_from_mp(e, 54, exp); sp_3072_from_mp(m, 54, mod); @@ -7774,13 +7791,13 @@ SP_NOINLINE static void sp_3072_lshift_54(sp_digit* r, sp_digit* a, byte n) static int sp_3072_mod_exp_2_54(sp_digit* r, const sp_digit* e, int bits, const sp_digit* m) { #ifndef WOLFSSL_SMALL_STACK - sp_digit norm[108]; - sp_digit tmp[55]; + sp_digit nd[108]; + sp_digit td[55]; #else sp_digit* td; +#endif sp_digit* norm; sp_digit* tmp; -#endif sp_digit mp = 1; sp_digit n, o; int i; @@ -7799,6 +7816,11 @@ static int sp_3072_mod_exp_2_54(sp_digit* r, const sp_digit* e, int bits, const #ifdef WOLFSSL_SMALL_STACK norm = td; tmp = td + 108; + XMEMSET(td, 0, sizeof(sp_digit) * 163); +#else + norm = nd; + tmp = td; + XMEMSET(td, 0, sizeof(td)); #endif sp_3072_mont_setup(m, &mp); @@ -8105,13 +8127,13 @@ 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 b[54], e[27], m[27]; + sp_digit bd[54], ed[27], md[27]; #else sp_digit* d = NULL; +#endif sp_digit* b; sp_digit* e; sp_digit* m; -#endif sp_digit* r; int err = MP_OKAY; int expBits = mp_count_bits(exp); @@ -8138,16 +8160,20 @@ int sp_ModExp_1536(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) if (d == NULL) err = MEMORY_E; } -#endif if (err == MP_OKAY) { -#ifdef WOLFSSL_SMALL_STACK b = d; e = b + 27 * 2; m = e + 27; -#endif r = b; + } +#else + r = b = bd; + e = ed; + m = md; +#endif + if (err == MP_OKAY) { sp_3072_from_mp(b, 27, base); sp_3072_from_mp(e, 27, exp); sp_3072_from_mp(m, 27, mod); @@ -9092,6 +9118,7 @@ SP_NOINLINE static void sp_4096_sqr_78(sp_digit* r, const sp_digit* a) #endif /* WOLFSSL_SP_SMALL */ #if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) +#if defined(WOLFSSL_HAVE_SP_RSA) && !defined(SP_RSA_PRIVATE_EXP_D) #ifdef WOLFSSL_SP_SMALL /* Add b to a into r. (r = a + b) * @@ -9236,6 +9263,7 @@ 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 */ /* Caclulate the bottom digit of -1/a mod 2^n. @@ -9318,6 +9346,7 @@ SP_NOINLINE static void sp_4096_mul_d_78(sp_digit* r, const sp_digit* a, } #if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) +#if defined(WOLFSSL_HAVE_SP_RSA) && !defined(SP_RSA_PRIVATE_EXP_D) /* 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. * @@ -9980,7 +10009,7 @@ static int sp_4096_mod_exp_39(sp_digit* r, const sp_digit* a, const sp_digit* e, #ifdef WOLFSSL_SP_SMALL sp_digit* td; sp_digit* t[3]; - sp_digit* norm = NULL; + sp_digit* norm; sp_digit mp = 1; sp_digit n; int i; @@ -10276,6 +10305,7 @@ 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 */ /* r = 2^n mod m where n is the number of bits to reduce by. @@ -10972,7 +11002,7 @@ static int sp_4096_mod_exp_78(sp_digit* r, const sp_digit* a, const sp_digit* e, #ifdef WOLFSSL_SP_SMALL sp_digit* td; sp_digit* t[3]; - sp_digit* norm = NULL; + sp_digit* norm; sp_digit mp = 1; sp_digit n; int i; @@ -11372,7 +11402,7 @@ int sp_RsaPublic_4096(const byte* in, word32 inLen, mp_int* em, mp_int* mm, #else e[0] = (sp_digit)em->dp[0]; if (em->used > 1) { - e[0] |= ((sp_int_digit)em->dp[1]) << DIGIT_BIT; + e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT; } #endif if (e[0] == 0) { @@ -11473,7 +11503,7 @@ int sp_RsaPublic_4096(const byte* in, word32 inLen, mp_int* em, mp_int* mm, #else e[0] = (sp_digit)em->dp[0]; if (em->used > 1) { - e[0] |= ((sp_int_digit)em->dp[1]) << DIGIT_BIT; + e[0] |= ((sp_digit)em->dp[1]) << DIGIT_BIT; } #endif if (e[0] == 0) { @@ -11945,13 +11975,13 @@ 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 b[156], e[78], m[78]; + sp_digit bd[156], ed[78], md[78]; #else sp_digit* d = NULL; +#endif sp_digit* b; sp_digit* e; sp_digit* m; -#endif sp_digit* r; int err = MP_OKAY; int expBits = mp_count_bits(exp); @@ -11978,16 +12008,20 @@ int sp_ModExp_4096(mp_int* base, mp_int* exp, mp_int* mod, mp_int* res) if (d == NULL) err = MEMORY_E; } -#endif if (err == MP_OKAY) { -#ifdef WOLFSSL_SMALL_STACK b = d; e = b + 78 * 2; m = e + 78; -#endif r = b; + } +#else + r = b = bd; + e = ed; + m = md; +#endif + if (err == MP_OKAY) { sp_4096_from_mp(b, 78, base); sp_4096_from_mp(e, 78, exp); sp_4096_from_mp(m, 78, mod); @@ -12199,13 +12233,13 @@ SP_NOINLINE static void sp_4096_lshift_78(sp_digit* r, sp_digit* a, byte n) static int sp_4096_mod_exp_2_78(sp_digit* r, const sp_digit* e, int bits, const sp_digit* m) { #ifndef WOLFSSL_SMALL_STACK - sp_digit norm[156]; - sp_digit tmp[79]; + sp_digit nd[156]; + sp_digit td[79]; #else sp_digit* td; +#endif sp_digit* norm; sp_digit* tmp; -#endif sp_digit mp = 1; sp_digit n, o; int i; @@ -12224,6 +12258,11 @@ static int sp_4096_mod_exp_2_78(sp_digit* r, const sp_digit* e, int bits, const #ifdef WOLFSSL_SMALL_STACK norm = td; tmp = td + 156; + XMEMSET(td, 0, sizeof(sp_digit) * 235); +#else + norm = nd; + tmp = td; + XMEMSET(td, 0, sizeof(td)); #endif sp_4096_mont_setup(m, &mp); @@ -12471,12 +12510,12 @@ int sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen, #ifndef WOLFSSL_SP_NO_256 /* Point structure to use. */ -typedef struct sp_point { +typedef struct sp_point_256 { sp_digit x[2 * 5]; sp_digit y[2 * 5]; sp_digit z[2 * 5]; int infinity; -} sp_point; +} sp_point_256; /* The modulus (prime) of the curve P256. */ static const sp_digit p256_mod[5] = { @@ -12515,21 +12554,24 @@ static const sp_digit p256_norm_order[5] = { static const sp_digit p256_mp_order = 0x1c8aaee00bc4fL; #endif /* The base point of curve P256. */ -static const sp_point p256_base = { +static const sp_point_256 p256_base = { /* X ordinate */ { 0x13945d898c296L,0x812deb33a0f4aL,0x3a440f277037dL,0x4247f8bce6e56L, - 0x06b17d1f2e12cL, 0L, 0L, 0L, 0L, 0L + 0x06b17d1f2e12cL, + 0L, 0L, 0L, 0L, 0L }, /* Y ordinate */ { 0x6406837bf51f5L,0x576b315ececbbL,0xc0f9e162bce33L,0x7f9b8ee7eb4a7L, - 0x04fe342e2fe1aL, 0L, 0L, 0L, 0L, 0L + 0x04fe342e2fe1aL, + 0L, 0L, 0L, 0L, 0L }, /* Z ordinate */ { 0x0000000000001L,0x0000000000000L,0x0000000000000L,0x0000000000000L, - 0x0000000000000L, 0L, 0L, 0L, 0L, 0L + 0x0000000000000L, + 0L, 0L, 0L, 0L, 0L }, /* infinity */ 0 @@ -12541,34 +12583,32 @@ static const sp_digit p256_b[5] = { }; #endif -static int sp_ecc_point_new_ex(void* heap, sp_point* sp, sp_point** p) +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) + (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; } - else { - #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - *p = (sp_point*)XMALLOC(sizeof(sp_point), heap, DYNAMIC_TYPE_ECC); - (void)sp; - #else - *p = sp; - (void)heap; - #endif - } return ret; } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) /* Allocate memory for point and return error. */ -#define sp_ecc_point_new(heap, sp, p) sp_ecc_point_new_ex((heap), NULL, &(p)) +#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_ecc_point_new(heap, sp, p) sp_ecc_point_new_ex((heap), &(sp), &(p)) +#define sp_256_point_new_5(heap, sp, p) sp_256_point_new_ex_5((heap), &(sp), &(p)) #endif -static void sp_ecc_point_free(sp_point* p, int clear, void* heap) +static void sp_256_point_free_5(sp_point_256* p, int clear, void* heap) { #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) /* If valid pointer then clear point data if requested and free data. */ @@ -12612,7 +12652,7 @@ static int sp_256_mod_mul_norm_5(sp_digit* r, const sp_digit* a, const sp_digit* #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) td = (int64_t*)XMALLOC(sizeof(int64_t) * 2 * 8, NULL, DYNAMIC_TYPE_ECC); if (td == NULL) { - err = MEMORY_E; + return MEMORY_E; } #endif @@ -12627,74 +12667,74 @@ static int sp_256_mod_mul_norm_5(sp_digit* r, const sp_digit* a, const sp_digit* a32[0] = (sp_digit)(a[0]) & 0xffffffffL; a32[1] = (sp_digit)(a[0] >> 32U); - a32[1] |= (sp_int_digit)a[1] << 20U; + a32[1] |= a[1] << 20U; a32[1] &= 0xffffffffL; a32[2] = (sp_digit)(a[1] >> 12U) & 0xffffffffL; a32[3] = (sp_digit)(a[1] >> 44U); - a32[3] |= (sp_int_digit)a[2] << 8U; + a32[3] |= a[2] << 8U; a32[3] &= 0xffffffffL; a32[4] = (sp_digit)(a[2] >> 24U); - a32[4] |= (sp_int_digit)a[3] << 28U; + a32[4] |= a[3] << 28U; a32[4] &= 0xffffffffL; a32[5] = (sp_digit)(a[3] >> 4U) & 0xffffffffL; a32[6] = (sp_digit)(a[3] >> 36U); - a32[6] |= (sp_int_digit)a[4] << 16U; + a32[6] |= 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]; + 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]; + 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]; + 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]; + 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]; + 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]; + 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]; + 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[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; + 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_int_digit)t[0]; - r[0] |= (sp_int_digit)t[1] << 32U; + r[0] = t[0]; + r[0] |= t[1] << 32U; r[0] &= 0xfffffffffffffLL; r[1] = (sp_digit)(t[1] >> 20); - r[1] |= (sp_int_digit)t[2] << 12U; - r[1] |= (sp_int_digit)t[3] << 44U; + r[1] |= t[2] << 12U; + r[1] |= t[3] << 44U; r[1] &= 0xfffffffffffffLL; r[2] = (sp_digit)(t[3] >> 8); - r[2] |= (sp_int_digit)t[4] << 24U; + r[2] |= t[4] << 24U; r[2] &= 0xfffffffffffffLL; r[3] = (sp_digit)(t[4] >> 28); - r[3] |= (sp_int_digit)t[5] << 4U; - r[3] |= (sp_int_digit)t[6] << 36U; + r[3] |= t[5] << 4U; + r[3] |= t[6] << 36U; r[3] &= 0xfffffffffffffLL; r[4] = (sp_digit)(t[6] >> 16); - r[4] |= (sp_int_digit)t[7] << 16U; + r[4] |= t[7] << 16U; } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) @@ -12788,12 +12828,12 @@ static void sp_256_from_mp(sp_digit* r, int size, const mp_int* a) #endif } -/* Convert a point of type ecc_point to type sp_point. +/* Convert a point of type ecc_point to type sp_point_256. * - * p Point of type sp_point (result). + * 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* p, const ecc_point* pm) +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)); @@ -12868,14 +12908,14 @@ static int sp_256_to_mp(const sp_digit* a, mp_int* r) return err; } -/* Convert a point of type sp_point to type ecc_point. +/* Convert a point of type sp_point_256 to type ecc_point. * - * p Point of type sp_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* p, ecc_point* pm) +static int sp_256_point_to_ecc_point_5(const sp_point_256* p, ecc_point* pm) { int err; @@ -12890,191 +12930,6 @@ static int sp_256_point_to_ecc_point_5(const sp_point* p, ecc_point* pm) 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_256_cmp_5(const sp_digit* a, const sp_digit* b) -{ - sp_digit r = 0; -#ifdef WOLFSSL_SP_SMALL - int i; - - for (i=4; i>=0; i--) { - r |= (a[i] - b[i]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); - } -#else - r |= (a[ 4] - b[ 4]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); - r |= (a[ 3] - b[ 3]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); - r |= (a[ 2] - b[ 2]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); - r |= (a[ 1] - b[ 1]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); - r |= (a[ 0] - b[ 0]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); -#endif /* WOLFSSL_SP_SMALL */ - - return r; -} - -/* Normalize the values in each word to 52. - * - * a Array of sp_digit to normalize. - */ -static void sp_256_norm_5(sp_digit* a) -{ -#ifdef WOLFSSL_SP_SMALL - int i; - for (i = 0; i < 4; i++) { - a[i+1] += a[i] >> 52; - a[i] &= 0xfffffffffffffL; - } -#else - a[1] += a[0] >> 52; a[0] &= 0xfffffffffffffL; - a[2] += a[1] >> 52; a[1] &= 0xfffffffffffffL; - a[3] += a[2] >> 52; a[2] &= 0xfffffffffffffL; - a[4] += a[3] >> 52; a[3] &= 0xfffffffffffffL; -#endif -} - -/* 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_256_cond_sub_5(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 < 5; i++) { - r[i] = a[i] - (b[i] & m); - } -#else - r[ 0] = a[ 0] - (b[ 0] & m); - r[ 1] = a[ 1] - (b[ 1] & m); - r[ 2] = a[ 2] - (b[ 2] & m); - r[ 3] = a[ 3] - (b[ 3] & m); - r[ 4] = a[ 4] - (b[ 4] & m); -#endif /* WOLFSSL_SP_SMALL */ -} - -#define sp_256_mont_reduce_order_5 sp_256_mont_reduce_5 - -/* 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_256_mul_add_5(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 < 5; i++) { - t += (tb * a[i]) + r[i]; - r[i] = t & 0xfffffffffffffL; - t >>= 52; - } - r[5] += t; -#else - int128_t tb = b; - int128_t t[5]; - - t[ 0] = tb * a[ 0]; - t[ 1] = tb * a[ 1]; - t[ 2] = tb * a[ 2]; - t[ 3] = tb * a[ 3]; - t[ 4] = tb * a[ 4]; - r[ 0] += (sp_digit)(t[ 0] & 0xfffffffffffffL); - r[ 1] += (sp_digit)((t[ 0] >> 52) + (t[ 1] & 0xfffffffffffffL)); - r[ 2] += (sp_digit)((t[ 1] >> 52) + (t[ 2] & 0xfffffffffffffL)); - r[ 3] += (sp_digit)((t[ 2] >> 52) + (t[ 3] & 0xfffffffffffffL)); - r[ 4] += (sp_digit)((t[ 3] >> 52) + (t[ 4] & 0xfffffffffffffL)); - r[ 5] += t[ 4] >> 52; -#endif /* WOLFSSL_SP_SMALL */ -} - -/* Shift the result in the high 256 bits down to the bottom. - * - * r A single precision number. - * a A single precision number. - */ -static void sp_256_mont_shift_5(sp_digit* r, const sp_digit* a) -{ -#ifdef WOLFSSL_SP_SMALL - int i; - word64 n; - - n = a[4] >> 48; - for (i = 0; i < 4; i++) { - n += (word64)a[5 + i] << 4; - r[i] = n & 0xfffffffffffffL; - n >>= 52; - } - n += (word64)a[9] << 4; - r[4] = n; -#else - word64 n; - - n = a[4] >> 48; - n += (word64)a[ 5] << 4U; r[ 0] = n & 0xfffffffffffffUL; n >>= 52U; - n += (word64)a[ 6] << 4U; r[ 1] = n & 0xfffffffffffffUL; n >>= 52U; - n += (word64)a[ 7] << 4U; r[ 2] = n & 0xfffffffffffffUL; n >>= 52U; - n += (word64)a[ 8] << 4U; r[ 3] = n & 0xfffffffffffffUL; n >>= 52U; - n += (word64)a[ 9] << 4U; r[ 4] = n; -#endif /* WOLFSSL_SP_SMALL */ - XMEMSET(&r[5], 0, sizeof(*r) * 5U); -} - -/* 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. - */ -static void sp_256_mont_reduce_5(sp_digit* a, const sp_digit* m, sp_digit mp) -{ - int i; - sp_digit mu; - - if (mp != 1) { - for (i=0; i<4; i++) { - mu = (a[i] * mp) & 0xfffffffffffffL; - sp_256_mul_add_5(a+i, m, mu); - a[i+1] += a[i] >> 52; - } - mu = (a[i] * mp) & 0xffffffffffffL; - sp_256_mul_add_5(a+i, m, mu); - a[i+1] += a[i] >> 52; - a[i] &= 0xfffffffffffffL; - } - else { - for (i=0; i<4; i++) { - mu = a[i] & 0xfffffffffffffL; - sp_256_mul_add_5(a+i, p256_mod, mu); - a[i+1] += a[i] >> 52; - } - mu = a[i] & 0xffffffffffffL; - sp_256_mul_add_5(a+i, p256_mod, mu); - a[i+1] += a[i] >> 52; - a[i] &= 0xfffffffffffffL; - } - - sp_256_mont_shift_5(a, a); - sp_256_cond_sub_5(a, a, m, 0 - (((a[4] >> 48) > 0) ? - (sp_digit)1 : (sp_digit)0)); - sp_256_norm_5(a); -} - #ifdef WOLFSSL_SP_SMALL /* Multiply a and b into r. (r = a * b) * @@ -13159,6 +13014,191 @@ SP_NOINLINE static void sp_256_mul_5(sp_digit* r, const sp_digit* a, } #endif /* WOLFSSL_SP_SMALL */ +#define sp_256_mont_reduce_order_5 sp_256_mont_reduce_5 + +/* 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_256_cmp_5(const sp_digit* a, const sp_digit* b) +{ + sp_digit r = 0; +#ifdef WOLFSSL_SP_SMALL + int i; + + for (i=4; i>=0; i--) { + r |= (a[i] - b[i]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + } +#else + r |= (a[ 4] - b[ 4]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[ 3] - b[ 3]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[ 2] - b[ 2]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[ 1] - b[ 1]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[ 0] - b[ 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_256_cond_sub_5(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 < 5; i++) { + r[i] = a[i] - (b[i] & m); + } +#else + r[ 0] = a[ 0] - (b[ 0] & m); + r[ 1] = a[ 1] - (b[ 1] & m); + r[ 2] = a[ 2] - (b[ 2] & m); + r[ 3] = a[ 3] - (b[ 3] & m); + r[ 4] = a[ 4] - (b[ 4] & 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_256_mul_add_5(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 < 5; i++) { + t += (tb * a[i]) + r[i]; + r[i] = t & 0xfffffffffffffL; + t >>= 52; + } + r[5] += t; +#else + int128_t tb = b; + int128_t t[5]; + + t[ 0] = tb * a[ 0]; + t[ 1] = tb * a[ 1]; + t[ 2] = tb * a[ 2]; + t[ 3] = tb * a[ 3]; + t[ 4] = tb * a[ 4]; + r[ 0] += (sp_digit)(t[ 0] & 0xfffffffffffffL); + r[ 1] += (sp_digit)((t[ 0] >> 52) + (t[ 1] & 0xfffffffffffffL)); + r[ 2] += (sp_digit)((t[ 1] >> 52) + (t[ 2] & 0xfffffffffffffL)); + r[ 3] += (sp_digit)((t[ 2] >> 52) + (t[ 3] & 0xfffffffffffffL)); + r[ 4] += (sp_digit)((t[ 3] >> 52) + (t[ 4] & 0xfffffffffffffL)); + r[ 5] += t[ 4] >> 52; +#endif /* WOLFSSL_SP_SMALL */ +} + +/* Normalize the values in each word to 52. + * + * a Array of sp_digit to normalize. + */ +static void sp_256_norm_5(sp_digit* a) +{ +#ifdef WOLFSSL_SP_SMALL + int i; + for (i = 0; i < 4; i++) { + a[i+1] += a[i] >> 52; + a[i] &= 0xfffffffffffffL; + } +#else + a[1] += a[0] >> 52; a[0] &= 0xfffffffffffffL; + a[2] += a[1] >> 52; a[1] &= 0xfffffffffffffL; + a[3] += a[2] >> 52; a[2] &= 0xfffffffffffffL; + a[4] += a[3] >> 52; a[3] &= 0xfffffffffffffL; +#endif +} + +/* Shift the result in the high 256 bits down to the bottom. + * + * r A single precision number. + * a A single precision number. + */ +static void sp_256_mont_shift_5(sp_digit* r, const sp_digit* a) +{ +#ifdef WOLFSSL_SP_SMALL + int i; + word64 n; + + n = a[4] >> 48; + for (i = 0; i < 4; i++) { + n += (word64)a[5 + i] << 4; + r[i] = n & 0xfffffffffffffL; + n >>= 52; + } + n += (word64)a[9] << 4; + r[4] = n; +#else + word64 n; + + n = a[4] >> 48; + n += (word64)a[ 5] << 4U; r[ 0] = n & 0xfffffffffffffUL; n >>= 52U; + n += (word64)a[ 6] << 4U; r[ 1] = n & 0xfffffffffffffUL; n >>= 52U; + n += (word64)a[ 7] << 4U; r[ 2] = n & 0xfffffffffffffUL; n >>= 52U; + n += (word64)a[ 8] << 4U; r[ 3] = n & 0xfffffffffffffUL; n >>= 52U; + n += (word64)a[ 9] << 4U; r[ 4] = n; +#endif /* WOLFSSL_SP_SMALL */ + XMEMSET(&r[5], 0, sizeof(*r) * 5U); +} + +/* 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. + */ +static void sp_256_mont_reduce_5(sp_digit* a, const sp_digit* m, sp_digit mp) +{ + int i; + sp_digit mu; + + if (mp != 1) { + for (i=0; i<4; i++) { + mu = (a[i] * mp) & 0xfffffffffffffL; + sp_256_mul_add_5(a+i, m, mu); + a[i+1] += a[i] >> 52; + } + mu = (a[i] * mp) & 0xffffffffffffL; + sp_256_mul_add_5(a+i, m, mu); + a[i+1] += a[i] >> 52; + a[i] &= 0xfffffffffffffL; + } + else { + for (i=0; i<4; i++) { + mu = a[i] & 0xfffffffffffffL; + sp_256_mul_add_5(a+i, p256_mod, mu); + a[i+1] += a[i] >> 52; + } + mu = a[i] & 0xffffffffffffL; + sp_256_mul_add_5(a+i, p256_mod, mu); + a[i+1] += a[i] >> 52; + a[i] &= 0xfffffffffffffL; + } + + sp_256_mont_shift_5(a, a); + sp_256_cond_sub_5(a, a, m, 0 - (((a[4] >> 48) > 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_256_norm_5(a); +} + /* Multiply two Montogmery form numbers mod the modulus (prime). * (r = a * b mod m) * @@ -13284,7 +13324,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 */ #ifdef WOLFSSL_SP_SMALL /* Mod-2 for the P256 curve. */ -static const uint64_t p256_mod_2[4] = { +static const uint64_t p256_mod_minus_2[4] = { 0xfffffffffffffffdU,0x00000000ffffffffU,0x0000000000000000U, 0xffffffff00000001U }; @@ -13306,61 +13346,56 @@ static void sp_256_mont_inv_5(sp_digit* r, const sp_digit* a, sp_digit* td) XMEMCPY(t, a, sizeof(sp_digit) * 5); for (i=254; i>=0; i--) { sp_256_mont_sqr_5(t, t, p256_mod, p256_mp_mod); - if (p256_mod_2[i / 64] & ((sp_digit)1 << (i % 64))) + if (p256_mod_minus_2[i / 64] & ((sp_digit)1 << (i % 64))) sp_256_mont_mul_5(t, t, a, p256_mod, p256_mp_mod); } XMEMCPY(r, t, sizeof(sp_digit) * 5); #else - sp_digit* t = td; + sp_digit* t1 = td; sp_digit* t2 = td + 2 * 5; sp_digit* t3 = td + 4 * 5; - - /* t = a^2 */ - sp_256_mont_sqr_5(t, a, p256_mod, p256_mp_mod); - /* t = a^3 = t * a */ - sp_256_mont_mul_5(t, t, a, p256_mod, p256_mp_mod); - /* t2= a^c = t ^ 2 ^ 2 */ - sp_256_mont_sqr_n_5(t2, t, 2, p256_mod, p256_mp_mod); - /* t3= a^d = t2 * a */ - sp_256_mont_mul_5(t3, t2, a, p256_mod, p256_mp_mod); - /* t = a^f = t2 * t */ - sp_256_mont_mul_5(t, t2, t, p256_mod, p256_mp_mod); - /* t2= a^f0 = t ^ 2 ^ 4 */ - sp_256_mont_sqr_n_5(t2, t, 4, p256_mod, p256_mp_mod); - /* t3= a^fd = t2 * t3 */ - sp_256_mont_mul_5(t3, t2, t3, p256_mod, p256_mp_mod); - /* t = a^ff = t2 * t */ - sp_256_mont_mul_5(t, t2, t, p256_mod, p256_mp_mod); - /* t2= a^ff00 = t ^ 2 ^ 8 */ - sp_256_mont_sqr_n_5(t2, t, 8, p256_mod, p256_mp_mod); - /* t3= a^fffd = t2 * t3 */ - sp_256_mont_mul_5(t3, t2, t3, p256_mod, p256_mp_mod); - /* t = a^ffff = t2 * t */ - sp_256_mont_mul_5(t, t2, t, p256_mod, p256_mp_mod); - /* t2= a^ffff0000 = t ^ 2 ^ 16 */ - sp_256_mont_sqr_n_5(t2, t, 16, p256_mod, p256_mp_mod); - /* t3= a^fffffffd = t2 * t3 */ - sp_256_mont_mul_5(t3, t2, t3, p256_mod, p256_mp_mod); - /* t = a^ffffffff = t2 * t */ - sp_256_mont_mul_5(t, t2, t, p256_mod, p256_mp_mod); - /* t = a^ffffffff00000000 = t ^ 2 ^ 32 */ - sp_256_mont_sqr_n_5(t2, t, 32, p256_mod, p256_mp_mod); - /* t2= a^ffffffffffffffff = t2 * t */ - sp_256_mont_mul_5(t, t2, t, p256_mod, p256_mp_mod); - /* t2= a^ffffffff00000001 = t2 * a */ - sp_256_mont_mul_5(t2, t2, a, p256_mod, p256_mp_mod); - /* t2= a^ffffffff000000010000000000000000000000000000000000000000 - * = t2 ^ 2 ^ 160 */ - sp_256_mont_sqr_n_5(t2, t2, 160, p256_mod, p256_mp_mod); - /* t2= a^ffffffff00000001000000000000000000000000ffffffffffffffff - * = t2 * t */ - sp_256_mont_mul_5(t2, t2, t, p256_mod, p256_mp_mod); - /* t2= a^ffffffff00000001000000000000000000000000ffffffffffffffff00000000 - * = t2 ^ 2 ^ 32 */ - sp_256_mont_sqr_n_5(t2, t2, 32, p256_mod, p256_mp_mod); - /* r = a^ffffffff00000001000000000000000000000000fffffffffffffffffffffffd - * = t2 * t3 */ - sp_256_mont_mul_5(r, t2, t3, p256_mod, p256_mp_mod); + /* 0x2 */ + sp_256_mont_sqr_5(t1, a, p256_mod, p256_mp_mod); + /* 0x3 */ + sp_256_mont_mul_5(t2, t1, a, p256_mod, p256_mp_mod); + /* 0xc */ + sp_256_mont_sqr_n_5(t1, t2, 2, p256_mod, p256_mp_mod); + /* 0xd */ + sp_256_mont_mul_5(t3, t1, a, p256_mod, p256_mp_mod); + /* 0xf */ + sp_256_mont_mul_5(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xf0 */ + sp_256_mont_sqr_n_5(t1, t2, 4, p256_mod, p256_mp_mod); + /* 0xfd */ + sp_256_mont_mul_5(t3, t3, t1, p256_mod, p256_mp_mod); + /* 0xff */ + sp_256_mont_mul_5(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xff00 */ + sp_256_mont_sqr_n_5(t1, t2, 8, p256_mod, p256_mp_mod); + /* 0xfffd */ + sp_256_mont_mul_5(t3, t3, t1, p256_mod, p256_mp_mod); + /* 0xffff */ + sp_256_mont_mul_5(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xffff0000 */ + sp_256_mont_sqr_n_5(t1, t2, 16, p256_mod, p256_mp_mod); + /* 0xfffffffd */ + sp_256_mont_mul_5(t3, t3, t1, p256_mod, p256_mp_mod); + /* 0xffffffff */ + sp_256_mont_mul_5(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xffffffff00000000 */ + sp_256_mont_sqr_n_5(t1, t2, 32, p256_mod, p256_mp_mod); + /* 0xffffffffffffffff */ + sp_256_mont_mul_5(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xffffffff00000001 */ + sp_256_mont_mul_5(r, t1, a, p256_mod, p256_mp_mod); + /* 0xffffffff000000010000000000000000000000000000000000000000 */ + sp_256_mont_sqr_n_5(r, r, 160, p256_mod, p256_mp_mod); + /* 0xffffffff00000001000000000000000000000000ffffffffffffffff */ + sp_256_mont_mul_5(r, r, t2, p256_mod, p256_mp_mod); + /* 0xffffffff00000001000000000000000000000000ffffffffffffffff00000000 */ + sp_256_mont_sqr_n_5(r, r, 32, p256_mod, p256_mp_mod); + /* 0xffffffff00000001000000000000000000000000fffffffffffffffffffffffd */ + sp_256_mont_mul_5(r, r, t3, p256_mod, p256_mp_mod); #endif /* WOLFSSL_SP_SMALL */ } @@ -13370,7 +13405,7 @@ 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* r, const sp_point* 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; @@ -13618,9 +13653,9 @@ static void sp_256_div2_5(sp_digit* r, const sp_digit* a, const sp_digit* m) * p Point to double. * t Temporary ordinate data. */ -static void sp_256_proj_point_dbl_5(sp_point* r, const sp_point* p, sp_digit* t) +static void sp_256_proj_point_dbl_5(sp_point_256* r, const sp_point_256* p, sp_digit* t) { - sp_point* rp[2]; + sp_point_256* rp[2]; sp_digit* t1 = t; sp_digit* t2 = t + 2*5; sp_digit* x; @@ -13632,8 +13667,8 @@ static void sp_256_proj_point_dbl_5(sp_point* r, const sp_point* p, sp_digit* t) rp[0] = r; /*lint allow cast to different type of pointer*/ - rp[1] = (sp_point*)t; /*lint !e9087 !e740*/ - XMEMSET(rp[1], 0, sizeof(sp_point)); + rp[1] = (sp_point_256*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_256)); x = rp[p->infinity]->x; y = rp[p->infinity]->y; z = rp[p->infinity]->z; @@ -13710,11 +13745,11 @@ static int sp_256_cmp_equal_5(const sp_digit* a, const sp_digit* b) * q Second point to add. * t Temporary ordinate data. */ -static void sp_256_proj_point_add_5(sp_point* r, const sp_point* p, const sp_point* q, +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* ap[2]; - sp_point* rp[2]; + const sp_point_256* ap[2]; + sp_point_256* rp[2]; sp_digit* t1 = t; sp_digit* t2 = t + 2*5; sp_digit* t3 = t + 4*5; @@ -13727,7 +13762,7 @@ static void sp_256_proj_point_add_5(sp_point* r, const sp_point* p, const sp_poi /* Ensure only the first point is the same as the result. */ if (q == r) { - const sp_point* a = p; + const sp_point_256* a = p; p = q; q = a; } @@ -13743,8 +13778,8 @@ static void sp_256_proj_point_add_5(sp_point* r, const sp_point* p, const sp_poi rp[0] = r; /*lint allow cast to different type of pointer*/ - rp[1] = (sp_point*)t; /*lint !e9087 !e740*/ - XMEMSET(rp[1], 0, sizeof(sp_point)); + rp[1] = (sp_point_256*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_256)); x = rp[p->infinity | q->infinity]->x; y = rp[p->infinity | q->infinity]->y; z = rp[p->infinity | q->infinity]->z; @@ -13808,11 +13843,11 @@ static void sp_256_proj_point_add_5(sp_point* r, const sp_point* p, const sp_poi * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_5(sp_point* r, const sp_point* g, const sp_digit* k, +static int sp_256_ecc_mulmod_5(sp_point_256* r, const sp_point_256* g, const sp_digit* k, int map, void* heap) { - sp_point* td; - sp_point* t[3]; + sp_point_256* td; + sp_point_256* t[3]; sp_digit* tmp; sp_digit n; int i; @@ -13821,7 +13856,7 @@ static int sp_256_ecc_mulmod_5(sp_point* r, const sp_point* g, const sp_digit* k (void)heap; - td = (sp_point*)XMALLOC(sizeof(sp_point) * 3, heap, DYNAMIC_TYPE_ECC); + td = (sp_point_256*)XMALLOC(sizeof(sp_point_256) * 3, heap, DYNAMIC_TYPE_ECC); if (td == NULL) err = MEMORY_E; tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 5 * 5, heap, @@ -13866,18 +13901,18 @@ static int sp_256_ecc_mulmod_5(sp_point* r, const sp_point* g, const sp_digit* k XMEMCPY(t[2], (void*)(((size_t)t[0] & addr_mask[y^1]) + ((size_t)t[1] & addr_mask[y])), - sizeof(sp_point)); + sizeof(sp_point_256)); sp_256_proj_point_dbl_5(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)); + sizeof(sp_point_256)); } if (map != 0) { sp_256_map_5(r, t[0], tmp); } else { - XMEMCPY(r, t[0], sizeof(sp_point)); + XMEMCPY(r, t[0], sizeof(sp_point_256)); } } @@ -13886,7 +13921,7 @@ static int sp_256_ecc_mulmod_5(sp_point* r, const sp_point* g, const sp_digit* k XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); } if (td != NULL) { - XMEMSET(td, 0, sizeof(sp_point) * 3); + XMEMSET(td, 0, sizeof(sp_point_256) * 3); XFREE(td, NULL, DYNAMIC_TYPE_ECC); } @@ -13904,14 +13939,14 @@ static int sp_256_ecc_mulmod_5(sp_point* r, const sp_point* g, const sp_digit* k * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_5(sp_point* r, const sp_point* g, const sp_digit* k, +static int sp_256_ecc_mulmod_5(sp_point_256* r, const sp_point_256* g, const sp_digit* k, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point td[3]; + sp_point_256 td[3]; sp_digit tmpd[2 * 5 * 5]; #endif - sp_point* t; + sp_point_256* t; sp_digit* tmp; sp_digit n; int i; @@ -13921,8 +13956,8 @@ static int sp_256_ecc_mulmod_5(sp_point* r, const sp_point* g, const sp_digit* k (void)heap; #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - sp_point td[3]; - t = (sp_point*)XMALLOC(sizeof(*td) * 3, heap, DYNAMIC_TYPE_ECC); + sp_point_256 td[3]; + t = (sp_point_256*)XMALLOC(sizeof(*td) * 3, heap, DYNAMIC_TYPE_ECC); if (t == NULL) err = MEMORY_E; tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 5 * 5, heap, @@ -13979,7 +14014,7 @@ static int sp_256_ecc_mulmod_5(sp_point* r, const sp_point* g, const sp_digit* k sp_256_map_5(r, &t[0], tmp); } else { - XMEMCPY(r, &t[0], sizeof(sp_point)); + XMEMCPY(r, &t[0], sizeof(sp_point_256)); } } @@ -13989,7 +14024,7 @@ static int sp_256_ecc_mulmod_5(sp_point* r, const sp_point* g, const sp_digit* k XFREE(tmp, heap, DYNAMIC_TYPE_ECC); } if (t != NULL) { - XMEMSET(t, 0, sizeof(sp_point) * 3); + XMEMSET(t, 0, sizeof(sp_point_256) * 3); XFREE(t, heap, DYNAMIC_TYPE_ECC); } #else @@ -14002,10 +14037,10 @@ static int sp_256_ecc_mulmod_5(sp_point* r, const sp_point* g, const sp_digit* k #else /* A table entry for pre-computed points. */ -typedef struct sp_table_entry { +typedef struct sp_table_entry_256 { sp_digit x[5]; sp_digit y[5]; -} sp_table_entry; +} sp_table_entry_256; /* Multiply the point by the scalar and return the result. * If map is true then convert result to affine coordinates. @@ -14017,16 +14052,16 @@ typedef struct sp_table_entry { * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_fast_5(sp_point* r, const sp_point* g, const sp_digit* k, +static int sp_256_ecc_mulmod_fast_5(sp_point_256* r, const sp_point_256* g, const sp_digit* k, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point td[16]; - sp_point rtd; + sp_point_256 td[16]; + sp_point_256 rtd; sp_digit tmpd[2 * 5 * 5]; #endif - sp_point* t; - sp_point* rt; + sp_point_256* t; + sp_point_256* rt; sp_digit* tmp; sp_digit n; int i; @@ -14035,9 +14070,9 @@ static int sp_256_ecc_mulmod_fast_5(sp_point* r, const sp_point* g, const sp_dig (void)heap; - err = sp_ecc_point_new(heap, rtd, rt); + err = sp_256_point_new_5(heap, rtd, rt); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - t = (sp_point*)XMALLOC(sizeof(sp_point) * 16, heap, DYNAMIC_TYPE_ECC); + t = (sp_point_256*)XMALLOC(sizeof(sp_point_256) * 16, heap, DYNAMIC_TYPE_ECC); if (t == NULL) err = MEMORY_E; tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 5 * 5, heap, @@ -14091,7 +14126,7 @@ static int sp_256_ecc_mulmod_fast_5(sp_point* r, const sp_point* g, const sp_dig n = k[i+1] << 12; c = 44; y = n >> 56; - XMEMCPY(rt, &t[y], sizeof(sp_point)); + XMEMCPY(rt, &t[y], sizeof(sp_point_256)); n <<= 8; for (; i>=0 || c>=4; ) { if (c < 4) { @@ -14114,7 +14149,7 @@ static int sp_256_ecc_mulmod_fast_5(sp_point* r, const sp_point* g, const sp_dig sp_256_map_5(r, rt, tmp); } else { - XMEMCPY(r, rt, sizeof(sp_point)); + XMEMCPY(r, rt, sizeof(sp_point_256)); } } @@ -14124,14 +14159,14 @@ static int sp_256_ecc_mulmod_fast_5(sp_point* r, const sp_point* g, const sp_dig XFREE(tmp, heap, DYNAMIC_TYPE_ECC); } if (t != NULL) { - XMEMSET(t, 0, sizeof(sp_point) * 16); + XMEMSET(t, 0, sizeof(sp_point_256) * 16); XFREE(t, heap, DYNAMIC_TYPE_ECC); } #else ForceZero(tmpd, sizeof(tmpd)); ForceZero(td, sizeof(td)); #endif - sp_ecc_point_free(rt, 1, heap); + sp_256_point_free_5(rt, 1, heap); return err; } @@ -14144,10 +14179,10 @@ static int sp_256_ecc_mulmod_fast_5(sp_point* r, const sp_point* g, const sp_dig * n Number of times to double * t Temporary ordinate data. */ -static void sp_256_proj_point_dbl_n_5(sp_point* r, const sp_point* p, int n, +static void sp_256_proj_point_dbl_n_5(sp_point_256* r, const sp_point_256* p, int n, sp_digit* t) { - sp_point* rp[2]; + sp_point_256* rp[2]; sp_digit* w = t; sp_digit* a = t + 2*5; sp_digit* b = t + 4*5; @@ -14161,8 +14196,8 @@ static void sp_256_proj_point_dbl_n_5(sp_point* r, const sp_point* p, int n, rp[0] = r; /*lint allow cast to different type of pointer*/ - rp[1] = (sp_point*)t; /*lint !e9087 !e740*/ - XMEMSET(rp[1], 0, sizeof(sp_point)); + rp[1] = (sp_point_256*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_256)); x = rp[p->infinity]->x; y = rp[p->infinity]->y; z = rp[p->infinity]->z; @@ -14224,11 +14259,11 @@ static void sp_256_proj_point_dbl_n_5(sp_point* r, const sp_point* p, int n, * q Second point to add. * t Temporary ordinate data. */ -static void sp_256_proj_point_add_qz1_5(sp_point* r, const sp_point* p, - const sp_point* q, sp_digit* t) +static void sp_256_proj_point_add_qz1_5(sp_point_256* r, const sp_point_256* p, + const sp_point_256* q, sp_digit* t) { - const sp_point* ap[2]; - sp_point* rp[2]; + const sp_point_256* ap[2]; + sp_point_256* rp[2]; sp_digit* t1 = t; sp_digit* t2 = t + 2*5; sp_digit* t3 = t + 4*5; @@ -14250,8 +14285,8 @@ static void sp_256_proj_point_add_qz1_5(sp_point* r, const sp_point* p, rp[0] = r; /*lint allow cast to different type of pointer*/ - rp[1] = (sp_point*)t; /*lint !e9087 !e740*/ - XMEMSET(rp[1], 0, sizeof(sp_point)); + rp[1] = (sp_point_256*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_256)); x = rp[p->infinity | q->infinity]->x; y = rp[p->infinity | q->infinity]->y; z = rp[p->infinity | q->infinity]->z; @@ -14304,7 +14339,7 @@ static void sp_256_proj_point_add_qz1_5(sp_point* r, const sp_point* p, * a Point to convert. * t Temporary data. */ -static void sp_256_proj_to_affine_5(sp_point* a, sp_digit* t) +static void sp_256_proj_to_affine_5(sp_point_256* a, sp_digit* t) { sp_digit* t1 = t; sp_digit* t2 = t + 2 * 5; @@ -14327,26 +14362,26 @@ static void sp_256_proj_to_affine_5(sp_point* a, sp_digit* t) * tmp Temporary data. * heap Heap to use for allocation. */ -static int sp_256_gen_stripe_table_5(const sp_point* a, - sp_table_entry* table, sp_digit* tmp, void* heap) +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) - sp_point td, s1d, s2d; + sp_point_256 td, s1d, s2d; #endif - sp_point* t; - sp_point* s1 = NULL; - sp_point* s2 = NULL; + sp_point_256* t; + sp_point_256* s1 = NULL; + sp_point_256* s2 = NULL; int i, j; int err; (void)heap; - err = sp_ecc_point_new(heap, td, t); + err = sp_256_point_new_5(heap, td, t); if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, s1d, s1); + err = sp_256_point_new_5(heap, s1d, s1); } if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, s2d, s2); + err = sp_256_point_new_5(heap, s2d, s2); } if (err == MP_OKAY) { @@ -14368,7 +14403,7 @@ static int sp_256_gen_stripe_table_5(const sp_point* a, s2->infinity = 0; /* table[0] = {0, 0, infinity} */ - XMEMSET(&table[0], 0, sizeof(sp_table_entry)); + XMEMSET(&table[0], 0, sizeof(sp_table_entry_256)); /* 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)); @@ -14394,9 +14429,9 @@ static int sp_256_gen_stripe_table_5(const sp_point* a, } } - sp_ecc_point_free(s2, 0, heap); - sp_ecc_point_free(s1, 0, heap); - sp_ecc_point_free( t, 0, heap); + sp_256_point_free_5(s2, 0, heap); + sp_256_point_free_5(s1, 0, heap); + sp_256_point_free_5( t, 0, heap); return err; } @@ -14411,16 +14446,16 @@ static int sp_256_gen_stripe_table_5(const sp_point* a, * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_stripe_5(sp_point* r, const sp_point* g, - const sp_table_entry* table, const sp_digit* k, int map, void* heap) +static int sp_256_ecc_mulmod_stripe_5(sp_point_256* r, const sp_point_256* g, + const sp_table_entry_256* table, const sp_digit* k, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point rtd; - sp_point pd; + sp_point_256 rtd; + sp_point_256 pd; sp_digit td[2 * 5 * 5]; #endif - sp_point* rt; - sp_point* p = NULL; + sp_point_256* rt; + sp_point_256* p = NULL; sp_digit* t; int i, j; int y, x; @@ -14429,9 +14464,10 @@ static int sp_256_ecc_mulmod_stripe_5(sp_point* r, const sp_point* g, (void)g; (void)heap; - err = sp_ecc_point_new(heap, rtd, rt); + + err = sp_256_point_new_5(heap, rtd, rt); if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, pd, p); + err = sp_256_point_new_5(heap, pd, p); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 5 * 5, heap, @@ -14471,7 +14507,7 @@ static int sp_256_ecc_mulmod_stripe_5(sp_point* r, const sp_point* g, sp_256_map_5(r, rt, t); } else { - XMEMCPY(r, rt, sizeof(sp_point)); + XMEMCPY(r, rt, sizeof(sp_point_256)); } } @@ -14480,8 +14516,8 @@ static int sp_256_ecc_mulmod_stripe_5(sp_point* r, const sp_point* g, XFREE(t, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(p, 0, heap); - sp_ecc_point_free(rt, 0, heap); + sp_256_point_free_5(p, 0, heap); + sp_256_point_free_5(rt, 0, heap); return err; } @@ -14491,43 +14527,43 @@ static int sp_256_ecc_mulmod_stripe_5(sp_point* r, const sp_point* g, #define FP_ENTRIES 16 #endif -typedef struct sp_cache_t { +typedef struct sp_cache_256_t { sp_digit x[5]; sp_digit y[5]; - sp_table_entry table[256]; + sp_table_entry_256 table[256]; uint32_t cnt; int set; -} sp_cache_t; +} sp_cache_256_t; -static THREAD_LS_T sp_cache_t sp_cache[FP_ENTRIES]; -static THREAD_LS_T int sp_cache_last = -1; -static THREAD_LS_T int sp_cache_inited = 0; +static THREAD_LS_T sp_cache_256_t sp_cache_256[FP_ENTRIES]; +static THREAD_LS_T int sp_cache_256_last = -1; +static THREAD_LS_T int sp_cache_256_inited = 0; #ifndef HAVE_THREAD_LS - static volatile int initCacheMutex = 0; - static wolfSSL_Mutex sp_cache_lock; + static volatile int initCacheMutex_256 = 0; + static wolfSSL_Mutex sp_cache_256_lock; #endif -static void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache) +static void sp_ecc_get_cache_256(const sp_point_256* g, sp_cache_256_t** cache) { int i, j; uint32_t least; - if (sp_cache_inited == 0) { + if (sp_cache_256_inited == 0) { for (i=0; ix, sp_cache[i].x) & - sp_256_cmp_equal_5(g->y, sp_cache[i].y)) { - sp_cache[i].cnt++; + if (sp_256_cmp_equal_5(g->x, sp_cache_256[i].x) & + sp_256_cmp_equal_5(g->y, sp_cache_256[i].y)) { + sp_cache_256[i].cnt++; break; } } @@ -14535,32 +14571,32 @@ static void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache) /* No match. */ if (i == FP_ENTRIES) { /* Find empty entry. */ - i = (sp_cache_last + 1) % FP_ENTRIES; - for (; i != sp_cache_last; i=(i+1)%FP_ENTRIES) { - if (!sp_cache[i].set) { + i = (sp_cache_256_last + 1) % FP_ENTRIES; + for (; i != sp_cache_256_last; i=(i+1)%FP_ENTRIES) { + if (!sp_cache_256[i].set) { break; } } /* Evict least used. */ - if (i == sp_cache_last) { - least = sp_cache[0].cnt; + if (i == sp_cache_256_last) { + least = sp_cache_256[0].cnt; for (j=1; jx, sizeof(sp_cache[i].x)); - XMEMCPY(sp_cache[i].y, g->y, sizeof(sp_cache[i].y)); - sp_cache[i].set = 1; - sp_cache[i].cnt = 1; + XMEMCPY(sp_cache_256[i].x, g->x, sizeof(sp_cache_256[i].x)); + XMEMCPY(sp_cache_256[i].y, g->y, sizeof(sp_cache_256[i].y)); + sp_cache_256[i].set = 1; + sp_cache_256[i].cnt = 1; } - *cache = &sp_cache[i]; - sp_cache_last = i; + *cache = &sp_cache_256[i]; + sp_cache_256_last = i; } #endif /* FP_ECC */ @@ -14574,32 +14610,32 @@ static void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache) * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_5(sp_point* r, const sp_point* g, const sp_digit* k, +static int sp_256_ecc_mulmod_5(sp_point_256* r, const sp_point_256* g, const sp_digit* k, int map, void* heap) { #ifndef FP_ECC return sp_256_ecc_mulmod_fast_5(r, g, k, map, heap); #else sp_digit tmp[2 * 5 * 5]; - sp_cache_t* cache; + sp_cache_256_t* cache; int err = MP_OKAY; #ifndef HAVE_THREAD_LS - if (initCacheMutex == 0) { - wc_InitMutex(&sp_cache_lock); - initCacheMutex = 1; + if (initCacheMutex_256 == 0) { + wc_InitMutex(&sp_cache_256_lock); + initCacheMutex_256 = 1; } - if (wc_LockMutex(&sp_cache_lock) != 0) + if (wc_LockMutex(&sp_cache_256_lock) != 0) err = BAD_MUTEX_E; #endif /* HAVE_THREAD_LS */ if (err == MP_OKAY) { - sp_ecc_get_cache(g, &cache); + sp_ecc_get_cache_256(g, &cache); if (cache->cnt == 2) sp_256_gen_stripe_table_5(g, cache->table, tmp, heap); #ifndef HAVE_THREAD_LS - wc_UnLockMutex(&sp_cache_lock); + wc_UnLockMutex(&sp_cache_256_lock); #endif /* HAVE_THREAD_LS */ if (cache->cnt < 2) { @@ -14630,15 +14666,14 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point p; - sp_digit k[5]; -#else - sp_digit* k = NULL; + sp_point_256 p; + sp_digit kd[5]; #endif - sp_point* point; - int err; + sp_point_256* point; + sp_digit* k = NULL; + int err = MP_OKAY; - err = sp_ecc_point_new(heap, p, point); + err = sp_256_point_new_5(heap, p, point); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 5, heap, @@ -14646,6 +14681,8 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, if (k == NULL) err = MEMORY_E; } +#else + k = kd; #endif if (err == MP_OKAY) { sp_256_from_mp(k, 5, km); @@ -14662,7 +14699,7 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, XFREE(k, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(point, 0, heap); + sp_256_point_free_5(point, 0, heap); return err; } @@ -14677,7 +14714,7 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_base_5(sp_point* r, const sp_digit* k, +static int sp_256_ecc_mulmod_base_5(sp_point_256* r, const sp_digit* k, int map, void* heap) { /* No pre-computed values. */ @@ -14685,7 +14722,7 @@ static int sp_256_ecc_mulmod_base_5(sp_point* r, const sp_digit* k, } #else -static const sp_table_entry p256_table[256] = { +static const sp_table_entry_256 p256_table[256] = { /* 0 */ { { 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00 } }, @@ -15975,7 +16012,7 @@ static const sp_table_entry p256_table[256] = { * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_base_5(sp_point* r, const sp_digit* k, +static int sp_256_ecc_mulmod_base_5(sp_point_256* r, const sp_digit* k, int map, void* heap) { return sp_256_ecc_mulmod_stripe_5(r, &p256_base, p256_table, @@ -15996,15 +16033,14 @@ static int sp_256_ecc_mulmod_base_5(sp_point* r, const sp_digit* k, int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point p; - sp_digit k[5]; -#else - sp_digit* k = NULL; + sp_point_256 p; + sp_digit kd[5]; #endif - sp_point* point; - int err; + sp_point_256* point; + sp_digit* k = NULL; + int err = MP_OKAY; - err = sp_ecc_point_new(heap, p, point); + err = sp_256_point_new_5(heap, p, point); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 5, heap, @@ -16013,6 +16049,8 @@ int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) err = MEMORY_E; } } +#else + k = kd; #endif if (err == MP_OKAY) { sp_256_from_mp(k, 5, km); @@ -16028,7 +16066,7 @@ int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) XFREE(k, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(point, 0, heap); + sp_256_point_free_5(point, 0, heap); return err; } @@ -16131,26 +16169,25 @@ static int sp_256_ecc_gen_k_5(WC_RNG* rng, sp_digit* k) int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point p; - sp_digit k[5]; + sp_point_256 p; + sp_digit kd[5]; #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN - sp_point inf; + sp_point_256 inf; #endif -#else +#endif + sp_point_256* point; sp_digit* k = NULL; -#endif - sp_point* point; #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN - sp_point* infinity; + sp_point_256* infinity; #endif int err; (void)heap; - err = sp_ecc_point_new(heap, p, point); + err = sp_256_point_new_5(heap, p, point); #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, inf, infinity); + err = sp_256_point_new_5(heap, inf, infinity); } #endif #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) @@ -16161,6 +16198,8 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) err = MEMORY_E; } } +#else + k = kd; #endif if (err == MP_OKAY) { @@ -16194,9 +16233,9 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) } #endif #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN - sp_ecc_point_free(infinity, 1, heap); + sp_256_point_free_5(infinity, 1, heap); #endif - sp_ecc_point_free(point, 1, heap); + sp_256_point_free_5(point, 1, heap); return err; } @@ -16257,12 +16296,11 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, word32* outLen, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point p; - sp_digit k[5]; -#else - sp_digit* k = NULL; + sp_point_256 p; + sp_digit kd[5]; #endif - sp_point* point = NULL; + sp_point_256* point = NULL; + sp_digit* k = NULL; int err = MP_OKAY; if (*outLen < 32U) { @@ -16270,7 +16308,7 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, } if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, p, point); + err = sp_256_point_new_5(heap, p, point); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { @@ -16279,6 +16317,8 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, if (k == NULL) err = MEMORY_E; } +#else + k = kd; #endif if (err == MP_OKAY) { @@ -16296,7 +16336,7 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, XFREE(k, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(point, 0, heap); + sp_256_point_free_5(point, 0, heap); return err; } @@ -16500,7 +16540,7 @@ static int sp_256_mod_5(sp_digit* r, const sp_digit* a, const sp_digit* m) #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) #ifdef WOLFSSL_SP_SMALL /* Order-2 for the P256 curve. */ -static const uint64_t p256_order_2[4] = { +static const uint64_t p256_order_minus_2[4] = { 0xf3b9cac2fc63254fU,0xbce6faada7179e84U,0xffffffffffffffffU, 0xffffffff00000000U }; @@ -16569,7 +16609,7 @@ static void sp_256_mont_inv_order_5(sp_digit* r, const sp_digit* a, XMEMCPY(t, a, sizeof(sp_digit) * 5); for (i=254; i>=0; i--) { sp_256_mont_sqr_order_5(t, t); - if ((p256_order_2[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) { + if ((p256_order_minus_2[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) { sp_256_mont_mul_order_5(t, t, a); } } @@ -16685,24 +16725,24 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_digit kd[2*5]; sp_digit rd[2*5]; sp_digit td[3 * 2*5]; - sp_point p; + sp_point_256 p; #endif sp_digit* e = NULL; sp_digit* x = NULL; sp_digit* k = NULL; sp_digit* r = NULL; sp_digit* tmp = NULL; - sp_point* point = NULL; + sp_point_256* point = NULL; sp_digit carry; sp_digit* s = NULL; sp_digit* kInv = NULL; - int err; + int err = MP_OKAY; int64_t c; int i; (void)heap; - err = sp_ecc_point_new(heap, p, point); + err = sp_256_point_new_5(heap, p, point); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7 * 2 * 5, heap, @@ -16818,7 +16858,7 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, XMEMSET(r, 0, sizeof(sp_digit) * 2U * 5U); XMEMSET(tmp, 0, sizeof(sp_digit) * 3U * 2U * 5U); #endif - sp_ecc_point_free(point, 1, heap); + sp_256_point_free_5(point, 1, heap); return err; } @@ -16855,22 +16895,22 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, sp_digit u2d[2*5]; sp_digit sd[2*5]; sp_digit tmpd[2*5 * 5]; - sp_point p1d; - sp_point p2d; + sp_point_256 p1d; + sp_point_256 p2d; #endif sp_digit* u1 = NULL; sp_digit* u2 = NULL; sp_digit* s = NULL; sp_digit* tmp = NULL; - sp_point* p1; - sp_point* p2 = NULL; + sp_point_256* p1; + sp_point_256* p2 = NULL; sp_digit carry; int64_t c; int err; - err = sp_ecc_point_new(heap, p1d, p1); + err = sp_256_point_new_5(heap, p1d, p1); if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, p2d, p2); + err = sp_256_point_new_5(heap, p2d, p2); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { @@ -16983,8 +17023,8 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, if (d != NULL) XFREE(d, heap, DYNAMIC_TYPE_ECC); #endif - sp_ecc_point_free(p1, 0, heap); - sp_ecc_point_free(p2, 0, heap); + sp_256_point_free_5(p1, 0, heap); + sp_256_point_free_5(p2, 0, heap); return err; } @@ -16998,10 +17038,10 @@ 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* point, void* heap) +static int sp_256_ecc_is_point_5(sp_point_256* point, void* heap) { #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - sp_digit* d; + sp_digit* d = NULL; #else sp_digit t1d[2*5]; sp_digit t2d[2*5]; @@ -17065,13 +17105,13 @@ static int sp_256_ecc_is_point_5(sp_point* point, void* heap) int sp_ecc_is_point_256(mp_int* pX, mp_int* pY) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point pubd; + sp_point_256 pubd; #endif - sp_point* pub; + sp_point_256* pub; byte one[1] = { 1 }; int err; - err = sp_ecc_point_new(NULL, pubd, pub); + err = sp_256_point_new_5(NULL, pubd, pub); if (err == MP_OKAY) { sp_256_from_mp(pub->x, 5, pX); sp_256_from_mp(pub->y, 5, pY); @@ -17080,7 +17120,7 @@ int sp_ecc_is_point_256(mp_int* pX, mp_int* pY) err = sp_256_ecc_is_point_5(pub, NULL); } - sp_ecc_point_free(pub, 0, NULL); + sp_256_point_free_5(pub, 0, NULL); return err; } @@ -17100,18 +17140,18 @@ int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_digit privd[5]; - sp_point pubd; - sp_point pd; + sp_point_256 pubd; + sp_point_256 pd; #endif sp_digit* priv = NULL; - sp_point* pub; - sp_point* p = NULL; + sp_point_256* pub; + sp_point_256* p = NULL; byte one[1] = { 1 }; int err; - err = sp_ecc_point_new(heap, pubd, pub); + err = sp_256_point_new_5(heap, pubd, pub); if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, pd, p); + err = sp_256_point_new_5(heap, pd, p); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { @@ -17182,8 +17222,8 @@ int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) XFREE(priv, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(p, 0, heap); - sp_ecc_point_free(pub, 0, heap); + sp_256_point_free_5(p, 0, heap); + sp_256_point_free_5(pub, 0, heap); return err; } @@ -17209,17 +17249,17 @@ int sp_ecc_proj_add_point_256(mp_int* pX, mp_int* pY, mp_int* pZ, { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_digit tmpd[2 * 5 * 5]; - sp_point pd; - sp_point qd; + sp_point_256 pd; + sp_point_256 qd; #endif sp_digit* tmp; - sp_point* p; - sp_point* q = NULL; + sp_point_256* p; + sp_point_256* q = NULL; int err; - err = sp_ecc_point_new(NULL, pd, p); + err = sp_256_point_new_5(NULL, pd, p); if (err == MP_OKAY) { - err = sp_ecc_point_new(NULL, qd, q); + err = sp_256_point_new_5(NULL, qd, q); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { @@ -17259,8 +17299,8 @@ int sp_ecc_proj_add_point_256(mp_int* pX, mp_int* pY, mp_int* pZ, XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(q, 0, NULL); - sp_ecc_point_free(p, 0, NULL); + sp_256_point_free_5(q, 0, NULL); + sp_256_point_free_5(p, 0, NULL); return err; } @@ -17281,13 +17321,13 @@ int sp_ecc_proj_dbl_point_256(mp_int* pX, mp_int* pY, mp_int* pZ, { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_digit tmpd[2 * 5 * 2]; - sp_point pd; + sp_point_256 pd; #endif sp_digit* tmp; - sp_point* p; + sp_point_256* p; int err; - err = sp_ecc_point_new(NULL, pd, p); + err = sp_256_point_new_5(NULL, pd, p); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 5 * 2, NULL, @@ -17323,7 +17363,7 @@ int sp_ecc_proj_dbl_point_256(mp_int* pX, mp_int* pY, mp_int* pZ, XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(p, 0, NULL); + sp_256_point_free_5(p, 0, NULL); return err; } @@ -17340,13 +17380,13 @@ int sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_digit tmpd[2 * 5 * 4]; - sp_point pd; + sp_point_256 pd; #endif sp_digit* tmp; - sp_point* p; + sp_point_256* p; int err; - err = sp_ecc_point_new(NULL, pd, p); + err = sp_256_point_new_5(NULL, pd, p); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 5 * 4, NULL, @@ -17381,7 +17421,7 @@ int sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ) XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(p, 0, NULL); + sp_256_point_free_5(p, 0, NULL); return err; } @@ -17462,6 +17502,7 @@ static int sp_256_mont_sqrt_5(sp_digit* y) return err; } + /* Uncompress the point given the X ordinate. * * xm X ordinate. @@ -17538,6 +17579,5720 @@ int sp_ecc_uncompress_256(mp_int* xm, int odd, mp_int* ym) } #endif #endif /* !WOLFSSL_SP_NO_256 */ +#ifdef WOLFSSL_SP_384 + +/* Point structure to use. */ +typedef struct sp_point_384 { + sp_digit x[2 * 7]; + sp_digit y[2 * 7]; + sp_digit z[2 * 7]; + int infinity; +} sp_point_384; + +/* The modulus (prime) of the curve P384. */ +static const sp_digit p384_mod[7] = { + 0x000000ffffffffL,0x7ffe0000000000L,0x7ffffffffbffffL,0x7fffffffffffffL, + 0x7fffffffffffffL,0x7fffffffffffffL,0x3fffffffffffffL +}; +/* The Montogmery normalizer for modulus of the curve P384. */ +static const sp_digit p384_norm_mod[7] = { + 0x7fffff00000001L,0x0001ffffffffffL,0x00000000040000L,0x00000000000000L, + 0x00000000000000L,0x00000000000000L,0x00000000000000L +}; +/* The Montogmery multiplier for modulus of the curve P384. */ +static sp_digit p384_mp_mod = 0x0000100000001; +#if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \ + defined(HAVE_ECC_VERIFY) +/* The order of the curve P384. */ +static const sp_digit p384_order[7] = { + 0x6c196accc52973L,0x1b6491614ef5d9L,0x07d0dcb77d6068L,0x7ffffffe3b1a6cL, + 0x7fffffffffffffL,0x7fffffffffffffL,0x3fffffffffffffL +}; +#endif +/* The order of the curve P384 minus 2. */ +static const sp_digit p384_order2[7] = { + 0x6c196accc52971L,0x1b6491614ef5d9L,0x07d0dcb77d6068L,0x7ffffffe3b1a6cL, + 0x7fffffffffffffL,0x7fffffffffffffL,0x3fffffffffffffL +}; +#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[7] = { + 0x13e695333ad68dL,0x649b6e9eb10a26L,0x782f2348829f97L,0x00000001c4e593L, + 0x00000000000000L,0x00000000000000L,0x00000000000000L +}; +#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; +#endif +/* The base point of curve P384. */ +static const sp_point_384 p384_base = { + /* X ordinate */ + { + 0x545e3872760ab7L,0x64bb7eaa52d874L,0x020950a8e1540bL, + 0x5d3cdcc2cfba0fL,0x0ad746e1d3b628L,0x26f1d638e3de64L,0x2aa1f288afa2c1L, + 0L, 0L, 0L, 0L, 0L, 0L, 0L + }, + /* Y ordinate */ + { + 0x431d7c90ea0e5fL,0x639c3afd033af4L,0x4ed7c2e3002982L, + 0x44d0a3e74ed188L,0x2dc29f8f41dbd2L,0x0debb3d317f252L,0x0d85f792a5898bL, + 0L, 0L, 0L, 0L, 0L, 0L, 0L + }, + /* Z ordinate */ + { + 0x00000000000001L,0x00000000000000L,0x00000000000000L, + 0x00000000000000L,0x00000000000000L,0x00000000000000L,0x00000000000000L, + 0L, 0L, 0L, 0L, 0L, 0L, 0L + }, + /* infinity */ + 0 +}; +#if defined(HAVE_ECC_CHECK_KEY) || defined(HAVE_COMP_KEY) +static const sp_digit p384_b[7] = { + 0x05c8edd3ec2aefL,0x731b145da33a55L,0x3d404e1d6b1958L,0x740a089018a044L, + 0x02d19181d9c6efL,0x7c9311c0ad7c7fL,0x2ccc4be9f88fb9L +}; +#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) + (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) +/* 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) +/* 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) + 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) + 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) + 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] |= a[1] << 23U; + a32[1] &= 0xffffffffL; + a32[2] = (sp_digit)(a[1] >> 9U) & 0xffffffffL; + a32[3] = (sp_digit)(a[1] >> 41U); + a32[3] |= a[2] << 14U; + a32[3] &= 0xffffffffL; + a32[4] = (sp_digit)(a[2] >> 18U) & 0xffffffffL; + a32[5] = (sp_digit)(a[2] >> 50U); + a32[5] |= a[3] << 5U; + a32[5] &= 0xffffffffL; + a32[6] = (sp_digit)(a[3] >> 27U); + a32[6] |= a[4] << 28U; + a32[6] &= 0xffffffffL; + a32[7] = (sp_digit)(a[4] >> 4U) & 0xffffffffL; + a32[8] = (sp_digit)(a[4] >> 36U); + a32[8] |= a[5] << 19U; + a32[8] &= 0xffffffffL; + a32[9] = (sp_digit)(a[5] >> 13U) & 0xffffffffL; + a32[10] = (sp_digit)(a[5] >> 45U); + a32[10] |= 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) + 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] |= a[i] << s; + r->dp[j] &= (1L << DIGIT_BIT) - 1; + s = DIGIT_BIT - s; + r->dp[++j] = 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] = 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) + * + * r A single precision integer. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static void sp_384_mul_7(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + int i, j, k; + int128_t c; + + c = ((int128_t)a[6]) * b[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) { + break; + } + if (j < 0) { + continue; + } + + c += ((int128_t)a[i]) * b[j]; + } + r[k + 2] += c >> 110; + r[k + 1] = (c >> 55) & 0x7fffffffffffffL; + c = (c & 0x7fffffffffffffL) << 55; + } + r[0] = (sp_digit)(c >> 55); +} + +#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_384_mul_7(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[ 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 t8 = ((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 t9 = ((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 t10 = ((int128_t)a[ 4]) * b[ 6] + + ((int128_t)a[ 5]) * b[ 5] + + ((int128_t)a[ 6]) * b[ 4]; + int128_t t11 = ((int128_t)a[ 5]) * b[ 6] + + ((int128_t)a[ 6]) * b[ 5]; + int128_t t12 = ((int128_t)a[ 6]) * b[ 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 */ +#define sp_384_mont_reduce_order_7 sp_384_mont_reduce_7 + +/* 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_384_cmp_7(const sp_digit* a, const sp_digit* b) +{ + sp_digit r = 0; +#ifdef WOLFSSL_SP_SMALL + int i; + + for (i=6; i>=0; i--) { + r |= (a[i] - b[i]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + } +#else + r |= (a[ 6] - b[ 6]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[ 5] - b[ 5]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[ 4] - b[ 4]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[ 3] - b[ 3]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[ 2] - b[ 2]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[ 1] - b[ 1]) & (0 - ((r == 0) ? (sp_digit)1 : (sp_digit)0)); + r |= (a[ 0] - b[ 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_384_cond_sub_7(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 < 7; i++) { + r[i] = a[i] - (b[i] & m); + } +#else + r[ 0] = a[ 0] - (b[ 0] & m); + r[ 1] = a[ 1] - (b[ 1] & m); + r[ 2] = a[ 2] - (b[ 2] & m); + r[ 3] = a[ 3] - (b[ 3] & m); + r[ 4] = a[ 4] - (b[ 4] & m); + r[ 5] = a[ 5] - (b[ 5] & m); + r[ 6] = a[ 6] - (b[ 6] & 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_384_mul_add_7(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 < 7; i++) { + t += (tb * a[i]) + r[i]; + r[i] = t & 0x7fffffffffffffL; + t >>= 55; + } + r[7] += t; +#else + int128_t tb = b; + int128_t t[7]; + + t[ 0] = tb * a[ 0]; + t[ 1] = tb * a[ 1]; + t[ 2] = tb * a[ 2]; + t[ 3] = tb * a[ 3]; + t[ 4] = tb * a[ 4]; + t[ 5] = tb * a[ 5]; + t[ 6] = tb * a[ 6]; + r[ 0] += (sp_digit)(t[ 0] & 0x7fffffffffffffL); + r[ 1] += (sp_digit)((t[ 0] >> 55) + (t[ 1] & 0x7fffffffffffffL)); + r[ 2] += (sp_digit)((t[ 1] >> 55) + (t[ 2] & 0x7fffffffffffffL)); + r[ 3] += (sp_digit)((t[ 2] >> 55) + (t[ 3] & 0x7fffffffffffffL)); + r[ 4] += (sp_digit)((t[ 3] >> 55) + (t[ 4] & 0x7fffffffffffffL)); + r[ 5] += (sp_digit)((t[ 4] >> 55) + (t[ 5] & 0x7fffffffffffffL)); + r[ 6] += (sp_digit)((t[ 5] >> 55) + (t[ 6] & 0x7fffffffffffffL)); + r[ 7] += t[ 6] >> 55; +#endif /* WOLFSSL_SP_SMALL */ +} + +/* Normalize the values in each word to 55. + * + * a Array of sp_digit to normalize. + */ +static void sp_384_norm_7(sp_digit* a) +{ +#ifdef WOLFSSL_SP_SMALL + int i; + for (i = 0; i < 6; i++) { + a[i+1] += a[i] >> 55; + a[i] &= 0x7fffffffffffffL; + } +#else + a[1] += a[0] >> 55; a[0] &= 0x7fffffffffffffL; + a[2] += a[1] >> 55; a[1] &= 0x7fffffffffffffL; + a[3] += a[2] >> 55; a[2] &= 0x7fffffffffffffL; + a[4] += a[3] >> 55; a[3] &= 0x7fffffffffffffL; + a[5] += a[4] >> 55; a[4] &= 0x7fffffffffffffL; + a[6] += a[5] >> 55; a[5] &= 0x7fffffffffffffL; +#endif +} + +/* Shift the result in the high 384 bits down to the bottom. + * + * r A single precision number. + * a A single precision number. + */ +static void sp_384_mont_shift_7(sp_digit* r, const sp_digit* a) +{ +#ifdef WOLFSSL_SP_SMALL + int i; + word64 n; + + n = a[6] >> 54; + for (i = 0; i < 6; i++) { + n += (word64)a[7 + i] << 1; + r[i] = n & 0x7fffffffffffffL; + n >>= 55; + } + n += (word64)a[13] << 1; + r[6] = n; +#else + word64 n; + + n = a[6] >> 54; + n += (word64)a[ 7] << 1U; r[ 0] = n & 0x7fffffffffffffUL; n >>= 55U; + n += (word64)a[ 8] << 1U; r[ 1] = n & 0x7fffffffffffffUL; n >>= 55U; + n += (word64)a[ 9] << 1U; r[ 2] = n & 0x7fffffffffffffUL; n >>= 55U; + n += (word64)a[10] << 1U; r[ 3] = n & 0x7fffffffffffffUL; n >>= 55U; + n += (word64)a[11] << 1U; r[ 4] = n & 0x7fffffffffffffUL; n >>= 55U; + n += (word64)a[12] << 1U; r[ 5] = n & 0x7fffffffffffffUL; n >>= 55U; + n += (word64)a[13] << 1U; r[ 6] = n; +#endif /* WOLFSSL_SP_SMALL */ + XMEMSET(&r[7], 0, sizeof(*r) * 7U); +} + +/* 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. + */ +static void sp_384_mont_reduce_7(sp_digit* a, const sp_digit* m, sp_digit mp) +{ + int i; + sp_digit mu; + + sp_384_norm_7(a + 7); + + for (i=0; i<6; i++) { + mu = (a[i] * mp) & 0x7fffffffffffffL; + sp_384_mul_add_7(a+i, m, mu); + a[i+1] += a[i] >> 55; + } + mu = (a[i] * mp) & 0x3fffffffffffffL; + 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)); + sp_384_norm_7(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_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] += c >> 110; + r[k + 1] = (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. + * a Number to square in Montogmery form. + * 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) +{ + sp_384_sqr_7(r, a); + sp_384_mont_reduce_7(r, m, mp); +} + +#if !defined(WOLFSSL_SP_SMALL) || defined(HAVE_COMP_KEY) +/* Square the Montgomery form number a number of times. (r = a ^ n mod m) + * + * r Result of squaring. + * a Number to square in Montogmery form. + * n Number of times to square. + * m Modulus (prime). + * mp Montogmery mulitplier. + */ +static void sp_384_mont_sqr_n_7(sp_digit* r, const sp_digit* a, int n, + const sp_digit* m, sp_digit mp) +{ + sp_384_mont_sqr_7(r, a, m, mp); + for (; n > 1; n--) { + sp_384_mont_sqr_7(r, r, m, mp); + } +} + +#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] = { + 0x00000000fffffffdU,0xffffffff00000000U,0xfffffffffffffffeU, + 0xffffffffffffffffU,0xffffffffffffffffU,0xffffffffffffffffU +}; +#endif /* !WOLFSSL_SP_SMALL */ + +/* Invert the number, in Montgomery form, modulo the modulus (prime) of the + * P384 curve. (r = 1 / a mod m) + * + * r Inverse result. + * a Number to invert. + * td Temporary data. + */ +static void sp_384_mont_inv_7(sp_digit* r, const sp_digit* a, sp_digit* td) +{ +#ifdef WOLFSSL_SP_SMALL + sp_digit* t = td; + int i; + + XMEMCPY(t, a, sizeof(sp_digit) * 7); + for (i=382; i>=0; i--) { + sp_384_mont_sqr_7(t, t, p384_mod, p384_mp_mod); + if (p384_mod_minus_2[i / 64] & ((sp_digit)1 << (i % 64))) + sp_384_mont_mul_7(t, t, a, p384_mod, p384_mp_mod); + } + XMEMCPY(r, t, sizeof(sp_digit) * 7); +#else + sp_digit* t1 = td; + sp_digit* t2 = td + 2 * 7; + sp_digit* t3 = td + 4 * 7; + sp_digit* t4 = td + 6 * 7; + sp_digit* t5 = td + 8 * 7; + + /* 0x2 */ + sp_384_mont_sqr_7(t1, a, p384_mod, p384_mp_mod); + /* 0x3 */ + sp_384_mont_mul_7(t5, t1, a, p384_mod, p384_mp_mod); + /* 0xc */ + sp_384_mont_sqr_n_7(t1, t5, 2, p384_mod, p384_mp_mod); + /* 0xf */ + sp_384_mont_mul_7(t2, t5, t1, p384_mod, p384_mp_mod); + /* 0x1e */ + sp_384_mont_sqr_7(t1, t2, p384_mod, p384_mp_mod); + /* 0x1f */ + sp_384_mont_mul_7(t4, t1, a, p384_mod, p384_mp_mod); + /* 0x3e0 */ + sp_384_mont_sqr_n_7(t1, t4, 5, p384_mod, p384_mp_mod); + /* 0x3ff */ + sp_384_mont_mul_7(t2, t4, t1, p384_mod, p384_mp_mod); + /* 0x7fe0 */ + sp_384_mont_sqr_n_7(t1, t2, 5, p384_mod, p384_mp_mod); + /* 0x7fff */ + sp_384_mont_mul_7(t4, t4, t1, p384_mod, p384_mp_mod); + /* 0x3fff8000 */ + sp_384_mont_sqr_n_7(t1, t4, 15, p384_mod, p384_mp_mod); + /* 0x3fffffff */ + sp_384_mont_mul_7(t2, t4, t1, p384_mod, p384_mp_mod); + /* 0xfffffffc */ + sp_384_mont_sqr_n_7(t3, t2, 2, p384_mod, p384_mp_mod); + /* 0xfffffffd */ + sp_384_mont_mul_7(r, t3, a, p384_mod, p384_mp_mod); + /* 0xffffffff */ + sp_384_mont_mul_7(t3, t5, t3, p384_mod, p384_mp_mod); + /* 0xfffffffc0000000 */ + sp_384_mont_sqr_n_7(t1, t2, 30, p384_mod, p384_mp_mod); + /* 0xfffffffffffffff */ + sp_384_mont_mul_7(t2, t2, t1, p384_mod, p384_mp_mod); + /* 0xfffffffffffffff000000000000000 */ + sp_384_mont_sqr_n_7(t1, t2, 60, p384_mod, p384_mp_mod); + /* 0xffffffffffffffffffffffffffffff */ + sp_384_mont_mul_7(t2, t2, t1, p384_mod, p384_mp_mod); + /* 0xffffffffffffffffffffffffffffff000000000000000000000000000000 */ + sp_384_mont_sqr_n_7(t1, t2, 120, p384_mod, p384_mp_mod); + /* 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */ + sp_384_mont_mul_7(t2, t2, t1, p384_mod, p384_mp_mod); + /* 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000 */ + sp_384_mont_sqr_n_7(t1, t2, 15, p384_mod, p384_mp_mod); + /* 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */ + sp_384_mont_mul_7(t2, t4, t1, p384_mod, p384_mp_mod); + /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00000000 */ + sp_384_mont_sqr_n_7(t1, t2, 33, p384_mod, p384_mp_mod); + /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff */ + sp_384_mont_mul_7(t2, t3, t1, p384_mod, p384_mp_mod); + /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff000000000000000000000000 */ + sp_384_mont_sqr_n_7(t1, t2, 96, p384_mod, p384_mp_mod); + /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffd */ + sp_384_mont_mul_7(r, r, t1, p384_mod, p384_mp_mod); + +#endif /* WOLFSSL_SP_SMALL */ +} + +/* 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_7(sp_point_384* r, const sp_point_384* p, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2*7; + int64_t n; + + sp_384_mont_inv_7(t1, p->z, t + 2*7); + + sp_384_mont_sqr_7(t2, t1, p384_mod, p384_mp_mod); + sp_384_mont_mul_7(t1, t2, t1, p384_mod, p384_mp_mod); + + /* x /= z^2 */ + sp_384_mont_mul_7(r->x, p->x, t2, p384_mod, p384_mp_mod); + XMEMSET(r->x + 7, 0, sizeof(r->x) / 2U); + sp_384_mont_reduce_7(r->x, p384_mod, p384_mp_mod); + /* Reduce x to less than modulus */ + n = sp_384_cmp_7(r->x, p384_mod); + sp_384_cond_sub_7(r->x, r->x, p384_mod, 0 - ((n >= 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_384_norm_7(r->x); + + /* y /= z^3 */ + sp_384_mont_mul_7(r->y, p->y, t1, p384_mod, p384_mp_mod); + XMEMSET(r->y + 7, 0, sizeof(r->y) / 2U); + sp_384_mont_reduce_7(r->y, p384_mod, p384_mp_mod); + /* Reduce y to less than modulus */ + n = sp_384_cmp_7(r->y, p384_mod); + sp_384_cond_sub_7(r->y, r->y, p384_mod, 0 - ((n >= 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_384_norm_7(r->y); + + XMEMSET(r->z, 0, sizeof(r->z)); + r->z[0] = 1; + +} + +#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. + * a First number to add in Montogmery form. + * b Second number to add in Montogmery form. + * m Modulus (prime). + */ +static void sp_384_mont_add_7(sp_digit* r, const sp_digit* a, const sp_digit* b, + const sp_digit* m) +{ + (void)sp_384_add_7(r, a, b); + sp_384_norm_7(r); + sp_384_cond_sub_7(r, r, m, 0 - (((r[6] >> 54) > 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_384_norm_7(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_384_mont_dbl_7(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + (void)sp_384_add_7(r, a, a); + sp_384_norm_7(r); + sp_384_cond_sub_7(r, r, m, 0 - (((r[6] >> 54) > 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_384_norm_7(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_384_mont_tpl_7(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + (void)sp_384_add_7(r, a, a); + sp_384_norm_7(r); + sp_384_cond_sub_7(r, r, m, 0 - (((r[6] >> 54) > 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_384_norm_7(r); + (void)sp_384_add_7(r, r, a); + sp_384_norm_7(r); + sp_384_cond_sub_7(r, r, m, 0 - (((r[6] >> 54) > 0) ? + (sp_digit)1 : (sp_digit)0)); + 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. + * + * 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_384_cond_add_7(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 < 7; i++) { + r[i] = a[i] + (b[i] & m); + } +#else + r[ 0] = a[ 0] + (b[ 0] & m); + r[ 1] = a[ 1] + (b[ 1] & m); + r[ 2] = a[ 2] + (b[ 2] & m); + r[ 3] = a[ 3] + (b[ 3] & m); + r[ 4] = a[ 4] + (b[ 4] & m); + r[ 5] = a[ 5] + (b[ 5] & m); + r[ 6] = a[ 6] + (b[ 6] & m); +#endif /* WOLFSSL_SP_SMALL */ +} + +/* 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_384_mont_sub_7(sp_digit* r, const sp_digit* a, const sp_digit* b, + const sp_digit* m) +{ + (void)sp_384_sub_7(r, a, b); + sp_384_cond_add_7(r, r, m, r[6] >> 54); + sp_384_norm_7(r); +} + +/* Shift number left one bit. + * Bottom bit is lost. + * + * r Result of shift. + * a Number to shift. + */ +SP_NOINLINE static void sp_384_rshift1_7(sp_digit* r, 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; + } +#else + r[0] = ((a[0] >> 1) | (a[1] << 54)) & 0x7fffffffffffffL; + r[1] = ((a[1] >> 1) | (a[2] << 54)) & 0x7fffffffffffffL; + r[2] = ((a[2] >> 1) | (a[3] << 54)) & 0x7fffffffffffffL; + r[3] = ((a[3] >> 1) | (a[4] << 54)) & 0x7fffffffffffffL; + r[4] = ((a[4] >> 1) | (a[5] << 54)) & 0x7fffffffffffffL; + r[5] = ((a[5] >> 1) | (a[6] << 54)) & 0x7fffffffffffffL; +#endif + r[6] = a[6] >> 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_384_div2_7(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + sp_384_cond_add_7(r, a, m, 0 - (a[0] & 1)); + sp_384_norm_7(r); + sp_384_rshift1_7(r, r); +} + +/* Double the Montgomery form projective point p. + * + * r Result of doubling point. + * p Point to double. + * t Temporary ordinate data. + */ +static void sp_384_proj_point_dbl_7(sp_point_384* r, const sp_point_384* p, sp_digit* t) +{ + sp_point_384* rp[2]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*7; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + /* When infinity don't double point passed in - constant time. */ + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_384*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_384)); + x = rp[p->infinity]->x; + y = rp[p->infinity]->y; + z = rp[p->infinity]->z; + /* Put point to double into result - good for infinity. */ + if (r != p) { + for (i=0; i<7; i++) { + r->x[i] = p->x[i]; + } + for (i=0; i<7; i++) { + r->y[i] = p->y[i]; + } + for (i=0; i<7; i++) { + r->z[i] = p->z[i]; + } + r->infinity = p->infinity; + } + + /* T1 = Z * Z */ + sp_384_mont_sqr_7(t1, z, p384_mod, p384_mp_mod); + /* Z = Y * Z */ + sp_384_mont_mul_7(z, y, z, p384_mod, p384_mp_mod); + /* Z = 2Z */ + sp_384_mont_dbl_7(z, z, p384_mod); + /* T2 = X - T1 */ + sp_384_mont_sub_7(t2, x, t1, p384_mod); + /* T1 = X + T1 */ + sp_384_mont_add_7(t1, x, t1, p384_mod); + /* T2 = T1 * T2 */ + sp_384_mont_mul_7(t2, t1, t2, p384_mod, p384_mp_mod); + /* T1 = 3T2 */ + sp_384_mont_tpl_7(t1, t2, p384_mod); + /* Y = 2Y */ + sp_384_mont_dbl_7(y, y, p384_mod); + /* Y = Y * Y */ + sp_384_mont_sqr_7(y, y, p384_mod, p384_mp_mod); + /* T2 = Y * Y */ + sp_384_mont_sqr_7(t2, y, p384_mod, p384_mp_mod); + /* T2 = T2/2 */ + sp_384_div2_7(t2, t2, p384_mod); + /* Y = Y * X */ + sp_384_mont_mul_7(y, y, x, p384_mod, p384_mp_mod); + /* X = T1 * T1 */ + sp_384_mont_mul_7(x, t1, t1, p384_mod, p384_mp_mod); + /* X = X - Y */ + sp_384_mont_sub_7(x, x, y, p384_mod); + /* X = X - Y */ + sp_384_mont_sub_7(x, x, y, p384_mod); + /* Y = Y - X */ + sp_384_mont_sub_7(y, y, x, p384_mod); + /* Y = Y * T1 */ + sp_384_mont_mul_7(y, y, t1, p384_mod, p384_mp_mod); + /* Y = Y - T2 */ + sp_384_mont_sub_7(y, y, t2, p384_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_384_cmp_equal_7(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])) == 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. + */ +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]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*7; + sp_digit* t3 = t + 4*7; + sp_digit* t4 = t + 6*7; + sp_digit* t5 = t + 8*7; + 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_384* a = p; + p = q; + q = a; + } + + /* Check double */ + (void)sp_384_sub_7(t1, p384_mod, q->y); + sp_384_norm_7(t1); + if ((sp_384_cmp_equal_7(p->x, q->x) & sp_384_cmp_equal_7(p->z, q->z) & + (sp_384_cmp_equal_7(p->y, q->y) | sp_384_cmp_equal_7(p->y, t1))) != 0) { + sp_384_proj_point_dbl_7(r, p, t); + } + else { + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_384*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_384)); + 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<7; i++) { + r->x[i] = ap[p->infinity]->x[i]; + } + for (i=0; i<7; i++) { + r->y[i] = ap[p->infinity]->y[i]; + } + for (i=0; i<7; i++) { + r->z[i] = ap[p->infinity]->z[i]; + } + r->infinity = ap[p->infinity]->infinity; + + /* U1 = X1*Z2^2 */ + sp_384_mont_sqr_7(t1, q->z, p384_mod, p384_mp_mod); + sp_384_mont_mul_7(t3, t1, q->z, p384_mod, p384_mp_mod); + sp_384_mont_mul_7(t1, t1, x, p384_mod, p384_mp_mod); + /* U2 = X2*Z1^2 */ + sp_384_mont_sqr_7(t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_7(t4, t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_7(t2, t2, q->x, p384_mod, p384_mp_mod); + /* S1 = Y1*Z2^3 */ + sp_384_mont_mul_7(t3, t3, y, p384_mod, p384_mp_mod); + /* S2 = Y2*Z1^3 */ + sp_384_mont_mul_7(t4, t4, q->y, p384_mod, p384_mp_mod); + /* H = U2 - U1 */ + sp_384_mont_sub_7(t2, t2, t1, p384_mod); + /* R = S2 - S1 */ + sp_384_mont_sub_7(t4, t4, t3, p384_mod); + /* Z3 = H*Z1*Z2 */ + sp_384_mont_mul_7(z, z, q->z, p384_mod, p384_mp_mod); + sp_384_mont_mul_7(z, z, t2, p384_mod, p384_mp_mod); + /* X3 = R^2 - H^3 - 2*U1*H^2 */ + sp_384_mont_sqr_7(x, t4, p384_mod, p384_mp_mod); + sp_384_mont_sqr_7(t5, t2, p384_mod, p384_mp_mod); + sp_384_mont_mul_7(y, t1, t5, p384_mod, p384_mp_mod); + sp_384_mont_mul_7(t5, t5, t2, p384_mod, p384_mp_mod); + sp_384_mont_sub_7(x, x, t5, p384_mod); + sp_384_mont_dbl_7(t1, y, p384_mod); + sp_384_mont_sub_7(x, x, t1, p384_mod); + /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */ + sp_384_mont_sub_7(y, y, x, p384_mod); + sp_384_mont_mul_7(y, y, t4, p384_mod, p384_mp_mod); + sp_384_mont_mul_7(t5, t5, t3, p384_mod, p384_mp_mod); + sp_384_mont_sub_7(y, y, t5, p384_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. + * + * r Resulting point. + * g Point to multiply. + * 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_384_ecc_mulmod_7(sp_point_384* r, const sp_point_384* g, const sp_digit* k, + int map, void* heap) +{ + sp_point_384* td; + sp_point_384* t[3]; + sp_digit* tmp; + sp_digit n; + int i; + int c, y; + int err = MP_OKAY; + + (void)heap; + + td = (sp_point_384*)XMALLOC(sizeof(sp_point_384) * 3, heap, DYNAMIC_TYPE_ECC); + if (td == NULL) + err = MEMORY_E; + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 7 * 6, heap, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) + err = MEMORY_E; + + if (err == MP_OKAY) { + XMEMSET(td, 0, sizeof(*td) * 3); + + t[0] = &td[0]; + t[1] = &td[1]; + t[2] = &td[2]; + + /* t[0] = {0, 0, 1} * norm */ + t[0]->infinity = 1; + /* t[1] = {g->x, g->y, g->z} * norm */ + err = sp_384_mod_mul_norm_7(t[1]->x, g->x, p384_mod); + } + if (err == MP_OKAY) + err = sp_384_mod_mul_norm_7(t[1]->y, g->y, p384_mod); + if (err == MP_OKAY) + err = sp_384_mod_mul_norm_7(t[1]->z, g->z, p384_mod); + + if (err == MP_OKAY) { + i = 6; + c = 54; + n = k[i--] << (55 - c); + for (; ; c--) { + if (c == 0) { + if (i == -1) + break; + + n = k[i--]; + c = 55; + } + + y = (n >> 54) & 1; + n <<= 1; + + sp_384_proj_point_add_7(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_384)); + sp_384_proj_point_dbl_7(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_384)); + } + + if (map != 0) { + sp_384_map_7(r, t[0], tmp); + } + else { + XMEMCPY(r, t[0], sizeof(sp_point_384)); + } + } + + if (tmp != NULL) { + XMEMSET(tmp, 0, sizeof(sp_digit) * 2 * 7 * 6); + XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); + } + if (td != NULL) { + XMEMSET(td, 0, sizeof(sp_point_384) * 3); + XFREE(td, NULL, DYNAMIC_TYPE_ECC); + } + + return err; +} + +#elif defined(WOLFSSL_SP_CACHE_RESISTANT) +/* Multiply the point 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. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_ecc_mulmod_7(sp_point_384* r, const sp_point_384* g, const sp_digit* k, + int map, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 td[3]; + sp_digit tmpd[2 * 7 * 6]; +#endif + sp_point_384* t; + sp_digit* tmp; + sp_digit n; + int i; + int c, y; + int err = MP_OKAY; + + (void)heap; + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_point_384 td[3]; + t = (sp_point_384*)XMALLOC(sizeof(*td) * 3, heap, DYNAMIC_TYPE_ECC); + if (t == NULL) + err = MEMORY_E; + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 7 * 6, heap, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) + err = MEMORY_E; +#else + t = td; + tmp = tmpd; +#endif + + if (err == MP_OKAY) { + t[0] = &td[0]; + t[1] = &td[1]; + t[2] = &td[2]; + + /* 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_384_mod_mul_norm_7(t[1].x, g->x, p384_mod); + } + if (err == MP_OKAY) + err = sp_384_mod_mul_norm_7(t[1].y, g->y, p384_mod); + if (err == MP_OKAY) + err = sp_384_mod_mul_norm_7(t[1].z, g->z, p384_mod); + + if (err == MP_OKAY) { + i = 6; + c = 54; + n = k[i--] << (55 - c); + for (; ; c--) { + if (c == 0) { + if (i == -1) + break; + + n = k[i--]; + c = 55; + } + + y = (n >> 54) & 1; + n <<= 1; + + sp_384_proj_point_add_7(&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(t[2])); + sp_384_proj_point_dbl_7(&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(t[2])); + } + + if (map != 0) { + sp_384_map_7(r, &t[0], tmp); + } + else { + XMEMCPY(r, &t[0], sizeof(sp_point_384)); + } + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (tmp != NULL) { + XMEMSET(tmp, 0, sizeof(sp_digit) * 2 * 7 * 6); + XFREE(tmp, heap, DYNAMIC_TYPE_ECC); + } + if (t != NULL) { + XMEMSET(t, 0, sizeof(sp_point_384) * 3); + XFREE(t, heap, DYNAMIC_TYPE_ECC); + } +#else + ForceZero(tmpd, sizeof(tmpd)); + ForceZero(td, sizeof(td)); +#endif + + return err; +} + +#else +/* A table entry for pre-computed points. */ +typedef struct sp_table_entry_384 { + sp_digit x[7]; + sp_digit y[7]; +} sp_table_entry_384; + +/* Multiply the point 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. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_ecc_mulmod_fast_7(sp_point_384* r, const sp_point_384* g, const sp_digit* k, + int map, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 td[16]; + sp_point_384 rtd; + sp_digit tmpd[2 * 7 * 6]; +#endif + sp_point_384* t; + sp_point_384* rt; + sp_digit* tmp; + sp_digit n; + int i; + int c, y; + int err; + + (void)heap; + + err = sp_384_point_new_7(heap, rtd, rt); +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + t = (sp_point_384*)XMALLOC(sizeof(sp_point_384) * 16, heap, DYNAMIC_TYPE_ECC); + if (t == NULL) + err = MEMORY_E; + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 7 * 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 */ + (void)sp_384_mod_mul_norm_7(t[1].x, g->x, p384_mod); + (void)sp_384_mod_mul_norm_7(t[1].y, g->y, p384_mod); + (void)sp_384_mod_mul_norm_7(t[1].z, g->z, p384_mod); + t[1].infinity = 0; + sp_384_proj_point_dbl_7(&t[ 2], &t[ 1], tmp); + t[ 2].infinity = 0; + sp_384_proj_point_add_7(&t[ 3], &t[ 2], &t[ 1], tmp); + t[ 3].infinity = 0; + sp_384_proj_point_dbl_7(&t[ 4], &t[ 2], tmp); + t[ 4].infinity = 0; + sp_384_proj_point_add_7(&t[ 5], &t[ 3], &t[ 2], tmp); + t[ 5].infinity = 0; + sp_384_proj_point_dbl_7(&t[ 6], &t[ 3], tmp); + t[ 6].infinity = 0; + sp_384_proj_point_add_7(&t[ 7], &t[ 4], &t[ 3], tmp); + t[ 7].infinity = 0; + sp_384_proj_point_dbl_7(&t[ 8], &t[ 4], tmp); + t[ 8].infinity = 0; + sp_384_proj_point_add_7(&t[ 9], &t[ 5], &t[ 4], tmp); + t[ 9].infinity = 0; + sp_384_proj_point_dbl_7(&t[10], &t[ 5], tmp); + t[10].infinity = 0; + sp_384_proj_point_add_7(&t[11], &t[ 6], &t[ 5], tmp); + t[11].infinity = 0; + sp_384_proj_point_dbl_7(&t[12], &t[ 6], tmp); + t[12].infinity = 0; + sp_384_proj_point_add_7(&t[13], &t[ 7], &t[ 6], tmp); + t[13].infinity = 0; + sp_384_proj_point_dbl_7(&t[14], &t[ 7], tmp); + t[14].infinity = 0; + sp_384_proj_point_add_7(&t[15], &t[ 8], &t[ 7], tmp); + t[15].infinity = 0; + + i = 5; + n = k[i+1] << 9; + c = 50; + y = n >> 59; + XMEMCPY(rt, &t[y], sizeof(sp_point_384)); + n <<= 5; + for (; i>=0 || c>=4; ) { + if (c < 4) { + n |= k[i--] << (9 - c); + c += 55; + } + y = (n >> 60) & 0xf; + n <<= 4; + c -= 4; + + sp_384_proj_point_dbl_7(rt, rt, tmp); + sp_384_proj_point_dbl_7(rt, rt, tmp); + sp_384_proj_point_dbl_7(rt, rt, tmp); + sp_384_proj_point_dbl_7(rt, rt, tmp); + + sp_384_proj_point_add_7(rt, rt, &t[y], tmp); + } + + if (map != 0) { + sp_384_map_7(r, rt, tmp); + } + else { + XMEMCPY(r, rt, sizeof(sp_point_384)); + } + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (tmp != NULL) { + XMEMSET(tmp, 0, sizeof(sp_digit) * 2 * 7 * 6); + XFREE(tmp, heap, DYNAMIC_TYPE_ECC); + } + if (t != NULL) { + XMEMSET(t, 0, sizeof(sp_point_384) * 16); + XFREE(t, heap, DYNAMIC_TYPE_ECC); + } +#else + ForceZero(tmpd, sizeof(tmpd)); + ForceZero(td, sizeof(td)); +#endif + sp_384_point_free_7(rt, 1, heap); + + return err; +} + +#ifdef FP_ECC +/* 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_384_proj_point_dbl_n_7(sp_point_384* r, const sp_point_384* p, int n, + sp_digit* t) +{ + sp_point_384* rp[2]; + sp_digit* w = t; + sp_digit* a = t + 2*7; + sp_digit* b = t + 4*7; + sp_digit* t1 = t + 6*7; + sp_digit* t2 = t + 8*7; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_384*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_384)); + x = rp[p->infinity]->x; + y = rp[p->infinity]->y; + z = rp[p->infinity]->z; + if (r != p) { + for (i=0; i<7; i++) { + r->x[i] = p->x[i]; + } + for (i=0; i<7; i++) { + r->y[i] = p->y[i]; + } + for (i=0; i<7; i++) { + r->z[i] = p->z[i]; + } + r->infinity = p->infinity; + } + + /* Y = 2*Y */ + sp_384_mont_dbl_7(y, y, p384_mod); + /* 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); + while (n-- > 0) { + /* 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); + sp_384_mont_tpl_7(a, t1, p384_mod); + /* 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 = A^2 - 2B */ + sp_384_mont_sqr_7(x, a, p384_mod, p384_mp_mod); + sp_384_mont_dbl_7(t1, b, p384_mod); + sp_384_mont_sub_7(x, x, t1, p384_mod); + /* Z = Z*Y */ + sp_384_mont_mul_7(z, z, y, p384_mod, p384_mp_mod); + /* t2 = Y^4 */ + sp_384_mont_sqr_7(t2, t2, p384_mod, p384_mp_mod); + if (n != 0) { + /* W = W*Y^4 */ + sp_384_mont_mul_7(w, w, t2, p384_mod, p384_mp_mod); + } + /* y = 2*A*(B - X) - Y^4 */ + sp_384_mont_sub_7(y, b, x, p384_mod); + sp_384_mont_mul_7(y, y, a, p384_mod, p384_mp_mod); + sp_384_mont_dbl_7(y, y, p384_mod); + sp_384_mont_sub_7(y, y, t2, p384_mod); + } + /* Y = Y/2 */ + sp_384_div2_7(y, y, p384_mod); +} + +#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_384_proj_point_add_qz1_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]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*7; + sp_digit* t3 = t + 4*7; + sp_digit* t4 = t + 6*7; + sp_digit* t5 = t + 8*7; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + /* Check double */ + (void)sp_384_sub_7(t1, p384_mod, q->y); + sp_384_norm_7(t1); + if ((sp_384_cmp_equal_7(p->x, q->x) & sp_384_cmp_equal_7(p->z, q->z) & + (sp_384_cmp_equal_7(p->y, q->y) | sp_384_cmp_equal_7(p->y, t1))) != 0) { + sp_384_proj_point_dbl_7(r, p, t); + } + else { + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_384*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_384)); + 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<7; i++) { + r->x[i] = ap[p->infinity]->x[i]; + } + for (i=0; i<7; i++) { + r->y[i] = ap[p->infinity]->y[i]; + } + for (i=0; i<7; i++) { + r->z[i] = ap[p->infinity]->z[i]; + } + r->infinity = ap[p->infinity]->infinity; + + /* U2 = X2*Z1^2 */ + sp_384_mont_sqr_7(t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_7(t4, t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_7(t2, t2, q->x, p384_mod, p384_mp_mod); + /* S2 = Y2*Z1^3 */ + sp_384_mont_mul_7(t4, t4, q->y, p384_mod, p384_mp_mod); + /* H = U2 - X1 */ + sp_384_mont_sub_7(t2, t2, x, p384_mod); + /* R = S2 - Y1 */ + sp_384_mont_sub_7(t4, t4, y, p384_mod); + /* Z3 = H*Z1 */ + sp_384_mont_mul_7(z, z, t2, p384_mod, p384_mp_mod); + /* X3 = R^2 - H^3 - 2*X1*H^2 */ + sp_384_mont_sqr_7(t1, t4, p384_mod, p384_mp_mod); + sp_384_mont_sqr_7(t5, t2, p384_mod, p384_mp_mod); + sp_384_mont_mul_7(t3, x, t5, p384_mod, p384_mp_mod); + sp_384_mont_mul_7(t5, t5, t2, p384_mod, p384_mp_mod); + sp_384_mont_sub_7(x, t1, t5, p384_mod); + sp_384_mont_dbl_7(t1, t3, p384_mod); + sp_384_mont_sub_7(x, x, t1, p384_mod); + /* Y3 = R*(X1*H^2 - X3) - Y1*H^3 */ + sp_384_mont_sub_7(t3, t3, x, p384_mod); + sp_384_mont_mul_7(t3, t3, t4, p384_mod, p384_mp_mod); + sp_384_mont_mul_7(t5, t5, y, p384_mod, p384_mp_mod); + sp_384_mont_sub_7(y, t3, t5, p384_mod); + } +} + +#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_7(sp_point_384* a, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 7; + sp_digit* tmp = t + 4 * 7; + + sp_384_mont_inv_7(t1, a->z, tmp); + + sp_384_mont_sqr_7(t2, t1, p384_mod, p384_mp_mod); + sp_384_mont_mul_7(t1, t2, t1, p384_mod, p384_mp_mod); + + sp_384_mont_mul_7(a->x, a->x, t2, p384_mod, p384_mp_mod); + sp_384_mont_mul_7(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. + * + * 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_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) + sp_point_384 td, s1d, s2d; +#endif + sp_point_384* t; + sp_point_384* s1 = NULL; + sp_point_384* s2 = NULL; + int i, j; + int err; + + (void)heap; + + err = sp_384_point_new_7(heap, td, t); + if (err == MP_OKAY) { + err = sp_384_point_new_7(heap, s1d, s1); + } + if (err == MP_OKAY) { + err = sp_384_point_new_7(heap, s2d, s2); + } + + if (err == MP_OKAY) { + err = sp_384_mod_mul_norm_7(t->x, a->x, p384_mod); + } + if (err == MP_OKAY) { + err = sp_384_mod_mul_norm_7(t->y, a->y, p384_mod); + } + if (err == MP_OKAY) { + err = sp_384_mod_mul_norm_7(t->z, a->z, p384_mod); + } + if (err == MP_OKAY) { + t->infinity = 0; + sp_384_proj_to_affine_7(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_7(t, t, 48, tmp); + sp_384_proj_to_affine_7(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_7(t, s1, s2, tmp); + sp_384_proj_to_affine_7(t, tmp); + XMEMCPY(table[j].x, t->x, sizeof(table->x)); + XMEMCPY(table[j].y, t->y, sizeof(table->y)); + } + } + } + + sp_384_point_free_7(s2, 0, heap); + sp_384_point_free_7(s1, 0, heap); + sp_384_point_free_7( t, 0, heap); + + return err; +} + +#endif /* FP_ECC */ +/* Multiply the point 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_384_ecc_mulmod_stripe_7(sp_point_384* r, const sp_point_384* g, + const sp_table_entry_384* table, const sp_digit* k, int map, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 rtd; + sp_point_384 pd; + sp_digit td[2 * 7 * 6]; +#endif + sp_point_384* rt; + sp_point_384* p = NULL; + sp_digit* t; + int i, j; + int y, x; + int err; + + (void)g; + (void)heap; + + + err = sp_384_point_new_7(heap, rtd, rt); + if (err == MP_OKAY) { + err = sp_384_point_new_7(heap, pd, p); + } +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 7 * 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; + for (j=0,x=47; j<8; j++,x+=48) { + y |= ((k[x / 55] >> (x % 55)) & 1) << j; + } + 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; + for (j=0,x=i; j<8; j++,x+=48) { + y |= ((k[x / 55] >> (x % 55)) & 1) << j; + } + + sp_384_proj_point_dbl_7(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_384_proj_point_add_qz1_7(rt, rt, p, t); + } + + if (map != 0) { + sp_384_map_7(r, rt, t); + } + else { + XMEMCPY(r, rt, sizeof(sp_point_384)); + } + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (t != NULL) { + XFREE(t, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_7(p, 0, heap); + sp_384_point_free_7(rt, 0, heap); + + return err; +} + +#ifdef FP_ECC +#ifndef FP_ENTRIES + #define FP_ENTRIES 16 +#endif + +typedef struct sp_cache_384_t { + sp_digit x[7]; + sp_digit y[7]; + sp_table_entry_384 table[256]; + uint32_t cnt; + int set; +} sp_cache_384_t; + +static THREAD_LS_T sp_cache_384_t sp_cache_384[FP_ENTRIES]; +static THREAD_LS_T int sp_cache_384_last = -1; +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 + +static void sp_ecc_get_cache_384(const sp_point_384* g, sp_cache_384_t** cache) +{ + int i, j; + uint32_t least; + + if (sp_cache_384_inited == 0) { + for (i=0; ix, sp_cache_384[i].x) & + sp_384_cmp_equal_7(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. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_ecc_mulmod_7(sp_point_384* r, const sp_point_384* g, const sp_digit* k, + int map, void* heap) +{ +#ifndef FP_ECC + return sp_384_ecc_mulmod_fast_7(r, g, k, map, heap); +#else + sp_digit tmp[2 * 7 * 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_7(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_fast_7(r, g, k, map, heap); + } + else { + err = sp_384_ecc_mulmod_stripe_7(r, g, cache->table, k, + map, 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_384(mp_int* km, ecc_point* gm, ecc_point* r, int map, + void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 p; + sp_digit kd[7]; +#endif + sp_point_384* point; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_384_point_new_7(heap, p, point); +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) + err = MEMORY_E; + } +#else + k = kd; +#endif + if (err == MP_OKAY) { + sp_384_from_mp(k, 7, km); + sp_384_point_from_ecc_point_7(point, gm); + + err = sp_384_ecc_mulmod_7(point, point, k, map, heap); + } + if (err == MP_OKAY) { + err = sp_384_point_to_ecc_point_7(point, r); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + 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. + * + * 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_384_ecc_mulmod_base_7(sp_point_384* r, const sp_digit* k, + int map, void* heap) +{ + /* No pre-computed values. */ + return sp_384_ecc_mulmod_7(r, &p384_base, k, map, heap); +} + +#else +static const sp_table_entry_384 p384_table[256] = { + /* 0 */ + { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 */ + { { 0x50756649c0b528L,0x71c541ad9c707bL,0x71506d35b8838dL, + 0x4d1877fc3ce1d7L,0x6de2b645486845L,0x227025fee46c29L, + 0x134eab708a6785L }, + { 0x043dad4b03a4feL,0x517ef769535846L,0x58ba0ec14286feL, + 0x47a7fecc5d6f3aL,0x1a840c6c352196L,0x3d3bb00044c72dL, + 0x0ade2af0968571L } }, + /* 2 */ + { { 0x0647532b0c535bL,0x52a6e0a0c52c53L,0x5085aae6b24375L, + 0x7096bb501c66b5L,0x47bdb3df9b7b7bL,0x11227e9b2f0be6L, + 0x088b172704fa51L }, + { 0x0e796f2680dc64L,0x796eb06a482ebfL,0x2b441d02e04839L, + 0x19bef7312a5aecL,0x02247c38b8efb5L,0x099ed1185c329eL, + 0x1ed71d7cdb096fL } }, + /* 3 */ + { { 0x6a3cc39edffea5L,0x7a386fafd3f9c4L,0x366f78fbd8d6efL, + 0x529c7ad7873b80L,0x79eb30380eb471L,0x07c5d3b51760b7L, + 0x36ee4f1cc69183L }, + { 0x5ba260f526b605L,0x2f1dfaf0aa6e6fL,0x6bb5ca812a5752L, + 0x3002d8d1276bc9L,0x01f82269483777L,0x1df33eaaf733cdL, + 0x2b97e555f59255L } }, + /* 4 */ + { { 0x480c57f26feef9L,0x4d28741c248048L,0x0c9cf8af1f0c68L, + 0x778f6a639a8016L,0x148e88c42e9c53L,0x464051757ecfe9L, + 0x1a940bd0e2a5e1L }, + { 0x713a46b74536feL,0x1757b153e1d7ebL,0x30dc8c9da07486L, + 0x3b7460c1879b5eL,0x4b766c5317b315L,0x1b9de3aaf4d377L, + 0x245f124c2cf8f5L } }, + /* 5 */ + { { 0x426e2ee349ddd0L,0x7df3365f84a022L,0x03b005d29a7c45L, + 0x422c2337f9b5a4L,0x060494f4bde761L,0x5245e5db6da0b0L, + 0x22b71d744677f2L }, + { 0x19d097b7d5a7ceL,0x6bcb468823d34cL,0x1c3692d3be1d09L, + 0x3c80ec7aa01f02L,0x7170f2ebaafd97L,0x06cbcc7d79d4e8L, + 0x04a8da511fe760L } }, + /* 6 */ + { { 0x79c07a4fc52870L,0x6e9034a752c251L,0x603860a367382cL, + 0x56d912d6aa87d0L,0x0a348a24abaf76L,0x6c5a23da14adcbL, + 0x3cf60479a522b2L }, + { 0x18dd774c61ed22L,0x0ff30168f93b0cL,0x3f79ae15642eddL, + 0x40510f4915fbcbL,0x2c9ddfdfd1c6d6L,0x67b81b62aee55eL, + 0x2824de79b07a43L } }, + /* 7 */ + { { 0x6c66efe085c629L,0x48c212b7913470L,0x4480fd2d057f0aL, + 0x725ec7a89a9eb1L,0x78ce97ca1972b7L,0x54760ee70154fbL, + 0x362a40e27b9f93L }, + { 0x474dc7e7b14461L,0x602819389ef037L,0x1a13bc284370b2L, + 0x0193ff1295a59dL,0x79615bde6ea5d2L,0x2e76e3d886acc1L, + 0x3bb796812e2b60L } }, + /* 8 */ + { { 0x04cbb3893b9a2dL,0x4c16010a18baabL,0x19f7cb50f60831L, + 0x084f400a0936c1L,0x72f1cdd5bbbf00L,0x1b30b725dc6702L, + 0x182753e4fcc50cL }, + { 0x059a07eadaf9d6L,0x26d81e24bf603cL,0x45583c839dc399L, + 0x5579d4d6b1103aL,0x2e14ea59489ae7L,0x492f6e1c5ecc97L, + 0x03740dc05db420L } }, + /* 9 */ + { { 0x413be88510521fL,0x3753ee49982e99L,0x6cd4f7098e1cc5L, + 0x613c92bda4ec1dL,0x495378b677efe0L,0x132a2143839927L, + 0x0cf8c336291c0bL }, + { 0x7fc89d2208353fL,0x751b9da85657e1L,0x349b8a97d405c3L, + 0x65a964b048428fL,0x1adf481276455eL,0x5560c8d89c2ffcL, + 0x144fc11fac21a3L } }, + /* 10 */ + { { 0x7611f4df5bdf53L,0x634eb16234db80L,0x3c713b8e51174cL, + 0x52c3c68ac4b2edL,0x53025ba8bebe75L,0x7175d98143105bL, + 0x33ca8e266a48faL }, + { 0x0c9281d24fd048L,0x76b3177604bbf3L,0x3b26ae754e106fL, + 0x7f782275c6efc6L,0x36662538a4cb67L,0x0ca1255843e464L, + 0x2a4674e142d9bcL } }, + /* 11 */ + { { 0x303b4085d480d8L,0x68f23650f4fa7bL,0x552a3ceeba3367L, + 0x6da0c4947926e3L,0x6e0f5482eb8003L,0x0de717f3d6738aL, + 0x22e5dcc826a477L }, + { 0x1b05b27209cfc2L,0x7f0a0b65b6e146L,0x63586549ed3126L, + 0x7d628dd2b23124L,0x383423fe510391L,0x57ff609eabd569L, + 0x301f04370131baL } }, + /* 12 */ + { { 0x22fe4cdb32f048L,0x7f228ebdadbf5aL,0x02a99adb2d7c8eL, + 0x01a02e05286706L,0x62d6adf627a89fL,0x49c6ce906fbf2bL, + 0x0207256dae90b9L }, + { 0x23e036e71d6cebL,0x199ed8d604e3d7L,0x0c1a11c076d16fL, + 0x389291fb3da3f3L,0x47adc60f8f942eL,0x177048468e4b9aL, + 0x20c09f5e61d927L } }, + /* 13 */ + { { 0x129ea63615b0b8L,0x03fb4a9b588367L,0x5ad6da8da2d051L, + 0x33f782f44caeaaL,0x5a27fa80d45291L,0x6d1ed796942da4L, + 0x08435a931ef556L }, + { 0x004abb25351130L,0x6d33207c6fd7e7L,0x702130972074b7L, + 0x0e34748af900f7L,0x762a531a28c87aL,0x3a903b5a4a6ac7L, + 0x1775b79c35b105L } }, + /* 14 */ + { { 0x7470fd846612ceL,0x7dd9b431b32e53L,0x04bcd2be1a61bcL, + 0x36ed7c5b5c260bL,0x6795f5ef0a4084L,0x46e2880b401c93L, + 0x17d246c5aa8bdeL }, + { 0x707ae4db41b38dL,0x233c31f7f9558fL,0x585110ec67bdf4L, + 0x4d0cc931d0c703L,0x26fbe4356841a7L,0x64323e95239c44L, + 0x371dc9230f3221L } }, + /* 15 */ + { { 0x70ff1ae4b1ec9dL,0x7c1dcfddee0daaL,0x53286782188748L, + 0x6a5d9381e6f207L,0x3aa6c7d6523c4cL,0x6c02d83e0d97e2L, + 0x16a9c916b45312L }, + { 0x78146744b74de8L,0x742ec415269c6fL,0x237a2c6a860e79L, + 0x186baf17ba68a7L,0x4261e8789fa51fL,0x3dc136480a5903L, + 0x1953899e0cf159L } }, + /* 16 */ + { { 0x0205de2f9fbe67L,0x1706fee51c886fL,0x31a0b803c712bfL, + 0x0a6aa11ede7603L,0x2463ef2a145c31L,0x615403b30e8f4aL, + 0x3f024d6c5f5c5eL }, + { 0x53bc4fd4d01f95L,0x7d512ac15a692cL,0x72be38fcfe6aa0L, + 0x437f0b77bbca1eL,0x7fdcf70774a10eL,0x392d6c5cde37f3L, + 0x229cbce79621d1L } }, + /* 17 */ + { { 0x2de4da2341c342L,0x5ca9d4e08844e7L,0x60dd073bcf74c9L, + 0x4f30aa499b63ecL,0x23efd1eafa00d5L,0x7c99a7db1257b3L, + 0x00febc9b3171b1L }, + { 0x7e2fcf3045f8acL,0x2a642e9e3ce610L,0x23f82be69c5299L, + 0x66e49ad967c279L,0x1c895ddfd7a842L,0x798981e22f6d25L, + 0x0d595cb59322f3L } }, + /* 18 */ + { { 0x4bac017d8c1bbaL,0x73872161e7aafdL,0x0fd865f43d8163L, + 0x019d89457708b7L,0x1b983c4dd70684L,0x095e109b74d841L, + 0x25f1f0b3e0c76fL }, + { 0x4e61ddf96010e8L,0x1c40a53f542e5eL,0x01a74dfc8365f9L, + 0x69b36b92773333L,0x08e0fccc139ed3L,0x266d216ddc4269L, + 0x1f2b47717ce9b5L } }, + /* 19 */ + { { 0x0a9a81da57a41fL,0x0825d800736cccL,0x2d7876b4579d28L, + 0x3340ea6211a1e3L,0x49e89284f3ff54L,0x6276a210fe2c6eL, + 0x01c3c8f31be7cbL }, + { 0x2211da5d186e14L,0x1e6ffbb61bfea8L,0x536c7d060211d2L, + 0x320168720d1d55L,0x5835525ed667baL,0x5125e52495205eL, + 0x16113b9f3e9129L } }, + /* 20 */ + { { 0x3086073f3b236fL,0x283b03c443b5f5L,0x78e49ed0a067a7L, + 0x2a878fb79fb2b8L,0x662f04348a9337L,0x57ee2cf732d50bL, + 0x18b50dd65fd514L }, + { 0x5feb9ef2955926L,0x2c3edbef06a7b0L,0x32728dad651029L, + 0x116d00b1c4b347L,0x13254052bf1a1aL,0x3e77bf7fee5ec1L, + 0x253943ca388882L } }, + /* 21 */ + { { 0x32e5b33062e8afL,0x46ebd147a6d321L,0x2c8076dec6a15cL, + 0x7328d511ff0d80L,0x10ad7e926def0eL,0x4e8ca85937d736L, + 0x02638c26e8bf2fL }, + { 0x1deeb3fff1d63fL,0x5014417fa6e8efL,0x6e1da3de5c8f43L, + 0x7ca942b42295d9L,0x23faacf75bb4d1L,0x4a71fcd680053dL, + 0x04af4f90204dceL } }, + /* 22 */ + { { 0x23780d104cbba5L,0x4e8ff46bba9980L,0x2072a6da8d881fL, + 0x3cc3d881ae11c9L,0x2eee84ff19be89L,0x69b708ed77f004L, + 0x2a82928534eef9L }, + { 0x794331187d4543L,0x70e0f3edc0cc41L,0x3ab1fa0b84c854L, + 0x1478355c1d87baL,0x6f35fa7748ba28L,0x37b8be0531584dL, + 0x03c3141c23a69fL } }, + /* 23 */ + { { 0x5c244cdef029ddL,0x0d0f0a0cc37018L,0x17f8476604f6afL, + 0x13a6dd6ccc95c3L,0x5a242e9801b8f6L,0x211ca9cc632131L, + 0x264a6a46a4694fL }, + { 0x3ffd7235285887L,0x284be28302046fL,0x57f4b9b882f1d6L, + 0x5e21772c940661L,0x7619a735c600cfL,0x2f76f5a50c9106L, + 0x28d89c8c69de31L } }, + /* 24 */ + { { 0x799b5c91361ed8L,0x36ead8c66cd95cL,0x046c9969a91f5cL, + 0x46bbdba2a66ea9L,0x29db0e0215a599L,0x26c8849b36f756L, + 0x22c3feb31ff679L }, + { 0x585d1237b5d9efL,0x5ac57f522e8e8dL,0x617e66e8b56c41L, + 0x68826f276823cfL,0x0983f0e6f39231L,0x4e1075099084bdL, + 0x2a541f82be0416L } }, + /* 25 */ + { { 0x468a6e14cf381cL,0x4f7b845c6399edL,0x36aa29732ebe74L, + 0x19c726911ab46aL,0x2ad1fe431eec0eL,0x301e35051fd1eaL, + 0x36da815e7a1ab3L }, + { 0x05672e4507832aL,0x4ebf10fca51251L,0x6015843421cff0L, + 0x3affad832fc013L,0x712b58d9b45540L,0x1e4751d1f6213eL, + 0x0e7c2b218bafa7L } }, + /* 26 */ + { { 0x7abf784c52edf5L,0x6fcb4b135ca7b1L,0x435e46ac5f735cL, + 0x67f8364ca48c5fL,0x46d45b5fbd956bL,0x10deda6065db94L, + 0x0b37fdf85068f9L }, + { 0x74b3ba61f47ec8L,0x42c7ddf08c10ccL,0x1531a1fe422a20L, + 0x366f913d12be38L,0x6a846e30cb2edfL,0x2785898c994fedL, + 0x061be85f331af3L } }, + /* 27 */ + { { 0x23f5361dfcb91eL,0x3c26c8da6b1491L,0x6e444a1e620d65L, + 0x0c3babd5e8ac13L,0x573723ce612b82L,0x2d10e62a142c37L, + 0x3d1a114c2d98bdL }, + { 0x33950b401896f6L,0x7134efe7c12110L,0x31239fd2978472L, + 0x30333bf5978965L,0x79f93313dd769fL,0x457fb9e11662caL, + 0x190a73b251ae3cL } }, + /* 28 */ + { { 0x04dd54bb75f9a4L,0x0d7253a76ae093L,0x08f5b930792bbcL, + 0x041f79adafc265L,0x4a9ff24c61c11bL,0x0019c94e724725L, + 0x21975945d9cc2aL }, + { 0x3dfe76722b4a2bL,0x17f2f6107c1d94L,0x546e1ae2944b01L, + 0x53f1f06401e72dL,0x2dbe43fc7632d6L,0x5639132e185903L, + 0x0f2f34eb448385L } }, + /* 29 */ + { { 0x7b4cc7ec30ce93L,0x58fb6e4e4145f7L,0x5d1ed5540043b5L, + 0x19ffbe1f633adfL,0x5bfc0907259033L,0x6378f872e7ca0eL, + 0x2c127b2c01eb3cL }, + { 0x076eaf4f58839cL,0x2db54560bc9f68L,0x42ad0319b84062L, + 0x46c325d1fb019dL,0x76d2a19ee9eebcL,0x6fbd6d9e2aa8f7L, + 0x2396a598fe0991L } }, + /* 30 */ + { { 0x662fddf7fbd5e1L,0x7ca8ed22563ad3L,0x5b4768efece3b3L, + 0x643786a422d1eaL,0x36ce80494950e1L,0x1a30795b7f2778L, + 0x107f395c93f332L }, + { 0x7939c28332c144L,0x491610e3c8dc0bL,0x099ba2bfdac5fcL, + 0x5c2e3149ec29a7L,0x31b731d06f1dc3L,0x1cbb60d465d462L, + 0x3ca5461362cfd9L } }, + /* 31 */ + { { 0x653ff736ddc103L,0x7c6f2bdec0dfb2L,0x73f81b73a097d0L, + 0x05b775f84f180fL,0x56b2085af23413L,0x0d6f36256a61feL, + 0x26d3ed267fa68fL }, + { 0x54f89251d27ac2L,0x4fc6ad94a71202L,0x7ebf01969b4cc5L, + 0x7ba364dbc14760L,0x4f8370959a2587L,0x7b7631e37c6188L, + 0x29e51845f104cbL } }, + /* 32 */ + { { 0x426b775e3c647bL,0x327319e0a69180L,0x0c5cb034f6ff2fL, + 0x73aa39b98e9897L,0x7ee615f49fde6eL,0x3f712aa61e0db4L, + 0x33ca06c2ba2ce9L }, + { 0x14973541b8a543L,0x4b4e6101ba61faL,0x1d94e4233d0698L, + 0x501513c715d570L,0x1b8f8c3d01436bL,0x52f41a0445cf64L, + 0x3f709c3a75fb04L } }, + /* 33 */ + { { 0x073c0cbc7f41d6L,0x227c36f5ac8201L,0x508e110fef65d8L, + 0x0f317229529b7fL,0x45fc6030d00e24L,0x118a65d30cebeaL, + 0x3340cc4223a448L }, + { 0x204c999797612cL,0x7c05dd4ce9c5a3L,0x7b865d0a8750e4L, + 0x2f82c876ab7d34L,0x2243ddd2ab4808L,0x6834b9df8a4914L, + 0x123319ed950e0fL } }, + /* 34 */ + { { 0x50430efc14ab48L,0x7e9e4ce0d4e89cL,0x2332207fd8656dL, + 0x4a2809e97f4511L,0x2162bb1b968e2dL,0x29526d54af2972L, + 0x13edd9adcd939dL }, + { 0x793bca31e1ff7fL,0x6b959c9e4d2227L,0x628ac27809a5baL, + 0x2c71ffc7fbaa5fL,0x0c0b058f13c9ceL,0x5676eae68de2cfL, + 0x35508036ea19a4L } }, + /* 35 */ + { { 0x030bbd6dda1265L,0x67f9d12e31bb34L,0x7e4d8196e3ded3L, + 0x7b9120e5352498L,0x75857bce72d875L,0x4ead976a396caeL, + 0x31c5860553a64dL }, + { 0x1a0f792ee32189L,0x564c4efb8165d0L,0x7adc7d1a7fbcbeL, + 0x7ed7c2ccf327b7L,0x35df1b448ce33dL,0x6f67eb838997cdL, + 0x3ee37ec0077917L } }, + /* 36 */ + { { 0x345fa74d5bb921L,0x097c9a56ccfd8eL,0x00a0b5e8f971f8L, + 0x723d95223f69d4L,0x08e2e5c2777f87L,0x68b13676200109L, + 0x26ab5df0acbad6L }, + { 0x01bca7daac34aeL,0x49ca4d5f664dadL,0x110687b850914bL, + 0x1203d6f06443c9L,0x7a2ac743b04d4cL,0x40d96bd3337f82L, + 0x13728be0929c06L } }, + /* 37 */ + { { 0x631ca61127bc1aL,0x2b362fd5a77cd1L,0x17897d68568fb7L, + 0x21070af33db5b2L,0x6872e76221794aL,0x436f29fb076963L, + 0x1f2acfc0ecb7b3L }, + { 0x19bf15ca9b3586L,0x32489a4a17aee2L,0x2b31af3c929551L, + 0x0db7c420b9b19fL,0x538c39bd308c2bL,0x438775c0dea88fL, + 0x1537304d7cd07fL } }, + /* 38 */ + { { 0x53598d943caf0dL,0x1d5244bfe266adL,0x7158feb7ab3811L, + 0x1f46e13cf6fb53L,0x0dcab632eb9447L,0x46302968cfc632L, + 0x0b53d3cc5b6ec7L }, + { 0x69811ca143b7caL,0x5865bcf9f2a11aL,0x74ded7fa093b06L, + 0x1c878ec911d5afL,0x04610e82616e49L,0x1e157fe9640eb0L, + 0x046e6f8561d6c2L } }, + /* 39 */ + { { 0x631a3d3bbe682cL,0x3a4ce9dde5ba95L,0x28f11f7502f1f1L, + 0x0a55cf0c957e88L,0x495e4ec7e0a3bcL,0x30ad4d87ba365cL, + 0x0217b97a4c26f3L }, + { 0x01a9088c2e67fdL,0x7501c4c3d5e5e7L,0x265b7bb854c820L, + 0x729263c87e6b52L,0x308b9e3b8fb035L,0x33f1b86c1b23abL, + 0x0e81b8b21fc99cL } }, + /* 40 */ + { { 0x59f5a87237cac0L,0x6b3a86b0cf28b9L,0x13a53db13a4fc2L, + 0x313c169a1c253bL,0x060158304ed2bbL,0x21e171b71679bcL, + 0x10cdb754d76f86L }, + { 0x44355392ab473aL,0x64eb7cbda08caeL,0x3086426a900c71L, + 0x49016ed9f3c33cL,0x7e6354ab7e04f9L,0x17c4c91a40cd2eL, + 0x3509f461024c66L } }, + /* 41 */ + { { 0x2848f50f9b5a31L,0x68d1755b6c5504L,0x48cd5d5672ec00L, + 0x4d77421919d023L,0x1e1e349ef68807L,0x4ab5130cf415d7L, + 0x305464c6c7dbe6L }, + { 0x64eb0bad74251eL,0x64c6957e52bda4L,0x6c12583440dee6L, + 0x6d3bee05b00490L,0x186970de53dbc4L,0x3be03b37567a56L, + 0x2b553b1ebdc55bL } }, + /* 42 */ + { { 0x74dc3579efdc58L,0x26d29fed1bb71cL,0x334c825a9515afL, + 0x433c1e839273a6L,0x0d8a4e41cff423L,0x3454098fe42f8eL, + 0x1046674bf98686L }, + { 0x09a3e029c05dd2L,0x54d7cfc7fb53a7L,0x35f0ad37e14d7cL, + 0x73a294a13767b9L,0x3f519678275f4fL,0x788c63393993a4L, + 0x0781680b620123L } }, + /* 43 */ + { { 0x4c8e2ed4d5ffe8L,0x112db7d42fe4ebL,0x433b8f2d2be2edL, + 0x23e30b29a82cbcL,0x35d2f4c06ee85aL,0x78ff31ffe4b252L, + 0x0d31295c8cbff5L }, + { 0x314806ea0376a2L,0x4ea09e22bc0589L,0x0879575f00ba97L, + 0x188226d2996bb7L,0x7799368dc9411fL,0x7ab24e5c8cae36L, + 0x2b6a8e2ee4ea33L } }, + /* 44 */ + { { 0x70c7127d4ed72aL,0x24c9743ef34697L,0x2fd30e7a93683aL, + 0x538a89c246012cL,0x6c660a5394ed82L,0x79a95ea239d7e0L, + 0x3f3af3bbfb170dL }, + { 0x3b75aa779ae8c1L,0x33995a3cc0dde4L,0x7489d5720b7bfdL, + 0x599677ef9fa937L,0x3defd64c5ab44bL,0x27d52dc234522bL, + 0x2ac65d1a8450e0L } }, + /* 45 */ + { { 0x478585ec837d7dL,0x5f7971dc174887L,0x67576ed7bb296dL, + 0x5a78e529a74926L,0x640f73f4fa104bL,0x7d42a8b16e4730L, + 0x108c7eaa75fd01L }, + { 0x60661ef96e6896L,0x18d3a0761f3aa7L,0x6e71e163455539L, + 0x165827d6a7e583L,0x4e7f77e9527935L,0x790bebe2ae912eL, + 0x0b8fe9561adb55L } }, + /* 46 */ + { { 0x4d48036a9951a8L,0x371084f255a085L,0x66aeca69cea2c5L, + 0x04c99f40c745e7L,0x08dc4bfd9a0924L,0x0b0ec146b29df7L, + 0x05106218d01c91L }, + { 0x2a56ee99caedc7L,0x5d9b23a203922cL,0x1ce4c80b6a3ec4L, + 0x2666bcb75338cbL,0x185a81aac8c4aaL,0x2b4fb60a06c39eL, + 0x0327e1b3633f42L } }, + /* 47 */ + { { 0x72814710b2a556L,0x52c864f6e16534L,0x4978de66ddd9f2L, + 0x151f5950276cf0L,0x450ac6781d2dc2L,0x114b7a22dd61b2L, + 0x3b32b07f29faf8L }, + { 0x68444fdc2d6e94L,0x68526bd9e437bcL,0x0ca780e8b0d887L, + 0x69f3f850a716aaL,0x500b953e42cd57L,0x4e57744d812e7dL, + 0x000a5f0e715f48L } }, + /* 48 */ + { { 0x2aab10b8243a7dL,0x727d1f4b18b675L,0x0e6b9fdd91bbbbL, + 0x0d58269fc337e5L,0x45d6664105a266L,0x11946af1b14072L, + 0x2c2334f91e46e1L }, + { 0x6dc5f8756d2411L,0x21b34eaa25188bL,0x0d2797da83529eL, + 0x324df55616784bL,0x7039ec66d267dfL,0x2de79cdb2d108cL, + 0x14011b1ad0bde0L } }, + /* 49 */ + { { 0x2e160266425043L,0x55fbe11b712125L,0x7e3c58b3947fd9L, + 0x67aacc79c37ad3L,0x4a18e18d2dea0fL,0x5eef06e5674351L, + 0x37c3483ae33439L }, + { 0x5d5e1d75bb4045L,0x0f9d72db296efdL,0x60b1899dd894a9L, + 0x06e8818ded949aL,0x747fd853c39434L,0x0953b937d9efabL, + 0x09f08c0beeb901L } }, + /* 50 */ + { { 0x1d208a8f2d49ceL,0x54042c5be1445aL,0x1c2681fd943646L, + 0x219c8094e2e674L,0x442cddf07238b8L,0x574a051c590832L, + 0x0b72f4d61c818aL }, + { 0x7bc3cbe4680967L,0x0c8b3f25ae596bL,0x0445b0da74a9efL, + 0x0bbf46c40363b7L,0x1df575c50677a3L,0x016ea6e73d68adL, + 0x0b5207bd8db0fdL } }, + /* 51 */ + { { 0x2d39fdfea1103eL,0x2b252bf0362e34L,0x63d66c992baab9L, + 0x5ac97706de8550L,0x0cca390c39c1acL,0x0d9bec5f01b2eaL, + 0x369360a0f7e5f3L }, + { 0x6dd3461e201067L,0x70b2d3f63ed614L,0x487580487c54c7L, + 0x6020e48a44af2aL,0x1ccf80b21aab04L,0x3cf3b12d88d798L, + 0x349368eccc506fL } }, + /* 52 */ + { { 0x5a053753b0a354L,0x65e818dbb9b0aeL,0x7d5855ee50e4bfL, + 0x58dc06885c7467L,0x5ee15073e57bd3L,0x63254ebc1e07fdL, + 0x1d48e0392aa39bL }, + { 0x4e227c6558ffe9L,0x0c3033d8a82a3eL,0x7bde65c214e8d2L, + 0x6e23561559c16aL,0x5094c5e6deaffdL,0x78dca2880f1f91L, + 0x3d9d3f947d838dL } }, + /* 53 */ + { { 0x387ae5af63408fL,0x6d539aeb4e6edfL,0x7f3d3186368e70L, + 0x01a6446bc19989L,0x35288fbcd4482fL,0x39288d34ec2736L, + 0x1de9c47159ad76L }, + { 0x695dc7944f8d65L,0x3eca2c35575094L,0x0c918059a79b69L, + 0x4573a48c32a74eL,0x580d8bc8b93f52L,0x190be3a3d071eaL, + 0x2333e686b3a8cbL } }, + /* 54 */ + { { 0x2b110c7196fee2L,0x3ac70e99128a51L,0x20a6bb6b75d5e6L, + 0x5f447fa513149aL,0x560d69714cc7b2L,0x1d3ee25279fab1L, + 0x369adb2ccca959L }, + { 0x3fddb13dd821c2L,0x70bf21ba647be8L,0x64121227e3cbc9L, + 0x12633a4c892320L,0x3c15c61660f26dL,0x1932c3b3d19900L, + 0x18c718563eab71L } }, + /* 55 */ + { { 0x72ebe0fd752366L,0x681c2737d11759L,0x143c805e7ae4f0L, + 0x78ed3c2cc7b324L,0x5c16e14820254fL,0x226a4f1c4ec9f0L, + 0x2891bb915eaac6L }, + { 0x061eb453763b33L,0x07f88b81781a87L,0x72b5ac7a87127cL, + 0x7ea4e4cd7ff8b5L,0x5e8c3ce33908b6L,0x0bcb8a3d37feffL, + 0x01da9e8e7fc50bL } }, + /* 56 */ + { { 0x639dfe9e338d10L,0x32dfe856823608L,0x46a1d73bca3b9aL, + 0x2da685d4b0230eL,0x6e0bc1057b6d69L,0x7144ec724a5520L, + 0x0b067c26b87083L }, + { 0x0fc3f0eef4c43dL,0x63500f509552b7L,0x220d74af6f8b86L, + 0x038996eafa2aa9L,0x7f6750f4aee4d2L,0x3e1d3f06718720L, + 0x1ea1d37243814cL } }, + /* 57 */ + { { 0x322d4597c27050L,0x1beeb3ce17f109L,0x15e5ce2e6ef42eL, + 0x6c8be27da6b3a0L,0x66e3347f4d5f5cL,0x7172133899c279L, + 0x250aff4e548743L }, + { 0x28f0f6a43b566dL,0x0cd2437fefbca0L,0x5b1108cb36bdbaL, + 0x48a834d41fb7c2L,0x6cb8565680579fL,0x42da2412b45d9fL, + 0x33dfc1abb6c06eL } }, + /* 58 */ + { { 0x56e3c48ef96c80L,0x65667bb6c1381eL,0x09f70514375487L, + 0x1548ff115f4a08L,0x237de2d21a0710L,0x1425cdee9f43dfL, + 0x26a6a42e055b0aL }, + { 0x4ea9ea9dc7dfcbL,0x4df858583ac58aL,0x1d274f819f1d39L, + 0x26e9c56cf91fcbL,0x6cee31c7c3a465L,0x0bb8e00b108b28L, + 0x226158da117301L } }, + /* 59 */ + { { 0x5a7cd4fce73946L,0x7b6a462d0ac653L,0x732ea4bb1a3da5L, + 0x7c8e9f54711af4L,0x0a6cd55d4655f9L,0x341e6d13e4754aL, + 0x373c87098879a8L }, + { 0x7bc82e61b818bfL,0x5f2db48f44879fL,0x2a2f06833f1d28L, + 0x494e5b691a74c0L,0x17d6cf35fd6b57L,0x5f7028d1c25dfcL, + 0x377a9ab9562cb6L } }, + /* 60 */ + { { 0x4de8877e787b2eL,0x183e7352621a52L,0x2ab0509974962bL, + 0x045a450496cb8aL,0x3bf7118b5591c7L,0x7724f98d761c35L, + 0x301607e8d5a0c1L }, + { 0x0f58a3f24d4d58L,0x3771c19c464f3cL,0x06746f9c0bfafaL, + 0x56564c9c8feb52L,0x0d66d9a7d8a45fL,0x403578141193caL, + 0x00b0d0bdc19260L } }, + /* 61 */ + { { 0x571407157bdbc2L,0x138d5a1c2c0b99L,0x2ee4a8057dcbeaL, + 0x051ff2b58e9ed1L,0x067378ad9e7cdaL,0x7cc2c1db97a49eL, + 0x1e7536ccd849d6L }, + { 0x531fd95f3497c4L,0x55dc08325f61a7L,0x144e942bce32bfL, + 0x642d572f09e53aL,0x556ff188261678L,0x3e79c0d9d513d6L, + 0x0bbbc6656f6d52L } }, + /* 62 */ + { { 0x57d3eb50596edcL,0x26c520a487451dL,0x0a92db40aea8d6L, + 0x27df6345109616L,0x7733d611fd727cL,0x61d14171fef709L, + 0x36169ae417c36bL }, + { 0x6899f5d4091cf7L,0x56ce5dfe4ed0c1L,0x2c430ce5913fbcL, + 0x1b13547e0f8caeL,0x4840a8275d3699L,0x59b8ef209e81adL, + 0x22362dff5ea1a2L } }, + /* 63 */ + { { 0x7237237bd98425L,0x73258e162a9d0bL,0x0a59a1e8bb5118L, + 0x4190a7ee5d8077L,0x13684905fdbf7cL,0x31c4033a52626bL, + 0x010a30e4fbd448L }, + { 0x47623f981e909aL,0x670af7c325b481L,0x3d004241fa4944L, + 0x0905a2ca47f240L,0x58f3cdd7a187c3L,0x78b93aee05b43fL, + 0x19b91d4ef8d63bL } }, + /* 64 */ + { { 0x0d34e116973cf4L,0x4116fc9e69ee0eL,0x657ae2b4a482bbL, + 0x3522eed134d7cdL,0x741e0dde0a036aL,0x6554316a51cc7bL, + 0x00f31c6ca89837L }, + { 0x26770aa06b1dd7L,0x38233a4ceba649L,0x065a1110c96feaL, + 0x18d367839e0f15L,0x794543660558d1L,0x39b605139065dcL, + 0x29abbec071b637L } }, + /* 65 */ + { { 0x1464b401ab5245L,0x16db891b27ff74L,0x724eb49cb26e34L, + 0x74fee3bc9cc33eL,0x6a8bdbebe085eaL,0x5c2e75ca207129L, + 0x1d03f2268e6b08L }, + { 0x28b0a328e23b23L,0x645dc26209a0bcL,0x62c28990348d49L, + 0x4dd9be1fa333d0L,0x6183aac74a72e4L,0x1d6f3ee69e1d03L, + 0x2fff96db0ff670L } }, + /* 66 */ + { { 0x2358f5c6a2123fL,0x5b2bfc51bedb63L,0x4fc6674be649ecL, + 0x51fc16e44b813aL,0x2ffe10a73754c1L,0x69a0c7a053aeefL, + 0x150e605fb6b9b4L }, + { 0x179eef6b8b83c4L,0x64293b28ad05efL,0x331795fab98572L, + 0x09823eec78727dL,0x36508042b89b81L,0x65f1106adb927eL, + 0x2fc0234617f47cL } }, + /* 67 */ + { { 0x12aa244e8068dbL,0x0c834ae5348f00L,0x310fc1a4771cb3L, + 0x6c90a2f9e19ef9L,0x77946fa0573471L,0x37f5df81e5f72fL, + 0x204f5d72cbe048L }, + { 0x613c724383bba6L,0x1ce14844967e0aL,0x797c85e69aa493L, + 0x4fb15b0f2ce765L,0x5807978e2e8aa7L,0x52c75859876a75L, + 0x1554635c763d3eL } }, + /* 68 */ + { { 0x4f292200623f3bL,0x6222be53d7fe07L,0x1e02a9a08c2571L, + 0x22c6058216b912L,0x1ec20044c7ba17L,0x53f94c5efde12bL, + 0x102b8aadfe32a4L }, + { 0x45377aa927b102L,0x0d41b8062ee371L,0x77085a9018e62aL, + 0x0c69980024847cL,0x14739b423a73a9L,0x52ec6961fe3c17L, + 0x38a779c94b5a7dL } }, + /* 69 */ + { { 0x4d14008435af04L,0x363bfd8325b4e8L,0x48cdb715097c95L, + 0x1b534540f8bee0L,0x4ca1e5c90c2a76L,0x4b52c193d6eee0L, + 0x277a33c79becf5L }, + { 0x0fee0d511d3d06L,0x4627f3d6a58f8cL,0x7c81ac245119b8L, + 0x0c8d526ba1e07aL,0x3dbc242f55bac2L,0x2399df8f91fffdL, + 0x353e982079ba3bL } }, + /* 70 */ + { { 0x6405d3b0ab9645L,0x7f31abe3ee236bL,0x456170a9babbb1L, + 0x09634a2456a118L,0x5b1c6045acb9e5L,0x2c75c20d89d521L, + 0x2e27ccf5626399L }, + { 0x307cd97fed2ce4L,0x1c2fbb02b64087L,0x542a068d27e64dL, + 0x148c030b3bc6a6L,0x671129e616ade5L,0x123f40db60dafcL, + 0x07688f3c621220L } }, + /* 71 */ + { { 0x1c46b342f2c4b5L,0x27decc0b3c8f04L,0x0d9bd433464c54L, + 0x1f3d893b818572L,0x2536043b536c94L,0x57e00c4b19ebf9L, + 0x3938fb9e5ad55eL }, + { 0x6b390024c8b22fL,0x4583f97e20a976L,0x2559d24abcbad7L, + 0x67a9cabc9bd8c6L,0x73a56f09432e4aL,0x79eb0beb53a3b7L, + 0x3e19d47f6f8221L } }, + /* 72 */ + { { 0x7399cb9d10e0b2L,0x32acc1b8a36e2aL,0x287d60c2407035L, + 0x42c82420ea4b5cL,0x13f286658bc268L,0x3c91181156e064L, + 0x234b83dcdeb963L }, + { 0x79bc95486cfee6L,0x4d8fd3cb78af36L,0x07362ba5e80da8L, + 0x79d024a0d681b0L,0x6b58406907f87fL,0x4b40f1e977e58fL, + 0x38dcc6fd5fa342L } }, + /* 73 */ + { { 0x72282be1cd0abeL,0x02bd0fdfdf44e5L,0x19b0e0d2f753e4L, + 0x4514e76ce8c4c0L,0x02ebc9c8cdcc1bL,0x6ac0c0373e9fddL, + 0x0dc414af1c81a9L }, + { 0x7a109246f32562L,0x26982e6a3768edL,0x5ecd8daed76ab5L, + 0x2eaa70061eb261L,0x09e7c038a8c514L,0x2a2603cc300658L, + 0x25d93ab9e55cd4L } }, + /* 74 */ + { { 0x11b19fcbd5256aL,0x41e4d94274770fL,0x0133c1a411001fL, + 0x360bac481dbca3L,0x45908b18a9c22bL,0x1e34396fafb03aL, + 0x1b84fea7486edaL }, + { 0x183c62a71e6e16L,0x5f1dc30e93da8eL,0x6cb97b502573c3L, + 0x3708bf0964e3fcL,0x35a7f042eeacceL,0x56370da902c27fL, + 0x3a873c3b72797fL } }, + /* 75 */ + { { 0x6573c9cea4cc9bL,0x2c3b5f9d91e6dcL,0x2a90e2dbd9505eL, + 0x66a75444025f81L,0x1571fb894b03cdL,0x5d1a1f00fd26f3L, + 0x0d19a9fd618855L }, + { 0x659acd56515664L,0x7279478bd616a3L,0x09a909e76d56c3L, + 0x2fd70474250358L,0x3a1a25c850579cL,0x11b9e0f71b74ccL, + 0x1268daef3d1bffL } }, + /* 76 */ + { { 0x7f5acc46d93106L,0x5bc15512f939c8L,0x504b5f92f996deL, + 0x25965549be7a64L,0x357a3a2ae9b80dL,0x3f2bcf9c139cc0L, + 0x0a7ddd99f23b35L }, + { 0x6868f5a8a0b1c5L,0x319ec52f15b1beL,0x0770000a849021L, + 0x7f4d50287bd608L,0x62c971d28a9d7fL,0x164e89309acb72L, + 0x2a29f002cf4a32L } }, + /* 77 */ + { { 0x58a852ae11a338L,0x27e3a35f2dcef8L,0x494d5731ce9e18L, + 0x49516f33f4bb3eL,0x386b26ba370097L,0x4e8fac1ec30248L, + 0x2ac26d4c44455dL }, + { 0x20484198eb9dd0L,0x75982a0e06512bL,0x152271b9279b05L, + 0x5908a9857e36d2L,0x6a933ab45a60abL,0x58d8b1acb24fafL, + 0x28fbcf19425590L } }, + /* 78 */ + { { 0x5420e9df010879L,0x4aba72aec2f313L,0x438e544eda7494L, + 0x2e8e189ce6f7eaL,0x2f771e4efe45bdL,0x0d780293bce7efL, + 0x1569ad3d0d02acL }, + { 0x325251ebeaf771L,0x02510f1a8511e2L,0x3863816bf8aad1L, + 0x60fdb15fe6ac19L,0x4792aef52a348cL,0x38e57a104e9838L, + 0x0d171611a1df1bL } }, + /* 79 */ + { { 0x15ceb0bea65e90L,0x6e56482db339bcL,0x37f618f7b0261fL, + 0x6351abc226dabcL,0x0e999f617b74baL,0x37d3cc57af5b69L, + 0x21df2b987aac68L }, + { 0x2dddaa3a358610L,0x2da264bc560e47L,0x545615d538bf13L, + 0x1c95ac244b8cc7L,0x77de1f741852cbL,0x75d324f00996abL, + 0x3a79b13b46aa3bL } }, + /* 80 */ + { { 0x7db63998683186L,0x6849bb989d530cL,0x7b53c39ef7ed73L, + 0x53bcfbf664d3ffL,0x25ef27c57f71c7L,0x50120ee80f3ad6L, + 0x243aba40ed0205L }, + { 0x2aae5e0ee1fcebL,0x3449d0d8343fbeL,0x5b2864fb7cffc7L, + 0x64dceb5407ac3eL,0x20303a5695523dL,0x3def70812010b2L, + 0x07be937f2e9b6fL } }, + /* 81 */ + { { 0x5838f9e0540015L,0x728d8720efb9f7L,0x1ab5864490b0c8L, + 0x6531754458fdcfL,0x600ff9612440c0L,0x48735b36a585b7L, + 0x3d4aaea86b865dL }, + { 0x6898942cac32adL,0x3c84c5531f23a1L,0x3c9dbd572f7edeL, + 0x5691f0932a2976L,0x186f0db1ac0d27L,0x4fbed18bed5bc9L, + 0x0e26b0dee0b38cL } }, + /* 82 */ + { { 0x1188b4f8e60f5bL,0x602a915455b4a2L,0x60e06af289ff99L, + 0x579fe4bed999e5L,0x2bc03b15e6d9ddL,0x1689649edd66d5L, + 0x3165e277dca9d2L }, + { 0x7cb8a529cf5279L,0x57f8035b34d84dL,0x352e2eb26de8f1L, + 0x6406820c3367c4L,0x5d148f4c899899L,0x483e1408482e15L, + 0x1680bd1e517606L } }, + /* 83 */ + { { 0x5c877cc1c90202L,0x2881f158eae1f4L,0x6f45e207df4267L, + 0x59280eba1452d8L,0x4465b61e267db5L,0x171f1137e09e5cL, + 0x1368eb821daa93L }, + { 0x70fe26e3e66861L,0x52a6663170da7dL,0x71d1ce5b7d79dcL, + 0x1cffe9be1e1afdL,0x703745115a29c4L,0x73b7f897b2f65aL, + 0x02218c3a95891aL } }, + /* 84 */ + { { 0x16866db8a9e8c9L,0x4770b770123d9bL,0x4c116cf34a8465L, + 0x079b28263fc86aL,0x3751c755a72b58L,0x7bc8df1673243aL, + 0x12fff72454f064L }, + { 0x15c049b89554e7L,0x4ea9ef44d7cd9aL,0x42f50765c0d4f1L, + 0x158bb603cb011bL,0x0809dde16470b1L,0x63cad7422ea819L, + 0x38b6cd70f90d7eL } }, + /* 85 */ + { { 0x1e4aab6328e33fL,0x70575f026da3aeL,0x7e1b55c8c55219L, + 0x328d4b403d24caL,0x03b6df1f0a5bd1L,0x26b4bb8b648ed0L, + 0x17161f2f10b76aL }, + { 0x6cdb32bae8b4c0L,0x33176266227056L,0x4975fa58519b45L, + 0x254602ea511d96L,0x4e82e93e402a67L,0x0ca8b5929cdb4fL, + 0x3ae7e0a07918f5L } }, + /* 86 */ + { { 0x60f9d1fecf5b9bL,0x6257e40d2cd469L,0x6c7aa814d28456L, + 0x58aac7caac8e79L,0x703a55f0293cbfL,0x702390a0f48378L, + 0x24b9ae07218b07L }, + { 0x1ebc66cdaf24e3L,0x7d9ae5f9f8e199L,0x42055ee921a245L, + 0x035595936e4d49L,0x129c45d425c08bL,0x6486c5f19ce6ddL, + 0x027dbd5f18ba24L } }, + /* 87 */ + { { 0x7d6b78d29375fbL,0x0a3dc6ba22ae38L,0x35090fa91feaf6L, + 0x7f18587fb7b16eL,0x6e7091dd924608L,0x54e102cdbf5ff8L, + 0x31b131a4c22079L }, + { 0x368f87d6a53fb0L,0x1d3f3d69a3f240L,0x36bf5f9e40e1c6L, + 0x17f150e01f8456L,0x76e5d0835eb447L,0x662fc0a1207100L, + 0x14e3dd97a98e39L } }, + /* 88 */ + { { 0x0249d9c2663b4bL,0x56b68f9a71ba1cL,0x74b119567f9c02L, + 0x5e6f336d8c92acL,0x2ced58f9f74a84L,0x4b75a2c2a467c5L, + 0x30557011cf740eL }, + { 0x6a87993be454ebL,0x29b7076fb99a68L,0x62ae74aaf99bbaL, + 0x399f9aa8fb6c1bL,0x553c24a396dd27L,0x2868337a815ea6L, + 0x343ab6635cc776L } }, + /* 89 */ + { { 0x0e0b0eec142408L,0x79728229662121L,0x605d0ac75e6250L, + 0x49a097a01edfbeL,0x1e20cd270df6b6L,0x7438a0ca9291edL, + 0x29daa430da5f90L }, + { 0x7a33844624825aL,0x181715986985c1L,0x53a6853cae0b92L, + 0x6d98401bd925e8L,0x5a0a34f5dd5e24L,0x7b818ef53cf265L, + 0x0836e43c9d3194L } }, + /* 90 */ + { { 0x1179b70e6c5fd9L,0x0246d9305dd44cL,0x635255edfbe2fbL, + 0x5397b3523b4199L,0x59350cc47e6640L,0x2b57aa97ed4375L, + 0x37efd31abd153aL }, + { 0x7a7afa6907f4faL,0x75c10cb94e6a7eL,0x60a925ab69cc47L, + 0x2ff5bcd9239bd5L,0x13c2113e425f11L,0x56bd3d2f8a1437L, + 0x2c9adbab13774fL } }, + /* 91 */ + { { 0x4ab9f52a2e5f2bL,0x5e537e70b58903L,0x0f242658ebe4f2L, + 0x2648a1e7a5f9aeL,0x1b4c5081e73007L,0x6827d4aff51850L, + 0x3925e41726cd01L }, + { 0x56dd8a55ab3cfbL,0x72d6a31b6d5beaL,0x697bd2e5575112L, + 0x66935519a7aa12L,0x55e97dda7a3aceL,0x0e16afb4237b4cL, + 0x00b68fbff08093L } }, + /* 92 */ + { { 0x4b00366481d0d9L,0x37cb031fbfc5c4L,0x14643f6800dd03L, + 0x6793fef60fe0faL,0x4f43e329c92803L,0x1fce86b96a6d26L, + 0x0ad416975e213aL }, + { 0x7cc6a6711adcc9L,0x64b8a63c43c2d9L,0x1e6caa2a67c0d0L, + 0x610deffd17a54bL,0x57d669d5f38423L,0x77364b8f022636L, + 0x36d4d13602e024L } }, + /* 93 */ + { { 0x72e667ae50a2f5L,0x1b15c950c3a21aL,0x3ccc37c72e6dfeL, + 0x027f7e1d094fb8L,0x43ae1e90aa5d7eL,0x3f5feac3d97ce5L, + 0x0363ed0a336e55L }, + { 0x235f73d7663784L,0x5d8cfc588ad5a4L,0x10ab6ff333016eL, + 0x7d8886af2e1497L,0x549f34fd17988eL,0x3fc4fcaee69a33L, + 0x0622b133a13d9eL } }, + /* 94 */ + { { 0x6344cfa796c53eL,0x0e9a10d00136fdL,0x5d1d284a56efd8L, + 0x608b1968f8aca7L,0x2fa5a66776edcaL,0x13430c44f1609cL, + 0x1499973cb2152aL }, + { 0x3764648104ab58L,0x3226e409fadafcL,0x1513a8466459ddL, + 0x649206ec365035L,0x46149aa3f765b1L,0x3aebf0a035248eL, + 0x1ee60b8c373494L } }, + /* 95 */ + { { 0x4e9efcc15f3060L,0x5e5d50fd77cdc8L,0x071e5403516b58L, + 0x1b7d4e89b24ceaL,0x53b1fa66d6dc03L,0x457f15f892ab5fL, + 0x076332c9397260L }, + { 0x31422b79d7584bL,0x0b01d47e41ba80L,0x3e5611a3171528L, + 0x5f53b9a9fc1be4L,0x7e2fc3d82f110fL,0x006cf350ef0fbfL, + 0x123ae98ec81c12L } }, + /* 96 */ + { { 0x310d41df46e2f6L,0x2ff032a286cf13L,0x64751a721c4eadL, + 0x7b62bcc0339b95L,0x49acf0c195afa4L,0x359d48742544e5L, + 0x276b7632d9e2afL }, + { 0x656c6be182579aL,0x75b65a4d85b199L,0x04a911d1721bfaL, + 0x46e023d0e33477L,0x1ec2d580acd869L,0x540b456f398a37L, + 0x001f698210153dL } }, + /* 97 */ + { { 0x3ca35217b00dd0L,0x73961d034f4d3cL,0x4f520b61c4119dL, + 0x4919fde5cccff7L,0x4d0e0e6f38134dL,0x55c22586003e91L, + 0x24d39d5d8f1b19L }, + { 0x4d4fc3d73234dcL,0x40c50c9d5f8368L,0x149afbc86bf2b8L, + 0x1dbafefc21d7f1L,0x42e6b61355107fL,0x6e506cf4b54f29L, + 0x0f498a6c615228L } }, + /* 98 */ + { { 0x30618f437cfaf8L,0x059640658532c4L,0x1c8a4d90e96e1dL, + 0x4a327bcca4fb92L,0x54143b8040f1a0L,0x4ec0928c5a49e4L, + 0x2af5ad488d9b1fL }, + { 0x1b392bd5338f55L,0x539c0292b41823L,0x1fe35d4df86a02L, + 0x5fa5bb17988c65L,0x02b6cb715adc26L,0x09a48a0c2cb509L, + 0x365635f1a5a9f2L } }, + /* 99 */ + { { 0x58aa87bdc21f31L,0x156900c7cb1935L,0x0ec1f75ee2b6cfL, + 0x5f3e35a77ec314L,0x582dec7b9b7621L,0x3e65deb0e8202aL, + 0x325c314b8a66b7L }, + { 0x702e2a22f24d66L,0x3a20e9982014f1L,0x6424c5b86bbfb0L, + 0x424eea4d795351L,0x7fc4cce7c22055L,0x581383fceb92d7L, + 0x32b663f49ee81bL } }, + /* 100 */ + { { 0x76e2d0b648b73eL,0x59ca39fa50bddaL,0x18bb44f786a7e4L, + 0x28c8d49d464360L,0x1b8bf1d3a574eaL,0x7c670b9bf1635aL, + 0x2efb30a291f4b3L }, + { 0x5326c069cec548L,0x03bbe481416531L,0x08a415c8d93d6fL, + 0x3414a52120d383L,0x1f17a0fc6e9c5cL,0x0de9a090717463L, + 0x22d84b3c67ff07L } }, + /* 101 */ + { { 0x30b5014c3830ebL,0x70791dc1a18b37L,0x09e6ea4e24f423L, + 0x65e148a5253132L,0x446f05d5d40449L,0x7ad5d3d707c0e9L, + 0x18eedd63dd3ab5L }, + { 0x40d2eac6bb29e0L,0x5b0e9605e83c38L,0x554f2c666a56a8L, + 0x0ac27b6c94c48bL,0x1aaecdd91bafe5L,0x73c6e2bdf72634L, + 0x306dab96d19e03L } }, + /* 102 */ + { { 0x6d3e4b42772f41L,0x1aba7796f3a39bL,0x3a03fbb980e9c0L, + 0x2f2ea5da2186a8L,0x358ff444ef1fcfL,0x0798cc0329fcdcL, + 0x39a28bcc9aa46dL }, + { 0x42775c977fe4d2L,0x5eb8fc5483d6b0L,0x0bfe37c039e3f7L, + 0x429292eaf9df60L,0x188bdf4b840cd5L,0x06e10e090749cdL, + 0x0e52678e73192eL } }, + /* 103 */ + { { 0x05de80b08df5feL,0x2af8c77406c5f8L,0x53573c50a0304aL, + 0x277b10b751bca0L,0x65cf8c559132a5L,0x4c667abe25f73cL, + 0x0271809e05a575L }, + { 0x41ced461f7a2fbL,0x0889a9ebdd7075L,0x320c63f2b7760eL, + 0x4f8d4324151c63L,0x5af47315be2e5eL,0x73c62f6aee2885L, + 0x206d6412a56a97L } }, + /* 104 */ + { { 0x6b1c508b21d232L,0x3781185974ead6L,0x1aba7c3ebe1fcfL, + 0x5bdc03cd3f3a5aL,0x74a25036a0985bL,0x5929e30b7211b2L, + 0x16a9f3bc366bd7L }, + { 0x566a7057dcfffcL,0x23b5708a644bc0L,0x348cda2aa5ba8cL, + 0x466aa96b9750d4L,0x6a435ed9b20834L,0x2e7730f2cf9901L, + 0x2b5cd71d5b0410L } }, + /* 105 */ + { { 0x285ab3cee76ef4L,0x68895e3a57275dL,0x6fab2e48fd1265L, + 0x0f1de060428c94L,0x668a2b080b5905L,0x1b589dc3b0cb37L, + 0x3c037886592c9bL }, + { 0x7fb5c0f2e90d4dL,0x334eefb3d8c91aL,0x75747124700388L, + 0x547a2c2e2737f5L,0x2af9c080e37541L,0x0a295370d9091aL, + 0x0bb5c36dad99e6L } }, + /* 106 */ + { { 0x644116586f25cbL,0x0c3f41f9ee1f5dL,0x00628d43a3dedaL, + 0x16e1437aae9669L,0x6aba7861bf3e59L,0x60735631ff4c44L, + 0x345609efaa615eL }, + { 0x41f54792e6acefL,0x4791583f75864dL,0x37f2ff5c7508b1L, + 0x1288912516c3b0L,0x51a2135f6a539bL,0x3b775511f42091L, + 0x127c6afa7afe66L } }, + /* 107 */ + { { 0x79f4f4f7492b73L,0x583d967256342dL,0x51a729bff33ca3L, + 0x3977d2c22d8986L,0x066f528ba8d40bL,0x5d759d30f8eb94L, + 0x0f8e649192b408L }, + { 0x22d84e752555bbL,0x76953855c728c7L,0x3b2254e72aaaa4L, + 0x508cd4ce6c0212L,0x726296d6b5a6daL,0x7a77aa066986f3L, + 0x2267a497bbcf31L } }, + /* 108 */ + { { 0x7f3651bf825dc4L,0x3988817388c56fL,0x257313ed6c3dd0L, + 0x3feab7f3b8ffadL,0x6c0d3cb9e9c9b4L,0x1317be0a7b6ac4L, + 0x2a5f399d7df850L }, + { 0x2fe5a36c934f5eL,0x429199df88ded1L,0x435ea21619b357L, + 0x6aac6a063bac2bL,0x600c149978f5edL,0x76543aa1114c95L, + 0x163ca9c83c7596L } }, + /* 109 */ + { { 0x7dda4a3e4daedbL,0x1824cba360a4cdL,0x09312efd70e0c6L, + 0x454e68a146c885L,0x40aee762fe5c47L,0x29811cbd755a59L, + 0x34b37c95f28319L }, + { 0x77c58b08b717d2L,0x309470d9a0f491L,0x1ab9f40448e01cL, + 0x21c8bd819207b1L,0x6a01803e9361bcL,0x6e5e4c350ec415L, + 0x14fd55a91f8798L } }, + /* 110 */ + { { 0x4cee562f512a90L,0x0008361d53e390L,0x3789b307a892cfL, + 0x064f7be8770ae9L,0x41435d848762cfL,0x662204dd38baa6L, + 0x23d6dcf73f6c5aL }, + { 0x69bef2d2c75d95L,0x2b037c0c9bb43eL,0x495fb4d79a34cfL, + 0x184e140c601260L,0x60193f8d435f9cL,0x283fa52a0c3ad2L, + 0x1998635e3a7925L } }, + /* 111 */ + { { 0x1cfd458ce382deL,0x0dddbd201bbcaeL,0x14d2ae8ed45d60L, + 0x73d764ab0c24cbL,0x2a97fe899778adL,0x0dbd1e01eddfe9L, + 0x2ba5c72d4042c3L }, + { 0x27eebc3af788f1L,0x53ffc827fc5a30L,0x6d1d0726d35188L, + 0x4721275c50aa2aL,0x077125f02e690fL,0x6da8142405db5dL, + 0x126cef68992513L } }, + /* 112 */ + { { 0x3c6067035b2d69L,0x2a1ad7db2361acL,0x3debece6cad41cL, + 0x30095b30f9afc1L,0x25f50b9bd9c011L,0x79201b2f2c1da1L, + 0x3b5c151449c5bdL }, + { 0x76eff4127abdb4L,0x2d31e03ce0382aL,0x24ff21f8bda143L, + 0x0671f244fd3ebaL,0x0c1c00b6bcc6fbL,0x18de9f7c3ebefbL, + 0x33dd48c3809c67L } }, + /* 113 */ + { { 0x61d6c2722d94edL,0x7e426e31041cceL,0x4097439f1b47b0L, + 0x579e798b2d205bL,0x6a430d67f830ebL,0x0d2c676700f727L, + 0x05fea83a82f25bL }, + { 0x3f3482df866b98L,0x3dd353b6a5a9cdL,0x77fe6ae1a48170L, + 0x2f75cc2a8f7cddL,0x7442a3863dad17L,0x643de42d877a79L, + 0x0fec8a38fe7238L } }, + /* 114 */ + { { 0x79b70c0760ac07L,0x195d3af37e9b29L,0x1317ff20f7cf27L, + 0x624e1c739e7504L,0x67330ef50f943dL,0x775e8cf455d793L, + 0x17b94d2d913a9fL }, + { 0x4b627203609e7fL,0x06aac5fb93e041L,0x603c515fdc2611L, + 0x2592ca0d7ae472L,0x02395d1f50a6cbL,0x466ef9648f85d9L, + 0x297cf879768f72L } }, + /* 115 */ + { { 0x3489d67d85fa94L,0x0a6e5b739c8e04L,0x7ebb5eab442e90L, + 0x52665a007efbd0L,0x0967ca57b0d739L,0x24891f9d932b63L, + 0x3cc2d6dbadc9d3L }, + { 0x4b4773c81c5338L,0x73cd47dad7a0f9L,0x7c755bab6ae158L, + 0x50b03d6becefcaL,0x574d6e256d57f0L,0x188db4fffb92aeL, + 0x197e10118071eaL } }, + /* 116 */ + { { 0x45d0cbcba1e7f1L,0x1180056abec91aL,0x6c5f86624bbc28L, + 0x442c83f3b8e518L,0x4e16ae1843ecb4L,0x670cef2fd786c9L, + 0x205b4acb637d2cL }, + { 0x70b0e539aa8671L,0x67c982056bebd0L,0x645c831a5e7c36L, + 0x09e06951a14b32L,0x5dd610ad4c89e6L,0x41c35f20164831L, + 0x3821f29cb4cdb8L } }, + /* 117 */ + { { 0x2831ffaba10079L,0x70f6dac9ffe444L,0x1cfa32ccc03717L, + 0x01519fda22a3c8L,0x23215e815aaa27L,0x390671ad65cbf7L, + 0x03dd4d72de7d52L }, + { 0x1ecd972ee95923L,0x166f8da3813e8eL,0x33199bbd387a1aL, + 0x04525fe15e3dc7L,0x44d2ef54165898L,0x4b7e47d3dc47f7L, + 0x10d5c8db0b5d44L } }, + /* 118 */ + { { 0x176d95ba9cdb1bL,0x14025f04f23dfcL,0x49379332891687L, + 0x6625e5ccbb2a57L,0x7ac0abdbf9d0e5L,0x7aded4fbea15b2L, + 0x314844ac184d67L }, + { 0x6d9ce34f05eae3L,0x3805d2875856d2L,0x1c2122f85e40ebL, + 0x51cb9f2d483a9aL,0x367e91e20f1702L,0x573c3559838dfdL, + 0x0b282b0cb85af1L } }, + /* 119 */ + { { 0x6a12e4ef871eb5L,0x64bb517e14f5ffL,0x29e04d3aaa530bL, + 0x1b07d88268f261L,0x411be11ed16fb0L,0x1f480536db70bfL, + 0x17a7deadfd34e4L }, + { 0x76d72f30646612L,0x5a3bbb43a1b0a0L,0x5e1687440e82bfL, + 0x713b5e69481112L,0x46c3dcb499e174L,0x0862da3b4e2a24L, + 0x31cb55b4d62681L } }, + /* 120 */ + { { 0x5ffc74dae5bb45L,0x18944c37adb9beL,0x6aaa63b1ee641aL, + 0x090f4b6ee057d3L,0x4045cedd2ee00fL,0x21c2c798f7c282L, + 0x2c2c6ef38cd6bdL }, + { 0x40d78501a06293L,0x56f8caa5cc89a8L,0x7231d5f91b37aeL, + 0x655f1e5a465c6dL,0x3f59a81f9cf783L,0x09bbba04c23624L, + 0x0f71ee23bbacdeL } }, + /* 121 */ + { { 0x38d398c4741456L,0x5204c0654243c3L,0x34498c916ea77eL, + 0x12238c60e5fe43L,0x0fc54f411c7625L,0x30b2ca43aa80b6L, + 0x06bead1bb6ea92L }, + { 0x5902ba8674b4adL,0x075ab5b0fa254eL,0x58db83426521adL, + 0x5b66b6b3958e39L,0x2ce4e39890e07bL,0x46702513338b37L, + 0x363690c2ded4d7L } }, + /* 122 */ + { { 0x765642c6b75791L,0x0f4c4300d7f673L,0x404d8bbe101425L, + 0x61e91c88651f1bL,0x61ddc9bc60aed8L,0x0ef36910ce2e65L, + 0x04b44367aa63b8L }, + { 0x72822d3651b7dcL,0x4b750157a2716dL,0x091cb4f2118d16L, + 0x662ba93b101993L,0x447cbd54a1d40aL,0x12cdd48d674848L, + 0x16f10415cbec69L } }, + /* 123 */ + { { 0x0c57a3a751cd0eL,0x0833d7478fadceL,0x1e751f55686436L, + 0x489636c58e1df7L,0x26ad6da941266fL,0x22225d3559880fL, + 0x35b397c45ba0e2L }, + { 0x3ca97b70e1f2ceL,0x78e50427a8680cL,0x06137e042a8f91L, + 0x7ec40d2500b712L,0x3f0ad688ad7b0dL,0x24746fb33f9513L, + 0x3638fcce688f0bL } }, + /* 124 */ + { { 0x753163750bed6fL,0x786507cd16157bL,0x1d6ec228ce022aL, + 0x587255f42d1b31L,0x0c6adf72a3a0f6L,0x4bfeee2da33f5eL, + 0x08b7300814de6cL }, + { 0x00bf8df9a56e11L,0x75aead48fe42e8L,0x3de9bad911b2e2L, + 0x0fadb233e4b8bbL,0x5b054e8fd84f7dL,0x5eb3064152889bL, + 0x01c1c6e8c777a1L } }, + /* 125 */ + { { 0x5fa0e598f8fcb9L,0x11c129a1ae18dfL,0x5c41b482a2273bL, + 0x545664e5044c9cL,0x7e01c915bfb9abL,0x7f626e19296aa0L, + 0x20c91a9822a087L }, + { 0x273a9fbe3c378fL,0x0f126b44b7d350L,0x493764a75df951L, + 0x32dec3c367d24bL,0x1a7ae987fed9d3L,0x58a93055928b85L, + 0x11626975d7775fL } }, + /* 126 */ + { { 0x2bb174a95540a9L,0x10de02c58b613fL,0x2fa8f7b861f3eeL, + 0x44731260bdf3b3L,0x19c38ff7da41feL,0x3535a16e3d7172L, + 0x21a948b83cc7feL }, + { 0x0e6f72868bc259L,0x0c70799df3c979L,0x526919955584c3L, + 0x4d95fda04f8fa2L,0x7bb228e6c0f091L,0x4f728b88d92194L, + 0x2b361c5a136bedL } }, + /* 127 */ + { { 0x0c72ca10c53841L,0x4036ab49f9da12L,0x578408d2b7082bL, + 0x2c4903201fbf5eL,0x14722b3f42a6a8L,0x1997b786181694L, + 0x25c6f10de32849L }, + { 0x79f46d517ff2ffL,0x2dc5d97528f6deL,0x518a494489aa72L, + 0x52748f8af3cf97L,0x472da30a96bb16L,0x1be228f92465a9L, + 0x196f0c47d60479L } }, + /* 128 */ + { { 0x47dd7d139b3239L,0x049c9b06775d0fL,0x627ffc00562d5eL, + 0x04f578d5e5e243L,0x43a788ffcef8b9L,0x7db320be9dde28L, + 0x00837528b8572fL }, + { 0x2969eca306d695L,0x195b72795ec194L,0x5e1fa9b8e77e50L, + 0x4c627f2b3fbfd5L,0x4b91e0d0ee10ffL,0x5698c8d0f35833L, + 0x12d3a9431f475eL } }, + /* 129 */ + { { 0x6409457a0db57eL,0x795b35192e0433L,0x146f973fe79805L, + 0x3d49c516dfb9cfL,0x50dfc3646b3cdaL,0x16a08a2210ad06L, + 0x2b4ef5bcd5b826L }, + { 0x5ebabfee2e3e3eL,0x2e048e724d9726L,0x0a7a7ed6abef40L, + 0x71ff7f83e39ad8L,0x3405ac52a1b852L,0x2e3233357a608dL, + 0x38c1bf3b0e40e6L } }, + /* 130 */ + { { 0x59aec823e4712cL,0x6ed9878331ddadL,0x1cc6faf629f2a0L, + 0x445ff79f36c18cL,0x4edc7ed57aff3dL,0x22ee54c8bdd9e8L, + 0x35398f42d72ec5L }, + { 0x4e7a1cceee0ecfL,0x4c66a707dd1d31L,0x629ad157a23c04L, + 0x3b2c6031dc3c83L,0x3336acbcd3d96cL,0x26ce43adfce0f0L, + 0x3c869c98d699dcL } }, + /* 131 */ + { { 0x58b3cd9586ba11L,0x5d6514b8090033L,0x7c88c3bd736782L, + 0x1735f84f2130edL,0x47784095a9dee0L,0x76312c6e47901bL, + 0x1725f6ebc51455L }, + { 0x6744344bc4503eL,0x16630b4d66e12fL,0x7b3481752c3ec7L, + 0x47bb2ed1f46f95L,0x08a1a497dd1bcfL,0x1f525df2b8ed93L, + 0x0fe492ea993713L } }, + /* 132 */ + { { 0x71b8dd7268b448L,0x1743dfaf3728d7L,0x23938d547f530aL, + 0x648c3d497d0fc6L,0x26c0d769e3ad45L,0x4d25108769a806L, + 0x3fbf2025143575L }, + { 0x485bfd90339366L,0x2de2b99ed87461L,0x24a33347713badL, + 0x1674bc7073958aL,0x5bb2373ee85b5fL,0x57f9bd657e662cL, + 0x2041b248d39042L } }, + /* 133 */ + { { 0x5f01617d02f4eeL,0x2a8e31c4244b91L,0x2dab3e790229e0L, + 0x72d319ea7544afL,0x01ffb8b000cb56L,0x065e63b0daafd3L, + 0x3d7200a7111d6fL }, + { 0x4561ce1b568973L,0x37034c532dd8ecL,0x1368215020be02L, + 0x30e7184cf289ebL,0x199e0c27d815deL,0x7ee1b4dff324e5L, + 0x2f4a11de7fab5cL } }, + /* 134 */ + { { 0x33c2f99b1cdf2bL,0x1e0d78bf42a2c0L,0x64485dececaa67L, + 0x2242a41be93e92L,0x62297b1f15273cL,0x16ebfaafb02205L, + 0x0f50f805f1fdabL }, + { 0x28bb0b3a70eb28L,0x5b1c7d0160d683L,0x05c30a37959f78L, + 0x3d9301184922d2L,0x46c1ead7dbcb1aL,0x03ee161146a597L, + 0x2d413ed9a6ccc1L } }, + /* 135 */ + { { 0x685ab5f97a27c2L,0x59178214023751L,0x4ffef3c585ab17L, + 0x2bc85302aba2a9L,0x675b001780e856L,0x103c8a37f0b33dL, + 0x2241e98ece70a6L }, + { 0x546738260189edL,0x086c8f7a6b96edL,0x00832ad878a129L, + 0x0b679056ba7462L,0x020ce6264bf8c4L,0x3f9f4b4d92abfbL, + 0x3e9c55343c92edL } }, + /* 136 */ + { { 0x482cec9b3f5034L,0x08b59b3cd1fa30L,0x5a55d1bc8e58b5L, + 0x464a5259337d8eL,0x0a5b6c66ade5a5L,0x55db77b504ddadL, + 0x015992935eac35L }, + { 0x54fe51025e32fcL,0x5d7f52dbe4a579L,0x08c564a8c58696L, + 0x4482a8bec4503fL,0x440e75d9d94de9L,0x6992d768020bfaL, + 0x06c311e8ba01f6L } }, + /* 137 */ + { { 0x2a6ac808223878L,0x04d3ccb4aab0b8L,0x6e6ef09ff6e823L, + 0x15cb03ee9158dcL,0x0dc58919171bf7L,0x3273568abf3cb1L, + 0x1b55245b88d98bL }, + { 0x28e9383b1de0c1L,0x30d5009e4f1f1bL,0x334d185a56a134L, + 0x0875865dfa4c46L,0x266edf5eae3beeL,0x2e03ff16d1f7e5L, + 0x29a36bd9f0c16dL } }, + /* 138 */ + { { 0x004cff44b2e045L,0x426c96380ba982L,0x422292281e46d7L, + 0x508dd8d29d7204L,0x3a4ea73fb2995eL,0x4be64090ae07b2L, + 0x3339177a0eff22L }, + { 0x74a97ec2b3106eL,0x0c616d09169f5fL,0x1bb5d8907241a7L, + 0x661fb67f6d41bdL,0x018a88a0daf136L,0x746333a093a7b4L, + 0x3e19f1ac76424eL } }, + /* 139 */ + { { 0x542a5656527296L,0x0e7b9ce22f1bc9L,0x31b0945992b89bL, + 0x6e0570eb85056dL,0x32daf813483ae5L,0x69eeae9d59bb55L, + 0x315ad4b730b557L }, + { 0x2bc16795f32923L,0x6b02b7ba55130eL,0x1e9da67c012f85L, + 0x5616f014dabf8fL,0x777395fcd9c723L,0x2ff075e7743246L, + 0x2993538aff142eL } }, + /* 140 */ + { { 0x72dae20e552b40L,0x2e4ba69aa5d042L,0x001e563e618bd2L, + 0x28feeba3c98772L,0x648c356da2a907L,0x687e2325069ea7L, + 0x0d34ab09a394f0L }, + { 0x73c21813111286L,0x5829b53b304e20L,0x6fba574de08076L, + 0x79f7058f61614eL,0x4e71c9316f1191L,0x24ef12193e0a89L, + 0x35dc4e2bc9d848L } }, + /* 141 */ + { { 0x045e6d3b4ad1cdL,0x729c95493782f0L,0x77f59de85b361aL, + 0x5309b4babf28f8L,0x4d893d9290935fL,0x736f47f2b2669eL, + 0x23270922d757f3L }, + { 0x23a4826f70d4e9L,0x68a8c63215d33eL,0x4d6c2069205c9cL, + 0x46b2938a5eebe0L,0x41d1f1e2de3892L,0x5ca1775544bcb0L, + 0x3130629e5d19dcL } }, + /* 142 */ + { { 0x6e2681593375acL,0x117cfbabc22621L,0x6c903cd4e13ccaL, + 0x6f358f14d4bd97L,0x1bc58fa11089f1L,0x36aa2db4ac426aL, + 0x15ced8464b7ea1L }, + { 0x6966836cba7df5L,0x7c2b1851568113L,0x22b50ff2ffca66L, + 0x50e77d9f48e49aL,0x32775e9bbc7cc9L,0x403915bb0ece71L, + 0x1b8ec7cb9dd7aaL } }, + /* 143 */ + { { 0x65a888b677788bL,0x51887fac2e7806L,0x06792636f98d2bL, + 0x47bbcd59824c3bL,0x1aca908c43e6dcL,0x2e00d15c708981L, + 0x08e031c2c80634L }, + { 0x77fbc3a297c5ecL,0x10a7948af2919eL,0x10cdafb1fb6b2fL, + 0x27762309b486f0L,0x13abf26bbac641L,0x53da38478fc3eeL, + 0x3c22eff379bf55L } }, + /* 144 */ + { { 0x0163f484770ee3L,0x7f28e8942e0cbfL,0x5f86cb51b43831L, + 0x00feccd4e4782fL,0x40e5b417eafe7dL,0x79e5742bbea228L, + 0x3717154aa469beL }, + { 0x271d74a270f721L,0x40eb400890b70cL,0x0e37be81d4cb02L, + 0x786907f4e8d43fL,0x5a1f5b590a7acbL,0x048861883851fdL, + 0x11534a1e563dbbL } }, + /* 145 */ + { { 0x37a6357c525435L,0x6afe6f897b78a5L,0x7b7ff311d4f67bL, + 0x38879df15dc9f4L,0x727def7b8ba987L,0x20285dd0db4436L, + 0x156b0fc64b9243L }, + { 0x7e3a6ec0c1c390L,0x668a88d9bcf690L,0x5925aba5440dbeL, + 0x0f6891a044f593L,0x70b46edfed4d97L,0x1a6cc361bab201L, + 0x046f5bc6e160bcL } }, + /* 146 */ + { { 0x79350f076bc9d1L,0x077d9e79a586b9L,0x0896bc0c705764L, + 0x58e632b90e7e46L,0x14e87e0ad32488L,0x4b1bb3f72c6e00L, + 0x3c3ce9684a5fc5L }, + { 0x108fbaf1f703aaL,0x08405ecec17577L,0x199a8e2d44be73L, + 0x2eb22ed0067763L,0x633944deda3300L,0x20d739eb8e5efbL, + 0x2bbbd94086b532L } }, + /* 147 */ + { { 0x03c8b17a19045dL,0x6205a0a504980bL,0x67fdb3e962b9f0L, + 0x16399e01511a4bL,0x44b09fe9dffc96L,0x00a74ff44a1381L, + 0x14590deed3f886L }, + { 0x54e3d5c2a23ddbL,0x310e5138209d28L,0x613f45490c1c9bL, + 0x6bbc85d44bbec8L,0x2f85fc559e73f6L,0x0d71fa7d0fa8cbL, + 0x2898571d17fbb9L } }, + /* 148 */ + { { 0x5607a84335167dL,0x3009c1eb910f91L,0x7ce63447e62d0bL, + 0x03a0633afcf89eL,0x1234b5aaa50872L,0x5a307b534d547bL, + 0x2f4e97138a952eL }, + { 0x13914c2db0f658L,0x6cdcb47e6e75baL,0x5549169caca772L, + 0x0f20423dfeb16fL,0x6b1ae19d180239L,0x0b7b3bee9b7626L, + 0x1ca81adacfe4efL } }, + /* 149 */ + { { 0x219ec3ad19d96fL,0x3549f6548132dbL,0x699889c7aacd0bL, + 0x74602a58730b19L,0x62dc63bcece81cL,0x316f991c0c317aL, + 0x2b8627867b95e3L }, + { 0x67a25ddced1eedL,0x7e14f0eba756e7L,0x0873fbc09b0495L, + 0x0fefb0e16596adL,0x03e6cd98ef39bbL,0x1179b1cded249dL, + 0x35c79c1db1edc2L } }, + /* 150 */ + { { 0x1368309d4245bfL,0x442e55852a7667L,0x095b0f0f348b65L, + 0x6834cf459dfad4L,0x6645950c9be910L,0x06bd81288c71e6L, + 0x1b015b6e944edfL }, + { 0x7a6a83045ab0e3L,0x6afe88b9252ad0L,0x2285bd65523502L, + 0x6c78543879a282L,0x1c5e264b5c6393L,0x3a820c6a7453eeL, + 0x37562d1d61d3c3L } }, + /* 151 */ + { { 0x6c084f62230c72L,0x599490270bc6cfL,0x1d3369ddd3c53dL, + 0x516ddb5fac5da0L,0x35ab1e15011b1aL,0x5fba9106d3a180L, + 0x3be0f092a0917cL }, + { 0x57328f9fdc2538L,0x0526323fc8d5f6L,0x10cbb79521e602L, + 0x50d01167147ae2L,0x2ec7f1b3cda99eL,0x43073cc736e7beL, + 0x1ded89cadd83a6L } }, + /* 152 */ + { { 0x1d51bda65d56d5L,0x63f2fd4d2dc056L,0x326413d310ea6dL, + 0x3abba5bca92876L,0x6b9aa8bc4d6ebeL,0x1961c687f15d5dL, + 0x311cf07464c381L }, + { 0x2321b1064cd8aeL,0x6e3caac4443850L,0x3346fc4887d2d0L, + 0x1640417e0e640fL,0x4a958a52a07a9eL,0x1346a1b1cb374cL, + 0x0a793cf79beccbL } }, + /* 153 */ + { { 0x29d56cba89aaa5L,0x1581898c0b3c15L,0x1af5b77293c082L, + 0x1617ba53a006ceL,0x62dd3b384e475fL,0x71a9820c3f962aL, + 0x0e4938920b854eL }, + { 0x0b8d98849808abL,0x64c14923546de7L,0x6a20883b78a6fcL, + 0x72de211428acd6L,0x009678b47915bbL,0x21b5269ae5dae6L, + 0x313cc0e60b9457L } }, + /* 154 */ + { { 0x69ee421b1de38bL,0x44b484c6cec1c7L,0x0240596c6a8493L, + 0x2321a62c85fb9eL,0x7a10921802a341L,0x3d2a95507e45c3L, + 0x0752f40f3b6714L }, + { 0x596a38798751e6L,0x46bf186a0feb85L,0x0b23093e23b49cL, + 0x1bfa7bc5afdc07L,0x4ba96f873eefadL,0x292e453fae9e44L, + 0x2773646667b75cL } }, + /* 155 */ + { { 0x1f81a64e94f22aL,0x3125ee3d8683ddL,0x76a660a13b9582L, + 0x5aa584c3640c6eL,0x27cc99fd472953L,0x7048f4d58061d1L, + 0x379a1397ac81e8L }, + { 0x5d1ecd2b6b956bL,0x0829e0366b0697L,0x49548cec502421L, + 0x7af5e2f717c059L,0x329a25a0fec54eL,0x028e99e4bcd7f1L, + 0x071d5fe81fca78L } }, + /* 156 */ + { { 0x4b5c4aeb0fdfe4L,0x1367e11326ce37L,0x7c16f020ef5f19L, + 0x3c55303d77b471L,0x23a4457a06e46aL,0x2174426dd98424L, + 0x226f592114bd69L }, + { 0x4411b94455f15aL,0x52e0115381fae4L,0x45b6d8efbc8f7eL, + 0x58b1221bd86d26L,0x284fb6f8a7ec1fL,0x045835939ddd30L, + 0x0216960accd598L } }, + /* 157 */ + { { 0x4b61f9ec1f138aL,0x4460cd1e18502bL,0x277e4fce3c4726L, + 0x0244246d6414b9L,0x28fbfcef256984L,0x3347ed0db40577L, + 0x3b57fa9e044718L }, + { 0x4f73bcd6d1c833L,0x2c0d0dcf7f0136L,0x2010ac75454254L, + 0x7dc4f6151539a8L,0x0b8929ef6ea495L,0x517e20119d2bdfL, + 0x1e29f9a126ba15L } }, + /* 158 */ + { { 0x683a7c10470cd8L,0x0d05f0dbe0007fL,0x2f6a5026d649cdL, + 0x249ce2fdaed603L,0x116dc1e7a96609L,0x199bd8d82a0b98L, + 0x0694ad0219aeb2L }, + { 0x03a3656e864045L,0x4e552273df82a6L,0x19bcc7553d17abL, + 0x74ac536c1df632L,0x440302fb4a86f6L,0x1becec0e31c9feL, + 0x002045f8fa46b8L } }, + /* 159 */ + { { 0x5833ba384310a2L,0x1db83fad93f8baL,0x0a12713ee2f7edL, + 0x40e0f0fdcd2788L,0x1746de5fb239a5L,0x573748965cfa15L, + 0x1e3dedda0ef650L }, + { 0x6c8ca1c87607aeL,0x785dab9554fc0eL,0x649d8f91860ac8L, + 0x4436f88b52c0f9L,0x67f22ca8a5e4a3L,0x1f990fd219e4c9L, + 0x013dd21c08573fL } }, + /* 160 */ + { { 0x05d116141d161cL,0x5c1d2789da2ea5L,0x11f0d861f99f34L, + 0x692c2650963153L,0x3bd69f5329539eL,0x215898eef8885fL, + 0x041f79dd86f7f1L }, + { 0x76dcc5e96beebdL,0x7f2b50cb42a332L,0x067621cabef8abL, + 0x31e0be607054edL,0x4c67c5e357a3daL,0x5b1a63fbfb1c2bL, + 0x3112efbf5e5c31L } }, + /* 161 */ + { { 0x3f83e24c0c62f1L,0x51dc9c32aae4e0L,0x2ff89b33b66c78L, + 0x21b1c7d354142cL,0x243d8d381c84bcL,0x68729ee50cf4b7L, + 0x0ed29e0f442e09L }, + { 0x1ad7b57576451eL,0x6b2e296d6b91dcL,0x53f2b306e30f42L, + 0x3964ebd9ee184aL,0x0a32855df110e4L,0x31f2f90ddae05fL, + 0x3410cd04e23702L } }, + /* 162 */ + { { 0x60d1522ca8f2feL,0x12909237a83e34L,0x15637f80d58590L, + 0x3c72431b6d714dL,0x7c8e59a615bea2L,0x5f977b688ef35aL, + 0x071c198c0b3ab0L }, + { 0x2b54c699699b4bL,0x14da473c2fd0bcL,0x7ba818ea0ad427L, + 0x35117013940b2fL,0x6e1df6b5e609dbL,0x3f42502720b64dL, + 0x01ee7dc890e524L } }, + /* 163 */ + { { 0x12ec1448ff4e49L,0x3e2edac882522bL,0x20455ab300f93aL, + 0x5849585bd67c14L,0x0393d5aa34ba8bL,0x30f9a1f2044fa7L, + 0x1059c9377a93e0L }, + { 0x4e641cc0139e73L,0x0d9f23c9b0fa78L,0x4b2ad87e2b83f9L, + 0x1c343a9f6d9e3cL,0x1098a4cb46de4dL,0x4ddc893843a41eL, + 0x1797f4167d6e3aL } }, + /* 164 */ + { { 0x4add4675856031L,0x499bd5e5f7a0ffL,0x39ea1f1202271eL, + 0x0ecd7480d7a91eL,0x395f5e5fc10956L,0x0fa7f6b0c9f79bL, + 0x2fad4623aed6cbL }, + { 0x1563c33ae65825L,0x29881cafac827aL,0x50650baf4c45a1L, + 0x034aad988fb9e9L,0x20a6224dc5904cL,0x6fb141a990732bL, + 0x3ec9ae1b5755deL } }, + /* 165 */ + { { 0x3108e7c686ae17L,0x2e73a383b4ad8aL,0x4e6bb142ba4243L, + 0x24d355922c1d80L,0x2f850dd9a088baL,0x21c50325dd5e70L, + 0x33237dd5bd7fa4L }, + { 0x7823a39cab7630L,0x1535f71cff830eL,0x70d92ff0599261L, + 0x227154d2a2477cL,0x495e9bbb4f871cL,0x40d2034835686bL, + 0x31b08f97eaa942L } }, + /* 166 */ + { { 0x0016c19034d8ddL,0x68961627cf376fL,0x6acc90681615aeL, + 0x6bc7690c2e3204L,0x6ddf28d2fe19a2L,0x609b98f84dae4dL, + 0x0f32bfd7c94413L }, + { 0x7d7edc6b21f843L,0x49bbd2ebbc9872L,0x593d6ada7b6a23L, + 0x55736602939e9cL,0x79461537680e39L,0x7a7ee9399ca7cdL, + 0x008776f6655effL } }, + /* 167 */ + { { 0x64585f777233cfL,0x63ec12854de0f6L,0x6b7f9bbbc3f99dL, + 0x301c014b1b55d3L,0x7cf3663bbeb568L,0x24959dcb085bd1L, + 0x12366aa6752881L }, + { 0x77a74c0da5e57aL,0x3279ca93ad939fL,0x33c3c8a1ef08c9L, + 0x641b05ab42825eL,0x02f416d7d098dbL,0x7e3d58be292b68L, + 0x1864dbc46e1f46L } }, + /* 168 */ + { { 0x1da167b8153a9dL,0x47593d07d9e155L,0x386d984e12927fL, + 0x421a6f08a60c7cL,0x5ae9661c24dab3L,0x7927b2e7874507L, + 0x3266ea80609d53L }, + { 0x7d198f4c26b1e3L,0x430d4ea2c4048eL,0x58d8ab77e84ba3L, + 0x1cb14299c37297L,0x6db6031e8f695cL,0x159bd855e26d55L, + 0x3f3f6d318a73ddL } }, + /* 169 */ + { { 0x3ee958cca40298L,0x02a7e5eba32ad6L,0x43b4bab96f0e1eL, + 0x534be79062b2b1L,0x029ead089b37e3L,0x4d585da558f5aaL, + 0x1f9737eb43c376L }, + { 0x0426dfd9b86202L,0x4162866bc0a9f3L,0x18fc518e7bb465L, + 0x6db63380fed812L,0x421e117f709c30L,0x1597f8d0f5cee6L, + 0x04ffbf1289b06aL } }, + /* 170 */ + { { 0x61a1987ffa0a5fL,0x42058c7fc213c6L,0x15b1d38447d2c9L, + 0x3d5f5d7932565eL,0x5db754af445fa7L,0x5d489189fba499L, + 0x02c4c55f51141bL }, + { 0x26b15972e9993dL,0x2fc90bcbd97c45L,0x2ff60f8684b0f1L, + 0x1dc641dd339ab0L,0x3e38e6be23f82cL,0x3368162752c817L, + 0x19bba80ceb45ceL } }, + /* 171 */ + { { 0x7c6e95b4c6c693L,0x6bbc6d5efa7093L,0x74d7f90bf3bf1cL, + 0x54d5be1f0299a1L,0x7cb24f0aa427c6L,0x0a18f3e086c941L, + 0x058a1c90e4faefL }, + { 0x3d6bd016927e1eL,0x1da4ce773098b8L,0x2133522e690056L, + 0x0751416d3fc37eL,0x1beed1643eda66L,0x5288b6727d5c54L, + 0x199320e78655c6L } }, + /* 172 */ + { { 0x74575027eeaf94L,0x124bd533c3ceaeL,0x69421ab7a8a1d7L, + 0x37f2127e093f3dL,0x40281765252a08L,0x25a228798d856dL, + 0x326eca62759c4cL }, + { 0x0c337c51acb0a5L,0x122ba78c1ef110L,0x02498adbb68dc4L, + 0x67240c124b089eL,0x135865d25d9f89L,0x338a76d5ae5670L, + 0x03a8efaf130385L } }, + /* 173 */ + { { 0x3a450ac5e49beaL,0x282af80bb4b395L,0x6779eb0db1a139L, + 0x737cabdd174e55L,0x017b14ca79b5f2L,0x61fdef6048e137L, + 0x3acc12641f6277L }, + { 0x0f730746fe5096L,0x21d05c09d55ea1L,0x64d44bddb1a560L, + 0x75e5035c4778deL,0x158b7776613513L,0x7b5efa90c7599eL, + 0x2caa0791253b95L } }, + /* 174 */ + { { 0x288e5b6d53e6baL,0x435228909d45feL,0x33b4cf23b2a437L, + 0x45b352017d6db0L,0x4372d579d6ef32L,0x0fa9e5badbbd84L, + 0x3a78cff24759bbL }, + { 0x0899d2039eab6eL,0x4cf47d2f76bc22L,0x373f739a3a8c69L, + 0x09beaa5b1000b3L,0x0acdfbe83ebae5L,0x10c10befb0e900L, + 0x33d2ac4cc31be3L } }, + /* 175 */ + { { 0x765845931e08fbL,0x2a3c2a0dc58007L,0x7270da587d90e1L, + 0x1ee648b2bc8f86L,0x5d2ca68107b29eL,0x2b7064846e9e92L, + 0x3633ed98dbb962L }, + { 0x5e0f16a0349b1bL,0x58d8941f570ca4L,0x20abe376a4cf34L, + 0x0f4bd69a360977L,0x21eb07cc424ba7L,0x720d2ecdbbe6ecL, + 0x255597d5a97c34L } }, + /* 176 */ + { { 0x67bbf21a0f5e94L,0x422a3b05a64fc1L,0x773ac447ebddc7L, + 0x1a1331c08019f1L,0x01ef6d269744ddL,0x55f7be5b3b401aL, + 0x072e031c681273L }, + { 0x7183289e21c677L,0x5e0a3391f3162fL,0x5e02d9e65d914aL, + 0x07c79ea1adce2fL,0x667ca5c2e1cbe4L,0x4f287f22caccdaL, + 0x27eaa81673e75bL } }, + /* 177 */ + { { 0x5246180a078fe6L,0x67cc8c9fa3bb15L,0x370f8dd123db31L, + 0x1938dafa69671aL,0x5af72624950c5eL,0x78cc5221ebddf8L, + 0x22d616fe2a84caL }, + { 0x723985a839327fL,0x24fa95584a5e22L,0x3d8a5b3138d38bL, + 0x3829ef4a017acfL,0x4f09b00ae055c4L,0x01df84552e4516L, + 0x2a7a18993e8306L } }, + /* 178 */ + { { 0x7b6224bc310eccL,0x69e2cff429da16L,0x01c850e5722869L, + 0x2e4889443ee84bL,0x264a8df1b3d09fL,0x18a73fe478d0d6L, + 0x370b52740f9635L }, + { 0x52b7d3a9d6f501L,0x5c49808129ee42L,0x5b64e2643fd30cL, + 0x27d903fe31b32cL,0x594cb084d078f9L,0x567fb33e3ae650L, + 0x0db7be9932cb65L } }, + /* 179 */ + { { 0x19b78113ed7cbeL,0x002b2f097a1c8cL,0x70b1dc17fa5794L, + 0x786e8419519128L,0x1a45ba376af995L,0x4f6aa84b8d806cL, + 0x204b4b3bc7ca47L }, + { 0x7581a05fd94972L,0x1c73cadb870799L,0x758f6fefc09b88L, + 0x35c62ba8049b42L,0x6f5e71fc164cc3L,0x0cd738b5702721L, + 0x10021afac9a423L } }, + /* 180 */ + { { 0x654f7937e3c115L,0x5d198288b515cbL,0x4add965c25a6e3L, + 0x5a37df33cd76ffL,0x57bb7e288e1631L,0x049b69089e1a31L, + 0x383a88f4122a99L }, + { 0x4c0e4ef3d80a73L,0x553c77ac9f30e2L,0x20bb18c2021e82L, + 0x2aec0d1c4225c5L,0x397fce0ac9c302L,0x2ab0c2a246e8aaL, + 0x02e5e5190be080L } }, + /* 181 */ + { { 0x7a255a4ae03080L,0x0d68b01513f624L,0x29905bd4e48c8cL, + 0x1d81507027466bL,0x1684aaeb70dee1L,0x7dd460719f0981L, + 0x29c43b0f0a390cL }, + { 0x272567681b1f7dL,0x1d2a5f8502e0efL,0x0fd5cd6b221befL, + 0x5eb4749e9a0434L,0x7d1553a324e2a6L,0x2eefd8e86a7804L, + 0x2ad80d5335109cL } }, + /* 182 */ + { { 0x25342aef4c209dL,0x24e811ac4e0865L,0x3f209757f8ae9dL, + 0x1473ff8a5da57bL,0x340f61c3919cedL,0x7523bf85fb9bc0L, + 0x319602ebca7cceL }, + { 0x121e7541d442cbL,0x4ffa748e49c95cL,0x11493cd1d131dcL, + 0x42b215172ab6b5L,0x045fd87e13cc77L,0x0ae305df76342fL, + 0x373b033c538512L } }, + /* 183 */ + { { 0x389541e9539819L,0x769f3b29b7e239L,0x0d05f695e3232cL, + 0x029d04f0e9a9fbL,0x58b78b7a697fb8L,0x7531b082e6386bL, + 0x215d235bed95a9L }, + { 0x503947c1859c5dL,0x4b82a6ba45443fL,0x78328eab71b3a5L, + 0x7d8a77f8cb3509L,0x53fcd9802e41d4L,0x77552091976edbL, + 0x226c60ad7a5156L } }, + /* 184 */ + { { 0x77ad6a43360710L,0x0fdeabd326d7aeL,0x4012886c92104aL, + 0x2d6c378dd7ae33L,0x7e72ef2c0725f3L,0x4a4671f4ca18e0L, + 0x0afe3b4bb6220fL }, + { 0x212cf4b56e0d6aL,0x7c24d086521960L,0x0662cf71bd414dL, + 0x1085b916c58c25L,0x781eed2be9a350L,0x26880e80db6ab2L, + 0x169e356442f061L } }, + /* 185 */ + { { 0x57aa2ad748b02cL,0x68a34256772a9aL,0x1591c44962f96cL, + 0x110a9edd6e53d2L,0x31eab597e091a3L,0x603e64e200c65dL, + 0x2f66b72e8a1cfcL }, + { 0x5c79d138543f7fL,0x412524363fdfa3L,0x547977e3b40008L, + 0x735ca25436d9f7L,0x232b4888cae049L,0x27ce37a53d8f23L, + 0x34d45881a9b470L } }, + /* 186 */ + { { 0x76b95255924f43L,0x035c9f3bd1aa5dL,0x5eb71a010b4bd0L, + 0x6ce8dda7e39f46L,0x35679627ea70c0L,0x5c987767c7d77eL, + 0x1fa28952b620b7L }, + { 0x106f50b5924407L,0x1cc3435a889411L,0x0597cdce3bc528L, + 0x738f8b0d5077d1L,0x5894dd60c7dd6aL,0x0013d0721f5e2eL, + 0x344573480527d3L } }, + /* 187 */ + { { 0x2e2c1da52abf77L,0x394aa8464ad05eL,0x095259b7330a83L, + 0x686e81cf6a11f5L,0x405c7e48c93c7cL,0x65c3ca9444a2ecL, + 0x07bed6c59c3563L }, + { 0x51f9d994fb1471L,0x3c3ecfa5283b4eL,0x494dccda63f6ccL, + 0x4d07b255363a75L,0x0d2b6d3155d118L,0x3c688299fc9497L, + 0x235692fa3dea3aL } }, + /* 188 */ + { { 0x16b4d452669e98L,0x72451fa85406b9L,0x674a145d39151fL, + 0x325ffd067ae098L,0x527e7805cd1ae0L,0x422a1d1789e48dL, + 0x3e27be63f55e07L }, + { 0x7f95f6dee0b63fL,0x008e444cc74969L,0x01348f3a72b614L, + 0x000cfac81348c3L,0x508ae3e5309ce5L,0x2584fcdee44d34L, + 0x3a4dd994899ee9L } }, + /* 189 */ + { { 0x4d289cc0368708L,0x0e5ebc60dc3b40L,0x78cc44bfab1162L, + 0x77ef2173b7d11eL,0x06091718e39746L,0x30fe19319b83a4L, + 0x17e8f2988529c6L }, + { 0x68188bdcaa9f2aL,0x0e64b1350c1bddL,0x5b18ebac7cc4b3L, + 0x75315a9fcc046eL,0x36e9770fd43db4L,0x54c5857fc69121L, + 0x0417e18f3e909aL } }, + /* 190 */ + { { 0x29795db38059adL,0x6efd20c8fd4016L,0x3b6d1ce8f95a1aL, + 0x4db68f177f8238L,0x14ec7278d2340fL,0x47bd77ff2b77abL, + 0x3d2dc8cd34e9fcL }, + { 0x285980a5a83f0bL,0x08352e2d516654L,0x74894460481e1bL, + 0x17f6f3709c480dL,0x6b590d1b55221eL,0x45c100dc4c9be9L, + 0x1b13225f9d8b91L } }, + /* 191 */ + { { 0x0b905fb4b41d9dL,0x48cc8a474cb7a2L,0x4eda67e8de09b2L, + 0x1de47c829adde8L,0x118ad5b9933d77L,0x7a12665ac3f9a4L, + 0x05631a4fb52997L }, + { 0x5fb2a8e6806e63L,0x27d96bbcca369bL,0x46066f1a6b8c7bL, + 0x63b58fc7ca3072L,0x170a36229c0d62L,0x57176f1e463203L, + 0x0c7ce083e73b9cL } }, + /* 192 */ + { { 0x31caf2c09e1c72L,0x6530253219e9d2L,0x7650c98b601c57L, + 0x182469f99d56c0L,0x415f65d292b7a7L,0x30f62a55549b8eL, + 0x30f443f643f465L }, + { 0x6b35c575ddadd0L,0x14a23cf6d299eeL,0x2f0198c0967d7dL, + 0x1013058178d5bfL,0x39da601c9cc879L,0x09d8963ec340baL, + 0x1b735db13ad2a7L } }, + /* 193 */ + { { 0x20916ffdc83f01L,0x16892aa7c9f217L,0x6bff179888d532L, + 0x4adf3c3d366288L,0x41a62b954726aeL,0x3139609022aeb6L, + 0x3e8ab9b37aff7aL }, + { 0x76bbc70f24659aL,0x33fa98513886c6L,0x13b26af62c4ea6L, + 0x3c4d5826389a0cL,0x526ec28c02bf6aL,0x751ff083d79a7cL, + 0x110ac647990224L } }, + /* 194 */ + { { 0x2c6c62fa2b6e20L,0x3d37edad30c299L,0x6ef25b44b65fcaL, + 0x7470846914558eL,0x712456eb913275L,0x075a967a9a280eL, + 0x186c8188f2a2a0L }, + { 0x2f3b41a6a560b1L,0x3a8070b3f9e858L,0x140936ff0e1e78L, + 0x5fd298abe6da8aL,0x3823a55d08f153L,0x3445eafaee7552L, + 0x2a5fc96731a8b2L } }, + /* 195 */ + { { 0x06317be58edbbbL,0x4a38f3bfbe2786L,0x445b60f75896b7L, + 0x6ec7c92b5adf57L,0x07b6be8038a441L,0x1bcfe002879655L, + 0x2a2174037d6d0eL }, + { 0x776790cf9e48bdL,0x73e14a2c4ed1d3L,0x7eb5ed5f2fc2f7L, + 0x3e0aedb821b384L,0x0ee3b7e151c12fL,0x51a6a29e044bb2L, + 0x0ba13a00cb0d86L } }, + /* 196 */ + { { 0x77607d563ec8d8L,0x023fc726996e44L,0x6bd63f577a9986L, + 0x114a6351e53973L,0x3efe97989da046L,0x1051166e117ed7L, + 0x0354933dd4fb5fL }, + { 0x7699ca2f30c073L,0x4c973b83b9e6d3L,0x2017c2abdbc3e8L, + 0x0cdcdd7a26522bL,0x511070f5b23c7dL,0x70672327e83d57L, + 0x278f842b4a9f26L } }, + /* 197 */ + { { 0x0824f0d4ae972fL,0x60578dd08dcf52L,0x48a74858290fbbL, + 0x7302748bf23030L,0x184b229a178acfL,0x3e8460ade089d6L, + 0x13f2b557fad533L }, + { 0x7f96f3ae728d15L,0x018d8d40066341L,0x01fb94955a289aL, + 0x2d32ed6afc2657L,0x23f4f5e462c3acL,0x60eba5703bfc5aL, + 0x1b91cc06f16c7aL } }, + /* 198 */ + { { 0x411d68af8219b9L,0x79cca36320f4eeL,0x5c404e0ed72e20L, + 0x417cb8692e43f2L,0x305d29c7d98599L,0x3b754d5794a230L, + 0x1c97fb4be404e9L }, + { 0x7cdbafababd109L,0x1ead0eb0ca5090L,0x1a2b56095303e3L, + 0x75dea935012c8fL,0x67e31c071b1d1dL,0x7c324fbfd172c3L, + 0x157e257e6498f7L } }, + /* 199 */ + { { 0x19b00db175645bL,0x4c4f6cb69725f1L,0x36d9ce67bd47ceL, + 0x2005e105179d64L,0x7b952e717867feL,0x3c28599204032cL, + 0x0f5659d44fb347L }, + { 0x1ebcdedb979775L,0x4378d45cfd11a8L,0x14c85413ca66e9L, + 0x3dd17d681c8a4dL,0x58368e7dc23142L,0x14f3eaac6116afL, + 0x0adb45b255f6a0L } }, + /* 200 */ + { { 0x2f5e76279ad982L,0x125b3917034d09L,0x3839a6399e6ed3L, + 0x32fe0b3ebcd6a2L,0x24ccce8be90482L,0x467e26befcc187L, + 0x2828434e2e218eL }, + { 0x17247cd386efd9L,0x27f36a468d85c3L,0x65e181ef203bbfL, + 0x0433a6761120afL,0x1d607a2a8f8625L,0x49f4e55a13d919L, + 0x3367c3b7943e9dL } }, + /* 201 */ + { { 0x3391c7d1a46d4dL,0x38233d602d260cL,0x02127a0f78b7d4L, + 0x56841c162c24c0L,0x4273648fd09aa8L,0x019480bb0e754eL, + 0x3b927987b87e58L }, + { 0x6676be48c76f73L,0x01ec024e9655aeL,0x720fe1c6376704L, + 0x17e06b98885db3L,0x656adec85a4200L,0x73780893c3ce88L, + 0x0a339cdd8df664L } }, + /* 202 */ + { { 0x69af7244544ac7L,0x31ab7402084d2fL,0x67eceb7ef7cb19L, + 0x16f8583b996f61L,0x1e208d12faf91aL,0x4a91584ce4a42eL, + 0x3e08337216c93eL }, + { 0x7a6eea94f4cf77L,0x07a52894678c60L,0x302dd06b14631eL, + 0x7fddb7225c9ceaL,0x55e441d7acd153L,0x2a00d4490b0f44L, + 0x053ef125338cdbL } }, + /* 203 */ + { { 0x120c0c51584e3cL,0x78b3efca804f37L,0x662108aefb1dccL, + 0x11deb55f126709L,0x66def11ada8125L,0x05bbc0d1001711L, + 0x1ee1c99c7fa316L }, + { 0x746f287de53510L,0x1733ef2e32d09cL,0x1df64a2b0924beL, + 0x19758da8f6405eL,0x28f6eb3913e484L,0x7175a1090cc640L, + 0x048aee0d63f0bcL } }, + /* 204 */ + { { 0x1f3b1e3b0b29c3L,0x48649f4882a215L,0x485eca3a9e0dedL, + 0x4228ba85cc82e4L,0x36da1f39bc9379L,0x1659a7078499d1L, + 0x0a67d5f6c04188L }, + { 0x6ac39658afdce3L,0x0d667a0bde8ef6L,0x0ae6ec0bfe8548L, + 0x6d9cb2650571bfL,0x54bea107760ab9L,0x705c53bd340cf2L, + 0x111a86b610c70fL } }, + /* 205 */ + { { 0x7ecea05c6b8195L,0x4f8be93ce3738dL,0x305de9eb9f5d12L, + 0x2c3b9d3d474b56L,0x673691a05746c3L,0x2e3482c428c6eaL, + 0x2a8085fde1f472L }, + { 0x69d15877fd3226L,0x4609c9ec017cc3L,0x71e9b7fc1c3dbcL, + 0x4f8951254e2675L,0x63ee9d15afa010L,0x0f05775b645190L, + 0x28a0a439397ae3L } }, + /* 206 */ + { { 0x387fa03e9de330L,0x40cc32b828b6abL,0x02a482fbc04ac9L, + 0x68cad6e70429b7L,0x741877bff6f2c4L,0x48efe633d3b28bL, + 0x3e612218fe24b3L }, + { 0x6fc1d34fe37657L,0x3d04b9e1c8b5a1L,0x6a2c332ef8f163L, + 0x7ca97e2b135690L,0x37357d2a31208aL,0x29f02f2332bd68L, + 0x17c674c3e63a57L } }, + /* 207 */ + { { 0x683d9a0e6865bbL,0x5e77ec68ad4ce5L,0x4d18f236788bd6L, + 0x7f34b87204f4e3L,0x391ca40e9e578dL,0x3470ed6ddf4e23L, + 0x225544b3e50989L }, + { 0x48eda8cb4e462bL,0x2a948825cf9109L,0x473adedc7e1300L, + 0x37b843b82192edL,0x2b9ac1537dde36L,0x4efe7412732332L, + 0x29cc5981b5262bL } }, + /* 208 */ + { { 0x190d2fcad260f5L,0x7c53dd81d18027L,0x003def5f55db0eL, + 0x7f5ed25bee2df7L,0x2b87e9be167d2eL,0x2b999c7bbcd224L, + 0x1d68a2c260ad50L }, + { 0x010bcde84607a6L,0x0250de9b7e1bedL,0x746d36bfaf1b56L, + 0x3359475ff56abbL,0x7e84b9bc440b20L,0x2eaa7e3b52f162L, + 0x01165412f36a69L } }, + /* 209 */ + { { 0x639a02329e5836L,0x7aa3ee2e4d3a27L,0x5bc9b258ecb279L, + 0x4cb3dfae2d62c6L,0x08d9d3b0c6c437L,0x5a2c177d47eab2L, + 0x36120479fc1f26L }, + { 0x7609a75bd20e4aL,0x3ba414e17551fcL,0x42cd800e1b90c9L, + 0x04921811b88f9bL,0x4443697f9562fdL,0x3a8081b8186959L, + 0x3f5b5c97379e73L } }, + /* 210 */ + { { 0x6fd0e3cf13eafbL,0x3976b5415cbf67L,0x4de40889e48402L, + 0x17e4d36f24062aL,0x16ae7755cf334bL,0x2730ac94b7e0e1L, + 0x377592742f48e0L }, + { 0x5e10b18a045041L,0x682792afaae5a1L,0x19383ec971b816L, + 0x208b17dae2ffc0L,0x439f9d933179b6L,0x55485a9090bcaeL, + 0x1c316f42a2a35cL } }, + /* 211 */ + { { 0x67173897bdf646L,0x0b6956653ef94eL,0x5be3c97f7ea852L, + 0x3110c12671f08eL,0x2474076a3fc7ecL,0x53408be503fe72L, + 0x09155f53a5b44eL }, + { 0x5c804bdd4c27cdL,0x61e81eb8ffd50eL,0x2f7157fdf84717L, + 0x081f880d646440L,0x7aa892acddec51L,0x6ae70683443f33L, + 0x31ed9e8b33a75aL } }, + /* 212 */ + { { 0x0d724f8e357586L,0x1febbec91b4134L,0x6ff7b98a9475fdL, + 0x1c4d9b94e1f364L,0x2b8790499cef00L,0x42fd2080a1b31dL, + 0x3a3bbc6d9b0145L }, + { 0x75bfebc37e3ca9L,0x28db49c1723bd7L,0x50b12fa8a1f17aL, + 0x733d95bbc84b98L,0x45ede81f6c109eL,0x18f5e46fb37b5fL, + 0x34b980804aaec1L } }, + /* 213 */ + { { 0x56060c8a4f57bfL,0x0d2dfe223054c2L,0x718a5bbc03e5d6L, + 0x7b3344cc19b3b9L,0x4d11c9c054bcefL,0x1f5ad422c22e33L, + 0x2609299076f86bL }, + { 0x7b7a5fba89fd01L,0x7013113ef3b016L,0x23d5e0a173e34eL, + 0x736c14462f0f50L,0x1ef5f7ac74536aL,0x4baba6f4400ea4L, + 0x17b310612c9828L } }, + /* 214 */ + { { 0x4ebb19a708c8d3L,0x209f8c7f03d9bbL,0x00461cfe5798fbL, + 0x4f93b6ae822fadL,0x2e5b33b5ad5447L,0x40b024e547a84bL, + 0x22ffad40443385L }, + { 0x33809c888228bfL,0x559f655fefbe84L,0x0032f529fd2f60L, + 0x5a2191ece3478cL,0x5b957fcd771246L,0x6fec181f9ed123L, + 0x33eed3624136a3L } }, + /* 215 */ + { { 0x6a5df93b26139aL,0x55076598fd7134L,0x356a592f34f81dL, + 0x493c6b5a3d4741L,0x435498a4e2a39bL,0x2cd26a0d931c88L, + 0x01925ea3fc7835L }, + { 0x6e8d992b1efa05L,0x79508a727c667bL,0x5f3c15e6b4b698L, + 0x11b6c755257b93L,0x617f5af4b46393L,0x248d995b2b6656L, + 0x339db62e2e22ecL } }, + /* 216 */ + { { 0x52537a083843dcL,0x6a283c82a768c7L,0x13aa6bf25227acL, + 0x768d76ba8baf5eL,0x682977a6525808L,0x67ace52ac23b0bL, + 0x2374b5a2ed612dL }, + { 0x7139e60133c3a4L,0x715697a4f1d446L,0x4b018bf36677a0L, + 0x1dd43837414d83L,0x505ec70730d4f6L,0x09ac100907fa79L, + 0x21caad6e03217eL } }, + /* 217 */ + { { 0x0776d3999d4d49L,0x33bdd87e8bcff8L,0x1036b87f068fadL, + 0x0a9b8ffde4c872L,0x7ab2533596b1eaL,0x305a88fb965378L, + 0x3356d8fa4d65e5L }, + { 0x3366fa77d1ff11L,0x1e0bdbdcd2075cL,0x46910cefc967caL, + 0x7ce700737a1ff6L,0x1c5dc15409c9bdL,0x368436b9bdb595L, + 0x3e7ccd6560b5efL } }, + /* 218 */ + { { 0x1443789422c792L,0x524792b1717f2bL,0x1f7c1d95048e7aL, + 0x5cfe2a225b0d12L,0x245594d29ce85bL,0x20134d254ce168L, + 0x1b83296803921aL }, + { 0x79a78285b3beceL,0x3c738c3f3124d6L,0x6ab9d1fe0907cdL, + 0x0652ceb7fc104cL,0x06b5f58c8ae3fdL,0x486959261c5328L, + 0x0b3813ae677c90L } }, + /* 219 */ + { { 0x66b9941ac37b82L,0x651a4b609b0686L,0x046711edf3fc31L, + 0x77f89f38faa89bL,0x2683ddbf2d5edbL,0x389ef1dfaa3c25L, + 0x20b3616e66273eL }, + { 0x3c6db6e0cb5d37L,0x5d7ae5dc342bc4L,0x74a1dc6c52062bL, + 0x6f7c0bec109557L,0x5c51f7bc221d91L,0x0d7b5880745288L, + 0x1c46c145c4b0ddL } }, + /* 220 */ + { { 0x59ed485ea99eccL,0x201b71956bc21dL,0x72d5c32f73de65L, + 0x1aefd76547643eL,0x580a452cfb2c2dL,0x7cb1a63f5c4dc9L, + 0x39a8df727737aaL }, + { 0x365a341deca452L,0x714a1ad1689cbaL,0x16981d12c42697L, + 0x5a124f4ac91c75L,0x1b2e3f2fedc0dbL,0x4a1c72b8e9d521L, + 0x3855b4694e4e20L } }, + /* 221 */ + { { 0x16b3d047181ae9L,0x17508832f011afL,0x50d33cfeb2ebd1L, + 0x1deae237349984L,0x147c641aa6adecL,0x24a9fb4ebb1ddbL, + 0x2b367504a7a969L }, + { 0x4c55a3d430301bL,0x379ef6a5d492cbL,0x3c56541fc0f269L, + 0x73a546e91698ceL,0x2c2b62ee0b9b5dL,0x6284184d43d0efL, + 0x0e1f5cf6a4b9f0L } }, + /* 222 */ + { { 0x44833e8cd3fdacL,0x28e6665cb71c27L,0x2f8bf87f4ddbf3L, + 0x6cc6c767fb38daL,0x3bc114d734e8b5L,0x12963d5a78ca29L, + 0x34532a161ece41L }, + { 0x2443af5d2d37e9L,0x54e6008c8c452bL,0x2c55d54111cf1bL, + 0x55ac7f7522575aL,0x00a6fba3f8575fL,0x3f92ef3b793b8dL, + 0x387b97d69ecdf7L } }, + /* 223 */ + { { 0x0b464812d29f46L,0x36161daa626f9aL,0x5202fbdb264ca5L, + 0x21245805ff1304L,0x7f9c4a65657885L,0x542d3887f9501cL, + 0x086420deef8507L }, + { 0x5e159aa1b26cfbL,0x3f0ef5ffd0a50eL,0x364b29663a432aL, + 0x49c56888af32a8L,0x6f937e3e0945d1L,0x3cbdeec6d766cdL, + 0x2d80d342ece61aL } }, + /* 224 */ + { { 0x255e3026d8356eL,0x4ddba628c4de9aL,0x074323b593e0d9L, + 0x333bdb0a10eefbL,0x318b396e473c52L,0x6ebb5a95efd3d3L, + 0x3f3bff52aa4e4fL }, + { 0x3138a111c731d5L,0x674365e283b308L,0x5585edd9c416f2L, + 0x466763d9070fd4L,0x1b568befce8128L,0x16eb040e7b921eL, + 0x3d5c898687c157L } }, + /* 225 */ + { { 0x14827736973088L,0x4e110d53f301e6L,0x1f811b09870023L, + 0x53b5e500dbcacaL,0x4ddf0df1e6a7dcL,0x1e9575fb10ce35L, + 0x3fdc153644d936L }, + { 0x763547e2260594L,0x26e5ae764efc59L,0x13be6f4d791a29L, + 0x2021e61e3a0cf1L,0x339cd2b4a1c202L,0x5c7451e08f5121L, + 0x3728b3a851be68L } }, + /* 226 */ + { { 0x78873653277538L,0x444b9ed2ee7156L,0x79ac8b8b069cd3L, + 0x5f0e90933770e8L,0x307662c615389eL,0x40fe6d95a80057L, + 0x04822170cf993cL }, + { 0x677d5690fbfec2L,0x0355af4ae95cb3L,0x417411794fe79eL, + 0x48daf87400a085L,0x33521d3b5f0aaaL,0x53567a3be00ff7L, + 0x04712ccfb1cafbL } }, + /* 227 */ + { { 0x2b983283c3a7f3L,0x579f11b146a9a6L,0x1143d3b16a020eL, + 0x20f1483ef58b20L,0x3f03e18d747f06L,0x3129d12f15de37L, + 0x24c911f7222833L }, + { 0x1e0febcf3d5897L,0x505e26c01cdaacL,0x4f45a9adcff0e9L, + 0x14dfac063c5cebL,0x69e5ce713fededL,0x3481444a44611aL, + 0x0ea49295c7fdffL } }, + /* 228 */ + { { 0x64554cb4093beeL,0x344b4b18dd81f6L,0x350f43b4de9b59L, + 0x28a96a220934caL,0x4aa8da5689a515L,0x27171cbd518509L, + 0x0cfc1753f47c95L }, + { 0x7dfe091b615d6eL,0x7d1ee0aa0fb5c1L,0x145eef3200b7b5L, + 0x33fe88feeab18fL,0x1d62d4f87453e2L,0x43b8db4e47fff1L, + 0x1572f2b8b8f368L } }, + /* 229 */ + { { 0x6bc94e6b4e84f3L,0x60629dee586a66L,0x3bbad5fe65ca18L, + 0x217670db6c2fefL,0x0320a7f4e3272aL,0x3ccff0d976a6deL, + 0x3c26da8ae48cccL }, + { 0x53ecf156778435L,0x7533064765a443L,0x6c5c12f03ca5deL, + 0x44f8245350dabfL,0x342cdd777cf8b3L,0x2b539c42e9f58dL, + 0x10138affc279b1L } }, + /* 230 */ + { { 0x1b135e204c5ddbL,0x40887dfeaa1d37L,0x7fb0ef83da76ffL, + 0x521f2b79af55a5L,0x3f9b38b4c3f0d0L,0x20a9838cce61ceL, + 0x24bb4e2f4b1e32L }, + { 0x003f6aa386e27cL,0x68df59db0a0f8eL,0x21677d5192e713L, + 0x14ab9757501276L,0x411944af961524L,0x3184f39abc5c3fL, + 0x2a8dda80ca078dL } }, + /* 231 */ + { { 0x0592233cdbc95cL,0x54d5de5c66f40fL,0x351caa1512ab86L, + 0x681bdbee020084L,0x6ee2480c853e68L,0x6a5a44262b918fL, + 0x06574e15a3b91dL }, + { 0x31ba03dacd7fbeL,0x0c3da7c18a57a9L,0x49aaaded492d6bL, + 0x3071ff53469e02L,0x5efb4f0d7248c6L,0x6db5fb67f12628L, + 0x29cff668e3d024L } }, + /* 232 */ + { { 0x1b9ef3bb1b17ceL,0x6ccf8c24fe6312L,0x34c15487f45008L, + 0x1a84044095972cL,0x515073a47e449eL,0x2ddc93f9097feeL, + 0x1008fdc894c434L }, + { 0x08e5edb73399faL,0x65b1aa65547d4cL,0x3a117a1057c498L, + 0x7e16c3089d13acL,0x502f2ae4b6f851L,0x57a70f3eb62673L, + 0x111b48a9a03667L } }, + /* 233 */ + { { 0x5023024be164f1L,0x25ad117032401eL,0x46612b3bfe3427L, + 0x2f4f406a8a02b7L,0x16a93a5c4ddf07L,0x7ee71968fcdbe9L, + 0x2267875ace37daL }, + { 0x687e88b59eb2a6L,0x3ac7368fe716d3L,0x28d953a554a036L, + 0x34d52c0acca08fL,0x742a7cf8dd4fd9L,0x10bfeb8575ea60L, + 0x290e454d868dccL } }, + /* 234 */ + { { 0x4e72a3a8a4bdd2L,0x1ba36d1dee04d5L,0x7a43136b63195bL, + 0x6ca8e286a519f3L,0x568e64aece08a9L,0x571d5000b5c10bL, + 0x3f75e9f5dbdd40L }, + { 0x6fb0a698d6fa45L,0x0ce42209d7199cL,0x1f68275f708a3eL, + 0x5749832e91ec3cL,0x6c3665521428b2L,0x14b2bf5747bd4aL, + 0x3b6f940e42a22bL } }, + /* 235 */ + { { 0x4da0adbfb26c82L,0x16792a585f39acL,0x17df9dfda3975cL, + 0x4796b4afaf479bL,0x67be67234e0020L,0x69df5f201dda25L, + 0x09f71a4d12b3dcL }, + { 0x64ff5ec260a46aL,0x579c5b86385101L,0x4f29a7d549f697L, + 0x4e64261242e2ebL,0x54ecacdfb6b296L,0x46e0638b5fddadL, + 0x31eefd3208891dL } }, + /* 236 */ + { { 0x5b72c749fe01b2L,0x230cf27523713aL,0x533d1810e0d1e1L, + 0x5590db7d1dd1e2L,0x7b8ab73e8e43d3L,0x4c8a19bd1c17caL, + 0x19222ce9f74810L }, + { 0x6398b3dddc4582L,0x0352b7d88dfd53L,0x3c55b4e10c5a63L, + 0x38194d13f8a237L,0x106683fd25dd87L,0x59e0b62443458eL, + 0x196cb70aa9cbb9L } }, + /* 237 */ + { { 0x2885f7cd021d63L,0x162bfd4c3e1043L,0x77173dcf98fcd1L, + 0x13d4591d6add36L,0x59311154d0d8f2L,0x74336e86e79b8aL, + 0x13faadc5661883L }, + { 0x18938e7d9ec924L,0x14bcda8fcaa0a1L,0x706d85d41a1355L, + 0x0ac34520d168deL,0x5a92499fe17826L,0x36c2e3b4f00600L, + 0x29c2fd7b5f63deL } }, + /* 238 */ + { { 0x41250dfe2216c5L,0x44a0ec0366a217L,0x575bc1adf8b0dfL, + 0x5ff5cdbdb1800bL,0x7843d4dde8ca18L,0x5fa9e420865705L, + 0x235c38be6c6b02L }, + { 0x473b78aae91abbL,0x39470c6051e44bL,0x3f973cc2dc08c3L, + 0x2837932c5c91f6L,0x25e39ed754ec25L,0x1371c837118e53L, + 0x3b99f3b0aeafe2L } }, + /* 239 */ + { { 0x03acf51be46c65L,0x271fceacbaf5c3L,0x476589ed3a5e25L, + 0x78ec8c3c3c399cL,0x1f5c8bf4ac4c19L,0x730bb733ec68d2L, + 0x29a37e00dd287eL }, + { 0x448ed1bf92b5faL,0x10827c17b86478L,0x55e6fc05b28263L, + 0x0af1226c73a66aL,0x0b66e5df0d09c1L,0x26128315a02682L, + 0x22d84932c5e808L } }, + /* 240 */ + { { 0x5ec3afc26e3392L,0x08e142e45c0084L,0x4388d5ad0f01feL, + 0x0f7acd36e6140cL,0x028c14ed97dffbL,0x311845675a38c6L, + 0x01c1c8f09a3062L }, + { 0x5a302f4cf49e7dL,0x79267e254a44e1L,0x746165052317a1L, + 0x53a09263a566e8L,0x7d478ad5f73abcL,0x187ce5c947dad3L, + 0x18564e1a1ec45fL } }, + /* 241 */ + { { 0x7b9577a9aa0486L,0x766b40c7aaaef6L,0x1f6a411f5db907L, + 0x4543dd4d80beaeL,0x0ad938c7482806L,0x451568bf4b9be1L, + 0x3367ec85d30a22L }, + { 0x5446425747843dL,0x18d94ac223c6b2L,0x052ff3a354d359L, + 0x0b4933f89723f5L,0x03fb517740e056L,0x226b892871dddaL, + 0x2768c2b753f0fdL } }, + /* 242 */ + { { 0x685282ccfa5200L,0x411ed433627b89L,0x77d5c9b8bc9c1dL, + 0x4a13ef2ee5cd29L,0x5582a612407c9eL,0x2307cb42fc3aa9L, + 0x2e661df79956b8L }, + { 0x0e972b015254deL,0x5b63e14def8adeL,0x06995be2ca4a95L, + 0x6cc0cc1e94bf27L,0x7ed8499fe0052aL,0x671a6ca5a5e0f9L, + 0x31e10d4ba10f05L } }, + /* 243 */ + { { 0x690af07e9b2d8aL,0x6030af9e32c8ddL,0x45c7ca3bf2b235L, + 0x40959077b76c81L,0x61eee7f70d5a96L,0x6b04f6aafe9e38L, + 0x3c726f55f1898dL }, + { 0x77d0142a1a6194L,0x1c1631215708b9L,0x403a4f0a9b7585L, + 0x066c8e29f7cef0L,0x6fc32f98cf575eL,0x518a09d818c297L, + 0x34144e99989e75L } }, + /* 244 */ + { { 0x6adbada859fb6aL,0x0dcfb6506ccd51L,0x68f88b8d573e0dL, + 0x4b1ce35bd9af30L,0x241c8293ece2c9L,0x3b5f402c5c4adeL, + 0x34b9b1ee6fde87L }, + { 0x5e625340075e63L,0x54c3f3d9050da1L,0x2a3f9152509016L, + 0x3274e46111bc18L,0x3a7504fd01ac73L,0x4169b387a43209L, + 0x35626f852bc6d4L } }, + /* 245 */ + { { 0x576a4f4662e53bL,0x5ea3f20eecec26L,0x4e5f02be5cd7b0L, + 0x72cc5ac3314be8L,0x0f604ed3201fe9L,0x2a29378ea54bceL, + 0x2d52bd4d6ec4b6L }, + { 0x6a4c2b212c1c76L,0x778fd64a1bfa6dL,0x326828691863d6L, + 0x5616c8bd06a336L,0x5fab552564da4dL,0x46640cab3e91d2L, + 0x1d21f06427299eL } }, + /* 246 */ + { { 0x2bfe37dde98e9cL,0x164c54822332ebL,0x5b736c7df266e4L, + 0x59dab3a8da084cL,0x0ae1eab346f118L,0x182090a4327e3fL, + 0x07b13489dae2e6L }, + { 0x3bc92645452baaL,0x30b159894ae574L,0x5b947c5c78e1f4L, + 0x18f0e004a3c77fL,0x48ca8f357077d9L,0x349ffdcef9bca9L, + 0x3ed224bfd54772L } }, + /* 247 */ + { { 0x1bdad02db8dff8L,0x69fab4450b44b6L,0x3b6802d187518bL, + 0x098368d8eb556cL,0x3fe1943fbefcf4L,0x008851d0de6d42L, + 0x322cbc4605fe25L }, + { 0x2528aaf0d51afbL,0x7d48a9363a0cecL,0x4ba8f77d9a8f8bL, + 0x7dee903437d6c7L,0x1ff5a0d9ccc4b4L,0x34d9bd2fa99831L, + 0x30d9e4f58667c6L } }, + /* 248 */ + { { 0x38909b51b85197L,0x7ba16992512bd4L,0x2c776cfcfffec5L, + 0x2be7879075843cL,0x557e2b05d28ffcL,0x641b17bc5ce357L, + 0x1fcaf8a3710306L }, + { 0x54dca2299a2d48L,0x745d06ef305acaL,0x7c41c65c6944c2L, + 0x679412ec431902L,0x48f2b15ee62827L,0x341a96d8afe06eL, + 0x2a78fd3690c0e1L } }, + /* 249 */ + { { 0x6b7cec83fbc9c6L,0x238e8a82eefc67L,0x5d3c1d9ff0928cL, + 0x55b816d6409bbfL,0x7969612adae364L,0x55b6ff96db654eL, + 0x129beca10073a9L }, + { 0x0b1d2acdfc73deL,0x5d1a3605fa64bdL,0x436076146743beL, + 0x64044b89fcce0cL,0x7ae7b3c18f7fafL,0x7f083ee27cea36L, + 0x0292cd0d7c1ff0L } }, + /* 250 */ + { { 0x5a3c4c019b7d2eL,0x1a35a9b89712fbL,0x38736cc4f18c72L, + 0x603dd832a44e6bL,0x000d1d44aed104L,0x69b1f2fc274ebeL, + 0x03a7b993f76977L }, + { 0x299f3b3e346910L,0x5243f45295afd5L,0x34342cbfa588bdL, + 0x72c40dd1155510L,0x718024fed2f991L,0x2f935e765ad82aL, + 0x246799ea371fb8L } }, + /* 251 */ + { { 0x24fe4c76250533L,0x01cafb02fdf18eL,0x505cb25d462882L, + 0x3e038175157d87L,0x7e3e99b10cdeb1L,0x38b7e72ebc7936L, + 0x081845f7c73433L }, + { 0x049e61be05ebd5L,0x6ab82d8f0581f6L,0x62adffb427ac2eL, + 0x19431f809d198dL,0x36195f6c58b1d6L,0x22cc4c9dedc9a7L, + 0x24b146d8e694fcL } }, + /* 252 */ + { { 0x7c7bc8288b364dL,0x5c10f683cb894aL,0x19a62a68452958L, + 0x1fc24dcb4ce90eL,0x726baa4ed9581fL,0x1f34447dde73d6L, + 0x04c56708f30a21L }, + { 0x131e583a3f4963L,0x071215b4d502e7L,0x196aca542e5940L, + 0x3afd5a91f7450eL,0x671b6eedf49497L,0x6aac7aca5c29e4L, + 0x3fb512470f138bL } }, + /* 253 */ + { { 0x5eadc3f4eb453eL,0x16c795ba34b666L,0x5d7612a4697fddL, + 0x24dd19bb499e86L,0x415b89ca3eeb9bL,0x7c83edf599d809L, + 0x13bc64c9b70269L }, + { 0x52d3243dca3233L,0x0b21444b3a96a7L,0x6d551bc0083b90L, + 0x4f535b88c61176L,0x11e61924298010L,0x0a155b415bb61dL, + 0x17f94fbd26658fL } }, + /* 254 */ + { { 0x2dd06b90c28c65L,0x48582339c8fa6eL,0x01ac8bf2085d94L, + 0x053e660e020fdcL,0x1bece667edf07bL,0x4558f2b33ce24cL, + 0x2f1a766e8673fcL }, + { 0x1d77cd13c06819L,0x4d5dc5056f3a01L,0x18896c6fa18d69L, + 0x120047ca76d625L,0x6af8457d4f4e45L,0x70ddc53358b60aL, + 0x330e11130e82f0L } }, + /* 255 */ + { { 0x0643b1cd4c2356L,0x10a2ea0a8f7c92L,0x2752513011d029L, + 0x4cd4c50321f579L,0x5fdf9ba5724792L,0x2f691653e2ddc0L, + 0x0cfed3d84226cbL }, + { 0x704902a950f955L,0x069bfdb87bbf0cL,0x5817eeda8a5f84L, + 0x1914cdd9089905L,0x0e4a323d7b93f4L,0x1cc3fc340af0b2L, + 0x23874161bd6303L } }, +}; + +/* 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. + * 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_7(sp_point_384* r, const sp_digit* k, + int map, void* heap) +{ + return sp_384_ecc_mulmod_stripe_7(r, &p384_base, p384_table, + k, map, heap); +} + +#endif + +/* Multiply the base point of P384 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_384(mp_int* km, ecc_point* r, int map, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 p; + sp_digit kd[7]; +#endif + sp_point_384* point; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_384_point_new_7(heap, p, point); +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + } +#else + k = kd; +#endif + if (err == MP_OKAY) { + sp_384_from_mp(k, 7, km); + + err = sp_384_ecc_mulmod_base_7(point, k, map, heap); + } + if (err == MP_OKAY) { + err = sp_384_point_to_ecc_point_7(point, r); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + 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. + * Implementation is constant time. + * + * a Number to check. + * returns 1 if the number is zero and 0 otherwise. + */ +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 */ +/* Add 1 to a. (a = a + 1) + * + * r A single precision integer. + * a A single precision integer. + */ +SP_NOINLINE static void sp_384_add_one_7(sp_digit* a) +{ + a[0]++; + sp_384_norm_7(a); +} + +/* 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_384_from_bin(sp_digit* r, int size, const byte* a, int n) +{ + int i, j = 0; + word32 s = 0; + + r[0] = 0; + for (i = n-1; i >= 0; i--) { + r[j] |= (((sp_digit)a[i]) << s); + if (s >= 47U) { + r[j] &= 0x7fffffffffffffL; + s = 55U - 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; + } +} + +/* Generates a scalar that is in the range 1..order-1. + * + * rng Random number generator. + * k Scalar value. + * returns RNG failures, MEMORY_E when memory allocation fails and + * MP_OKAY on success. + */ +static int sp_384_ecc_gen_k_7(WC_RNG* rng, sp_digit* k) +{ + int err; + byte buf[48]; + + do { + err = wc_RNG_GenerateBlock(rng, buf, sizeof(buf)); + if (err == 0) { + sp_384_from_bin(k, 7, buf, (int)sizeof(buf)); + if (sp_384_cmp_7(k, p384_order2) < 0) { + sp_384_add_one_7(k); + break; + } + } + } + while (err == 0); + + return err; +} + +/* Makes a random EC key pair. + * + * rng Random number generator. + * priv Generated private value. + * pub Generated public point. + * heap Heap to use for allocation. + * returns ECC_INF_E when the point does not have the correct order, RNG + * failures, MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_make_key_384(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 p; + sp_digit kd[7]; +#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN + sp_point_384 inf; +#endif +#endif + sp_point_384* point; + sp_digit* k = NULL; +#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN + sp_point_384* infinity; +#endif + int err; + + (void)heap; + + err = sp_384_point_new_7(heap, p, point); +#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN + if (err == MP_OKAY) { + err = sp_384_point_new_7(heap, inf, infinity); + } +#endif +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + } +#else + k = kd; +#endif + + if (err == MP_OKAY) { + err = sp_384_ecc_gen_k_7(rng, k); + } + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_base_7(point, k, 1, NULL); + } + +#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_7(infinity, point, p384_order, 1, NULL); + } + if (err == MP_OKAY) { + if ((sp_384_iszero_7(point->x) == 0) || (sp_384_iszero_7(point->y) == 0)) { + err = ECC_INF_E; + } + } +#endif + + if (err == MP_OKAY) { + err = sp_384_to_mp(k, priv); + } + if (err == MP_OKAY) { + err = sp_384_point_to_ecc_point_7(point, pub); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif +#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN + sp_384_point_free_7(infinity, 1, heap); +#endif + sp_384_point_free_7(point, 1, heap); + + return err; +} + +#ifdef HAVE_ECC_DHE +/* Write r as big endian to byte array. + * Fixed length number of bytes written: 48 + * + * r A single precision integer. + * a Byte array. + */ +static void sp_384_to_bin(sp_digit* r, byte* a) +{ + int i, j, s = 0, b; + + for (i=0; i<6; i++) { + r[i+1] += r[i] >> 55; + r[i] &= 0x7fffffffffffffL; + } + j = 384 / 8 - 1; + a[j] = 0; + for (i=0; i<7 && j>=0; i++) { + b = 0; + /* lint allow cast of mismatch sp_digit and int */ + a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ + if (j < 0) { + break; + } + while (b < 55) { + a[j--] = r[i] >> b; b += 8; + if (j < 0) { + break; + } + } + s = 8 - (b - 55); + if (j >= 0) { + a[j] = 0; + } + if (s != 0) { + j++; + } + } +} + +/* Multiply the point by the scalar and serialize the X ordinate. + * The number is 0 padded to maximum size on output. + * + * priv Scalar to multiply the point by. + * pub Point to multiply. + * out Buffer to hold X ordinate. + * outLen On entry, size of the buffer in bytes. + * On exit, length of data in buffer in bytes. + * heap Heap to use for allocation. + * 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, + word32* outLen, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 p; + sp_digit kd[7]; +#endif + sp_point_384* point = NULL; + sp_digit* k = NULL; + int err = MP_OKAY; + + if (*outLen < 48U) { + err = BUFFER_E; + } + + if (err == MP_OKAY) { + err = sp_384_point_new_7(heap, p, point); + } +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) + err = MEMORY_E; + } +#else + k = kd; +#endif + + if (err == MP_OKAY) { + sp_384_from_mp(k, 7, priv); + sp_384_point_from_ecc_point_7(point, pub); + err = sp_384_ecc_mulmod_7(point, point, k, 1, heap); + } + if (err == MP_OKAY) { + sp_384_to_bin(point->x, out); + *outLen = 48; + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_7(point, 0, heap); + + return err; +} +#endif /* HAVE_ECC_DHE */ + +#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) +#endif +#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) +/* 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_384_mul_d_7(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 < 7; i++) { + t += tb * a[i]; + r[i] = t & 0x7fffffffffffffL; + t >>= 55; + } + r[7] = (sp_digit)t; +#else + int128_t tb = b; + int128_t t[7]; + + t[ 0] = tb * a[ 0]; + t[ 1] = tb * a[ 1]; + t[ 2] = tb * a[ 2]; + t[ 3] = tb * a[ 3]; + t[ 4] = tb * a[ 4]; + t[ 5] = tb * a[ 5]; + t[ 6] = tb * a[ 6]; + r[ 0] = (t[ 0] & 0x7fffffffffffffL); + r[ 1] = (sp_digit)(t[ 0] >> 55) + (t[ 1] & 0x7fffffffffffffL); + r[ 2] = (sp_digit)(t[ 1] >> 55) + (t[ 2] & 0x7fffffffffffffL); + r[ 3] = (sp_digit)(t[ 2] >> 55) + (t[ 3] & 0x7fffffffffffffL); + r[ 4] = (sp_digit)(t[ 3] >> 55) + (t[ 4] & 0x7fffffffffffffL); + r[ 5] = (sp_digit)(t[ 4] >> 55) + (t[ 5] & 0x7fffffffffffffL); + r[ 6] = (sp_digit)(t[ 5] >> 55) + (t[ 6] & 0x7fffffffffffffL); + r[ 7] = (sp_digit)(t[ 6] >> 55); +#endif /* WOLFSSL_SP_SMALL */ +} + +#ifdef WOLFSSL_SP_DIV_64 +static WC_INLINE sp_digit sp_384_div_word_7(sp_digit d1, sp_digit d0, + sp_digit dv) +{ + sp_digit d, r, t; + + /* All 55 bits from d1 and top 8 bits from d0. */ + d = (d1 << 8) | (d0 >> 47); + r = d / dv; + d -= r * dv; + /* Up to 9 bits in r */ + /* Next 8 bits from d0. */ + r <<= 8; + d <<= 8; + d |= (d0 >> 39) & ((1 << 8) - 1); + t = d / dv; + d -= t * dv; + r += t; + /* Up to 17 bits in r */ + /* Next 8 bits from d0. */ + r <<= 8; + d <<= 8; + d |= (d0 >> 31) & ((1 << 8) - 1); + t = d / dv; + d -= t * dv; + r += t; + /* Up to 25 bits in r */ + /* Next 8 bits from d0. */ + r <<= 8; + d <<= 8; + d |= (d0 >> 23) & ((1 << 8) - 1); + t = d / dv; + d -= t * dv; + r += t; + /* Up to 33 bits in r */ + /* Next 8 bits from d0. */ + r <<= 8; + d <<= 8; + d |= (d0 >> 15) & ((1 << 8) - 1); + t = d / dv; + d -= t * dv; + r += t; + /* Up to 41 bits in r */ + /* Next 8 bits from d0. */ + r <<= 8; + d <<= 8; + d |= (d0 >> 7) & ((1 << 8) - 1); + t = d / dv; + d -= t * dv; + r += t; + /* Up to 49 bits in r */ + /* Remaining 7 bits from d0. */ + r <<= 7; + d <<= 7; + d |= d0 & ((1 << 7) - 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. + * + * 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) +{ + int i; +#ifndef WOLFSSL_SP_DIV_64 + int128_t d1; +#endif + sp_digit dv, r1; +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_digit* td; +#else + sp_digit t1d[14], t2d[7 + 1]; +#endif + sp_digit* t1; + sp_digit* t2; + int err = MP_OKAY; + + (void)m; + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + td = (sp_digit*)XMALLOC(sizeof(sp_digit) * (3 * 7 + 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) + t1 = td; + t2 = td + 2 * 7; +#else + t1 = t1d; + t2 = t2d; +#endif + + dv = d[6]; + XMEMCPY(t1, a, sizeof(*t1) * 2U * 7U); + for (i=6; i>=0; i--) { + t1[7 + i] += t1[7 + i - 1] >> 55; + t1[7 + i - 1] &= 0x7fffffffffffffL; +#ifndef WOLFSSL_SP_DIV_64 + d1 = t1[7 + i]; + d1 <<= 55; + d1 += t1[7 + i - 1]; + r1 = (sp_digit)(d1 / dv); +#else + r1 = sp_384_div_word_7(t1[7 + i], t1[7 + i - 1], dv); +#endif + + sp_384_mul_d_7(t2, d, r1); + (void)sp_384_sub_7(&t1[i], &t1[i], t2); + t1[7 + i] -= t2[7]; + t1[7 + i] += t1[7 + i - 1] >> 55; + t1[7 + i - 1] &= 0x7fffffffffffffL; + r1 = (((-t1[7 + i]) << 55) - t1[7 + i - 1]) / dv; + r1++; + sp_384_mul_d_7(t2, d, r1); + (void)sp_384_add_7(&t1[i], &t1[i], t2); + t1[7 + i] += t1[7 + i - 1] >> 55; + t1[7 + i - 1] &= 0x7fffffffffffffL; + } + t1[7 - 1] += t1[7 - 2] >> 55; + t1[7 - 2] &= 0x7fffffffffffffL; + r1 = t1[7 - 1] / dv; + + sp_384_mul_d_7(t2, d, r1); + (void)sp_384_sub_7(t1, t1, t2); + XMEMCPY(r, t1, sizeof(*r) * 2U * 7U); + for (i=0; i<5; i++) { + r[i+1] += r[i] >> 55; + r[i] &= 0x7fffffffffffffL; + } + sp_384_cond_add_7(r, r, d, 0 - ((r[6] < 0) ? + (sp_digit)1 : (sp_digit)0)); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + 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_384_mod_7(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + return sp_384_div_7(a, m, NULL, r); +} + +#endif +#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) +#ifdef WOLFSSL_SP_SMALL +/* Order-2 for the P384 curve. */ +static const uint64_t p384_order_minus_2[6] = { + 0xecec196accc52971U,0x581a0db248b0a77aU,0xc7634d81f4372ddfU, + 0xffffffffffffffffU,0xffffffffffffffffU,0xffffffffffffffffU +}; +#else +/* 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 */ + +/* Multiply two number mod the order of P384 curve. (r = a * b mod order) + * + * r Result of the multiplication. + * a First operand of the multiplication. + * b Second operand of the multiplication. + */ +static void sp_384_mont_mul_order_7(sp_digit* r, const sp_digit* a, const sp_digit* b) +{ + sp_384_mul_7(r, a, b); + sp_384_mont_reduce_order_7(r, p384_order, p384_mp_order); +} + +/* Square number mod the order of P384 curve. (r = a * a mod order) + * + * r Result of the squaring. + * a Number to square. + */ +static void sp_384_mont_sqr_order_7(sp_digit* r, const sp_digit* a) +{ + sp_384_sqr_7(r, a); + sp_384_mont_reduce_order_7(r, p384_order, p384_mp_order); +} + +#ifndef WOLFSSL_SP_SMALL +/* Square number mod the order of P384 curve a number of times. + * (r = a ^ n mod order) + * + * r Result of the squaring. + * a Number to square. + */ +static void sp_384_mont_sqr_n_order_7(sp_digit* r, const sp_digit* a, int n) +{ + int i; + + sp_384_mont_sqr_order_7(r, a); + for (i=1; i=0; i--) { + sp_384_mont_sqr_order_7(t, t); + if ((p384_order_minus_2[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) { + sp_384_mont_mul_order_7(t, t, a); + } + } + XMEMCPY(r, t, sizeof(sp_digit) * 7U); +#else + sp_digit* t = td; + sp_digit* t2 = td + 2 * 7; + sp_digit* t3 = td + 4 * 7; + int i; + + /* t = a^2 */ + sp_384_mont_sqr_order_7(t, a); + /* t = a^3 = t * a */ + sp_384_mont_mul_order_7(t, t, a); + /* t2= a^c = t ^ 2 ^ 2 */ + sp_384_mont_sqr_n_order_7(t2, t, 2); + /* t = a^f = t2 * t */ + sp_384_mont_mul_order_7(t, t2, t); + /* t2= a^f0 = t ^ 2 ^ 4 */ + sp_384_mont_sqr_n_order_7(t2, t, 4); + /* t = a^ff = t2 * t */ + sp_384_mont_mul_order_7(t, t2, t); + /* t2= a^ff00 = t ^ 2 ^ 8 */ + sp_384_mont_sqr_n_order_7(t2, t, 8); + /* t3= a^ffff = t2 * t */ + sp_384_mont_mul_order_7(t3, t2, t); + /* t2= a^ffff0000 = t3 ^ 2 ^ 16 */ + sp_384_mont_sqr_n_order_7(t2, t3, 16); + /* t = a^ffffffff = t2 * t3 */ + sp_384_mont_mul_order_7(t, t2, t3); + /* t2= a^ffffffff0000 = t ^ 2 ^ 16 */ + sp_384_mont_sqr_n_order_7(t2, t, 16); + /* t = a^ffffffffffff = t2 * t3 */ + sp_384_mont_mul_order_7(t, t2, t3); + /* t2= a^ffffffffffff000000000000 = t ^ 2 ^ 48 */ + sp_384_mont_sqr_n_order_7(t2, t, 48); + /* t= a^fffffffffffffffffffffffff = t2 * t */ + sp_384_mont_mul_order_7(t, t2, t); + /* t2= a^ffffffffffffffffffffffff000000000000000000000000 */ + sp_384_mont_sqr_n_order_7(t2, t, 96); + /* t2= a^ffffffffffffffffffffffffffffffffffffffffffffffff = t2 * t */ + 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) { + sp_384_mont_mul_order_7(t2, t2, a); + } + } + sp_384_mont_sqr_order_7(t2, t2); + sp_384_mont_mul_order_7(r, t2, a); +#endif /* WOLFSSL_SP_SMALL */ +} + +#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 + +/* Sign the hash using the private key. + * e = [hash, 384 bits] from binary + * r = (k.G)->x mod order + * s = (r * x + e) / k mod order + * The hash is truncated to the first 384 bits. + * + * hash Hash to sign. + * hashLen Length of the hash data. + * rng Random number generator. + * priv Private part of key - scalar. + * 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. + */ +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) +{ +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_digit* d = NULL; +#else + sp_digit ed[2*7]; + sp_digit xd[2*7]; + sp_digit kd[2*7]; + sp_digit rd[2*7]; + sp_digit td[3 * 2*7]; + sp_point_384 p; +#endif + sp_digit* e = NULL; + sp_digit* x = NULL; + sp_digit* k = NULL; + 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 i; + + (void)heap; + + err = sp_384_point_new_7(heap, p, point); +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7 * 2 * 7, heap, + DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + e = d + 0 * 7; + x = d + 2 * 7; + k = d + 4 * 7; + r = d + 6 * 7; + tmp = d + 8 * 7; +#else + e = ed; + x = xd; + k = kd; + r = rd; + tmp = td; +#endif + s = e; + kInv = k; + + if (hashLen > 48U) { + hashLen = 48U; + } + + sp_384_from_bin(e, 7, hash, (int)hashLen); + } + + 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); + } + else { + sp_384_from_mp(k, 7, km); + mp_zero(km); + } + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_base_7(point, k, 1, NULL); + } + + if (err == MP_OKAY) { + /* r = point->x mod order */ + XMEMCPY(r, point->x, sizeof(sp_digit) * 7U); + sp_384_norm_7(r); + c = sp_384_cmp_7(r, p384_order); + 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); + 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); + + /* Check that signature is usable. */ + if (sp_384_iszero_7(s) == 0) { + break; + } + } + } + + if (i == 0) { + err = RNG_FAILURE_E; + } + + if (err == MP_OKAY) { + err = sp_384_to_mp(r, rm); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(s, sm); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (d != NULL) { + XMEMSET(d, 0, sizeof(sp_digit) * 8 * 7); + XFREE(d, heap, DYNAMIC_TYPE_ECC); + } +#else + XMEMSET(e, 0, sizeof(sp_digit) * 2U * 7U); + 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); + + return err; +} +#endif /* HAVE_ECC_SIGN */ + +#ifdef HAVE_ECC_VERIFY +/* Verify the signature values with the hash and public key. + * e = Truncate(hash, 384) + * u1 = e/s mod order + * u2 = r/s mod order + * r == (u1.G + u2.Q)->x mod order + * Optimization: Leave point in projective form. + * (x, y, 1) == (x' / z'*z', y' / z'*z'*z', z' / z') + * (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' + * The hash is truncated to the first 384 bits. + * + * hash Hash to sign. + * hashLen Length of the hash data. + * rng Random number generator. + * priv Private part of key - scalar. + * 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. + */ +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) +{ +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_digit* d = NULL; +#else + sp_digit u1d[2*7]; + sp_digit u2d[2*7]; + sp_digit sd[2*7]; + sp_digit tmpd[2*7 * 5]; + sp_point_384 p1d; + sp_point_384 p2d; +#endif + sp_digit* u1 = NULL; + sp_digit* u2 = NULL; + sp_digit* s = NULL; + sp_digit* tmp = NULL; + sp_point_384* p1; + sp_point_384* p2 = NULL; + sp_digit carry; + int64_t c; + int err; + + err = sp_384_point_new_7(heap, p1d, p1); + if (err == MP_OKAY) { + err = sp_384_point_new_7(heap, p2d, p2); + } +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 7, heap, + DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + u1 = d + 0 * 7; + u2 = d + 2 * 7; + s = d + 4 * 7; + tmp = d + 6 * 7; +#else + u1 = u1d; + u2 = u2d; + s = sd; + tmp = tmpd; +#endif + + if (hashLen > 48U) { + hashLen = 48U; + } + + sp_384_from_bin(u1, 7, hash, (int)hashLen); + sp_384_from_mp(u2, 7, r); + sp_384_from_mp(s, 7, sm); + sp_384_from_mp(p2->x, 7, pX); + sp_384_from_mp(p2->y, 7, pY); + sp_384_from_mp(p2->z, 7, pZ); + + { + 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); + { + 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); + } + + err = sp_384_ecc_mulmod_base_7(p1, u1, 0, heap); + } + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_7(p2, p2, u2, 0, heap); + } + + 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); + err = sp_384_mod_mul_norm_7(u2, u2, p384_mod); + } + + if (err == MP_OKAY) { + /* u1 = r.z'.z' mod prime */ + sp_384_mont_sqr_7(p1->z, p1->z, p384_mod, p384_mp_mod); + 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) { + /* Reload r and add order. */ + sp_384_from_mp(u2, 7, r); + carry = sp_384_add_7(u2, u2, p384_order); + /* Carry means result is greater than mod and is not valid. */ + if (carry == 0) { + sp_384_norm_7(u2); + + /* 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 defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (d != NULL) + XFREE(d, heap, DYNAMIC_TYPE_ECC); +#endif + sp_384_point_free_7(p1, 0, heap); + sp_384_point_free_7(p2, 0, heap); + + return err; +} +#endif /* HAVE_ECC_VERIFY */ + +#ifdef HAVE_ECC_CHECK_KEY +/* 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_384_ecc_is_point_7(sp_point_384* point, void* heap) +{ +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_digit* d = NULL; +#else + sp_digit t1d[2*7]; + sp_digit t2d[2*7]; +#endif + sp_digit* t1; + sp_digit* t2; + int err = MP_OKAY; + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7 * 4, heap, DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + t1 = d + 0 * 7; + t2 = d + 2 * 7; +#else + (void)heap; + + t1 = t1d; + t2 = t2d; +#endif + + sp_384_sqr_7(t1, point->y); + (void)sp_384_mod_7(t1, t1, p384_mod); + sp_384_sqr_7(t2, point->x); + (void)sp_384_mod_7(t2, t2, p384_mod); + sp_384_mul_7(t2, t2, point->x); + (void)sp_384_mod_7(t2, t2, p384_mod); + (void)sp_384_sub_7(t2, p384_mod, t2); + sp_384_mont_add_7(t1, t1, t2, p384_mod); + + sp_384_mont_add_7(t1, t1, point->x, p384_mod); + sp_384_mont_add_7(t1, t1, point->x, p384_mod); + sp_384_mont_add_7(t1, t1, point->x, p384_mod); + + if (sp_384_cmp_7(t1, p384_b) != 0) { + err = MP_VAL; + } + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + 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_384(mp_int* pX, mp_int* pY) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 pubd; +#endif + sp_point_384* pub; + byte one[1] = { 1 }; + int err; + + err = sp_384_point_new_7(NULL, pubd, pub); + if (err == MP_OKAY) { + sp_384_from_mp(pub->x, 7, pX); + sp_384_from_mp(pub->y, 7, pY); + sp_384_from_bin(pub->z, 7, one, (int)sizeof(one)); + + err = sp_384_ecc_is_point_7(pub, NULL); + } + + sp_384_point_free_7(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_384(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_digit privd[7]; + sp_point_384 pubd; + sp_point_384 pd; +#endif + sp_digit* priv = NULL; + sp_point_384* pub; + sp_point_384* p = NULL; + byte one[1] = { 1 }; + int err; + + err = sp_384_point_new_7(heap, pubd, pub); + if (err == MP_OKAY) { + err = sp_384_point_new_7(heap, pd, p); + } +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + priv = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7, heap, + DYNAMIC_TYPE_ECC); + if (priv == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if !(defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) + priv = privd; +#endif + + sp_384_from_mp(pub->x, 7, pX); + sp_384_from_mp(pub->y, 7, pY); + sp_384_from_bin(pub->z, 7, one, (int)sizeof(one)); + sp_384_from_mp(priv, 7, privm); + + /* Check point at infinitiy. */ + if ((sp_384_iszero_7(pub->x) != 0) && + (sp_384_iszero_7(pub->y) != 0)) { + err = ECC_INF_E; + } + } + + 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; + } + } + + if (err == MP_OKAY) { + /* Check point is on curve */ + err = sp_384_ecc_is_point_7(pub, heap); + } + + if (err == MP_OKAY) { + /* Point * order = infinity */ + err = sp_384_ecc_mulmod_7(p, pub, p384_order, 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; + } + } + + if (err == MP_OKAY) { + /* Base * private = point */ + err = sp_384_ecc_mulmod_base_7(p, priv, 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; + } + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (priv != NULL) { + XFREE(priv, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_7(p, 0, heap); + sp_384_point_free_7(pub, 0, heap); + + return err; +} +#endif +#ifdef WOLFSSL_PUBLIC_ECC_ADD_DBL +/* Add two projective EC points together. + * (pX, pY, pZ) + (qX, qY, qZ) = (rX, rY, rZ) + * + * pX First EC point's X ordinate. + * pY First EC point's Y ordinate. + * pZ First EC point's Z ordinate. + * qX Second EC point's X ordinate. + * qY Second EC point's Y ordinate. + * qZ Second EC point's Z ordinate. + * rX Resultant EC point's X ordinate. + * rY Resultant EC point's Y ordinate. + * rZ Resultant EC point's Z ordinate. + * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise. + */ +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) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_digit tmpd[2 * 7 * 5]; + sp_point_384 pd; + sp_point_384 qd; +#endif + sp_digit* tmp; + sp_point_384* p; + sp_point_384* q = NULL; + int err; + + err = sp_384_point_new_7(NULL, pd, p); + if (err == MP_OKAY) { + err = sp_384_point_new_7(NULL, qd, q); + } +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 7 * 5, NULL, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) { + err = MEMORY_E; + } + } +#else + tmp = tmpd; +#endif + + if (err == MP_OKAY) { + sp_384_from_mp(p->x, 7, pX); + sp_384_from_mp(p->y, 7, pY); + sp_384_from_mp(p->z, 7, pZ); + sp_384_from_mp(q->x, 7, qX); + sp_384_from_mp(q->y, 7, qY); + sp_384_from_mp(q->z, 7, qZ); + + sp_384_proj_point_add_7(p, p, q, tmp); + } + + if (err == MP_OKAY) { + err = sp_384_to_mp(p->x, rX); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->y, rY); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->z, rZ); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (tmp != NULL) { + XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_7(q, 0, NULL); + sp_384_point_free_7(p, 0, NULL); + + return err; +} + +/* Double a projective EC point. + * (pX, pY, pZ) + (pX, pY, pZ) = (rX, rY, rZ) + * + * pX EC point's X ordinate. + * pY EC point's Y ordinate. + * pZ EC point's Z ordinate. + * rX Resultant EC point's X ordinate. + * rY Resultant EC point's Y ordinate. + * rZ Resultant EC point's Z ordinate. + * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise. + */ +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) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_digit tmpd[2 * 7 * 2]; + sp_point_384 pd; +#endif + sp_digit* tmp; + sp_point_384* p; + int err; + + err = sp_384_point_new_7(NULL, pd, p); +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 7 * 2, NULL, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) { + err = MEMORY_E; + } + } +#else + tmp = tmpd; +#endif + + if (err == MP_OKAY) { + sp_384_from_mp(p->x, 7, pX); + sp_384_from_mp(p->y, 7, pY); + sp_384_from_mp(p->z, 7, pZ); + + sp_384_proj_point_dbl_7(p, p, tmp); + } + + if (err == MP_OKAY) { + err = sp_384_to_mp(p->x, rX); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->y, rY); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->z, rZ); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (tmp != NULL) { + XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_7(p, 0, NULL); + + return err; +} + +/* Map a projective EC point to affine in place. + * pZ will be one. + * + * pX EC point's X ordinate. + * pY EC point's Y ordinate. + * pZ EC point's Z ordinate. + * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise. + */ +int sp_ecc_map_384(mp_int* pX, mp_int* pY, mp_int* pZ) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_digit tmpd[2 * 7 * 6]; + sp_point_384 pd; +#endif + sp_digit* tmp; + sp_point_384* p; + int err; + + err = sp_384_point_new_7(NULL, pd, p); +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 7 * 6, NULL, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) { + err = MEMORY_E; + } + } +#else + tmp = tmpd; +#endif + if (err == MP_OKAY) { + sp_384_from_mp(p->x, 7, pX); + sp_384_from_mp(p->y, 7, pY); + sp_384_from_mp(p->z, 7, pZ); + + sp_384_map_7(p, p, tmp); + } + + if (err == MP_OKAY) { + err = sp_384_to_mp(p->x, pX); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->y, pY); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->z, pZ); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (tmp != NULL) { + XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_7(p, 0, NULL); + + return err; +} +#endif /* WOLFSSL_PUBLIC_ECC_ADD_DBL */ +#ifdef HAVE_COMP_KEY +/* Find the square root of a number mod the prime of the curve. + * + * y The number to operate on and the result. + * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise. + */ +static int sp_384_mont_sqrt_7(sp_digit* y) +{ +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_digit* d; +#else + sp_digit t1d[2 * 7]; + sp_digit t2d[2 * 7]; + sp_digit t3d[2 * 7]; + sp_digit t4d[2 * 7]; + sp_digit t5d[2 * 7]; +#endif + sp_digit* t1; + sp_digit* t2; + sp_digit* t3; + sp_digit* t4; + sp_digit* t5; + int err = MP_OKAY; + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 5 * 2 * 7, NULL, DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + t1 = d + 0 * 7; + t2 = d + 2 * 7; + t3 = d + 4 * 7; + t4 = d + 6 * 7; + t5 = d + 8 * 7; +#else + t1 = t1d; + t2 = t2d; + t3 = t3d; + t4 = t4d; + t5 = t5d; +#endif + + { + /* t2 = y ^ 0x2 */ + sp_384_mont_sqr_7(t2, y, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x3 */ + sp_384_mont_mul_7(t1, t2, y, p384_mod, p384_mp_mod); + /* t5 = y ^ 0xc */ + sp_384_mont_sqr_n_7(t5, t1, 2, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xf */ + sp_384_mont_mul_7(t1, t1, t5, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x1e */ + sp_384_mont_sqr_7(t2, t1, p384_mod, p384_mp_mod); + /* t3 = y ^ 0x1f */ + sp_384_mont_mul_7(t3, t2, y, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3e0 */ + sp_384_mont_sqr_n_7(t2, t3, 5, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x3ff */ + sp_384_mont_mul_7(t1, t3, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x7fe0 */ + sp_384_mont_sqr_n_7(t2, t1, 5, p384_mod, p384_mp_mod); + /* t3 = y ^ 0x7fff */ + sp_384_mont_mul_7(t3, t3, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3fff800 */ + sp_384_mont_sqr_n_7(t2, t3, 15, p384_mod, p384_mp_mod); + /* t4 = y ^ 0x3ffffff */ + sp_384_mont_mul_7(t4, t3, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0xffffffc000000 */ + sp_384_mont_sqr_n_7(t2, t4, 30, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xfffffffffffff */ + sp_384_mont_mul_7(t1, t4, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0xfffffffffffffff000000000000000 */ + sp_384_mont_sqr_n_7(t2, t1, 60, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xffffffffffffffffffffffffffffff */ + sp_384_mont_mul_7(t1, t1, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0xffffffffffffffffffffffffffffff000000000000000000000000000000 */ + sp_384_mont_sqr_n_7(t2, t1, 120, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */ + sp_384_mont_mul_7(t1, t1, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000 */ + sp_384_mont_sqr_n_7(t2, t1, 15, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */ + sp_384_mont_mul_7(t1, t3, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000 */ + sp_384_mont_sqr_n_7(t2, t1, 31, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffff */ + sp_384_mont_mul_7(t1, t4, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffff0 */ + sp_384_mont_sqr_n_7(t2, t1, 4, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffc */ + sp_384_mont_mul_7(t1, t5, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000 */ + sp_384_mont_sqr_n_7(t2, t1, 62, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000001 */ + sp_384_mont_mul_7(t1, y, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffc00000000000000040000000 */ + sp_384_mont_sqr_n_7(y, t1, 30, p384_mod, p384_mp_mod); + } + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (d != NULL) { + XFREE(d, NULL, DYNAMIC_TYPE_ECC); + } +#endif + + return err; +} + + +/* Uncompress the point given the X ordinate. + * + * xm X ordinate. + * odd Whether the Y ordinate is odd. + * ym Calculated Y ordinate. + * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise. + */ +int sp_ecc_uncompress_384(mp_int* xm, int odd, mp_int* ym) +{ +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_digit* d; +#else + sp_digit xd[2 * 7]; + sp_digit yd[2 * 7]; +#endif + sp_digit* x = NULL; + sp_digit* y = NULL; + int err = MP_OKAY; + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4 * 7, NULL, DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + x = d + 0 * 7; + y = d + 2 * 7; +#else + x = xd; + y = yd; +#endif + + sp_384_from_mp(x, 7, xm); + err = sp_384_mod_mul_norm_7(x, x, p384_mod); + } + if (err == MP_OKAY) { + /* y = x^3 */ + { + sp_384_mont_sqr_7(y, x, p384_mod, p384_mp_mod); + sp_384_mont_mul_7(y, y, x, p384_mod, p384_mp_mod); + } + /* y = x^3 - 3x */ + sp_384_mont_sub_7(y, y, x, p384_mod); + sp_384_mont_sub_7(y, y, x, p384_mod); + sp_384_mont_sub_7(y, y, x, p384_mod); + /* y = x^3 - 3x + b */ + err = sp_384_mod_mul_norm_7(x, p384_b, p384_mod); + } + if (err == MP_OKAY) { + sp_384_mont_add_7(y, y, x, p384_mod); + /* y = sqrt(x^3 - 3x + b) */ + err = sp_384_mont_sqrt_7(y); + } + if (err == MP_OKAY) { + XMEMSET(y + 7, 0, 7U * sizeof(sp_digit)); + sp_384_mont_reduce_7(y, p384_mod, p384_mp_mod); + if ((((word32)y[0] ^ (word32)odd) & 1U) != 0U) { + sp_384_mont_sub_7(y, p384_mod, y, p384_mod); + } + + err = sp_384_to_mp(y, ym); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (d != NULL) { + XFREE(d, NULL, DYNAMIC_TYPE_ECC); + } +#endif + + return err; +} +#endif +#endif /* WOLFSSL_SP_384 */ #endif /* WOLFSSL_HAVE_SP_ECC */ #endif /* SP_WORD_SIZE == 64 */ #endif /* !WOLFSSL_SP_ASM */ diff --git a/wolfcrypt/src/sp_cortexm.c b/wolfcrypt/src/sp_cortexm.c index f6a928d54..94decf725 100644 --- a/wolfcrypt/src/sp_cortexm.c +++ b/wolfcrypt/src/sp_cortexm.c @@ -13383,12 +13383,12 @@ int sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen, #ifndef WOLFSSL_SP_NO_256 /* Point structure to use. */ -typedef struct sp_point { +typedef struct sp_point_256 { sp_digit x[2 * 8]; sp_digit y[2 * 8]; sp_digit z[2 * 8]; int infinity; -} sp_point; +} sp_point_256; /* The modulus (prime) of the curve P256. */ static const sp_digit p256_mod[8] = { @@ -13427,21 +13427,24 @@ static const sp_digit p256_norm_order[8] = { static const sp_digit p256_mp_order = 0xee00bc4f; #endif /* The base point of curve P256. */ -static const sp_point p256_base = { +static const sp_point_256 p256_base = { /* X ordinate */ { 0xd898c296,0xf4a13945,0x2deb33a0,0x77037d81,0x63a440f2,0xf8bce6e5, - 0xe12c4247,0x6b17d1f2, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + 0xe12c4247,0x6b17d1f2, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L }, /* Y ordinate */ { 0x37bf51f5,0xcbb64068,0x6b315ece,0x2bce3357,0x7c0f9e16,0x8ee7eb4a, - 0xfe1a7f9b,0x4fe342e2, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + 0xfe1a7f9b,0x4fe342e2, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L }, /* Z ordinate */ { 0x00000001,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000, - 0x00000000,0x00000000, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + 0x00000000,0x00000000, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L }, /* infinity */ 0 @@ -13453,34 +13456,32 @@ static const sp_digit p256_b[8] = { }; #endif -static int sp_ecc_point_new_ex(void* heap, sp_point* sp, sp_point** p) +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) + (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; } - else { - #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - *p = (sp_point*)XMALLOC(sizeof(sp_point), heap, DYNAMIC_TYPE_ECC); - (void)sp; - #else - *p = sp; - (void)heap; - #endif - } return ret; } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) /* Allocate memory for point and return error. */ -#define sp_ecc_point_new(heap, sp, p) sp_ecc_point_new_ex((heap), NULL, &(p)) +#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_ecc_point_new(heap, sp, p) sp_ecc_point_new_ex((heap), &(sp), &(p)) +#define sp_256_point_new_8(heap, sp, p) sp_256_point_new_ex_8((heap), &(sp), &(p)) #endif -static void sp_ecc_point_free(sp_point* p, int clear, void* heap) +static void sp_256_point_free_8(sp_point_256* p, int clear, void* heap) { #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) /* If valid pointer then clear point data if requested and free data. */ @@ -13652,12 +13653,12 @@ static void sp_256_from_mp(sp_digit* r, int size, const mp_int* a) #endif } -/* Convert a point of type ecc_point to type sp_point. +/* Convert a point of type ecc_point to type sp_point_256. * - * p Point of type sp_point (result). + * 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* 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)); @@ -13732,14 +13733,14 @@ static int sp_256_to_mp(const sp_digit* a, mp_int* r) return err; } -/* Convert a point of type sp_point to type ecc_point. +/* Convert a point of type sp_point_256 to type ecc_point. * - * p Point of type sp_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* p, ecc_point* pm) +static int sp_256_point_to_ecc_point_8(const sp_point_256* p, ecc_point* pm) { int err; @@ -13754,306 +13755,6 @@ static int sp_256_point_to_ecc_point_8(const sp_point* p, ecc_point* pm) 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. - */ -SP_NOINLINE static int32_t sp_256_cmp_8(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, #28\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" - "bge 1b\n\t" - : [r] "+r" (r) - : [a] "r" (a), [b] "r" (b) - : "r3", "r4", "r5", "r6", "r8" - ); - - return r; -} - -/* Normalize the values in each word to 32. - * - * a Array of sp_digit to normalize. - */ -#define sp_256_norm_8(a) - -/* 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_256_cond_sub_8(sp_digit* r, const sp_digit* a, - const sp_digit* b, sp_digit m) -{ - sp_digit c = 0; - - __asm__ __volatile__ ( - "mov r5, #32\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" - "blt 1b\n\t" - : [c] "+r" (c) - : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) - : "memory", "r5", "r6", "r8", "r9" - ); - - return c; -} - -/* 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. - */ -SP_NOINLINE static void sp_256_mont_reduce_8(sp_digit* a, const sp_digit* m, - sp_digit mp) -{ - (void)mp; - (void)m; - - __asm__ __volatile__ ( - "mov r2, #0\n\t" - "mov r1, #0\n\t" - /* i = 0 */ - "mov r9, r2\n\t" - "\n1:\n\t" - "mov r4, #0\n\t" - /* mu = a[i] * 1 (mp) = a[i] */ - "ldr r3, [%[a]]\n\t" - /* a[i] += -1 * mu = -1 * a[i] => a[i] = 0 no carry */ - /* a[i+1] += -1 * mu */ - "ldr r6, [%[a], #4]\n\t" - "mov r5, #0\n\t" - "adds r4, r4, r6\n\t" - "adc r5, r5, r2\n\t" - "str r4, [%[a], #4]\n\t" - /* a[i+2] += -1 * mu */ - "ldr r6, [%[a], #8]\n\t" - "mov r4, #0\n\t" - "adds r5, r5, r6\n\t" - "adc r4, r4, r2\n\t" - "str r5, [%[a], #8]\n\t" - /* a[i+3] += 0 * mu */ - "ldr r6, [%[a], #12]\n\t" - "mov r5, #0\n\t" - "adds r4, r4, r3\n\t" - "adc r5, r5, r2\n\t" - "adds r4, r4, r6\n\t" - "adc r5, r5, r2\n\t" - "str r4, [%[a], #12]\n\t" - /* a[i+4] += 0 * mu */ - "ldr r6, [%[a], #16]\n\t" - "mov r4, #0\n\t" - "adds r5, r5, r6\n\t" - "adc r4, r4, r2\n\t" - "str r5, [%[a], #16]\n\t" - /* a[i+5] += 0 * mu */ - "ldr r6, [%[a], #20]\n\t" - "mov r5, #0\n\t" - "adds r4, r4, r6\n\t" - "adc r5, r5, r2\n\t" - "str r4, [%[a], #20]\n\t" - /* a[i+6] += 1 * mu */ - "ldr r6, [%[a], #24]\n\t" - "mov r4, #0\n\t" - "adds r5, r5, r3\n\t" - "adc r4, r4, r2\n\t" - "adds r5, r5, r6\n\t" - "adc r4, r4, r2\n\t" - "str r5, [%[a], #24]\n\t" - /* a[i+7] += -1 * mu */ - "ldr r6, [%[a], #28]\n\t" - "ldr r8, [%[a], #32]\n\t" - "adds r5, r1, r3\n\t" - "mov r1, #0\n\t" - "adc r1, r1, r2\n\t" - "subs r4, r4, r3\n\t" - "sbcs r5, r5, r2\n\t" - "sbc r1, r1, r2\n\t" - "adds r4, r4, r6\n\t" - "adcs r5, r5, r8\n\t" - "adc r1, r1, r2\n\t" - "str r4, [%[a], #28]\n\t" - "str r5, [%[a], #32]\n\t" - /* i += 1 */ - "add r9, r9, #1\n\t" - "add %[a], %[a], #4\n\t" - "mov r6, #8\n\t" - "cmp r9, r6\n\t" - "blt 1b\n\t" - "sub %[a], %[a], #32\n\t" - "mov r3, r1\n\t" - "sub r1, r1, #1\n\t" - "mvn r1, r1\n\t" - "ldr r4, [%[a],#32]\n\t" - "ldr r5, [%[a],#36]\n\t" - "ldr r6, [%[a],#40]\n\t" - "ldr r8, [%[a],#44]\n\t" - "subs r4, r4, r1\n\t" - "sbcs r5, r5, r1\n\t" - "sbcs r6, r6, r1\n\t" - "sbcs r8, r8, r2\n\t" - "str r4, [%[a],#0]\n\t" - "str r5, [%[a],#4]\n\t" - "str r6, [%[a],#8]\n\t" - "str r8, [%[a],#12]\n\t" - "ldr r4, [%[a],#48]\n\t" - "ldr r5, [%[a],#52]\n\t" - "ldr r6, [%[a],#56]\n\t" - "ldr r8, [%[a],#60]\n\t" - "sbcs r4, r4, r2\n\t" - "sbcs r5, r5, r2\n\t" - "sbcs r6, r6, r3\n\t" - "sbc r8, r8, r1\n\t" - "str r4, [%[a],#16]\n\t" - "str r5, [%[a],#20]\n\t" - "str r6, [%[a],#24]\n\t" - "str r8, [%[a],#28]\n\t" - : [a] "+r" (a) - : - : "memory", "r1", "r2", "r3", "r4", "r5", "r6", "r8", "r9" - ); - - - (void)m; - (void)mp; -} - -/* 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. - */ -SP_NOINLINE static void sp_256_mont_reduce_order_8(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, #32\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, #24\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" - "blt 2b\n\t" - /* a[i+6] += m[6] * 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+7] += m[7] * mu */ - "mov r4, %[ca]\n\t" - "mov %[ca], #0\n\t" - /* Multiply m[7] 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[7] 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, #24\n\t" - "cmp r10, r11\n\t" - "blt 1b\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_256_cond_sub_8(a - 8, a, m, (sp_digit)0 - ca); -} - /* Multiply a and b into r. (r = a * b) * * r A single precision integer. @@ -14562,6 +14263,257 @@ SP_NOINLINE static void sp_256_mul_8(sp_digit* r, const sp_digit* a, ); } +/* 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_256_cond_sub_8(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "mov r5, #32\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" + "blt 1b\n\t" + : [c] "+r" (c) + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) + : "memory", "r5", "r6", "r8", "r9" + ); + + return c; +} + +/* 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. + */ +SP_NOINLINE static void sp_256_mont_reduce_8(sp_digit* a, const sp_digit* m, + sp_digit mp) +{ + (void)mp; + (void)m; + + __asm__ __volatile__ ( + "mov r2, #0\n\t" + "mov r1, #0\n\t" + /* i = 0 */ + "mov r9, r2\n\t" + "\n1:\n\t" + "mov r4, #0\n\t" + /* mu = a[i] * 1 (mp) = a[i] */ + "ldr r3, [%[a]]\n\t" + /* a[i] += -1 * mu = -1 * a[i] => a[i] = 0 no carry */ + /* a[i+1] += -1 * mu */ + "ldr r6, [%[a], #4]\n\t" + "mov r5, #0\n\t" + "adds r4, r4, r6\n\t" + "adc r5, r5, r2\n\t" + "str r4, [%[a], #4]\n\t" + /* a[i+2] += -1 * mu */ + "ldr r6, [%[a], #8]\n\t" + "mov r4, #0\n\t" + "adds r5, r5, r6\n\t" + "adc r4, r4, r2\n\t" + "str r5, [%[a], #8]\n\t" + /* a[i+3] += 0 * mu */ + "ldr r6, [%[a], #12]\n\t" + "mov r5, #0\n\t" + "adds r4, r4, r3\n\t" + "adc r5, r5, r2\n\t" + "adds r4, r4, r6\n\t" + "adc r5, r5, r2\n\t" + "str r4, [%[a], #12]\n\t" + /* a[i+4] += 0 * mu */ + "ldr r6, [%[a], #16]\n\t" + "mov r4, #0\n\t" + "adds r5, r5, r6\n\t" + "adc r4, r4, r2\n\t" + "str r5, [%[a], #16]\n\t" + /* a[i+5] += 0 * mu */ + "ldr r6, [%[a], #20]\n\t" + "mov r5, #0\n\t" + "adds r4, r4, r6\n\t" + "adc r5, r5, r2\n\t" + "str r4, [%[a], #20]\n\t" + /* a[i+6] += 1 * mu */ + "ldr r6, [%[a], #24]\n\t" + "mov r4, #0\n\t" + "adds r5, r5, r3\n\t" + "adc r4, r4, r2\n\t" + "adds r5, r5, r6\n\t" + "adc r4, r4, r2\n\t" + "str r5, [%[a], #24]\n\t" + /* a[i+7] += -1 * mu */ + "ldr r6, [%[a], #28]\n\t" + "ldr r8, [%[a], #32]\n\t" + "adds r5, r1, r3\n\t" + "mov r1, #0\n\t" + "adc r1, r1, r2\n\t" + "subs r4, r4, r3\n\t" + "sbcs r5, r5, r2\n\t" + "sbc r1, r1, r2\n\t" + "adds r4, r4, r6\n\t" + "adcs r5, r5, r8\n\t" + "adc r1, r1, r2\n\t" + "str r4, [%[a], #28]\n\t" + "str r5, [%[a], #32]\n\t" + /* i += 1 */ + "add r9, r9, #1\n\t" + "add %[a], %[a], #4\n\t" + "mov r6, #8\n\t" + "cmp r9, r6\n\t" + "blt 1b\n\t" + "sub %[a], %[a], #32\n\t" + "mov r3, r1\n\t" + "sub r1, r1, #1\n\t" + "mvn r1, r1\n\t" + "ldr r4, [%[a],#32]\n\t" + "ldr r5, [%[a],#36]\n\t" + "ldr r6, [%[a],#40]\n\t" + "ldr r8, [%[a],#44]\n\t" + "subs r4, r4, r1\n\t" + "sbcs r5, r5, r1\n\t" + "sbcs r6, r6, r1\n\t" + "sbcs r8, r8, r2\n\t" + "str r4, [%[a],#0]\n\t" + "str r5, [%[a],#4]\n\t" + "str r6, [%[a],#8]\n\t" + "str r8, [%[a],#12]\n\t" + "ldr r4, [%[a],#48]\n\t" + "ldr r5, [%[a],#52]\n\t" + "ldr r6, [%[a],#56]\n\t" + "ldr r8, [%[a],#60]\n\t" + "sbcs r4, r4, r2\n\t" + "sbcs r5, r5, r2\n\t" + "sbcs r6, r6, r3\n\t" + "sbc r8, r8, r1\n\t" + "str r4, [%[a],#16]\n\t" + "str r5, [%[a],#20]\n\t" + "str r6, [%[a],#24]\n\t" + "str r8, [%[a],#28]\n\t" + : [a] "+r" (a) + : + : "memory", "r1", "r2", "r3", "r4", "r5", "r6", "r8", "r9" + ); + + + (void)m; + (void)mp; +} + +/* 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. + */ +SP_NOINLINE static void sp_256_mont_reduce_order_8(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, #32\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, #24\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" + "blt 2b\n\t" + /* a[i+6] += m[6] * 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+7] += m[7] * mu */ + "mov r4, %[ca]\n\t" + "mov %[ca], #0\n\t" + /* Multiply m[7] 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[7] 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, #24\n\t" + "cmp r10, r11\n\t" + "blt 1b\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_256_cond_sub_8(a - 8, a, m, (sp_digit)0 - ca); +} + /* Multiply two Montogmery form numbers mod the modulus (prime). * (r = a * b mod m) * @@ -14963,7 +14915,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 */ #ifdef WOLFSSL_SP_SMALL /* Mod-2 for the P256 curve. */ -static const uint32_t p256_mod_2[8] = { +static const uint32_t p256_mod_minus_2[8] = { 0xfffffffdU,0xffffffffU,0xffffffffU,0x00000000U,0x00000000U,0x00000000U, 0x00000001U,0xffffffffU }; @@ -14985,71 +14937,115 @@ static void sp_256_mont_inv_8(sp_digit* r, const sp_digit* a, sp_digit* td) XMEMCPY(t, a, sizeof(sp_digit) * 8); for (i=254; i>=0; i--) { sp_256_mont_sqr_8(t, t, p256_mod, p256_mp_mod); - if (p256_mod_2[i / 32] & ((sp_digit)1 << (i % 32))) + if (p256_mod_minus_2[i / 32] & ((sp_digit)1 << (i % 32))) sp_256_mont_mul_8(t, t, a, p256_mod, p256_mp_mod); } XMEMCPY(r, t, sizeof(sp_digit) * 8); #else - sp_digit* t = td; + sp_digit* t1 = td; sp_digit* t2 = td + 2 * 8; sp_digit* t3 = td + 4 * 8; - - /* t = a^2 */ - sp_256_mont_sqr_8(t, a, p256_mod, p256_mp_mod); - /* t = a^3 = t * a */ - sp_256_mont_mul_8(t, t, a, p256_mod, p256_mp_mod); - /* t2= a^c = t ^ 2 ^ 2 */ - sp_256_mont_sqr_n_8(t2, t, 2, p256_mod, p256_mp_mod); - /* t3= a^d = t2 * a */ - sp_256_mont_mul_8(t3, t2, a, p256_mod, p256_mp_mod); - /* t = a^f = t2 * t */ - sp_256_mont_mul_8(t, t2, t, p256_mod, p256_mp_mod); - /* t2= a^f0 = t ^ 2 ^ 4 */ - sp_256_mont_sqr_n_8(t2, t, 4, p256_mod, p256_mp_mod); - /* t3= a^fd = t2 * t3 */ - sp_256_mont_mul_8(t3, t2, t3, p256_mod, p256_mp_mod); - /* t = a^ff = t2 * t */ - sp_256_mont_mul_8(t, t2, t, p256_mod, p256_mp_mod); - /* t2= a^ff00 = t ^ 2 ^ 8 */ - sp_256_mont_sqr_n_8(t2, t, 8, p256_mod, p256_mp_mod); - /* t3= a^fffd = t2 * t3 */ - sp_256_mont_mul_8(t3, t2, t3, p256_mod, p256_mp_mod); - /* t = a^ffff = t2 * t */ - sp_256_mont_mul_8(t, t2, t, p256_mod, p256_mp_mod); - /* t2= a^ffff0000 = t ^ 2 ^ 16 */ - sp_256_mont_sqr_n_8(t2, t, 16, p256_mod, p256_mp_mod); - /* t3= a^fffffffd = t2 * t3 */ - sp_256_mont_mul_8(t3, t2, t3, p256_mod, p256_mp_mod); - /* t = a^ffffffff = t2 * t */ - sp_256_mont_mul_8(t, t2, t, p256_mod, p256_mp_mod); - /* t = a^ffffffff00000000 = t ^ 2 ^ 32 */ - sp_256_mont_sqr_n_8(t2, t, 32, p256_mod, p256_mp_mod); - /* t2= a^ffffffffffffffff = t2 * t */ - sp_256_mont_mul_8(t, t2, t, p256_mod, p256_mp_mod); - /* t2= a^ffffffff00000001 = t2 * a */ - sp_256_mont_mul_8(t2, t2, a, p256_mod, p256_mp_mod); - /* t2= a^ffffffff000000010000000000000000000000000000000000000000 - * = t2 ^ 2 ^ 160 */ - sp_256_mont_sqr_n_8(t2, t2, 160, p256_mod, p256_mp_mod); - /* t2= a^ffffffff00000001000000000000000000000000ffffffffffffffff - * = t2 * t */ - sp_256_mont_mul_8(t2, t2, t, p256_mod, p256_mp_mod); - /* t2= a^ffffffff00000001000000000000000000000000ffffffffffffffff00000000 - * = t2 ^ 2 ^ 32 */ - sp_256_mont_sqr_n_8(t2, t2, 32, p256_mod, p256_mp_mod); - /* r = a^ffffffff00000001000000000000000000000000fffffffffffffffffffffffd - * = t2 * t3 */ - sp_256_mont_mul_8(r, t2, t3, p256_mod, p256_mp_mod); + /* 0x2 */ + sp_256_mont_sqr_8(t1, a, p256_mod, p256_mp_mod); + /* 0x3 */ + sp_256_mont_mul_8(t2, t1, a, p256_mod, p256_mp_mod); + /* 0xc */ + sp_256_mont_sqr_n_8(t1, t2, 2, p256_mod, p256_mp_mod); + /* 0xd */ + sp_256_mont_mul_8(t3, t1, a, p256_mod, p256_mp_mod); + /* 0xf */ + sp_256_mont_mul_8(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xf0 */ + sp_256_mont_sqr_n_8(t1, t2, 4, p256_mod, p256_mp_mod); + /* 0xfd */ + sp_256_mont_mul_8(t3, t3, t1, p256_mod, p256_mp_mod); + /* 0xff */ + sp_256_mont_mul_8(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xff00 */ + sp_256_mont_sqr_n_8(t1, t2, 8, p256_mod, p256_mp_mod); + /* 0xfffd */ + sp_256_mont_mul_8(t3, t3, t1, p256_mod, p256_mp_mod); + /* 0xffff */ + sp_256_mont_mul_8(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xffff0000 */ + sp_256_mont_sqr_n_8(t1, t2, 16, p256_mod, p256_mp_mod); + /* 0xfffffffd */ + sp_256_mont_mul_8(t3, t3, t1, p256_mod, p256_mp_mod); + /* 0xffffffff */ + sp_256_mont_mul_8(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xffffffff00000000 */ + sp_256_mont_sqr_n_8(t1, t2, 32, p256_mod, p256_mp_mod); + /* 0xffffffffffffffff */ + sp_256_mont_mul_8(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xffffffff00000001 */ + sp_256_mont_mul_8(r, t1, a, p256_mod, p256_mp_mod); + /* 0xffffffff000000010000000000000000000000000000000000000000 */ + sp_256_mont_sqr_n_8(r, r, 160, p256_mod, p256_mp_mod); + /* 0xffffffff00000001000000000000000000000000ffffffffffffffff */ + sp_256_mont_mul_8(r, r, t2, p256_mod, p256_mp_mod); + /* 0xffffffff00000001000000000000000000000000ffffffffffffffff00000000 */ + sp_256_mont_sqr_n_8(r, r, 32, p256_mod, p256_mp_mod); + /* 0xffffffff00000001000000000000000000000000fffffffffffffffffffffffd */ + sp_256_mont_mul_8(r, r, t3, p256_mod, p256_mp_mod); #endif /* WOLFSSL_SP_SMALL */ } +/* 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_256_cmp_8(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, #28\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" + "bge 1b\n\t" + : [r] "+r" (r) + : [a] "r" (a), [b] "r" (b) + : "r3", "r4", "r5", "r6", "r8" + ); + + return r; +} + +/* Normalize the values in each word to 32. + * + * a Array of sp_digit to normalize. + */ +#define sp_256_norm_8(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_256_map_8(sp_point* r, const sp_point* 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; @@ -15575,9 +15571,9 @@ SP_NOINLINE static void sp_256_div2_8(sp_digit* r, const sp_digit* a, const sp_d * p Point to double. * t Temporary ordinate data. */ -static void sp_256_proj_point_dbl_8(sp_point* r, const sp_point* p, sp_digit* t) +static void sp_256_proj_point_dbl_8(sp_point_256* r, const sp_point_256* p, sp_digit* t) { - sp_point* rp[2]; + sp_point_256* rp[2]; sp_digit* t1 = t; sp_digit* t2 = t + 2*8; sp_digit* x; @@ -15589,8 +15585,8 @@ static void sp_256_proj_point_dbl_8(sp_point* r, const sp_point* p, sp_digit* t) rp[0] = r; /*lint allow cast to different type of pointer*/ - rp[1] = (sp_point*)t; /*lint !e9087 !e740*/ - XMEMSET(rp[1], 0, sizeof(sp_point)); + rp[1] = (sp_point_256*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_256)); x = rp[p->infinity]->x; y = rp[p->infinity]->y; z = rp[p->infinity]->z; @@ -15758,11 +15754,11 @@ static int sp_256_cmp_equal_8(const sp_digit* a, const sp_digit* b) * q Second point to add. * t Temporary ordinate data. */ -static void sp_256_proj_point_add_8(sp_point* r, const sp_point* p, const sp_point* q, +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* ap[2]; - sp_point* rp[2]; + const sp_point_256* ap[2]; + sp_point_256* rp[2]; sp_digit* t1 = t; sp_digit* t2 = t + 2*8; sp_digit* t3 = t + 4*8; @@ -15775,7 +15771,7 @@ static void sp_256_proj_point_add_8(sp_point* r, const sp_point* p, const sp_poi /* Ensure only the first point is the same as the result. */ if (q == r) { - const sp_point* a = p; + const sp_point_256* a = p; p = q; q = a; } @@ -15791,8 +15787,8 @@ static void sp_256_proj_point_add_8(sp_point* r, const sp_point* p, const sp_poi rp[0] = r; /*lint allow cast to different type of pointer*/ - rp[1] = (sp_point*)t; /*lint !e9087 !e740*/ - XMEMSET(rp[1], 0, sizeof(sp_point)); + rp[1] = (sp_point_256*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_256)); x = rp[p->infinity | q->infinity]->x; y = rp[p->infinity | q->infinity]->y; z = rp[p->infinity | q->infinity]->z; @@ -15855,16 +15851,16 @@ static void sp_256_proj_point_add_8(sp_point* r, const sp_point* p, const sp_poi * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_fast_8(sp_point* r, const sp_point* g, const sp_digit* k, +static int sp_256_ecc_mulmod_fast_8(sp_point_256* r, const sp_point_256* g, const sp_digit* k, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point td[16]; - sp_point rtd; + sp_point_256 td[16]; + sp_point_256 rtd; sp_digit tmpd[2 * 8 * 5]; #endif - sp_point* t; - sp_point* rt; + sp_point_256* t; + sp_point_256* rt; sp_digit* tmp; sp_digit n; int i; @@ -15873,9 +15869,9 @@ static int sp_256_ecc_mulmod_fast_8(sp_point* r, const sp_point* g, const sp_dig (void)heap; - err = sp_ecc_point_new(heap, rtd, rt); + err = sp_256_point_new_8(heap, rtd, rt); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - t = (sp_point*)XMALLOC(sizeof(sp_point) * 16, heap, DYNAMIC_TYPE_ECC); + t = (sp_point_256*)XMALLOC(sizeof(sp_point_256) * 16, heap, DYNAMIC_TYPE_ECC); if (t == NULL) err = MEMORY_E; tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 5, heap, @@ -15929,7 +15925,7 @@ static int sp_256_ecc_mulmod_fast_8(sp_point* r, const sp_point* g, const sp_dig n = k[i+1] << 0; c = 28; y = n >> 28; - XMEMCPY(rt, &t[y], sizeof(sp_point)); + XMEMCPY(rt, &t[y], sizeof(sp_point_256)); n <<= 4; for (; i>=0 || c>=4; ) { if (c < 4) { @@ -15952,7 +15948,7 @@ static int sp_256_ecc_mulmod_fast_8(sp_point* r, const sp_point* g, const sp_dig sp_256_map_8(r, rt, tmp); } else { - XMEMCPY(r, rt, sizeof(sp_point)); + XMEMCPY(r, rt, sizeof(sp_point_256)); } } @@ -15962,23 +15958,23 @@ static int sp_256_ecc_mulmod_fast_8(sp_point* r, const sp_point* g, const sp_dig XFREE(tmp, heap, DYNAMIC_TYPE_ECC); } if (t != NULL) { - XMEMSET(t, 0, sizeof(sp_point) * 16); + XMEMSET(t, 0, sizeof(sp_point_256) * 16); XFREE(t, heap, DYNAMIC_TYPE_ECC); } #else ForceZero(tmpd, sizeof(tmpd)); ForceZero(td, sizeof(td)); #endif - sp_ecc_point_free(rt, 1, heap); + sp_256_point_free_8(rt, 1, heap); return err; } /* A table entry for pre-computed points. */ -typedef struct sp_table_entry { +typedef struct sp_table_entry_256 { sp_digit x[8]; sp_digit y[8]; -} sp_table_entry; +} sp_table_entry_256; #ifdef FP_ECC /* Double the Montgomery form projective point p a number of times. @@ -15988,10 +15984,10 @@ typedef struct sp_table_entry { * n Number of times to double * t Temporary ordinate data. */ -static void sp_256_proj_point_dbl_n_8(sp_point* r, const sp_point* p, int n, +static void sp_256_proj_point_dbl_n_8(sp_point_256* r, const sp_point_256* p, int n, sp_digit* t) { - sp_point* rp[2]; + sp_point_256* rp[2]; sp_digit* w = t; sp_digit* a = t + 2*8; sp_digit* b = t + 4*8; @@ -16005,8 +16001,8 @@ static void sp_256_proj_point_dbl_n_8(sp_point* r, const sp_point* p, int n, rp[0] = r; /*lint allow cast to different type of pointer*/ - rp[1] = (sp_point*)t; /*lint !e9087 !e740*/ - XMEMSET(rp[1], 0, sizeof(sp_point)); + rp[1] = (sp_point_256*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_256)); x = rp[p->infinity]->x; y = rp[p->infinity]->y; z = rp[p->infinity]->z; @@ -16064,7 +16060,7 @@ static void sp_256_proj_point_dbl_n_8(sp_point* r, const sp_point* p, int n, * a Point to convert. * t Temporary data. */ -static void sp_256_proj_to_affine_8(sp_point* a, sp_digit* t) +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; @@ -16090,11 +16086,11 @@ static void sp_256_proj_to_affine_8(sp_point* a, sp_digit* t) * q Second point to add. * t Temporary ordinate data. */ -static void sp_256_proj_point_add_qz1_8(sp_point* r, const sp_point* p, - const sp_point* q, sp_digit* t) +static void sp_256_proj_point_add_qz1_8(sp_point_256* r, const sp_point_256* p, + const sp_point_256* q, sp_digit* t) { - const sp_point* ap[2]; - sp_point* rp[2]; + const sp_point_256* ap[2]; + sp_point_256* rp[2]; sp_digit* t1 = t; sp_digit* t2 = t + 2*8; sp_digit* t3 = t + 4*8; @@ -16116,8 +16112,8 @@ static void sp_256_proj_point_add_qz1_8(sp_point* r, const sp_point* p, rp[0] = r; /*lint allow cast to different type of pointer*/ - rp[1] = (sp_point*)t; /*lint !e9087 !e740*/ - XMEMSET(rp[1], 0, sizeof(sp_point)); + rp[1] = (sp_point_256*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_256)); x = rp[p->infinity | q->infinity]->x; y = rp[p->infinity | q->infinity]->y; z = rp[p->infinity | q->infinity]->z; @@ -16172,26 +16168,26 @@ static void sp_256_proj_point_add_qz1_8(sp_point* r, const sp_point* p, * tmp Temporary data. * heap Heap to use for allocation. */ -static int sp_256_gen_stripe_table_8(const sp_point* a, - sp_table_entry* table, sp_digit* tmp, void* heap) +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) - sp_point td, s1d, s2d; + sp_point_256 td, s1d, s2d; #endif - sp_point* t; - sp_point* s1 = NULL; - sp_point* s2 = NULL; + sp_point_256* t; + sp_point_256* s1 = NULL; + sp_point_256* s2 = NULL; int i, j; int err; (void)heap; - err = sp_ecc_point_new(heap, td, t); + err = sp_256_point_new_8(heap, td, t); if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, s1d, s1); + err = sp_256_point_new_8(heap, s1d, s1); } if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, s2d, s2); + err = sp_256_point_new_8(heap, s2d, s2); } if (err == MP_OKAY) { @@ -16213,7 +16209,7 @@ static int sp_256_gen_stripe_table_8(const sp_point* a, s2->infinity = 0; /* table[0] = {0, 0, infinity} */ - XMEMSET(&table[0], 0, sizeof(sp_table_entry)); + XMEMSET(&table[0], 0, sizeof(sp_table_entry_256)); /* 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)); @@ -16239,9 +16235,9 @@ static int sp_256_gen_stripe_table_8(const sp_point* a, } } - sp_ecc_point_free(s2, 0, heap); - sp_ecc_point_free(s1, 0, heap); - sp_ecc_point_free( t, 0, heap); + sp_256_point_free_8(s2, 0, heap); + sp_256_point_free_8(s1, 0, heap); + sp_256_point_free_8( t, 0, heap); return err; } @@ -16256,16 +16252,16 @@ static int sp_256_gen_stripe_table_8(const sp_point* a, * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_stripe_8(sp_point* r, const sp_point* g, - const sp_table_entry* table, const sp_digit* k, int map, void* heap) +static int sp_256_ecc_mulmod_stripe_8(sp_point_256* r, const sp_point_256* g, + const sp_table_entry_256* table, const sp_digit* k, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point rtd; - sp_point pd; + sp_point_256 rtd; + sp_point_256 pd; sp_digit td[2 * 8 * 5]; #endif - sp_point* rt; - sp_point* p = NULL; + sp_point_256* rt; + sp_point_256* p = NULL; sp_digit* t; int i, j; int y, x; @@ -16274,9 +16270,10 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point* r, const sp_point* g, (void)g; (void)heap; - err = sp_ecc_point_new(heap, rtd, rt); + + err = sp_256_point_new_8(heap, rtd, rt); if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, pd, p); + err = sp_256_point_new_8(heap, pd, p); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 5, heap, @@ -16316,7 +16313,7 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point* r, const sp_point* g, sp_256_map_8(r, rt, t); } else { - XMEMCPY(r, rt, sizeof(sp_point)); + XMEMCPY(r, rt, sizeof(sp_point_256)); } } @@ -16325,8 +16322,8 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point* r, const sp_point* g, XFREE(t, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(p, 0, heap); - sp_ecc_point_free(rt, 0, heap); + sp_256_point_free_8(p, 0, heap); + sp_256_point_free_8(rt, 0, heap); return err; } @@ -16336,43 +16333,43 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point* r, const sp_point* g, #define FP_ENTRIES 16 #endif -typedef struct sp_cache_t { +typedef struct sp_cache_256_t { sp_digit x[8]; sp_digit y[8]; - sp_table_entry table[16]; + sp_table_entry_256 table[16]; uint32_t cnt; int set; -} sp_cache_t; +} sp_cache_256_t; -static THREAD_LS_T sp_cache_t sp_cache[FP_ENTRIES]; -static THREAD_LS_T int sp_cache_last = -1; -static THREAD_LS_T int sp_cache_inited = 0; +static THREAD_LS_T sp_cache_256_t sp_cache_256[FP_ENTRIES]; +static THREAD_LS_T int sp_cache_256_last = -1; +static THREAD_LS_T int sp_cache_256_inited = 0; #ifndef HAVE_THREAD_LS - static volatile int initCacheMutex = 0; - static wolfSSL_Mutex sp_cache_lock; + static volatile int initCacheMutex_256 = 0; + static wolfSSL_Mutex sp_cache_256_lock; #endif -static void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache) +static void sp_ecc_get_cache_256(const sp_point_256* g, sp_cache_256_t** cache) { int i, j; uint32_t least; - if (sp_cache_inited == 0) { + if (sp_cache_256_inited == 0) { for (i=0; ix, sp_cache[i].x) & - sp_256_cmp_equal_8(g->y, sp_cache[i].y)) { - sp_cache[i].cnt++; + if (sp_256_cmp_equal_8(g->x, sp_cache_256[i].x) & + sp_256_cmp_equal_8(g->y, sp_cache_256[i].y)) { + sp_cache_256[i].cnt++; break; } } @@ -16380,32 +16377,32 @@ static void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache) /* No match. */ if (i == FP_ENTRIES) { /* Find empty entry. */ - i = (sp_cache_last + 1) % FP_ENTRIES; - for (; i != sp_cache_last; i=(i+1)%FP_ENTRIES) { - if (!sp_cache[i].set) { + i = (sp_cache_256_last + 1) % FP_ENTRIES; + for (; i != sp_cache_256_last; i=(i+1)%FP_ENTRIES) { + if (!sp_cache_256[i].set) { break; } } /* Evict least used. */ - if (i == sp_cache_last) { - least = sp_cache[0].cnt; + if (i == sp_cache_256_last) { + least = sp_cache_256[0].cnt; for (j=1; jx, sizeof(sp_cache[i].x)); - XMEMCPY(sp_cache[i].y, g->y, sizeof(sp_cache[i].y)); - sp_cache[i].set = 1; - sp_cache[i].cnt = 1; + XMEMCPY(sp_cache_256[i].x, g->x, sizeof(sp_cache_256[i].x)); + XMEMCPY(sp_cache_256[i].y, g->y, sizeof(sp_cache_256[i].y)); + sp_cache_256[i].set = 1; + sp_cache_256[i].cnt = 1; } - *cache = &sp_cache[i]; - sp_cache_last = i; + *cache = &sp_cache_256[i]; + sp_cache_256_last = i; } #endif /* FP_ECC */ @@ -16419,32 +16416,32 @@ static void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache) * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_8(sp_point* r, const sp_point* g, const sp_digit* k, +static int sp_256_ecc_mulmod_8(sp_point_256* r, const sp_point_256* g, const sp_digit* k, int map, void* heap) { #ifndef FP_ECC return sp_256_ecc_mulmod_fast_8(r, g, k, map, heap); #else sp_digit tmp[2 * 8 * 5]; - sp_cache_t* cache; + sp_cache_256_t* cache; int err = MP_OKAY; #ifndef HAVE_THREAD_LS - if (initCacheMutex == 0) { - wc_InitMutex(&sp_cache_lock); - initCacheMutex = 1; + if (initCacheMutex_256 == 0) { + wc_InitMutex(&sp_cache_256_lock); + initCacheMutex_256 = 1; } - if (wc_LockMutex(&sp_cache_lock) != 0) + if (wc_LockMutex(&sp_cache_256_lock) != 0) err = BAD_MUTEX_E; #endif /* HAVE_THREAD_LS */ if (err == MP_OKAY) { - sp_ecc_get_cache(g, &cache); + sp_ecc_get_cache_256(g, &cache); if (cache->cnt == 2) sp_256_gen_stripe_table_8(g, cache->table, tmp, heap); #ifndef HAVE_THREAD_LS - wc_UnLockMutex(&sp_cache_lock); + wc_UnLockMutex(&sp_cache_256_lock); #endif /* HAVE_THREAD_LS */ if (cache->cnt < 2) { @@ -16469,26 +16466,26 @@ static int sp_256_ecc_mulmod_8(sp_point* r, const sp_point* g, const sp_digit* k * tmp Temporary data. * heap Heap to use for allocation. */ -static int sp_256_gen_stripe_table_8(const sp_point* a, - sp_table_entry* table, sp_digit* tmp, void* heap) +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) - sp_point td, s1d, s2d; + sp_point_256 td, s1d, s2d; #endif - sp_point* t; - sp_point* s1 = NULL; - sp_point* s2 = NULL; + sp_point_256* t; + sp_point_256* s1 = NULL; + sp_point_256* s2 = NULL; int i, j; int err; (void)heap; - err = sp_ecc_point_new(heap, td, t); + err = sp_256_point_new_8(heap, td, t); if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, s1d, s1); + err = sp_256_point_new_8(heap, s1d, s1); } if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, s2d, s2); + err = sp_256_point_new_8(heap, s2d, s2); } if (err == MP_OKAY) { @@ -16510,7 +16507,7 @@ static int sp_256_gen_stripe_table_8(const sp_point* a, s2->infinity = 0; /* table[0] = {0, 0, infinity} */ - XMEMSET(&table[0], 0, sizeof(sp_table_entry)); + XMEMSET(&table[0], 0, sizeof(sp_table_entry_256)); /* 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)); @@ -16536,9 +16533,9 @@ static int sp_256_gen_stripe_table_8(const sp_point* a, } } - sp_ecc_point_free(s2, 0, heap); - sp_ecc_point_free(s1, 0, heap); - sp_ecc_point_free( t, 0, heap); + sp_256_point_free_8(s2, 0, heap); + sp_256_point_free_8(s1, 0, heap); + sp_256_point_free_8( t, 0, heap); return err; } @@ -16553,16 +16550,16 @@ static int sp_256_gen_stripe_table_8(const sp_point* a, * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_stripe_8(sp_point* r, const sp_point* g, - const sp_table_entry* table, const sp_digit* k, int map, void* heap) +static int sp_256_ecc_mulmod_stripe_8(sp_point_256* r, const sp_point_256* g, + const sp_table_entry_256* table, const sp_digit* k, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point rtd; - sp_point pd; + sp_point_256 rtd; + sp_point_256 pd; sp_digit td[2 * 8 * 5]; #endif - sp_point* rt; - sp_point* p = NULL; + sp_point_256* rt; + sp_point_256* p = NULL; sp_digit* t; int i, j; int y, x; @@ -16571,9 +16568,10 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point* r, const sp_point* g, (void)g; (void)heap; - err = sp_ecc_point_new(heap, rtd, rt); + + err = sp_256_point_new_8(heap, rtd, rt); if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, pd, p); + err = sp_256_point_new_8(heap, pd, p); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 5, heap, @@ -16613,7 +16611,7 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point* r, const sp_point* g, sp_256_map_8(r, rt, t); } else { - XMEMCPY(r, rt, sizeof(sp_point)); + XMEMCPY(r, rt, sizeof(sp_point_256)); } } @@ -16622,8 +16620,8 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point* r, const sp_point* g, XFREE(t, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(p, 0, heap); - sp_ecc_point_free(rt, 0, heap); + sp_256_point_free_8(p, 0, heap); + sp_256_point_free_8(rt, 0, heap); return err; } @@ -16633,43 +16631,43 @@ static int sp_256_ecc_mulmod_stripe_8(sp_point* r, const sp_point* g, #define FP_ENTRIES 16 #endif -typedef struct sp_cache_t { +typedef struct sp_cache_256_t { sp_digit x[8]; sp_digit y[8]; - sp_table_entry table[256]; + sp_table_entry_256 table[256]; uint32_t cnt; int set; -} sp_cache_t; +} sp_cache_256_t; -static THREAD_LS_T sp_cache_t sp_cache[FP_ENTRIES]; -static THREAD_LS_T int sp_cache_last = -1; -static THREAD_LS_T int sp_cache_inited = 0; +static THREAD_LS_T sp_cache_256_t sp_cache_256[FP_ENTRIES]; +static THREAD_LS_T int sp_cache_256_last = -1; +static THREAD_LS_T int sp_cache_256_inited = 0; #ifndef HAVE_THREAD_LS - static volatile int initCacheMutex = 0; - static wolfSSL_Mutex sp_cache_lock; + static volatile int initCacheMutex_256 = 0; + static wolfSSL_Mutex sp_cache_256_lock; #endif -static void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache) +static void sp_ecc_get_cache_256(const sp_point_256* g, sp_cache_256_t** cache) { int i, j; uint32_t least; - if (sp_cache_inited == 0) { + if (sp_cache_256_inited == 0) { for (i=0; ix, sp_cache[i].x) & - sp_256_cmp_equal_8(g->y, sp_cache[i].y)) { - sp_cache[i].cnt++; + if (sp_256_cmp_equal_8(g->x, sp_cache_256[i].x) & + sp_256_cmp_equal_8(g->y, sp_cache_256[i].y)) { + sp_cache_256[i].cnt++; break; } } @@ -16677,32 +16675,32 @@ static void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache) /* No match. */ if (i == FP_ENTRIES) { /* Find empty entry. */ - i = (sp_cache_last + 1) % FP_ENTRIES; - for (; i != sp_cache_last; i=(i+1)%FP_ENTRIES) { - if (!sp_cache[i].set) { + i = (sp_cache_256_last + 1) % FP_ENTRIES; + for (; i != sp_cache_256_last; i=(i+1)%FP_ENTRIES) { + if (!sp_cache_256[i].set) { break; } } /* Evict least used. */ - if (i == sp_cache_last) { - least = sp_cache[0].cnt; + if (i == sp_cache_256_last) { + least = sp_cache_256[0].cnt; for (j=1; jx, sizeof(sp_cache[i].x)); - XMEMCPY(sp_cache[i].y, g->y, sizeof(sp_cache[i].y)); - sp_cache[i].set = 1; - sp_cache[i].cnt = 1; + XMEMCPY(sp_cache_256[i].x, g->x, sizeof(sp_cache_256[i].x)); + XMEMCPY(sp_cache_256[i].y, g->y, sizeof(sp_cache_256[i].y)); + sp_cache_256[i].set = 1; + sp_cache_256[i].cnt = 1; } - *cache = &sp_cache[i]; - sp_cache_last = i; + *cache = &sp_cache_256[i]; + sp_cache_256_last = i; } #endif /* FP_ECC */ @@ -16716,32 +16714,32 @@ static void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache) * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_8(sp_point* r, const sp_point* g, const sp_digit* k, +static int sp_256_ecc_mulmod_8(sp_point_256* r, const sp_point_256* g, const sp_digit* k, int map, void* heap) { #ifndef FP_ECC return sp_256_ecc_mulmod_fast_8(r, g, k, map, heap); #else sp_digit tmp[2 * 8 * 5]; - sp_cache_t* cache; + sp_cache_256_t* cache; int err = MP_OKAY; #ifndef HAVE_THREAD_LS - if (initCacheMutex == 0) { - wc_InitMutex(&sp_cache_lock); - initCacheMutex = 1; + if (initCacheMutex_256 == 0) { + wc_InitMutex(&sp_cache_256_lock); + initCacheMutex_256 = 1; } - if (wc_LockMutex(&sp_cache_lock) != 0) + if (wc_LockMutex(&sp_cache_256_lock) != 0) err = BAD_MUTEX_E; #endif /* HAVE_THREAD_LS */ if (err == MP_OKAY) { - sp_ecc_get_cache(g, &cache); + sp_ecc_get_cache_256(g, &cache); if (cache->cnt == 2) sp_256_gen_stripe_table_8(g, cache->table, tmp, heap); #ifndef HAVE_THREAD_LS - wc_UnLockMutex(&sp_cache_lock); + wc_UnLockMutex(&sp_cache_256_lock); #endif /* HAVE_THREAD_LS */ if (cache->cnt < 2) { @@ -16772,15 +16770,14 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point p; - sp_digit k[8]; -#else - sp_digit* k = NULL; + sp_point_256 p; + sp_digit kd[8]; #endif - sp_point* point; - int err; + sp_point_256* point; + sp_digit* k = NULL; + int err = MP_OKAY; - err = sp_ecc_point_new(heap, p, point); + err = sp_256_point_new_8(heap, p, point); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8, heap, @@ -16788,6 +16785,8 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, if (k == NULL) err = MEMORY_E; } +#else + k = kd; #endif if (err == MP_OKAY) { sp_256_from_mp(k, 8, km); @@ -16804,13 +16803,13 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, XFREE(k, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(point, 0, heap); + sp_256_point_free_8(point, 0, heap); return err; } #ifdef WOLFSSL_SP_SMALL -static const sp_table_entry p256_table[16] = { +static const sp_table_entry_256 p256_table[16] = { /* 0 */ { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, @@ -16900,7 +16899,7 @@ static const sp_table_entry p256_table[16] = { * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_base_8(sp_point* r, const sp_digit* k, +static int sp_256_ecc_mulmod_base_8(sp_point_256* r, const sp_digit* k, int map, void* heap) { return sp_256_ecc_mulmod_stripe_8(r, &p256_base, p256_table, @@ -16908,7 +16907,7 @@ static int sp_256_ecc_mulmod_base_8(sp_point* r, const sp_digit* k, } #else -static const sp_table_entry p256_table[256] = { +static const sp_table_entry_256 p256_table[256] = { /* 0 */ { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, @@ -18198,7 +18197,7 @@ static const sp_table_entry p256_table[256] = { * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_base_8(sp_point* r, const sp_digit* k, +static int sp_256_ecc_mulmod_base_8(sp_point_256* r, const sp_digit* k, int map, void* heap) { return sp_256_ecc_mulmod_stripe_8(r, &p256_base, p256_table, @@ -18219,15 +18218,14 @@ static int sp_256_ecc_mulmod_base_8(sp_point* r, const sp_digit* k, int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point p; - sp_digit k[8]; -#else - sp_digit* k = NULL; + sp_point_256 p; + sp_digit kd[8]; #endif - sp_point* point; - int err; + sp_point_256* point; + sp_digit* k = NULL; + int err = MP_OKAY; - err = sp_ecc_point_new(heap, p, point); + err = sp_256_point_new_8(heap, p, point); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 8, heap, @@ -18236,6 +18234,8 @@ int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) err = MEMORY_E; } } +#else + k = kd; #endif if (err == MP_OKAY) { sp_256_from_mp(k, 8, km); @@ -18251,7 +18251,7 @@ int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) XFREE(k, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(point, 0, heap); + sp_256_point_free_8(point, 0, heap); return err; } @@ -18382,26 +18382,25 @@ static int sp_256_ecc_gen_k_8(WC_RNG* rng, sp_digit* k) int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point p; - sp_digit k[8]; + sp_point_256 p; + sp_digit kd[8]; #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN - sp_point inf; + sp_point_256 inf; #endif -#else +#endif + sp_point_256* point; sp_digit* k = NULL; -#endif - sp_point* point; #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN - sp_point* infinity; + sp_point_256* infinity; #endif int err; (void)heap; - err = sp_ecc_point_new(heap, p, point); + err = sp_256_point_new_8(heap, p, point); #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, inf, infinity); + err = sp_256_point_new_8(heap, inf, infinity); } #endif #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) @@ -18412,6 +18411,8 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) err = MEMORY_E; } } +#else + k = kd; #endif if (err == MP_OKAY) { @@ -18445,9 +18446,9 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) } #endif #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN - sp_ecc_point_free(infinity, 1, heap); + sp_256_point_free_8(infinity, 1, heap); #endif - sp_ecc_point_free(point, 1, heap); + sp_256_point_free_8(point, 1, heap); return err; } @@ -18504,12 +18505,11 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, word32* outLen, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point p; - sp_digit k[8]; -#else - sp_digit* k = NULL; + sp_point_256 p; + sp_digit kd[8]; #endif - sp_point* point = NULL; + sp_point_256* point = NULL; + sp_digit* k = NULL; int err = MP_OKAY; if (*outLen < 32U) { @@ -18517,7 +18517,7 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, } if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, p, point); + err = sp_256_point_new_8(heap, p, point); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { @@ -18526,6 +18526,8 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, if (k == NULL) err = MEMORY_E; } +#else + k = kd; #endif if (err == MP_OKAY) { @@ -18543,7 +18545,7 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, XFREE(k, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(point, 0, heap); + sp_256_point_free_8(point, 0, heap); return err; } @@ -18802,7 +18804,7 @@ static WC_INLINE int sp_256_mod_8(sp_digit* r, const sp_digit* a, const sp_digit #if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) #ifdef WOLFSSL_SP_SMALL /* Order-2 for the P256 curve. */ -static const uint32_t p256_order_2[8] = { +static const uint32_t p256_order_minus_2[8] = { 0xfc63254fU,0xf3b9cac2U,0xa7179e84U,0xbce6faadU,0xffffffffU,0xffffffffU, 0x00000000U,0xffffffffU }; @@ -18871,7 +18873,7 @@ static void sp_256_mont_inv_order_8(sp_digit* r, const sp_digit* a, XMEMCPY(t, a, sizeof(sp_digit) * 8); for (i=254; i>=0; i--) { sp_256_mont_sqr_order_8(t, t); - if ((p256_order_2[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { + if ((p256_order_minus_2[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { sp_256_mont_mul_order_8(t, t, a); } } @@ -18987,24 +18989,24 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_digit kd[2*8]; sp_digit rd[2*8]; sp_digit td[3 * 2*8]; - sp_point p; + sp_point_256 p; #endif sp_digit* e = NULL; sp_digit* x = NULL; sp_digit* k = NULL; sp_digit* r = NULL; sp_digit* tmp = NULL; - sp_point* point = NULL; + sp_point_256* point = NULL; sp_digit carry; sp_digit* s = NULL; sp_digit* kInv = NULL; - int err; + int err = MP_OKAY; int32_t c; int i; (void)heap; - err = sp_ecc_point_new(heap, p, point); + err = sp_256_point_new_8(heap, p, point); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7 * 2 * 8, heap, @@ -19120,7 +19122,7 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, XMEMSET(r, 0, sizeof(sp_digit) * 2U * 8U); XMEMSET(tmp, 0, sizeof(sp_digit) * 3U * 2U * 8U); #endif - sp_ecc_point_free(point, 1, heap); + sp_256_point_free_8(point, 1, heap); return err; } @@ -19157,22 +19159,22 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, sp_digit u2d[2*8]; sp_digit sd[2*8]; sp_digit tmpd[2*8 * 5]; - sp_point p1d; - sp_point p2d; + sp_point_256 p1d; + sp_point_256 p2d; #endif sp_digit* u1 = NULL; sp_digit* u2 = NULL; sp_digit* s = NULL; sp_digit* tmp = NULL; - sp_point* p1; - sp_point* p2 = NULL; + sp_point_256* p1; + sp_point_256* p2 = NULL; sp_digit carry; int32_t c; int err; - err = sp_ecc_point_new(heap, p1d, p1); + err = sp_256_point_new_8(heap, p1d, p1); if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, p2d, p2); + err = sp_256_point_new_8(heap, p2d, p2); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { @@ -19288,8 +19290,8 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, if (d != NULL) XFREE(d, heap, DYNAMIC_TYPE_ECC); #endif - sp_ecc_point_free(p1, 0, heap); - sp_ecc_point_free(p2, 0, heap); + sp_256_point_free_8(p1, 0, heap); + sp_256_point_free_8(p2, 0, heap); return err; } @@ -19303,10 +19305,10 @@ 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* point, void* heap) +static int sp_256_ecc_is_point_8(sp_point_256* point, void* heap) { #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - sp_digit* d; + sp_digit* d = NULL; #else sp_digit t1d[2*8]; sp_digit t2d[2*8]; @@ -19370,13 +19372,13 @@ static int sp_256_ecc_is_point_8(sp_point* point, void* heap) int sp_ecc_is_point_256(mp_int* pX, mp_int* pY) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point pubd; + sp_point_256 pubd; #endif - sp_point* pub; + sp_point_256* pub; byte one[1] = { 1 }; int err; - err = sp_ecc_point_new(NULL, pubd, pub); + err = sp_256_point_new_8(NULL, pubd, pub); if (err == MP_OKAY) { sp_256_from_mp(pub->x, 8, pX); sp_256_from_mp(pub->y, 8, pY); @@ -19385,7 +19387,7 @@ int sp_ecc_is_point_256(mp_int* pX, mp_int* pY) err = sp_256_ecc_is_point_8(pub, NULL); } - sp_ecc_point_free(pub, 0, NULL); + sp_256_point_free_8(pub, 0, NULL); return err; } @@ -19405,18 +19407,18 @@ int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_digit privd[8]; - sp_point pubd; - sp_point pd; + sp_point_256 pubd; + sp_point_256 pd; #endif sp_digit* priv = NULL; - sp_point* pub; - sp_point* p = NULL; + sp_point_256* pub; + sp_point_256* p = NULL; byte one[1] = { 1 }; int err; - err = sp_ecc_point_new(heap, pubd, pub); + err = sp_256_point_new_8(heap, pubd, pub); if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, pd, p); + err = sp_256_point_new_8(heap, pd, p); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { @@ -19487,8 +19489,8 @@ int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) XFREE(priv, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(p, 0, heap); - sp_ecc_point_free(pub, 0, heap); + sp_256_point_free_8(p, 0, heap); + sp_256_point_free_8(pub, 0, heap); return err; } @@ -19514,17 +19516,17 @@ int sp_ecc_proj_add_point_256(mp_int* pX, mp_int* pY, mp_int* pZ, { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_digit tmpd[2 * 8 * 5]; - sp_point pd; - sp_point qd; + sp_point_256 pd; + sp_point_256 qd; #endif sp_digit* tmp; - sp_point* p; - sp_point* q = NULL; + sp_point_256* p; + sp_point_256* q = NULL; int err; - err = sp_ecc_point_new(NULL, pd, p); + err = sp_256_point_new_8(NULL, pd, p); if (err == MP_OKAY) { - err = sp_ecc_point_new(NULL, qd, q); + err = sp_256_point_new_8(NULL, qd, q); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { @@ -19564,8 +19566,8 @@ int sp_ecc_proj_add_point_256(mp_int* pX, mp_int* pY, mp_int* pZ, XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(q, 0, NULL); - sp_ecc_point_free(p, 0, NULL); + sp_256_point_free_8(q, 0, NULL); + sp_256_point_free_8(p, 0, NULL); return err; } @@ -19586,13 +19588,13 @@ int sp_ecc_proj_dbl_point_256(mp_int* pX, mp_int* pY, mp_int* pZ, { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_digit tmpd[2 * 8 * 2]; - sp_point pd; + sp_point_256 pd; #endif sp_digit* tmp; - sp_point* p; + sp_point_256* p; int err; - err = sp_ecc_point_new(NULL, pd, p); + err = sp_256_point_new_8(NULL, pd, p); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 2, NULL, @@ -19628,7 +19630,7 @@ int sp_ecc_proj_dbl_point_256(mp_int* pX, mp_int* pY, mp_int* pZ, XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(p, 0, NULL); + sp_256_point_free_8(p, 0, NULL); return err; } @@ -19645,13 +19647,13 @@ int sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_digit tmpd[2 * 8 * 4]; - sp_point pd; + sp_point_256 pd; #endif sp_digit* tmp; - sp_point* p; + sp_point_256* p; int err; - err = sp_ecc_point_new(NULL, pd, p); + err = sp_256_point_new_8(NULL, pd, p); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 8 * 4, NULL, @@ -19686,7 +19688,7 @@ int sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ) XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(p, 0, NULL); + sp_256_point_free_8(p, 0, NULL); return err; } @@ -19767,6 +19769,7 @@ static int sp_256_mont_sqrt_8(sp_digit* y) return err; } + /* Uncompress the point given the X ordinate. * * xm X ordinate. @@ -19843,6 +19846,5559 @@ int sp_ecc_uncompress_256(mp_int* xm, int odd, mp_int* ym) } #endif #endif /* !WOLFSSL_SP_NO_256 */ +#ifdef WOLFSSL_SP_384 + +/* Point structure to use. */ +typedef struct sp_point_384 { + sp_digit x[2 * 12]; + sp_digit y[2 * 12]; + sp_digit z[2 * 12]; + int infinity; +} sp_point_384; + +/* The modulus (prime) of the curve P384. */ +static const sp_digit p384_mod[12] = { + 0xffffffff,0x00000000,0x00000000,0xffffffff,0xfffffffe,0xffffffff, + 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff +}; +/* The Montogmery normalizer for modulus of the curve P384. */ +static const sp_digit p384_norm_mod[12] = { + 0x00000001,0xffffffff,0xffffffff,0x00000000,0x00000001,0x00000000, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 +}; +/* The Montogmery multiplier for modulus of the curve P384. */ +static sp_digit p384_mp_mod = 0x00000001; +#if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \ + defined(HAVE_ECC_VERIFY) +/* The order of the curve P384. */ +static const sp_digit p384_order[12] = { + 0xccc52973,0xecec196a,0x48b0a77a,0x581a0db2,0xf4372ddf,0xc7634d81, + 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff +}; +#endif +/* The order of the curve P384 minus 2. */ +static const sp_digit p384_order2[12] = { + 0xccc52971,0xecec196a,0x48b0a77a,0x581a0db2,0xf4372ddf,0xc7634d81, + 0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff +}; +#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[12] = { + 0x333ad68d,0x1313e695,0xb74f5885,0xa7e5f24d,0x0bc8d220,0x389cb27e, + 0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000 +}; +#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 = 0xe88fdc45; +#endif +/* The base point of curve P384. */ +static const sp_point_384 p384_base = { + /* X ordinate */ + { + 0x72760ab7,0x3a545e38,0xbf55296c,0x5502f25d,0x82542a38,0x59f741e0, + 0x8ba79b98,0x6e1d3b62,0xf320ad74,0x8eb1c71e,0xbe8b0537,0xaa87ca22, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + }, + /* Y ordinate */ + { + 0x90ea0e5f,0x7a431d7c,0x1d7e819d,0x0a60b1ce,0xb5f0b8c0,0xe9da3113, + 0x289a147c,0xf8f41dbd,0x9292dc29,0x5d9e98bf,0x96262c6f,0x3617de4a, + 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, + 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L + }, + /* infinity */ + 0 +}; +#if defined(HAVE_ECC_CHECK_KEY) || defined(HAVE_COMP_KEY) +static const sp_digit p384_b[12] = { + 0xd3ec2aef,0x2a85c8ed,0x8a2ed19d,0xc656398d,0x5013875a,0x0314088f, + 0xfe814112,0x181d9c6e,0xe3f82d19,0x988e056b,0xe23ee7e4,0xb3312fa7 +}; +#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) + (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) +/* 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) +/* 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) + 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) + 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) + 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] |= a[i] << s; + r->dp[j] &= (1L << DIGIT_BIT) - 1; + s = DIGIT_BIT - s; + r->dp[++j] = 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] = 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. + * a A single precision integer. + * b A single precision integer. + */ +SP_NOINLINE static void sp_384_mul_12(sp_digit* r, const sp_digit* a, + const sp_digit* b) +{ + sp_digit tmp[12 * 2]; + __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, #48\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, #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 %[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" + "beq 3f\n\t" + "mov r6, r9\n\t" + "add r6, r6, r10\n\t" + "cmp %[a], r6\n\t" + "ble 2b\n\t" + "\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, #88\n\t" + "cmp r8, r6\n\t" + "ble 1b\n\t" + "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, sizeof(tmp)); +} + +/* 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_384_cond_sub_12(sp_digit* r, const sp_digit* a, + const sp_digit* b, sp_digit m) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "mov r5, #48\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" + "blt 1b\n\t" + : [c] "+r" (c) + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) + : "memory", "r5", "r6", "r8", "r9" + ); + + return c; +} + +#define sp_384_mont_reduce_order_12 sp_384_mont_reduce_12 + +/* 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_12(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, #48\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, #40\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" + "blt 2b\n\t" + /* a[i+10] += m[10] * 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+11] += m[11] * mu */ + "mov r4, %[ca]\n\t" + "mov %[ca], #0\n\t" + /* Multiply m[11] 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[11] 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, #40\n\t" + "cmp r10, r11\n\t" + "blt 1b\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_384_cond_sub_12(a - 12, 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_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" + "beq 4f\n\t" + /* 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 */ + "bal 5f\n\t" + "\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" + "beq 3f\n\t" + "cmp %[a], r2\n\t" + "bgt 3f\n\t" + "mov r8, r9\n\t" + "add r8, r8, r10\n\t" + "cmp %[a], r8\n\t" + "ble 2b\n\t" + "\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" + "ble 1b\n\t" + "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" + "bge 4b\n\t" + "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. + * a Number to square in Montogmery form. + * 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) +{ + sp_384_sqr_12(r, a); + sp_384_mont_reduce_12(r, m, mp); +} + +#if !defined(WOLFSSL_SP_SMALL) || defined(HAVE_COMP_KEY) +/* Square the Montgomery form number a number of times. (r = a ^ n mod m) + * + * r Result of squaring. + * a Number to square in Montogmery form. + * n Number of times to square. + * m Modulus (prime). + * mp Montogmery mulitplier. + */ +static void sp_384_mont_sqr_n_12(sp_digit* r, const sp_digit* a, int n, + const sp_digit* m, sp_digit mp) +{ + sp_384_mont_sqr_12(r, a, m, mp); + for (; n > 1; n--) { + sp_384_mont_sqr_12(r, r, m, mp); + } +} + +#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] = { + 0xfffffffdU,0x00000000U,0x00000000U,0xffffffffU,0xfffffffeU,0xffffffffU, + 0xffffffffU,0xffffffffU,0xffffffffU,0xffffffffU,0xffffffffU,0xffffffffU +}; +#endif /* !WOLFSSL_SP_SMALL */ + +/* Invert the number, in Montgomery form, modulo the modulus (prime) of the + * P384 curve. (r = 1 / a mod m) + * + * r Inverse result. + * a Number to invert. + * td Temporary data. + */ +static void sp_384_mont_inv_12(sp_digit* r, const sp_digit* a, sp_digit* td) +{ +#ifdef WOLFSSL_SP_SMALL + sp_digit* t = td; + int i; + + XMEMCPY(t, a, sizeof(sp_digit) * 12); + for (i=382; i>=0; i--) { + sp_384_mont_sqr_12(t, t, p384_mod, p384_mp_mod); + if (p384_mod_minus_2[i / 32] & ((sp_digit)1 << (i % 32))) + sp_384_mont_mul_12(t, t, a, p384_mod, p384_mp_mod); + } + XMEMCPY(r, t, sizeof(sp_digit) * 12); +#else + sp_digit* t1 = td; + sp_digit* t2 = td + 2 * 12; + sp_digit* t3 = td + 4 * 12; + sp_digit* t4 = td + 6 * 12; + sp_digit* t5 = td + 8 * 12; + + /* 0x2 */ + sp_384_mont_sqr_12(t1, a, p384_mod, p384_mp_mod); + /* 0x3 */ + sp_384_mont_mul_12(t5, t1, a, p384_mod, p384_mp_mod); + /* 0xc */ + sp_384_mont_sqr_n_12(t1, t5, 2, p384_mod, p384_mp_mod); + /* 0xf */ + sp_384_mont_mul_12(t2, t5, t1, p384_mod, p384_mp_mod); + /* 0x1e */ + sp_384_mont_sqr_12(t1, t2, p384_mod, p384_mp_mod); + /* 0x1f */ + sp_384_mont_mul_12(t4, t1, a, p384_mod, p384_mp_mod); + /* 0x3e0 */ + sp_384_mont_sqr_n_12(t1, t4, 5, p384_mod, p384_mp_mod); + /* 0x3ff */ + sp_384_mont_mul_12(t2, t4, t1, p384_mod, p384_mp_mod); + /* 0x7fe0 */ + sp_384_mont_sqr_n_12(t1, t2, 5, p384_mod, p384_mp_mod); + /* 0x7fff */ + sp_384_mont_mul_12(t4, t4, t1, p384_mod, p384_mp_mod); + /* 0x3fff8000 */ + sp_384_mont_sqr_n_12(t1, t4, 15, p384_mod, p384_mp_mod); + /* 0x3fffffff */ + sp_384_mont_mul_12(t2, t4, t1, p384_mod, p384_mp_mod); + /* 0xfffffffc */ + sp_384_mont_sqr_n_12(t3, t2, 2, p384_mod, p384_mp_mod); + /* 0xfffffffd */ + sp_384_mont_mul_12(r, t3, a, p384_mod, p384_mp_mod); + /* 0xffffffff */ + sp_384_mont_mul_12(t3, t5, t3, p384_mod, p384_mp_mod); + /* 0xfffffffc0000000 */ + sp_384_mont_sqr_n_12(t1, t2, 30, p384_mod, p384_mp_mod); + /* 0xfffffffffffffff */ + sp_384_mont_mul_12(t2, t2, t1, p384_mod, p384_mp_mod); + /* 0xfffffffffffffff000000000000000 */ + sp_384_mont_sqr_n_12(t1, t2, 60, p384_mod, p384_mp_mod); + /* 0xffffffffffffffffffffffffffffff */ + sp_384_mont_mul_12(t2, t2, t1, p384_mod, p384_mp_mod); + /* 0xffffffffffffffffffffffffffffff000000000000000000000000000000 */ + sp_384_mont_sqr_n_12(t1, t2, 120, p384_mod, p384_mp_mod); + /* 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */ + sp_384_mont_mul_12(t2, t2, t1, p384_mod, p384_mp_mod); + /* 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000 */ + sp_384_mont_sqr_n_12(t1, t2, 15, p384_mod, p384_mp_mod); + /* 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */ + sp_384_mont_mul_12(t2, t4, t1, p384_mod, p384_mp_mod); + /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00000000 */ + sp_384_mont_sqr_n_12(t1, t2, 33, p384_mod, p384_mp_mod); + /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff */ + sp_384_mont_mul_12(t2, t3, t1, p384_mod, p384_mp_mod); + /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff000000000000000000000000 */ + sp_384_mont_sqr_n_12(t1, t2, 96, p384_mod, p384_mp_mod); + /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffd */ + sp_384_mont_mul_12(r, r, t1, p384_mod, p384_mp_mod); + +#endif /* WOLFSSL_SP_SMALL */ +} + +/* 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_384_cmp_12(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, #44\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" + "bge 1b\n\t" + : [r] "+r" (r) + : [a] "r" (a), [b] "r" (b) + : "r3", "r4", "r5", "r6", "r8" + ); + + return r; +} + +/* Normalize the values in each word to 32. + * + * a Array of sp_digit to normalize. + */ +#define sp_384_norm_12(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_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; + int32_t n; + + sp_384_mont_inv_12(t1, p->z, t + 2*12); + + 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); + + /* x /= z^2 */ + sp_384_mont_mul_12(r->x, p->x, t2, p384_mod, p384_mp_mod); + XMEMSET(r->x + 12, 0, sizeof(r->x) / 2U); + sp_384_mont_reduce_12(r->x, p384_mod, p384_mp_mod); + /* Reduce x to less than modulus */ + n = sp_384_cmp_12(r->x, p384_mod); + sp_384_cond_sub_12(r->x, r->x, p384_mod, 0 - ((n >= 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_384_norm_12(r->x); + + /* y /= z^3 */ + sp_384_mont_mul_12(r->y, p->y, t1, p384_mod, p384_mp_mod); + XMEMSET(r->y + 12, 0, sizeof(r->y) / 2U); + sp_384_mont_reduce_12(r->y, p384_mod, p384_mp_mod); + /* Reduce y to less than modulus */ + n = sp_384_cmp_12(r->y, p384_mod); + sp_384_cond_sub_12(r->y, r->y, p384_mod, 0 - ((n >= 0) ? + (sp_digit)1 : (sp_digit)0)); + sp_384_norm_12(r->y); + + XMEMSET(r->z, 0, sizeof(r->z)); + r->z[0] = 1; + +} + +#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" + "bne 1b\n\t" + : [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. + * a First number to add in Montogmery form. + * b Second number to add in Montogmery form. + * m Modulus (prime). + */ +SP_NOINLINE static void sp_384_mont_add_12(sp_digit* r, const sp_digit* a, const sp_digit* b, + const sp_digit* m) +{ + sp_digit o; + + o = sp_384_add_12(r, a, b); + sp_384_cond_sub_12(r, r, m, 0 - o); +} + +/* 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_384_mont_dbl_12(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + sp_digit o; + + o = sp_384_add_12(r, a, a); + sp_384_cond_sub_12(r, r, m, 0 - o); +} + +/* 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_384_mont_tpl_12(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + sp_digit o; + + o = sp_384_add_12(r, a, a); + sp_384_cond_sub_12(r, r, m, 0 - o); + o = sp_384_add_12(r, r, a); + 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" + "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 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. + * + * 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_384_cond_add_12(sp_digit* r, const sp_digit* a, const sp_digit* b, + sp_digit m) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "mov r10, #0\n\t" + "mov r6, #48\n\t" + "sub r10, #1\n\t" + "mov r9, r6\n\t" + "mov r8, #0\n\t" + "\n1:\n\t" + "ldr r5, [%[a], r8]\n\t" + "ldr r6, [%[b], r8]\n\t" + "and r6, r6, %[m]\n\t" + "adds %[c], %[c], r10\n\t" + "adcs r5, r5, r6\n\t" + "str r5, [%[r], r8]\n\t" + "mov %[c], #0\n\t" + "adc %[c], %[c], %[c]\n\t" + "add r8, r8, #4\n\t" + "cmp r8, r9\n\t" + "blt 1b\n\t" + : [c] "+r" (c) + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) + : "memory", "r5", "r6", "r8", "r9", "r10" + ); + + return c; +} + +/* 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_384_mont_sub_12(sp_digit* r, const sp_digit* a, const sp_digit* b, + const sp_digit* m) +{ + sp_digit o; + + o = sp_384_sub_12(r, a, b); + sp_384_cond_add_12(r, r, m, o); +} + +static void sp_384_rshift1_12(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" + "str r3, [%[r], #40]\n\t" + "str r4, [%[r], #44]\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_384_div2_12(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + sp_digit o; + + o = sp_384_cond_add_12(r, a, m, 0 - (a[0] & 1)); + sp_384_rshift1_12(r, r); + r[11] |= o << 31; +} + +/* Double the Montgomery form projective point p. + * + * r Result of doubling point. + * p Point to double. + * t Temporary ordinate data. + */ +static void sp_384_proj_point_dbl_12(sp_point_384* r, const sp_point_384* p, sp_digit* t) +{ + sp_point_384* rp[2]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*12; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + /* When infinity don't double point passed in - constant time. */ + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_384*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_384)); + x = rp[p->infinity]->x; + y = rp[p->infinity]->y; + z = rp[p->infinity]->z; + /* Put point to double into result - good for infinity. */ + if (r != p) { + for (i=0; i<12; i++) { + r->x[i] = p->x[i]; + } + for (i=0; i<12; i++) { + r->y[i] = p->y[i]; + } + for (i=0; i<12; i++) { + r->z[i] = p->z[i]; + } + r->infinity = p->infinity; + } + + /* T1 = Z * Z */ + sp_384_mont_sqr_12(t1, z, p384_mod, p384_mp_mod); + /* Z = Y * Z */ + sp_384_mont_mul_12(z, y, z, p384_mod, p384_mp_mod); + /* Z = 2Z */ + sp_384_mont_dbl_12(z, z, p384_mod); + /* T2 = X - T1 */ + sp_384_mont_sub_12(t2, x, t1, p384_mod); + /* T1 = X + T1 */ + sp_384_mont_add_12(t1, x, t1, p384_mod); + /* T2 = T1 * T2 */ + sp_384_mont_mul_12(t2, t1, t2, p384_mod, p384_mp_mod); + /* T1 = 3T2 */ + sp_384_mont_tpl_12(t1, t2, p384_mod); + /* Y = 2Y */ + sp_384_mont_dbl_12(y, y, p384_mod); + /* Y = Y * Y */ + sp_384_mont_sqr_12(y, y, p384_mod, p384_mp_mod); + /* T2 = Y * Y */ + sp_384_mont_sqr_12(t2, y, p384_mod, p384_mp_mod); + /* T2 = T2/2 */ + sp_384_div2_12(t2, t2, p384_mod); + /* Y = Y * X */ + sp_384_mont_mul_12(y, y, x, p384_mod, p384_mp_mod); + /* X = T1 * T1 */ + sp_384_mont_mul_12(x, t1, t1, p384_mod, p384_mp_mod); + /* X = X - Y */ + sp_384_mont_sub_12(x, x, y, p384_mod); + /* X = X - Y */ + sp_384_mont_sub_12(x, x, y, p384_mod); + /* Y = Y - X */ + sp_384_mont_sub_12(y, y, x, p384_mod); + /* Y = Y * T1 */ + sp_384_mont_mul_12(y, y, t1, p384_mod, p384_mp_mod); + /* Y = Y - T2 */ + sp_384_mont_sub_12(y, y, t2, p384_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_384_cmp_equal_12(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])) == 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. + */ +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]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*12; + sp_digit* t3 = t + 4*12; + sp_digit* t4 = t + 6*12; + sp_digit* t5 = t + 8*12; + 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_384* a = p; + p = q; + q = a; + } + + /* Check double */ + (void)sp_384_sub_12(t1, p384_mod, q->y); + sp_384_norm_12(t1); + if ((sp_384_cmp_equal_12(p->x, q->x) & sp_384_cmp_equal_12(p->z, q->z) & + (sp_384_cmp_equal_12(p->y, q->y) | sp_384_cmp_equal_12(p->y, t1))) != 0) { + sp_384_proj_point_dbl_12(r, p, t); + } + else { + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_384*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_384)); + 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<12; i++) { + r->x[i] = ap[p->infinity]->x[i]; + } + for (i=0; i<12; i++) { + r->y[i] = ap[p->infinity]->y[i]; + } + for (i=0; i<12; i++) { + r->z[i] = ap[p->infinity]->z[i]; + } + r->infinity = ap[p->infinity]->infinity; + + /* U1 = X1*Z2^2 */ + sp_384_mont_sqr_12(t1, q->z, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(t3, t1, q->z, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(t1, t1, x, p384_mod, p384_mp_mod); + /* U2 = X2*Z1^2 */ + sp_384_mont_sqr_12(t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(t4, t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(t2, t2, q->x, p384_mod, p384_mp_mod); + /* S1 = Y1*Z2^3 */ + sp_384_mont_mul_12(t3, t3, y, p384_mod, p384_mp_mod); + /* S2 = Y2*Z1^3 */ + sp_384_mont_mul_12(t4, t4, q->y, p384_mod, p384_mp_mod); + /* H = U2 - U1 */ + sp_384_mont_sub_12(t2, t2, t1, p384_mod); + /* R = S2 - S1 */ + sp_384_mont_sub_12(t4, t4, t3, p384_mod); + /* Z3 = H*Z1*Z2 */ + sp_384_mont_mul_12(z, z, q->z, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(z, z, t2, p384_mod, p384_mp_mod); + /* X3 = R^2 - H^3 - 2*U1*H^2 */ + sp_384_mont_sqr_12(x, t4, p384_mod, p384_mp_mod); + sp_384_mont_sqr_12(t5, t2, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(y, t1, t5, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(t5, t5, t2, p384_mod, p384_mp_mod); + sp_384_mont_sub_12(x, x, t5, p384_mod); + sp_384_mont_dbl_12(t1, y, p384_mod); + sp_384_mont_sub_12(x, x, t1, p384_mod); + /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */ + sp_384_mont_sub_12(y, y, x, p384_mod); + sp_384_mont_mul_12(y, y, t4, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(t5, t5, t3, p384_mod, p384_mp_mod); + sp_384_mont_sub_12(y, y, t5, p384_mod); + } +} + +/* Multiply the point 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. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_ecc_mulmod_fast_12(sp_point_384* r, const sp_point_384* g, const sp_digit* k, + int map, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 td[16]; + sp_point_384 rtd; + sp_digit tmpd[2 * 12 * 6]; +#endif + sp_point_384* t; + sp_point_384* rt; + sp_digit* tmp; + sp_digit n; + int i; + int c, y; + int err; + + (void)heap; + + err = sp_384_point_new_12(heap, rtd, rt); +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + t = (sp_point_384*)XMALLOC(sizeof(sp_point_384) * 16, heap, DYNAMIC_TYPE_ECC); + if (t == NULL) + err = MEMORY_E; + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 12 * 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 */ + (void)sp_384_mod_mul_norm_12(t[1].x, g->x, p384_mod); + (void)sp_384_mod_mul_norm_12(t[1].y, g->y, p384_mod); + (void)sp_384_mod_mul_norm_12(t[1].z, g->z, p384_mod); + t[1].infinity = 0; + sp_384_proj_point_dbl_12(&t[ 2], &t[ 1], tmp); + t[ 2].infinity = 0; + sp_384_proj_point_add_12(&t[ 3], &t[ 2], &t[ 1], tmp); + t[ 3].infinity = 0; + sp_384_proj_point_dbl_12(&t[ 4], &t[ 2], tmp); + t[ 4].infinity = 0; + sp_384_proj_point_add_12(&t[ 5], &t[ 3], &t[ 2], tmp); + t[ 5].infinity = 0; + sp_384_proj_point_dbl_12(&t[ 6], &t[ 3], tmp); + t[ 6].infinity = 0; + sp_384_proj_point_add_12(&t[ 7], &t[ 4], &t[ 3], tmp); + t[ 7].infinity = 0; + sp_384_proj_point_dbl_12(&t[ 8], &t[ 4], tmp); + t[ 8].infinity = 0; + sp_384_proj_point_add_12(&t[ 9], &t[ 5], &t[ 4], tmp); + t[ 9].infinity = 0; + sp_384_proj_point_dbl_12(&t[10], &t[ 5], tmp); + t[10].infinity = 0; + sp_384_proj_point_add_12(&t[11], &t[ 6], &t[ 5], tmp); + t[11].infinity = 0; + sp_384_proj_point_dbl_12(&t[12], &t[ 6], tmp); + t[12].infinity = 0; + sp_384_proj_point_add_12(&t[13], &t[ 7], &t[ 6], tmp); + t[13].infinity = 0; + sp_384_proj_point_dbl_12(&t[14], &t[ 7], tmp); + t[14].infinity = 0; + sp_384_proj_point_add_12(&t[15], &t[ 8], &t[ 7], tmp); + t[15].infinity = 0; + + i = 10; + n = k[i+1] << 0; + c = 28; + y = n >> 28; + XMEMCPY(rt, &t[y], sizeof(sp_point_384)); + n <<= 4; + for (; i>=0 || c>=4; ) { + if (c < 4) { + n |= k[i--] << (0 - c); + c += 32; + } + y = (n >> 28) & 0xf; + n <<= 4; + c -= 4; + + sp_384_proj_point_dbl_12(rt, rt, tmp); + sp_384_proj_point_dbl_12(rt, rt, tmp); + sp_384_proj_point_dbl_12(rt, rt, tmp); + sp_384_proj_point_dbl_12(rt, rt, tmp); + + sp_384_proj_point_add_12(rt, rt, &t[y], tmp); + } + + if (map != 0) { + sp_384_map_12(r, rt, tmp); + } + else { + XMEMCPY(r, rt, sizeof(sp_point_384)); + } + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (tmp != NULL) { + XMEMSET(tmp, 0, sizeof(sp_digit) * 2 * 12 * 6); + XFREE(tmp, heap, DYNAMIC_TYPE_ECC); + } + if (t != NULL) { + XMEMSET(t, 0, sizeof(sp_point_384) * 16); + XFREE(t, heap, DYNAMIC_TYPE_ECC); + } +#else + ForceZero(tmpd, sizeof(tmpd)); + ForceZero(td, sizeof(td)); +#endif + sp_384_point_free_12(rt, 1, heap); + + 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. + * + * r Result of repeated doubling of point. + * p Point to double. + * n Number of times to double + * t Temporary ordinate data. + */ +static void sp_384_proj_point_dbl_n_12(sp_point_384* r, const sp_point_384* p, int n, + sp_digit* t) +{ + sp_point_384* rp[2]; + sp_digit* w = t; + sp_digit* a = t + 2*12; + sp_digit* b = t + 4*12; + sp_digit* t1 = t + 6*12; + sp_digit* t2 = t + 8*12; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_384*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_384)); + x = rp[p->infinity]->x; + y = rp[p->infinity]->y; + z = rp[p->infinity]->z; + if (r != p) { + for (i=0; i<12; i++) { + r->x[i] = p->x[i]; + } + for (i=0; i<12; i++) { + r->y[i] = p->y[i]; + } + for (i=0; i<12; i++) { + r->z[i] = p->z[i]; + } + r->infinity = p->infinity; + } + + /* Y = 2*Y */ + sp_384_mont_dbl_12(y, y, p384_mod); + /* W = Z^4 */ + sp_384_mont_sqr_12(w, z, p384_mod, p384_mp_mod); + sp_384_mont_sqr_12(w, w, p384_mod, p384_mp_mod); + while (n-- > 0) { + /* A = 3*(X^2 - W) */ + sp_384_mont_sqr_12(t1, x, p384_mod, p384_mp_mod); + sp_384_mont_sub_12(t1, t1, w, p384_mod); + sp_384_mont_tpl_12(a, t1, p384_mod); + /* B = X*Y^2 */ + sp_384_mont_sqr_12(t2, y, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(b, t2, x, p384_mod, p384_mp_mod); + /* X = A^2 - 2B */ + sp_384_mont_sqr_12(x, a, p384_mod, p384_mp_mod); + sp_384_mont_dbl_12(t1, b, p384_mod); + sp_384_mont_sub_12(x, x, t1, p384_mod); + /* Z = Z*Y */ + sp_384_mont_mul_12(z, z, y, p384_mod, p384_mp_mod); + /* t2 = Y^4 */ + sp_384_mont_sqr_12(t2, t2, p384_mod, p384_mp_mod); + if (n != 0) { + /* W = W*Y^4 */ + sp_384_mont_mul_12(w, w, t2, p384_mod, p384_mp_mod); + } + /* y = 2*A*(B - X) - Y^4 */ + sp_384_mont_sub_12(y, b, x, p384_mod); + sp_384_mont_mul_12(y, y, a, p384_mod, p384_mp_mod); + sp_384_mont_dbl_12(y, y, p384_mod); + sp_384_mont_sub_12(y, y, t2, p384_mod); + } + /* Y = Y/2 */ + 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 */ +/* 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_384_proj_point_add_qz1_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]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*12; + sp_digit* t3 = t + 4*12; + sp_digit* t4 = t + 6*12; + sp_digit* t5 = t + 8*12; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + /* Check double */ + (void)sp_384_sub_12(t1, p384_mod, q->y); + sp_384_norm_12(t1); + if ((sp_384_cmp_equal_12(p->x, q->x) & sp_384_cmp_equal_12(p->z, q->z) & + (sp_384_cmp_equal_12(p->y, q->y) | sp_384_cmp_equal_12(p->y, t1))) != 0) { + sp_384_proj_point_dbl_12(r, p, t); + } + else { + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_384*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_384)); + 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<12; i++) { + r->x[i] = ap[p->infinity]->x[i]; + } + for (i=0; i<12; i++) { + r->y[i] = ap[p->infinity]->y[i]; + } + for (i=0; i<12; i++) { + r->z[i] = ap[p->infinity]->z[i]; + } + r->infinity = ap[p->infinity]->infinity; + + /* U2 = X2*Z1^2 */ + sp_384_mont_sqr_12(t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(t4, t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(t2, t2, q->x, p384_mod, p384_mp_mod); + /* S2 = Y2*Z1^3 */ + sp_384_mont_mul_12(t4, t4, q->y, p384_mod, p384_mp_mod); + /* H = U2 - X1 */ + sp_384_mont_sub_12(t2, t2, x, p384_mod); + /* R = S2 - Y1 */ + sp_384_mont_sub_12(t4, t4, y, p384_mod); + /* Z3 = H*Z1 */ + sp_384_mont_mul_12(z, z, t2, p384_mod, p384_mp_mod); + /* X3 = R^2 - H^3 - 2*X1*H^2 */ + sp_384_mont_sqr_12(t1, t4, p384_mod, p384_mp_mod); + sp_384_mont_sqr_12(t5, t2, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(t3, x, t5, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(t5, t5, t2, p384_mod, p384_mp_mod); + sp_384_mont_sub_12(x, t1, t5, p384_mod); + sp_384_mont_dbl_12(t1, t3, p384_mod); + sp_384_mont_sub_12(x, x, t1, p384_mod); + /* Y3 = R*(X1*H^2 - X3) - Y1*H^3 */ + sp_384_mont_sub_12(t3, t3, x, p384_mod); + sp_384_mont_mul_12(t3, t3, t4, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(t5, t5, y, p384_mod, p384_mp_mod); + sp_384_mont_sub_12(y, t3, t5, p384_mod); + } +} + +#ifdef WOLFSSL_SP_SMALL +#ifdef FP_ECC +/* Generate the pre-computed table of points for the base point. + * + * 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_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) + sp_point_384 td, s1d, s2d; +#endif + sp_point_384* t; + sp_point_384* s1 = NULL; + sp_point_384* s2 = NULL; + int i, j; + int err; + + (void)heap; + + err = sp_384_point_new_12(heap, td, t); + if (err == MP_OKAY) { + err = sp_384_point_new_12(heap, s1d, s1); + } + if (err == MP_OKAY) { + err = sp_384_point_new_12(heap, s2d, s2); + } + + if (err == MP_OKAY) { + err = sp_384_mod_mul_norm_12(t->x, a->x, p384_mod); + } + if (err == MP_OKAY) { + err = sp_384_mod_mul_norm_12(t->y, a->y, p384_mod); + } + if (err == MP_OKAY) { + err = sp_384_mod_mul_norm_12(t->z, a->z, p384_mod); + } + if (err == MP_OKAY) { + t->infinity = 0; + sp_384_proj_to_affine_12(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<4; i++) { + sp_384_proj_point_dbl_n_12(t, t, 96, tmp); + sp_384_proj_to_affine_12(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_384_proj_point_add_qz1_12(t, s1, s2, tmp); + sp_384_proj_to_affine_12(t, tmp); + XMEMCPY(table[j].x, t->x, sizeof(table->x)); + XMEMCPY(table[j].y, t->y, sizeof(table->y)); + } + } + } + + sp_384_point_free_12(s2, 0, heap); + sp_384_point_free_12(s1, 0, heap); + sp_384_point_free_12( t, 0, heap); + + return err; +} + +#endif /* FP_ECC */ +/* Multiply the point 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_384_ecc_mulmod_stripe_12(sp_point_384* r, const sp_point_384* g, + const sp_table_entry_384* table, const sp_digit* k, int map, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 rtd; + sp_point_384 pd; + sp_digit td[2 * 12 * 6]; +#endif + sp_point_384* rt; + sp_point_384* p = NULL; + sp_digit* t; + int i, j; + int y, x; + int err; + + (void)g; + (void)heap; + + + err = sp_384_point_new_12(heap, rtd, rt); + if (err == MP_OKAY) { + err = sp_384_point_new_12(heap, pd, p); + } +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 12 * 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; + for (j=0,x=95; j<4; j++,x+=96) { + y |= ((k[x / 32] >> (x % 32)) & 1) << j; + } + 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=94; i>=0; i--) { + y = 0; + for (j=0,x=i; j<4; j++,x+=96) { + y |= ((k[x / 32] >> (x % 32)) & 1) << j; + } + + sp_384_proj_point_dbl_12(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_384_proj_point_add_qz1_12(rt, rt, p, t); + } + + if (map != 0) { + sp_384_map_12(r, rt, t); + } + else { + XMEMCPY(r, rt, sizeof(sp_point_384)); + } + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (t != NULL) { + XFREE(t, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_12(p, 0, heap); + sp_384_point_free_12(rt, 0, heap); + + return err; +} + +#ifdef FP_ECC +#ifndef FP_ENTRIES + #define FP_ENTRIES 16 +#endif + +typedef struct sp_cache_384_t { + sp_digit x[12]; + sp_digit y[12]; + sp_table_entry_384 table[16]; + uint32_t cnt; + int set; +} sp_cache_384_t; + +static THREAD_LS_T sp_cache_384_t sp_cache_384[FP_ENTRIES]; +static THREAD_LS_T int sp_cache_384_last = -1; +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 + +static void sp_ecc_get_cache_384(const sp_point_384* g, sp_cache_384_t** cache) +{ + int i, j; + uint32_t least; + + if (sp_cache_384_inited == 0) { + for (i=0; ix, sp_cache_384[i].x) & + sp_384_cmp_equal_12(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. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_ecc_mulmod_12(sp_point_384* r, const sp_point_384* g, const sp_digit* k, + int map, void* heap) +{ +#ifndef FP_ECC + return sp_384_ecc_mulmod_fast_12(r, g, k, map, heap); +#else + sp_digit tmp[2 * 12 * 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_12(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_fast_12(r, g, k, map, heap); + } + else { + err = sp_384_ecc_mulmod_stripe_12(r, g, cache->table, k, + map, heap); + } + } + + return err; +#endif +} + +#else +#ifdef FP_ECC +/* Generate the pre-computed table of points for the base point. + * + * 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_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) + sp_point_384 td, s1d, s2d; +#endif + sp_point_384* t; + sp_point_384* s1 = NULL; + sp_point_384* s2 = NULL; + int i, j; + int err; + + (void)heap; + + err = sp_384_point_new_12(heap, td, t); + if (err == MP_OKAY) { + err = sp_384_point_new_12(heap, s1d, s1); + } + if (err == MP_OKAY) { + err = sp_384_point_new_12(heap, s2d, s2); + } + + if (err == MP_OKAY) { + err = sp_384_mod_mul_norm_12(t->x, a->x, p384_mod); + } + if (err == MP_OKAY) { + err = sp_384_mod_mul_norm_12(t->y, a->y, p384_mod); + } + if (err == MP_OKAY) { + err = sp_384_mod_mul_norm_12(t->z, a->z, p384_mod); + } + if (err == MP_OKAY) { + t->infinity = 0; + sp_384_proj_to_affine_12(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_12(t, t, 48, tmp); + sp_384_proj_to_affine_12(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_12(t, s1, s2, tmp); + sp_384_proj_to_affine_12(t, tmp); + XMEMCPY(table[j].x, t->x, sizeof(table->x)); + XMEMCPY(table[j].y, t->y, sizeof(table->y)); + } + } + } + + sp_384_point_free_12(s2, 0, heap); + sp_384_point_free_12(s1, 0, heap); + sp_384_point_free_12( t, 0, heap); + + return err; +} + +#endif /* FP_ECC */ +/* Multiply the point 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_384_ecc_mulmod_stripe_12(sp_point_384* r, const sp_point_384* g, + const sp_table_entry_384* table, const sp_digit* k, int map, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 rtd; + sp_point_384 pd; + sp_digit td[2 * 12 * 6]; +#endif + sp_point_384* rt; + sp_point_384* p = NULL; + sp_digit* t; + int i, j; + int y, x; + int err; + + (void)g; + (void)heap; + + + err = sp_384_point_new_12(heap, rtd, rt); + if (err == MP_OKAY) { + err = sp_384_point_new_12(heap, pd, p); + } +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 12 * 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; + for (j=0,x=47; j<8; j++,x+=48) { + y |= ((k[x / 32] >> (x % 32)) & 1) << j; + } + 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; + for (j=0,x=i; j<8; j++,x+=48) { + y |= ((k[x / 32] >> (x % 32)) & 1) << j; + } + + sp_384_proj_point_dbl_12(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_384_proj_point_add_qz1_12(rt, rt, p, t); + } + + if (map != 0) { + sp_384_map_12(r, rt, t); + } + else { + XMEMCPY(r, rt, sizeof(sp_point_384)); + } + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (t != NULL) { + XFREE(t, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_12(p, 0, heap); + sp_384_point_free_12(rt, 0, heap); + + return err; +} + +#ifdef FP_ECC +#ifndef FP_ENTRIES + #define FP_ENTRIES 16 +#endif + +typedef struct sp_cache_384_t { + sp_digit x[12]; + sp_digit y[12]; + sp_table_entry_384 table[256]; + uint32_t cnt; + int set; +} sp_cache_384_t; + +static THREAD_LS_T sp_cache_384_t sp_cache_384[FP_ENTRIES]; +static THREAD_LS_T int sp_cache_384_last = -1; +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 + +static void sp_ecc_get_cache_384(const sp_point_384* g, sp_cache_384_t** cache) +{ + int i, j; + uint32_t least; + + if (sp_cache_384_inited == 0) { + for (i=0; ix, sp_cache_384[i].x) & + sp_384_cmp_equal_12(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. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_ecc_mulmod_12(sp_point_384* r, const sp_point_384* g, const sp_digit* k, + int map, void* heap) +{ +#ifndef FP_ECC + return sp_384_ecc_mulmod_fast_12(r, g, k, map, heap); +#else + sp_digit tmp[2 * 12 * 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_12(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_fast_12(r, g, k, map, heap); + } + else { + err = sp_384_ecc_mulmod_stripe_12(r, g, cache->table, k, + map, 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_384(mp_int* km, ecc_point* gm, ecc_point* r, int map, + void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 p; + sp_digit kd[12]; +#endif + sp_point_384* point; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_384_point_new_12(heap, p, point); +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 12, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) + err = MEMORY_E; + } +#else + k = kd; +#endif + if (err == MP_OKAY) { + sp_384_from_mp(k, 12, km); + sp_384_point_from_ecc_point_12(point, gm); + + err = sp_384_ecc_mulmod_12(point, point, k, map, heap); + } + if (err == MP_OKAY) { + err = sp_384_point_to_ecc_point_12(point, r); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_12(point, 0, heap); + + return err; +} + +#ifdef WOLFSSL_SP_SMALL +static const sp_table_entry_384 p384_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 } }, + /* 1 */ + { { 0x49c0b528,0x3dd07566,0xa0d6ce38,0x20e378e2,0x541b4d6e,0x879c3afc, + 0x59a30eff,0x64548684,0x614ede2b,0x812ff723,0x299e1513,0x4d3aadc2 }, + { 0x4b03a4fe,0x23043dad,0x7bb4a9ac,0xa1bfa8bf,0x2e83b050,0x8bade756, + 0x68f4ffd9,0xc6c35219,0x3969a840,0xdd800226,0x5a15c5e9,0x2b78abc2 } }, + /* 2 */ + { { 0xf26feef9,0x24480c57,0x3a0e1240,0xc31a2694,0x273e2bc7,0x735002c3, + 0x3ef1ed4c,0x8c42e9c5,0x7f4948e8,0x028babf6,0x8a978632,0x6a502f43 }, + { 0xb74536fe,0xf5f13a46,0xd8a9f0eb,0x1d218bab,0x37232768,0x30f36bcc, + 0x576e8c18,0xc5317b31,0x9bbcb766,0xef1d57a6,0xb3e3d4dc,0x917c4930 } }, + /* 3 */ + { { 0xe349ddd0,0x11426e2e,0x9b2fc250,0x9f117ef9,0xec0174a6,0xff36b480, + 0x18458466,0x4f4bde76,0x05806049,0x2f2edb6d,0x19dfca92,0x8adc75d1 }, + { 0xb7d5a7ce,0xa619d097,0xa34411e9,0x874275e5,0x0da4b4ef,0x5403e047, + 0x77901d8f,0x2ebaafd9,0xa747170f,0x5e63ebce,0x7f9d8036,0x12a36944 } }, + /* 4 */ + { { 0x2f9fbe67,0x378205de,0x7f728e44,0xc4afcb83,0x682e00f1,0xdbcec06c, + 0x114d5423,0xf2a145c3,0x7a52463e,0xa01d9874,0x7d717b0a,0xfc0935b1 }, + { 0xd4d01f95,0x9653bc4f,0x9560ad34,0x9aa83ea8,0xaf8e3f3f,0xf77943dc, + 0xe86fe16e,0x70774a10,0xbf9ffdcf,0x6b62e6f1,0x588745c9,0x8a72f39e } }, + /* 5 */ + { { 0x2341c342,0x73ade4da,0xea704422,0xdd326e54,0x3741cef3,0x336c7d98, + 0x59e61549,0x1eafa00d,0xbd9a3efd,0xcd3ed892,0xc5c6c7e4,0x03faf26c }, + { 0x3045f8ac,0x087e2fcf,0x174f1e73,0x14a65532,0xfe0af9a7,0x2cf84f28, + 0x2cdc935b,0xddfd7a84,0x6929c895,0x4c0f117b,0x4c8bcfcc,0x356572d6 } }, + /* 6 */ + { { 0x3f3b236f,0xfab08607,0x81e221da,0x19e9d41d,0x3927b428,0xf3f6571e, + 0x7550f1f6,0x4348a933,0xa85e62f0,0x7167b996,0x7f5452bf,0x62d43759 }, + { 0xf2955926,0xd85feb9e,0x6df78353,0x440a561f,0x9ca36b59,0x389668ec, + 0xa22da016,0x052bf1a1,0xf6093254,0xbdfbff72,0xe22209f3,0x94e50f28 } }, + /* 7 */ + { { 0x3062e8af,0x90b2e5b3,0xe8a3d369,0xa8572375,0x201db7b1,0x3fe1b00b, + 0xee651aa2,0xe926def0,0xb9b10ad7,0x6542c9be,0xa2fcbe74,0x098e309b }, + { 0xfff1d63f,0x779deeb3,0x20bfd374,0x23d0e80a,0x8768f797,0x8452bb3b, + 0x1f952856,0xcf75bb4d,0x29ea3faa,0x8fe6b400,0x81373a53,0x12bd3e40 } }, + /* 8 */ + { { 0x16973cf4,0x070d34e1,0x7e4f34f7,0x20aee08b,0x5eb8ad29,0x269af9b9, + 0xa6a45dda,0xdde0a036,0x63df41e0,0xa18b528e,0xa260df2a,0x03cc71b2 }, + { 0xa06b1dd7,0x24a6770a,0x9d2675d3,0x5bfa9c11,0x96844432,0x73c1e2a1, + 0x131a6cf0,0x3660558d,0x2ee79454,0xb0289c83,0xc6d8ddcd,0xa6aefb01 } }, + /* 9 */ + { { 0x01ab5245,0xba1464b4,0xc48d93ff,0x9b8d0b6d,0x93ad272c,0x939867dc, + 0xae9fdc77,0xbebe085e,0x894ea8bd,0x73ae5103,0x39ac22e1,0x740fc89a }, + { 0x28e23b23,0x5e28b0a3,0xe13104d0,0x2352722e,0xb0a2640d,0xf4667a18, + 0x49bb37c3,0xac74a72e,0xe81e183a,0x79f734f0,0x3fd9c0eb,0xbffe5b6c } }, + /* 10 */ + { { 0x00623f3b,0x03cf2922,0x5f29ebff,0x095c7111,0x80aa6823,0x42d72247, + 0x7458c0b0,0x044c7ba1,0x0959ec20,0xca62f7ef,0xf8ca929f,0x40ae2ab7 }, + { 0xa927b102,0xb8c5377a,0xdc031771,0x398a86a0,0xc216a406,0x04908f9d, + 0x918d3300,0xb423a73a,0xe0b94739,0x634b0ff1,0x2d69f697,0xe29de725 } }, + /* 11 */ + { { 0x8435af04,0x744d1400,0xfec192da,0x5f255b1d,0x336dc542,0x1f17dc12, + 0x636a68a8,0x5c90c2a7,0x7704ca1e,0x960c9eb7,0x6fb3d65a,0x9de8cf1e }, + { 0x511d3d06,0xc60fee0d,0xf9eb52c7,0x466e2313,0x206b0914,0x743c0f5f, + 0x2191aa4d,0x42f55bac,0xffebdbc2,0xcefc7c8f,0xe6e8ed1c,0xd4fa6081 } }, + /* 12 */ + { { 0x98683186,0x867db639,0xddcc4ea9,0xfb5cf424,0xd4f0e7bd,0xcc9a7ffe, + 0x7a779f7e,0x7c57f71c,0xd6b25ef2,0x90774079,0xb4081680,0x90eae903 }, + { 0x0ee1fceb,0xdf2aae5e,0xe86c1a1f,0x3ff1da24,0xca193edf,0x80f587d6, + 0xdc9b9d6a,0xa5695523,0x85920303,0x7b840900,0xba6dbdef,0x1efa4dfc } }, + /* 13 */ + { { 0xe0540015,0xfbd838f9,0xc39077dc,0x2c323946,0xad619124,0x8b1fb9e6, + 0x0ca62ea8,0x9612440c,0x2dbe00ff,0x9ad9b52c,0xae197643,0xf52abaa1 }, + { 0x2cac32ad,0xd0e89894,0x62a98f91,0xdfb79e42,0x276f55cb,0x65452ecf, + 0x7ad23e12,0xdb1ac0d2,0xde4986f0,0xf68c5f6a,0x82ce327d,0x389ac37b } }, + /* 14 */ + { { 0xb8a9e8c9,0xcd96866d,0x5bb8091e,0xa11963b8,0x045b3cd2,0xc7f90d53, + 0x80f36504,0x755a72b5,0x21d3751c,0x46f8b399,0x53c193de,0x4bffdc91 }, + { 0xb89554e7,0xcd15c049,0xf7a26be6,0x353c6754,0xbd41d970,0x79602370, + 0x12b176c0,0xde16470b,0x40c8809d,0x56ba1175,0xe435fb1e,0xe2db35c3 } }, + /* 15 */ + { { 0x6328e33f,0xd71e4aab,0xaf8136d1,0x5486782b,0x86d57231,0x07a4995f, + 0x1651a968,0xf1f0a5bd,0x76803b6d,0xa5dc5b24,0x42dda935,0x5c587cbc }, + { 0xbae8b4c0,0x2b6cdb32,0xb1331138,0x66d1598b,0x5d7e9614,0x4a23b2d2, + 0x74a8c05d,0x93e402a6,0xda7ce82e,0x45ac94e6,0xe463d465,0xeb9f8281 } }, +}; + +/* 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. + * 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_12(sp_point_384* r, const sp_digit* k, + int map, void* heap) +{ + return sp_384_ecc_mulmod_stripe_12(r, &p384_base, p384_table, + k, map, heap); +} + +#else +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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }, + /* 1 */ + { { 0x49c0b528,0x3dd07566,0xa0d6ce38,0x20e378e2,0x541b4d6e,0x879c3afc, + 0x59a30eff,0x64548684,0x614ede2b,0x812ff723,0x299e1513,0x4d3aadc2 }, + { 0x4b03a4fe,0x23043dad,0x7bb4a9ac,0xa1bfa8bf,0x2e83b050,0x8bade756, + 0x68f4ffd9,0xc6c35219,0x3969a840,0xdd800226,0x5a15c5e9,0x2b78abc2 } }, + /* 2 */ + { { 0x2b0c535b,0x29864753,0x70506296,0x90dd6953,0x216ab9ac,0x038cd6b4, + 0xbe12d76a,0x3df9b7b7,0x5f347bdb,0x13f4d978,0x13e94489,0x222c5c9c }, + { 0x2680dc64,0x5f8e796f,0x58352417,0x120e7cb7,0xd10740b8,0x254b5d8a, + 0x5337dee6,0xc38b8efb,0x94f02247,0xf688c2e1,0x6c25bc4c,0x7b5c75f3 } }, + /* 3 */ + { { 0x9edffea5,0xe26a3cc3,0x37d7e9fc,0x35bbfd1c,0x9bde3ef6,0xf0e7700d, + 0x1a538f5a,0x0380eb47,0x05bf9eb3,0x2e9da8bb,0x1a460c3e,0xdbb93c73 }, + { 0xf526b605,0x37dba260,0xfd785537,0x95d4978e,0xed72a04a,0x24ed793a, + 0x76005b1a,0x26948377,0x9e681f82,0x99f557b9,0xd64954ef,0xae5f9557 } }, + /* 4 */ + { { 0xf26feef9,0x24480c57,0x3a0e1240,0xc31a2694,0x273e2bc7,0x735002c3, + 0x3ef1ed4c,0x8c42e9c5,0x7f4948e8,0x028babf6,0x8a978632,0x6a502f43 }, + { 0xb74536fe,0xf5f13a46,0xd8a9f0eb,0x1d218bab,0x37232768,0x30f36bcc, + 0x576e8c18,0xc5317b31,0x9bbcb766,0xef1d57a6,0xb3e3d4dc,0x917c4930 } }, + /* 5 */ + { { 0xe349ddd0,0x11426e2e,0x9b2fc250,0x9f117ef9,0xec0174a6,0xff36b480, + 0x18458466,0x4f4bde76,0x05806049,0x2f2edb6d,0x19dfca92,0x8adc75d1 }, + { 0xb7d5a7ce,0xa619d097,0xa34411e9,0x874275e5,0x0da4b4ef,0x5403e047, + 0x77901d8f,0x2ebaafd9,0xa747170f,0x5e63ebce,0x7f9d8036,0x12a36944 } }, + /* 6 */ + { { 0x4fc52870,0x28f9c07a,0x1a53a961,0xce0b3748,0x0e1828d9,0xd550fa18, + 0x6adb225a,0xa24abaf7,0x6e58a348,0xd11ed0a5,0x948acb62,0xf3d811e6 }, + { 0x4c61ed22,0x8618dd77,0x80b47c9d,0x0bb747f9,0xde6b8559,0x22bf796f, + 0x680a21e9,0xfdfd1c6d,0x2af2c9dd,0xc0db1577,0xc1e90f3d,0xa09379e6 } }, + /* 7 */ + { { 0xe085c629,0x386c66ef,0x095bc89a,0x5fc2a461,0x203f4b41,0x1353d631, + 0x7e4bd8f5,0x7ca1972b,0xa7df8ce9,0xb077380a,0xee7e4ea3,0xd8a90389 }, + { 0xe7b14461,0x1bc74dc7,0x0c9c4f78,0xdc2cb014,0x84ef0a10,0x52b4b3a6, + 0x20327fe2,0xbde6ea5d,0x660f9615,0xb71ec435,0xb8ad8173,0xeede5a04 } }, + /* 8 */ + { { 0x893b9a2d,0x5584cbb3,0x00850c5d,0x820c660b,0x7df2d43d,0x4126d826, + 0x0109e801,0xdd5bbbf0,0x38172f1c,0x85b92ee3,0xf31430d9,0x609d4f93 }, + { 0xeadaf9d6,0x1e059a07,0x0f125fb0,0x70e6536c,0x560f20e7,0xd6220751, + 0x7aaf3a9a,0xa59489ae,0x64bae14e,0x7b70e2f6,0x76d08249,0x0dd03701 } }, + /* 9 */ + { { 0x8510521f,0x4cc13be8,0xf724cc17,0x87315ba9,0x353dc263,0xb49d83bb, + 0x0c279257,0x8b677efe,0xc93c9537,0x510a1c1c,0xa4702c99,0x33e30cd8 }, + { 0x2208353f,0xf0ffc89d,0xced42b2b,0x0170fa8d,0x26e2a5f5,0x090851ed, + 0xecb52c96,0x81276455,0x7fe1adf4,0x0646c4e1,0xb0868eab,0x513f047e } }, + /* 10 */ + { { 0xdf5bdf53,0xc07611f4,0x58b11a6d,0x45d331a7,0x1c4ee394,0x58965daf, + 0x5a5878d1,0xba8bebe7,0x82dd3025,0xaecc0a18,0xa923eb8b,0xcf2a3899 }, + { 0xd24fd048,0xf98c9281,0x8bbb025d,0x841bfb59,0xc9ab9d53,0xb8ddf8ce, + 0x7fef044e,0x538a4cb6,0x23236662,0x092ac21f,0x0b66f065,0xa919d385 } }, + /* 11 */ + { { 0x85d480d8,0x3db03b40,0x1b287a7d,0x8cd9f479,0x4a8f3bae,0x8f24dc75, + 0x3db41892,0x482eb800,0x9c56e0f5,0x38bf9eb3,0x9a91dc6f,0x8b977320 }, + { 0x7209cfc2,0xa31b05b2,0x05b2db70,0x4c49bf85,0xd619527b,0x56462498, + 0x1fac51ba,0x3fe51039,0xab4b8342,0xfb04f55e,0x04c6eabf,0xc07c10dc } }, + /* 12 */ + { { 0xdb32f048,0xad22fe4c,0x475ed6df,0x5f23bf91,0xaa66b6cb,0xa50ce0c0, + 0xf03405c0,0xdf627a89,0xf95e2d6a,0x3674837d,0xba42e64e,0x081c95b6 }, + { 0xe71d6ceb,0xeba3e036,0x6c6b0271,0xb45bcccf,0x0684701d,0x67b47e63, + 0xe712523f,0x60f8f942,0x5cd47adc,0x82423472,0x87649cbb,0x83027d79 } }, + /* 13 */ + { { 0x3615b0b8,0xb3929ea6,0xa54dac41,0xb41441fd,0xb5b6a368,0x8995d556, + 0x167ef05e,0xa80d4529,0x6d25a27f,0xf6bcb4a1,0x7bd55b68,0x210d6a4c }, + { 0x25351130,0xf3804abb,0x903e37eb,0x1d2df699,0x084c25c8,0x5f201efc, + 0xa1c68e91,0x31a28c87,0x563f62a5,0x81dad253,0xd6c415d4,0x5dd6de70 } }, + /* 14 */ + { { 0x846612ce,0x29f470fd,0xda18d997,0x986f3eec,0x2f34af86,0x6b84c161, + 0x46ddaf8b,0x5ef0a408,0xe49e795f,0x14405a00,0xaa2f7a37,0x5f491b16 }, + { 0xdb41b38d,0xc7f07ae4,0x18fbfcaa,0xef7d119e,0x14443b19,0x3a18e076, + 0x79a19926,0x4356841a,0xe2226fbe,0x91f4a91c,0x3cc88721,0xdc77248c } }, + /* 15 */ + { { 0xe4b1ec9d,0xd570ff1a,0xe7eef706,0x21d23e0e,0xca19e086,0x3cde40f4, + 0xcd4bb270,0x7d6523c4,0xbf13aa6c,0x16c1f06c,0xd14c4b60,0x5aa7245a }, + { 0x44b74de8,0x37f81467,0x620a934e,0x839e7a17,0xde8b1aa1,0xf74d14e8, + 0xf30d75e2,0x8789fa51,0xc81c261e,0x09b24052,0x33c565ee,0x654e2678 } }, + /* 16 */ + { { 0x2f9fbe67,0x378205de,0x7f728e44,0xc4afcb83,0x682e00f1,0xdbcec06c, + 0x114d5423,0xf2a145c3,0x7a52463e,0xa01d9874,0x7d717b0a,0xfc0935b1 }, + { 0xd4d01f95,0x9653bc4f,0x9560ad34,0x9aa83ea8,0xaf8e3f3f,0xf77943dc, + 0xe86fe16e,0x70774a10,0xbf9ffdcf,0x6b62e6f1,0x588745c9,0x8a72f39e } }, + /* 17 */ + { { 0x2341c342,0x73ade4da,0xea704422,0xdd326e54,0x3741cef3,0x336c7d98, + 0x59e61549,0x1eafa00d,0xbd9a3efd,0xcd3ed892,0xc5c6c7e4,0x03faf26c }, + { 0x3045f8ac,0x087e2fcf,0x174f1e73,0x14a65532,0xfe0af9a7,0x2cf84f28, + 0x2cdc935b,0xddfd7a84,0x6929c895,0x4c0f117b,0x4c8bcfcc,0x356572d6 } }, + /* 18 */ + { { 0x7d8c1bba,0x7ecbac01,0x90b0f3d5,0x6058f9c3,0xf6197d0f,0xaee116e3, + 0x4033b128,0xc4dd7068,0xc209b983,0xf084dba6,0x831dbc4a,0x97c7c2cf }, + { 0xf96010e8,0x2f4e61dd,0x529faa17,0xd97e4e20,0x69d37f20,0x4ee66660, + 0x3d366d72,0xccc139ed,0x13488e0f,0x690b6ee2,0xf3a6d533,0x7cad1dc5 } }, + /* 19 */ + { { 0xda57a41f,0x660a9a81,0xec0039b6,0xe74a0412,0x5e1dad15,0x42343c6b, + 0x46681d4c,0x284f3ff5,0x63749e89,0xb51087f1,0x6f9f2f13,0x070f23cc }, + { 0x5d186e14,0x542211da,0xfddb0dff,0x84748f37,0xdb1f4180,0x41a3aab4, + 0xa6402d0e,0x25ed667b,0x02f58355,0x2f2924a9,0xfa44a689,0x5844ee7c } }, + /* 20 */ + { { 0x3f3b236f,0xfab08607,0x81e221da,0x19e9d41d,0x3927b428,0xf3f6571e, + 0x7550f1f6,0x4348a933,0xa85e62f0,0x7167b996,0x7f5452bf,0x62d43759 }, + { 0xf2955926,0xd85feb9e,0x6df78353,0x440a561f,0x9ca36b59,0x389668ec, + 0xa22da016,0x052bf1a1,0xf6093254,0xbdfbff72,0xe22209f3,0x94e50f28 } }, + /* 21 */ + { { 0x3062e8af,0x90b2e5b3,0xe8a3d369,0xa8572375,0x201db7b1,0x3fe1b00b, + 0xee651aa2,0xe926def0,0xb9b10ad7,0x6542c9be,0xa2fcbe74,0x098e309b }, + { 0xfff1d63f,0x779deeb3,0x20bfd374,0x23d0e80a,0x8768f797,0x8452bb3b, + 0x1f952856,0xcf75bb4d,0x29ea3faa,0x8fe6b400,0x81373a53,0x12bd3e40 } }, + /* 22 */ + { { 0x104cbba5,0xc023780d,0xfa35dd4c,0x6207e747,0x1ca9b6a3,0x35c23928, + 0x97987b10,0x4ff19be8,0x8022eee8,0xb8476bbf,0xd3bbe74d,0xaa0a4a14 }, + { 0x187d4543,0x20f94331,0x79f6e066,0x32153870,0xac7e82e1,0x83b0f74e, + 0x828f06ab,0xa7748ba2,0xc26ef35f,0xc5f0298a,0x8e9a7dbd,0x0f0c5070 } }, + /* 23 */ + { { 0xdef029dd,0x0c5c244c,0x850661b8,0x3dabc687,0xfe11d981,0x9992b865, + 0x6274dbad,0xe9801b8f,0x098da242,0xe54e6319,0x91a53d08,0x9929a91a }, + { 0x35285887,0x37bffd72,0xf1418102,0xbc759425,0xfd2e6e20,0x9280cc35, + 0xfbc42ee5,0x735c600c,0x8837619a,0xb7ad2864,0xa778c57b,0xa3627231 } }, + /* 24 */ + { { 0x91361ed8,0xae799b5c,0x6c63366c,0x47d71b75,0x1b265a6a,0x54cdd521, + 0x98d77b74,0xe0215a59,0xbab29db0,0x4424d9b7,0x7fd9e536,0x8b0ffacc }, + { 0x37b5d9ef,0x46d85d12,0xbfa91747,0x5b106d62,0x5f99ba2d,0xed0479f8, + 0x1d104de4,0x0e6f3923,0x25e8983f,0x83a84c84,0xf8105a70,0xa9507e0a } }, + /* 25 */ + { { 0x14cf381c,0xf6c68a6e,0xc22e31cc,0xaf9d27bd,0xaa8a5ccb,0x23568d4d, + 0xe338e4d2,0xe431eec0,0x8f52ad1f,0xf1a828fe,0xe86acd80,0xdb6a0579 }, + { 0x4507832a,0x2885672e,0x887e5289,0x73fc275f,0x05610d08,0x65f80278, + 0x075ff5b0,0x8d9b4554,0x09f712b5,0x3a8e8fb1,0x2ebe9cf2,0x39f0ac86 } }, + /* 26 */ + { { 0x4c52edf5,0xd8fabf78,0xa589ae53,0xdcd737e5,0xd791ab17,0x94918bf0, + 0xbcff06c9,0xb5fbd956,0xdca46d45,0xf6d3032e,0x41a3e486,0x2cdff7e1 }, + { 0x61f47ec8,0x6674b3ba,0xeef84608,0x8a882163,0x4c687f90,0xa257c705, + 0xf6cdf227,0xe30cb2ed,0x7f6ea846,0x2c4c64ca,0xcc6bcd3c,0x186fa17c } }, + /* 27 */ + { { 0x1dfcb91e,0x48a3f536,0x646d358a,0x83595e13,0x91128798,0xbd15827b, + 0x2187757a,0x3ce612b8,0x61bd7372,0x873150a1,0xb662f568,0xf4684530 }, + { 0x401896f6,0x8833950b,0x77f3e090,0xe11cb89a,0x48e7f4a5,0xb2f12cac, + 0xf606677e,0x313dd769,0x16579f93,0xfdcf08b3,0x46b8f22b,0x6429cec9 } }, + /* 28 */ + { { 0xbb75f9a4,0x4984dd54,0x29d3b570,0x4aef06b9,0x3d6e4c1e,0xb5f84ca2, + 0xb083ef35,0x24c61c11,0x392ca9ff,0xce4a7392,0x6730a800,0x865d6517 }, + { 0x722b4a2b,0xca3dfe76,0x7b083e0e,0x12c04bf9,0x1b86b8a5,0x803ce5b5, + 0x6a7e3e0c,0x3fc7632d,0xc81adbe4,0xc89970c2,0x120e16b1,0x3cbcd3ad } }, + /* 29 */ + { { 0xec30ce93,0xfbfb4cc7,0xb72720a2,0x10ed6c7d,0x47b55500,0xec675bf7, + 0x333ff7c3,0x90725903,0x5075bfc0,0xc7c3973e,0x07acf31b,0xb049ecb0 }, + { 0x4f58839c,0xb4076eaf,0xa2b05e4f,0x101896da,0xab40c66e,0x3f6033b0, + 0xc8d864ba,0x19ee9eeb,0x47bf6d2a,0xeb6cf155,0xf826477d,0x8e5a9663 } }, + /* 30 */ + { { 0xf7fbd5e1,0x69e62fdd,0x76912b1d,0x38ecfe54,0xd1da3bfb,0x845a3d56, + 0x1c86f0d4,0x0494950e,0x3bc36ce8,0x83cadbf9,0x4fccc8d1,0x41fce572 }, + { 0x8332c144,0x05f939c2,0x0871e46e,0xb17f248b,0x66e8aff6,0x3d8534e2, + 0x3b85c629,0x1d06f1dc,0xa3131b73,0xdb06a32e,0x8b3f64e5,0xf295184d } }, + /* 31 */ + { { 0x36ddc103,0xd9653ff7,0x95ef606f,0x25f43e37,0xfe06dce8,0x09e301fc, + 0x30b6eebf,0x85af2341,0x0ff56b20,0x79b12b53,0xfe9a3c6b,0x9b4fb499 }, + { 0x51d27ac2,0x0154f892,0x56ca5389,0xd33167e3,0xafc065a6,0x7828ec1f, + 0x7f746c9b,0x0959a258,0x0c44f837,0xb18f1be3,0xc4132fdb,0xa7946117 } }, + /* 32 */ + { { 0x5e3c647b,0xc0426b77,0x8cf05348,0xbfcbd939,0x172c0d3d,0x31d312e3, + 0xee754737,0x5f49fde6,0x6da7ee61,0x895530f0,0xe8b3a5fb,0xcf281b0a }, + { 0x41b8a543,0xfd149735,0x3080dd30,0x41a625a7,0x653908cf,0xe2baae07, + 0xba02a278,0xc3d01436,0x7b21b8f8,0xa0d0222e,0xd7ec1297,0xfdc270e9 } }, + /* 33 */ + { { 0xbc7f41d6,0x00873c0c,0x1b7ad641,0xd976113e,0x238443fb,0x2a536ff4, + 0x41e62e45,0x030d00e2,0x5f545fc6,0x532e9867,0x8e91208c,0xcd033108 }, + { 0x9797612c,0xd1a04c99,0xeea674e2,0xd4393e02,0xe19742a1,0xd56fa69e, + 0x85f0590e,0xdd2ab480,0x48a2243d,0xa5cefc52,0x54383f41,0x48cc67b6 } }, + /* 34 */ + { { 0xfc14ab48,0x4e50430e,0x26706a74,0x195b7f4f,0xcc881ff6,0x2fe8a228, + 0xd945013d,0xb1b968e2,0x4b92162b,0x936aa579,0x364e754a,0x4fb766b7 }, + { 0x31e1ff7f,0x13f93bca,0xce4f2691,0x696eb5ca,0xa2b09e02,0xff754bf8, + 0xe58e3ff8,0x58f13c9c,0x1678c0b0,0xb757346f,0xa86692b3,0xd54200db } }, + /* 35 */ + { { 0x6dda1265,0x9a030bbd,0xe89718dd,0xf7b4f3fc,0x936065b8,0xa6a4931f, + 0x5f72241c,0xbce72d87,0x65775857,0x6cbb51cb,0x4e993675,0xc7161815 }, + { 0x2ee32189,0xe81a0f79,0x277dc0b2,0xef2fab26,0xb71f469f,0x9e64f6fe, + 0xdfdaf859,0xb448ce33,0xbe6b5df1,0x3f5c1c4c,0x1de45f7b,0xfb8dfb00 } }, + /* 36 */ + { { 0x4d5bb921,0xc7345fa7,0x4d2b667e,0x5c7e04be,0x282d7a3e,0x47ed3a80, + 0x7e47b2a4,0x5c2777f8,0x08488e2e,0x89b3b100,0xb2eb5b45,0x9aad77c2 }, + { 0xdaac34ae,0xd681bca7,0x26afb326,0x2452e4e5,0x41a1ee14,0x0c887924, + 0xc2407ade,0x743b04d4,0xfc17a2ac,0xcb5e999b,0x4a701a06,0x4dca2f82 } }, + /* 37 */ + { { 0x1127bc1a,0x68e31ca6,0x17ead3be,0xa3edd59b,0xe25f5a15,0x67b6b645, + 0xa420e15e,0x76221794,0x4b1e872e,0x794fd83b,0xb2dece1b,0x7cab3f03 }, + { 0xca9b3586,0x7119bf15,0x4d250bd7,0xa5545924,0xcc6bcf24,0x173633ea, + 0xb1b6f884,0x9bd308c2,0x447d38c3,0x3bae06f5,0xf341fe1c,0x54dcc135 } }, + /* 38 */ + { { 0x943caf0d,0x56d3598d,0x225ff133,0xce044ea9,0x563fadea,0x9edf6a7c, + 0x73e8dc27,0x632eb944,0x3190dcab,0x814b467e,0x6dbb1e31,0x2d4f4f31 }, + { 0xa143b7ca,0x8d69811c,0xde7cf950,0x4ec1ac32,0x37b5fe82,0x223ab5fd, + 0x9390f1d9,0xe82616e4,0x75804610,0xabff4b20,0x875b08f0,0x11b9be15 } }, + /* 39 */ + { { 0x3bbe682c,0x4ae31a3d,0x74eef2dd,0xbc7c5d26,0x3c47dd40,0x92afd10a, + 0xc14ab9e1,0xec7e0a3b,0xb2e495e4,0x6a6c3dd1,0x309bcd85,0x085ee5e9 }, + { 0x8c2e67fd,0xf381a908,0xe261eaf2,0x32083a80,0x96deee15,0x0fcd6a49, + 0x5e524c79,0xe3b8fb03,0x1d5b08b9,0x8dc360d9,0x7f26719f,0x3a06e2c8 } }, + /* 40 */ + { { 0x7237cac0,0x5cd9f5a8,0x43586794,0x93f0b59d,0xe94f6c4e,0x4384a764, + 0xb62782d3,0x8304ed2b,0xcde06015,0x0b8db8b3,0x5dbe190f,0x4336dd53 }, + { 0x92ab473a,0x57443553,0xbe5ed046,0x031c7275,0x21909aa4,0x3e78678c, + 0x99202ddb,0x4ab7e04f,0x6977e635,0x2648d206,0x093198be,0xd427d184 } }, + /* 41 */ + { { 0x0f9b5a31,0x822848f5,0xbaadb62a,0xbb003468,0x3357559c,0x233a0472, + 0x79aee843,0x49ef6880,0xaeb9e1e3,0xa89867a0,0x1f6f9a55,0xc151931b }, + { 0xad74251e,0xd264eb0b,0x4abf295e,0x37b9b263,0x04960d10,0xb600921b, + 0x4da77dc0,0x0de53dbc,0xd2b18697,0x01d9bab3,0xf7156ddf,0xad54ec7a } }, + /* 42 */ + { { 0x79efdc58,0x8e74dc35,0x4ff68ddb,0x456bd369,0xd32096a5,0x724e74cc, + 0x386783d0,0xe41cff42,0x7c70d8a4,0xa04c7f21,0xe61a19a2,0x41199d2f }, + { 0x29c05dd2,0xd389a3e0,0xe7e3fda9,0x535f2a6b,0x7c2b4df8,0x26ecf72d, + 0xfe745294,0x678275f4,0x9d23f519,0x6319c9cc,0x88048fc4,0x1e05a02d } }, + /* 43 */ + { { 0xd4d5ffe8,0x75cc8e2e,0xdbea17f2,0xf8bb4896,0xcee3cb4a,0x35059790, + 0xa47c6165,0x4c06ee85,0x92935d2f,0xf98fff25,0x32ffd7c7,0x34c4a572 }, + { 0xea0376a2,0xc4b14806,0x4f115e02,0x2ea5e750,0x1e55d7c0,0x532d76e2, + 0xf31044da,0x68dc9411,0x71b77993,0x9272e465,0x93a8cfd5,0xadaa38bb } }, + /* 44 */ + { { 0x7d4ed72a,0x4bf0c712,0xba1f79a3,0xda0e9264,0xf4c39ea4,0x48c0258b, + 0x2a715138,0xa5394ed8,0xbf06c660,0x4af511ce,0xec5c37cd,0xfcebceef }, + { 0x779ae8c1,0xf23b75aa,0xad1e606e,0xdeff59cc,0x22755c82,0xf3f526fd, + 0xbb32cefd,0x64c5ab44,0x915bdefd,0xa96e11a2,0x1143813e,0xab19746a } }, + /* 45 */ + { { 0xec837d7d,0x43c78585,0xb8ee0ba4,0xca5b6fbc,0xd5dbb5ee,0x34e924d9, + 0xbb4f1ca5,0x3f4fa104,0x398640f7,0x15458b72,0xd7f407ea,0x4231faa9 }, + { 0xf96e6896,0x53e0661e,0xd03b0f9d,0x554e4c69,0x9c7858d1,0xd4fcb07b, + 0x52cb04fa,0x7e952793,0x8974e7f7,0x5f5f1574,0x6b6d57c8,0x2e3fa558 } }, + /* 46 */ + { { 0x6a9951a8,0x42cd4803,0x42792ad0,0xa8b15b88,0xabb29a73,0x18e8bcf9, + 0x409933e8,0xbfd9a092,0xefb88dc4,0x760a3594,0x40724458,0x14418863 }, + { 0x99caedc7,0x162a56ee,0x91d101c9,0x8fb12ecd,0x393202da,0xea671967, + 0xa4ccd796,0x1aac8c4a,0x1cf185a8,0x7db05036,0x8cfd095a,0x0c9f86cd } }, + /* 47 */ + { { 0x10b2a556,0x9a728147,0x327b70b2,0x767ca964,0x5e3799b7,0x04ed9e12, + 0x22a3eb2a,0x6781d2dc,0x0d9450ac,0x5bd116eb,0xa7ebe08a,0xeccac1fc }, + { 0xdc2d6e94,0xde68444f,0x35ecf21b,0x3621f429,0x29e03a2c,0x14e2d543, + 0x7d3e7f0a,0x53e42cd5,0x73ed00b9,0xbba26c09,0xc57d2272,0x00297c39 } }, + /* 48 */ + { { 0xb8243a7d,0x3aaaab10,0x8fa58c5b,0x6eeef93e,0x9ae7f764,0xf866fca3, + 0x61ab04d3,0x64105a26,0x03945d66,0xa3578d8a,0x791b848c,0xb08cd3e4 }, + { 0x756d2411,0x45edc5f8,0xa755128c,0xd4a790d9,0x49e5f6a0,0xc2cf0963, + 0xf649beaa,0xc66d267d,0x8467039e,0x3ce6d968,0x42f7816f,0x50046c6b } }, + /* 49 */ + { { 0x66425043,0x92ae1602,0xf08db890,0x1ff66afd,0x8f162ce5,0x386f5a7f, + 0xfcf5598f,0x18d2dea0,0x1a8ca18e,0x78372b3a,0x8cd0e6f7,0xdf0d20eb }, + { 0x75bb4045,0x7edd5e1d,0xb96d94b7,0x252a47ce,0x2c626776,0xbdb29358, + 0x40dd1031,0x853c3943,0x7d5f47fd,0x9dc9becf,0xbae4044a,0x27c2302f } }, + /* 50 */ + { { 0x8f2d49ce,0x2d1d208a,0x162df0a2,0x0d91aa02,0x09a07f65,0x9c5cce87, + 0x84339012,0xdf07238b,0x419442cd,0x5028e2c8,0x72062aba,0x2dcbd358 }, + { 0xe4680967,0xb5fbc3cb,0x9f92d72c,0x2a7bc645,0x116c369d,0x806c76e1, + 0x3177e8d8,0x5c50677a,0x4569df57,0x753739eb,0x36c3f40b,0x2d481ef6 } }, + /* 51 */ + { { 0xfea1103e,0x1a2d39fd,0x95f81b17,0xeaae5592,0xf59b264a,0xdbd0aa18, + 0xcb592ee0,0x90c39c1a,0x9750cca3,0xdf62f80d,0xdf97cc6c,0xda4d8283 }, + { 0x1e201067,0x0a6dd346,0x69fb1f6b,0x1531f859,0x1d60121f,0x4895e552, + 0x4c041c91,0x0b21aab0,0xbcc1ccf8,0x9d896c46,0x3141bde7,0xd24da3b3 } }, + /* 52 */ + { { 0x53b0a354,0x575a0537,0x0c6ddcd8,0x392ff2f4,0x56157b94,0x0b8e8cff, + 0x3b1b80d1,0x073e57bd,0x3fedee15,0x2a75e0f0,0xaa8e6f19,0x752380e4 }, + { 0x6558ffe9,0x1f4e227c,0x19ec5415,0x3a348618,0xf7997085,0xab382d5e, + 0xddc46ac2,0x5e6deaff,0xfc8d094c,0xe5144078,0xf60e37c6,0xf674fe51 } }, + /* 53 */ + { { 0xaf63408f,0x6fb87ae5,0xcd75a737,0xa39c36a9,0xcf4c618d,0x7833313f, + 0xf034c88d,0xfbcd4482,0x39b35288,0x4469a761,0x66b5d9c9,0x77a711c5 }, + { 0x944f8d65,0x4a695dc7,0x161aaba8,0xe6da5f65,0x24601669,0x8654e9c3, + 0x28ae7491,0xbc8b93f5,0x8f5580d8,0x5f1d1e83,0xcea32cc8,0x8ccf9a1a } }, + /* 54 */ + { { 0x7196fee2,0x28ab110c,0x874c8945,0x75799d63,0x29aedadd,0xa2629348, + 0x2be88ff4,0x9714cc7b,0xd58d60d6,0xf71293cf,0x32a564e9,0xda6b6cb3 }, + { 0x3dd821c2,0xf43fddb1,0x90dd323d,0xf2f2785f,0x048489f8,0x91246419, + 0xd24c6749,0x61660f26,0xc803c15c,0x961d9e8c,0xfaadc4c9,0x631c6158 } }, + /* 55 */ + { { 0xfd752366,0xacf2ebe0,0x139be88b,0xb93c340e,0x0f20179e,0x98f66485, + 0xff1da785,0x14820254,0x4f85c16e,0x5278e276,0x7aab1913,0xa246ee45 }, + { 0x53763b33,0x43861eb4,0x45c0bc0d,0xc49f03fc,0xad6b1ea1,0xafff16bc, + 0x6fd49c99,0xce33908b,0xf7fde8c3,0x5c51e9bf,0xff142c5e,0x076a7a39 } }, + /* 56 */ + { { 0x9e338d10,0x04639dfe,0xf42b411b,0x8ee6996f,0xa875cef2,0x960461d1, + 0x95b4d0ba,0x1057b6d6,0xa906e0bc,0x27639252,0xe1c20f8a,0x2c19f09a }, + { 0xeef4c43d,0x5b8fc3f0,0x07a84aa9,0xe2e1b1a8,0x835d2bdb,0x5f455528, + 0x207132dd,0x0f4aee4d,0x3907f675,0xe9f8338c,0x0e0531f0,0x7a874dc9 } }, + /* 57 */ + { { 0x97c27050,0x84b22d45,0x59e70bf8,0xbd0b8df7,0x79738b9b,0xb4d67405, + 0xcd917c4f,0x47f4d5f5,0x13ce6e33,0x9099c4ce,0x521d0f8b,0x942bfd39 }, + { 0xa43b566d,0x5028f0f6,0x21bff7de,0xaf6e8669,0xc44232cd,0x83f6f856, + 0xf915069a,0x65680579,0xecfecb85,0xd12095a2,0xdb01ba16,0xcf7f06ae } }, + /* 58 */ + { { 0x8ef96c80,0x0f56e3c4,0x3ddb609c,0xd521f2b3,0x7dc1450d,0x2be94102, + 0x02a91fe2,0x2d21a071,0x1efa37de,0x2e6f74fa,0x156c28a1,0x9a9a90b8 }, + { 0x9dc7dfcb,0xc54ea9ea,0x2c2c1d62,0xc74e66fc,0x49d3e067,0x9f23f967, + 0x54dd38ad,0x1c7c3a46,0x5946cee3,0xc7005884,0x45cc045d,0x89856368 } }, + /* 59 */ + { { 0xfce73946,0x29da7cd4,0x23168563,0x8f697db5,0xcba92ec6,0x8e235e9c, + 0x9f91d3ea,0x55d4655f,0xaa50a6cd,0xf3689f23,0x21e6a1a0,0xdcf21c26 }, + { 0x61b818bf,0xcffbc82e,0xda47a243,0xc74a2f96,0x8bc1a0cf,0x234e980a, + 0x7929cb6d,0xf35fd6b5,0xefe17d6c,0x81468e12,0x58b2dafb,0xddea6ae5 } }, + /* 60 */ + { { 0x7e787b2e,0x294de887,0x39a9310d,0x258acc1f,0xac14265d,0x92d9714a, + 0x708b48a0,0x18b5591c,0xe1abbf71,0x27cc6bb0,0x568307b9,0xc0581fa3 }, + { 0xf24d4d58,0x9e0f58a3,0xe0ce2327,0xfebe9bb8,0x9d1be702,0x91fd6a41, + 0xfacac993,0x9a7d8a45,0x9e50d66d,0xabc0a08c,0x06498201,0x02c342f7 } }, + /* 61 */ + { { 0x157bdbc2,0xccd71407,0xad0e1605,0x72fa89c6,0xb92a015f,0xb1d3da2b, + 0xa0a3fe56,0x8ad9e7cd,0x24f06737,0x160edcbd,0x61275be6,0x79d4db33 }, + { 0x5f3497c4,0xd3d31fd9,0x04192fb0,0x8cafeaee,0x13a50af3,0xe13ca745, + 0x8c85aae5,0x18826167,0x9eb556ff,0xce06cea8,0xbdb549f3,0x2eef1995 } }, + /* 62 */ + { { 0x50596edc,0x8ed7d3eb,0x905243a2,0xaa359362,0xa4b6d02b,0xa212c2c2, + 0xc4fbec68,0x611fd727,0xb84f733d,0x8a0b8ff7,0x5f0daf0e,0xd85a6b90 }, + { 0xd4091cf7,0x60e899f5,0x2eff2768,0x4fef2b67,0x10c33964,0xc1f195cb, + 0x93626a8f,0x8275d369,0x0d6c840a,0xc77904f4,0x7a868acd,0x88d8b7fd } }, + /* 63 */ + { { 0x7bd98425,0x85f23723,0xc70b154e,0xd4463992,0x96687a2e,0xcbb00ee2, + 0xc83214fd,0x905fdbf7,0x13593684,0x2019d293,0xef51218e,0x0428c393 }, + { 0x981e909a,0x40c7623f,0x7be192da,0x92513385,0x4010907e,0x48fe480f, + 0x3120b459,0xdd7a187c,0xa1fd8f3c,0xc9d7702d,0xe358efc5,0x66e4753b } }, + /* 64 */ + { { 0x16973cf4,0x070d34e1,0x7e4f34f7,0x20aee08b,0x5eb8ad29,0x269af9b9, + 0xa6a45dda,0xdde0a036,0x63df41e0,0xa18b528e,0xa260df2a,0x03cc71b2 }, + { 0xa06b1dd7,0x24a6770a,0x9d2675d3,0x5bfa9c11,0x96844432,0x73c1e2a1, + 0x131a6cf0,0x3660558d,0x2ee79454,0xb0289c83,0xc6d8ddcd,0xa6aefb01 } }, + /* 65 */ + { { 0x01ab5245,0xba1464b4,0xc48d93ff,0x9b8d0b6d,0x93ad272c,0x939867dc, + 0xae9fdc77,0xbebe085e,0x894ea8bd,0x73ae5103,0x39ac22e1,0x740fc89a }, + { 0x28e23b23,0x5e28b0a3,0xe13104d0,0x2352722e,0xb0a2640d,0xf4667a18, + 0x49bb37c3,0xac74a72e,0xe81e183a,0x79f734f0,0x3fd9c0eb,0xbffe5b6c } }, + /* 66 */ + { { 0xc6a2123f,0xb1a358f5,0xfe28df6d,0x927b2d95,0xf199d2f9,0x89702753, + 0x1a3f82dc,0x0a73754c,0x777affe1,0x063d029d,0xdae6d34d,0x5439817e }, + { 0x6b8b83c4,0xf7979eef,0x9d945682,0x615cb214,0xc5e57eae,0x8f0e4fac, + 0x113047dd,0x042b89b8,0x93f36508,0x888356dc,0x5fd1f32f,0xbf008d18 } }, + /* 67 */ + { { 0x4e8068db,0x8012aa24,0xa5729a47,0xc72cc641,0x43f0691d,0x3c33df2c, + 0x1d92145f,0xfa057347,0xb97f7946,0xaefc0f2f,0x2f8121bf,0x813d75cb }, + { 0x4383bba6,0x05613c72,0xa4224b3f,0xa924ce70,0x5f2179a6,0xe59cecbe, + 0x79f62b61,0x78e2e8aa,0x53ad8079,0x3ac2cc3b,0xd8f4fa96,0x55518d71 } }, + /* 68 */ + { { 0x00623f3b,0x03cf2922,0x5f29ebff,0x095c7111,0x80aa6823,0x42d72247, + 0x7458c0b0,0x044c7ba1,0x0959ec20,0xca62f7ef,0xf8ca929f,0x40ae2ab7 }, + { 0xa927b102,0xb8c5377a,0xdc031771,0x398a86a0,0xc216a406,0x04908f9d, + 0x918d3300,0xb423a73a,0xe0b94739,0x634b0ff1,0x2d69f697,0xe29de725 } }, + /* 69 */ + { { 0x8435af04,0x744d1400,0xfec192da,0x5f255b1d,0x336dc542,0x1f17dc12, + 0x636a68a8,0x5c90c2a7,0x7704ca1e,0x960c9eb7,0x6fb3d65a,0x9de8cf1e }, + { 0x511d3d06,0xc60fee0d,0xf9eb52c7,0x466e2313,0x206b0914,0x743c0f5f, + 0x2191aa4d,0x42f55bac,0xffebdbc2,0xcefc7c8f,0xe6e8ed1c,0xd4fa6081 } }, + /* 70 */ + { { 0xb0ab9645,0xb5e405d3,0xd5f1f711,0xaeec7f98,0x585c2a6e,0x8ad42311, + 0x512c6944,0x045acb9e,0xa90db1c6,0xae106c4e,0x898e6563,0xb89f33d5 }, + { 0x7fed2ce4,0x43b07cd9,0xdd815b20,0xf9934e17,0x0a81a349,0x6778d4d5, + 0x52918061,0x9e616ade,0xd7e67112,0xfa06db06,0x88488091,0x1da23cf1 } }, + /* 71 */ + { { 0x42f2c4b5,0x821c46b3,0x66059e47,0x931513ef,0x66f50cd1,0x7030ae43, + 0x43e7b127,0x43b536c9,0x5fca5360,0x006258cf,0x6b557abf,0xe4e3ee79 }, + { 0x24c8b22f,0xbb6b3900,0xfcbf1054,0x2eb5e2c1,0x567492af,0x937b18c9, + 0xacf53957,0xf09432e4,0x1dbf3a56,0x585f5a9d,0xbe0887cf,0xf86751fd } }, + /* 72 */ + { { 0x9d10e0b2,0x157399cb,0x60dc51b7,0x1c0d5956,0x1f583090,0x1d496b8a, + 0x88590484,0x6658bc26,0x03213f28,0x88c08ab7,0x7ae58de4,0x8d2e0f73 }, + { 0x486cfee6,0x9b79bc95,0xe9e5bc57,0x036a26c7,0xcd8ae97a,0x1ad03601, + 0xff3a0494,0x06907f87,0x2c7eb584,0x078f4bbf,0x7e8d0a5a,0xe3731bf5 } }, + /* 73 */ + { { 0xe1cd0abe,0x72f2282b,0x87efefa2,0xd4f9015e,0x6c3834bd,0x9d189806, + 0xb8a29ced,0x9c8cdcc1,0xfee82ebc,0x0601b9f4,0x7206a756,0x371052bc }, + { 0x46f32562,0x76fa1092,0x17351bb4,0xdaad534c,0xb3636bb5,0xc3d64c37, + 0x45d54e00,0x038a8c51,0x32c09e7c,0x301e6180,0x95735151,0x9764eae7 } }, + /* 74 */ + { { 0xcbd5256a,0x8791b19f,0x6ca13a3b,0x4007e0f2,0x4cf06904,0x03b79460, + 0xb6c17589,0xb18a9c22,0x81d45908,0xa1cb7d7d,0x21bb68f1,0x6e13fa9d }, + { 0xa71e6e16,0x47183c62,0xe18749ed,0x5cf0ef8e,0x2e5ed409,0x2c9c7f9b, + 0xe6e117e1,0x042eeacc,0x13fb5a7f,0xb86d4816,0xc9e5feb1,0xea1cf0ed } }, + /* 75 */ + { { 0xcea4cc9b,0x6e6573c9,0xafcec8f3,0x5417961d,0xa438b6f6,0x804bf02a, + 0xdcd4ea88,0xb894b03c,0x3799571f,0xd0f807e9,0x862156e8,0x3466a7f5 }, + { 0x56515664,0x51e59acd,0xa3c5eb0b,0x55b0f93c,0x6a4279db,0x84a06b02, + 0xc5fae08e,0x5c850579,0xa663a1a2,0xcf07b8db,0xf46ffc8d,0x49a36bbc } }, + /* 76 */ + { { 0x46d93106,0xe47f5acc,0xaa897c9c,0x65b7ade0,0x12d7e4be,0x37cf4c94, + 0xd4b2caa9,0xa2ae9b80,0xe60357a3,0x5e7ce09c,0xc8ecd5f9,0x29f77667 }, + { 0xa8a0b1c5,0xdf6868f5,0x62978ad8,0x240858cf,0xdc0002a1,0x0f7ac101, + 0xffe9aa05,0x1d28a9d7,0x5b962c97,0x744984d6,0x3d28c8b2,0xa8a7c00b } }, + /* 77 */ + { { 0xae11a338,0x7c58a852,0xd1af96e7,0xa78613f1,0x5355cc73,0x7e9767d2, + 0x792a2de6,0x6ba37009,0x124386b2,0x7d60f618,0x11157674,0xab09b531 }, + { 0x98eb9dd0,0x95a04841,0x15070328,0xe6c17acc,0x489c6e49,0xafc6da45, + 0xbb211530,0xab45a60a,0x7d7ea933,0xc58d6592,0x095642c6,0xa3ef3c65 } }, + /* 78 */ + { { 0xdf010879,0x89d420e9,0x39576179,0x9d25255d,0xe39513b6,0x9cdefd50, + 0xd5d1c313,0xe4efe45b,0x3f7af771,0xc0149de7,0x340ab06b,0x55a6b4f4 }, + { 0xebeaf771,0xf1325251,0x878d4288,0x2ab44128,0x18e05afe,0xfcd5832e, + 0xcc1fb62b,0xef52a348,0xc1c4792a,0x2bd08274,0x877c6dc7,0x345c5846 } }, + /* 79 */ + { { 0xbea65e90,0xde15ceb0,0x2416d99c,0x0987f72b,0xfd863dec,0x44db578d, + 0xac6a3578,0xf617b74b,0xdb48e999,0x9e62bd7a,0xeab1a1be,0x877cae61 }, + { 0x3a358610,0x23adddaa,0x325e2b07,0x2fc4d6d1,0x1585754e,0x897198f5, + 0xb392b584,0xf741852c,0xb55f7de1,0x9927804c,0x1aa8efae,0xe9e6c4ed } }, + /* 80 */ + { { 0x98683186,0x867db639,0xddcc4ea9,0xfb5cf424,0xd4f0e7bd,0xcc9a7ffe, + 0x7a779f7e,0x7c57f71c,0xd6b25ef2,0x90774079,0xb4081680,0x90eae903 }, + { 0x0ee1fceb,0xdf2aae5e,0xe86c1a1f,0x3ff1da24,0xca193edf,0x80f587d6, + 0xdc9b9d6a,0xa5695523,0x85920303,0x7b840900,0xba6dbdef,0x1efa4dfc } }, + /* 81 */ + { { 0xe0540015,0xfbd838f9,0xc39077dc,0x2c323946,0xad619124,0x8b1fb9e6, + 0x0ca62ea8,0x9612440c,0x2dbe00ff,0x9ad9b52c,0xae197643,0xf52abaa1 }, + { 0x2cac32ad,0xd0e89894,0x62a98f91,0xdfb79e42,0x276f55cb,0x65452ecf, + 0x7ad23e12,0xdb1ac0d2,0xde4986f0,0xf68c5f6a,0x82ce327d,0x389ac37b } }, + /* 82 */ + { { 0xf8e60f5b,0x511188b4,0x48aa2ada,0x7fe67015,0x381abca2,0xdb333cb8, + 0xdaf3fc97,0xb15e6d9d,0x36aabc03,0x4b24f6eb,0x72a748b4,0xc59789df }, + { 0x29cf5279,0x26fcb8a5,0x01ad9a6c,0x7a3c6bfc,0x4b8bac9b,0x866cf88d, + 0x9c80d041,0xf4c89989,0x70add148,0xf0a04241,0x45d81a41,0x5a02f479 } }, + /* 83 */ + { { 0xc1c90202,0xfa5c877c,0xf8ac7570,0xd099d440,0xd17881f7,0x428a5b1b, + 0x5b2501d7,0x61e267db,0xf2e4465b,0xf889bf04,0x76aa4cb8,0x4da3ae08 }, + { 0xe3e66861,0x3ef0fe26,0x3318b86d,0x5e772953,0x747396df,0xc3c35fbc, + 0x439ffd37,0x5115a29c,0xb2d70374,0xbfc4bd97,0x56246b9d,0x088630ea } }, + /* 84 */ + { { 0xb8a9e8c9,0xcd96866d,0x5bb8091e,0xa11963b8,0x045b3cd2,0xc7f90d53, + 0x80f36504,0x755a72b5,0x21d3751c,0x46f8b399,0x53c193de,0x4bffdc91 }, + { 0xb89554e7,0xcd15c049,0xf7a26be6,0x353c6754,0xbd41d970,0x79602370, + 0x12b176c0,0xde16470b,0x40c8809d,0x56ba1175,0xe435fb1e,0xe2db35c3 } }, + /* 85 */ + { { 0x6328e33f,0xd71e4aab,0xaf8136d1,0x5486782b,0x86d57231,0x07a4995f, + 0x1651a968,0xf1f0a5bd,0x76803b6d,0xa5dc5b24,0x42dda935,0x5c587cbc }, + { 0xbae8b4c0,0x2b6cdb32,0xb1331138,0x66d1598b,0x5d7e9614,0x4a23b2d2, + 0x74a8c05d,0x93e402a6,0xda7ce82e,0x45ac94e6,0xe463d465,0xeb9f8281 } }, + /* 86 */ + { { 0xfecf5b9b,0x34e0f9d1,0xf206966a,0xa115b12b,0x1eaa0534,0x5591cf3b, + 0xfb1558f9,0x5f0293cb,0x1bc703a5,0x1c8507a4,0x862c1f81,0x92e6b81c }, + { 0xcdaf24e3,0xcc9ebc66,0x72fcfc70,0x68917ecd,0x8157ba48,0x6dc9a930, + 0xb06ab2b2,0x5d425c08,0x36e929c4,0x362f8ce7,0x62e89324,0x09f6f57c } }, + /* 87 */ + { { 0xd29375fb,0x1c7d6b78,0xe35d1157,0xfabd851e,0x4243ea47,0xf6f62dcd, + 0x8fe30b0f,0x1dd92460,0xffc6e709,0x08166dfa,0x0881e6a7,0xc6c4c693 }, + { 0xd6a53fb0,0x20368f87,0x9eb4d1f9,0x38718e9f,0xafd7e790,0x03f08acd, + 0x72fe2a1c,0x0835eb44,0x88076e5d,0x7e050903,0xa638e731,0x538f765e } }, + /* 88 */ + { { 0xc2663b4b,0x0e0249d9,0x47cd38dd,0xe700ab5b,0x2c46559f,0xb192559d, + 0x4bcde66d,0x8f9f74a8,0x3e2aced5,0xad161523,0x3dd03a5b,0xc155c047 }, + { 0x3be454eb,0x346a8799,0x83b7dccd,0x66ee94db,0xab9d2abe,0x1f6d8378, + 0x7733f355,0x4a396dd2,0xf53553c2,0x419bd40a,0x731dd943,0xd0ead98d } }, + /* 89 */ + { { 0xec142408,0x908e0b0e,0x4114b310,0x98943cb9,0x1742b1d7,0x03dbf7d8, + 0x693412f4,0xd270df6b,0x8f69e20c,0xc5065494,0x697e43a1,0xa76a90c3 }, + { 0x4624825a,0xe0fa3384,0x8acc34c2,0x82e48c0b,0xe9a14f2b,0x7b24bd14, + 0x4db30803,0x4f5dd5e2,0x932da0a3,0x0c77a9e7,0x74c653dc,0x20db90f2 } }, + /* 90 */ + { { 0x0e6c5fd9,0x261179b7,0x6c982eea,0xf8bec123,0xd4957b7e,0x47683338, + 0x0a72f66a,0xcc47e664,0x1bad9350,0xbd54bf6a,0xf454e95a,0xdfbf4c6a }, + { 0x6907f4fa,0x3f7a7afa,0x865ca735,0x7311fae0,0x2a496ada,0x24737ab8, + 0x15feb79b,0x13e425f1,0xa1b93c21,0xe9e97c50,0x4ddd3eb5,0xb26b6eac } }, + /* 91 */ + { { 0x2a2e5f2b,0x81cab9f5,0xbf385ac4,0xf93caf29,0xc909963a,0xf4bf35c3, + 0x74c9143c,0x081e7300,0xc281b4c5,0x3ea57fa8,0x9b340741,0xe497905c }, + { 0x55ab3cfb,0xf556dd8a,0x518db6ad,0xd444b96b,0x5ef4b955,0x34f5425a, + 0xecd26aa3,0xdda7a3ac,0xda655e97,0xb57da11b,0xc2024c70,0x02da3eff } }, + /* 92 */ + { { 0x6481d0d9,0xe24b0036,0x818fdfe2,0x3740dbe5,0x190fda00,0xc1fc1f45, + 0x3cf27fde,0x329c9280,0x6934f43e,0x7435cb53,0x7884e8fe,0x2b505a5d }, + { 0x711adcc9,0x6cfcc6a6,0x531e21e1,0xf034325c,0x9b2a8a99,0xa2f4a967, + 0x3c21bdff,0x9d5f3842,0x31b57d66,0xb25c7811,0x0b8093b9,0xdb5344d8 } }, + /* 93 */ + { { 0xae50a2f5,0x0d72e667,0xe4a861d1,0x9b7f8d8a,0x330df1cb,0xa129f70f, + 0xe04fefc3,0xe90aa5d7,0xe72c3ae1,0xff561ecb,0xcdb955fa,0x0d8fb428 }, + { 0xd7663784,0xd2235f73,0x7e2c456a,0xc05baec6,0x2adbfccc,0xe5c292e4, + 0xefb110d5,0x4fd17988,0xd19d49f3,0x27e57734,0x84f679fe,0x188ac4ce } }, + /* 94 */ + { { 0xa796c53e,0x7ee344cf,0x0868009b,0xbbf6074d,0x474a1295,0x1f1594f7, + 0xac11632d,0x66776edc,0x04e2fa5a,0x1862278b,0xc854a89a,0x52665cf2 }, + { 0x8104ab58,0x7e376464,0x7204fd6d,0x16775913,0x44ea1199,0x86ca06a5, + 0x1c9240dd,0xaa3f765b,0x24746149,0x5f8501a9,0xdcd251d7,0x7b982e30 } }, + /* 95 */ + { { 0xc15f3060,0xe44e9efc,0xa87ebbe6,0x5ad62f2e,0xc79500d4,0x36499d41, + 0x336fa9d1,0xa66d6dc0,0x5afd3b1f,0xf8afc495,0xe5c9822b,0x1d8ccb24 }, + { 0x79d7584b,0x4031422b,0xea3f20dd,0xc54a0580,0x958468c5,0x3f837c8f, + 0xfbea7735,0x3d82f110,0x7dffe2fc,0x679a8778,0x20704803,0x48eba63b } }, + /* 96 */ + { { 0xdf46e2f6,0x89b10d41,0x19514367,0x13ab57f8,0x1d469c87,0x067372b9, + 0x4f6c5798,0x0c195afa,0x272c9acf,0xea43a12a,0x678abdac,0x9dadd8cb }, + { 0xe182579a,0xcce56c6b,0x2d26c2d8,0x86febadb,0x2a44745c,0x1c668ee1, + 0x98dc047a,0x580acd86,0x51b9ec2d,0x5a2b79cc,0x4054f6a0,0x007da608 } }, + /* 97 */ + { { 0x17b00dd0,0x9e3ca352,0x0e81a7a6,0x046779cb,0xd482d871,0xb999fef3, + 0xd9233fbc,0xe6f38134,0xf48cd0e0,0x112c3001,0x3c6c66ae,0x934e7576 }, + { 0xd73234dc,0xb44d4fc3,0x864eafc1,0xfcae2062,0x26bef21a,0x843afe25, + 0xf3b75fdf,0x61355107,0x794c2e6b,0x8367a5aa,0x8548a372,0x3d2629b1 } }, + /* 98 */ + { { 0x437cfaf8,0x6230618f,0x2032c299,0x5b8742cb,0x2293643a,0x949f7247, + 0x09464f79,0xb8040f1a,0x4f254143,0x049462d2,0x366c7e76,0xabd6b522 }, + { 0xd5338f55,0x119b392b,0x01495a0c,0x1a80a9ce,0xf8d7537e,0xf3118ca7, + 0x6bf4b762,0xb715adc2,0xa8482b6c,0x24506165,0x96a7c84d,0xd958d7c6 } }, + /* 99 */ + { { 0xbdc21f31,0x9ad8aa87,0x8063e58c,0xadb3cab4,0xb07dd7b8,0xefd86283, + 0x1be7c6b4,0xc7b9b762,0x015582de,0x2ef58741,0x299addf3,0xc970c52e }, + { 0x22f24d66,0x78f02e2a,0x74cc100a,0xefec1d10,0x09316e1a,0xaf2a6a39, + 0x5849dd49,0xce7c2205,0x96bffc4c,0x9c1fe75c,0x7ba06ec0,0xcad98fd2 } }, + /* 100 */ + { { 0xb648b73e,0xed76e2d0,0x1cfd285e,0xa9f92ce5,0x2ed13de1,0xa8c86c06, + 0xa5191a93,0x1d3a574e,0x1ad1b8bf,0x385cdf8b,0x47d2cfe3,0xbbecc28a }, + { 0x69cec548,0x98d326c0,0xf240a0b2,0x4f5bc1dd,0x29057236,0x241a7062, + 0xc68294a4,0x0fc6e9c5,0xa319f17a,0x4d04838b,0x9ffc1c6f,0x8b612cf1 } }, + /* 101 */ + { { 0x4c3830eb,0x9bb0b501,0x8ee0d0c5,0x3d08f83c,0x79ba9389,0xa4a62642, + 0x9cbc2914,0x5d5d4044,0x074c46f0,0xae9eb83e,0x74ead7d6,0x63bb758f }, + { 0xc6bb29e0,0x1c40d2ea,0x4b02f41e,0x95aa2d87,0x53cb199a,0x92989175, + 0x51584f6d,0xdd91bafe,0x31a1aaec,0x3715efb9,0x46780f9e,0xc1b6ae5b } }, + /* 102 */ + { { 0x42772f41,0xcded3e4b,0x3bcb79d1,0x3a700d5d,0x80feee60,0x4430d50e, + 0xf5e5d4bb,0x444ef1fc,0xe6e358ff,0xc660194f,0x6a91b43c,0xe68a2f32 }, + { 0x977fe4d2,0x5842775c,0x7e2a41eb,0x78fdef5c,0xff8df00e,0x5f3bec02, + 0x5852525d,0xf4b840cd,0x4e6988bd,0x0870483a,0xcc64b837,0x39499e39 } }, + /* 103 */ + { { 0xb08df5fe,0xfc05de80,0x63ba0362,0x0c12957c,0xd5cf1428,0xea379414, + 0x54ef6216,0xc559132a,0xb9e65cf8,0x33d5f12f,0x1695d663,0x09c60278 }, + { 0x61f7a2fb,0x3ac1ced4,0xd4f5eeb8,0xdd838444,0x8318fcad,0x82a38c6c, + 0xe9f1a864,0x315be2e5,0x442daf47,0x317b5771,0x95aa5f9e,0x81b5904a } }, + /* 104 */ + { { 0x8b21d232,0x6b6b1c50,0x8c2cba75,0x87f3dbc0,0xae9f0faf,0xa7e74b46, + 0xbb7b8079,0x036a0985,0x8d974a25,0x4f185b90,0xd9af5ec9,0x5aa7cef0 }, + { 0x57dcfffc,0xe0566a70,0xb8453225,0x6ea311da,0x23368aa9,0x72ea1a8d, + 0x48cd552d,0xed9b2083,0xc80ea435,0xb987967c,0x6c104173,0xad735c75 } }, + /* 105 */ + { { 0xcee76ef4,0xaea85ab3,0xaf1d2b93,0x44997444,0xeacb923f,0x0851929b, + 0x51e3bc0c,0xb080b590,0x59be68a2,0xc4ee1d86,0x64b26cda,0xf00de219 }, + { 0xf2e90d4d,0x8d7fb5c0,0x77d9ec64,0x00e219a7,0x5d1c491c,0xc4e6febd, + 0x1a8f4585,0x080e3754,0x48d2af9c,0x4a9b86c8,0xb6679851,0x2ed70db6 } }, + /* 106 */ + { { 0x586f25cb,0xaee44116,0xa0fcf70f,0xf7b6861f,0x18a350e8,0x55d2cd20, + 0x92dc286f,0x861bf3e5,0x6226aba7,0x9ab18ffa,0xa9857b03,0xd15827be }, + { 0x92e6acef,0x26c1f547,0xac1fbac3,0x422c63c8,0xfcbfd71d,0xa2d8760d, + 0xb2511224,0x35f6a539,0x048d1a21,0xbaa88fa1,0xebf999db,0x49f1abe9 } }, + /* 107 */ + { { 0xf7492b73,0x16f9f4f4,0xcb392b1a,0xcf28ec1e,0x69ca6ffc,0x45b130d4, + 0xb72efa58,0x28ba8d40,0x5ca066f5,0xace987c7,0x4ad022eb,0x3e399246 }, + { 0x752555bb,0x63a2d84e,0x9c2ae394,0xaaa93b4a,0xc89539ca,0xcd80424e, + 0xaa119a99,0x6d6b5a6d,0x379f2629,0xbd50334c,0xef3cc7d3,0x899e925e } }, + /* 108 */ + { { 0xbf825dc4,0xb7ff3651,0x40b9c462,0x0f741cc4,0x5cc4fb5b,0x771ff5a9, + 0x47fd56fe,0xcb9e9c9b,0x5626c0d3,0xbdf053db,0xf7e14098,0xa97ce675 }, + { 0x6c934f5e,0x68afe5a3,0xccefc46f,0x6cd5e148,0xd7a88586,0xc7758570, + 0xdd558d40,0x49978f5e,0x64ae00c1,0xa1d5088a,0xf1d65bb2,0x58f2a720 } }, + /* 109 */ + { { 0x3e4daedb,0x66fdda4a,0x65d1b052,0x38318c12,0x4c4bbf5c,0x28d910a2, + 0x78a9cd14,0x762fe5c4,0xd2cc0aee,0x08e5ebaa,0xca0c654c,0xd2cdf257 }, + { 0x08b717d2,0x48f7c58b,0x386cd07a,0x3807184a,0xae7d0112,0x3240f626, + 0xc43917b0,0x03e9361b,0x20aea018,0xf261a876,0x7e1e6372,0x53f556a4 } }, + /* 110 */ + { { 0x2f512a90,0xc84cee56,0x1b0ea9f1,0x24b3c004,0xe26cc1ea,0x0ee15d2d, + 0xf0c9ef7d,0xd848762c,0xd5341435,0x1026e9c5,0xfdb16b31,0x8f5b73dc }, + { 0xd2c75d95,0x1f69bef2,0xbe064dda,0x8d33d581,0x57ed35e6,0x8c024c12, + 0xc309c281,0xf8d435f9,0xd6960193,0xfd295061,0xe9e49541,0x66618d78 } }, + /* 111 */ + { { 0x8ce382de,0x571cfd45,0xde900dde,0x175806ee,0x34aba3b5,0x61849965, + 0xde7aec95,0xe899778a,0xff4aa97f,0xe8f00f6e,0x010b0c6d,0xae971cb5 }, + { 0x3af788f1,0x1827eebc,0xe413fe2d,0xd46229ff,0x4741c9b4,0x8a15455b, + 0xf8e424eb,0x5f02e690,0xdae87712,0x40a1202e,0x64944f6d,0x49b3bda2 } }, + /* 112 */ + { { 0x035b2d69,0xd63c6067,0x6bed91b0,0xb507150d,0x7afb39b2,0x1f35f82f, + 0x16012b66,0xb9bd9c01,0xed0a5f50,0x00d97960,0x2716f7c9,0xed705451 }, + { 0x127abdb4,0x1576eff4,0xf01e701c,0x6850d698,0x3fc87e2f,0x9fa7d749, + 0xb0ce3e48,0x0b6bcc6f,0xf7d8c1c0,0xf4fbe1f5,0x02719cc6,0xcf75230e } }, + /* 113 */ + { { 0x722d94ed,0x6761d6c2,0x3718820e,0xd1ec3f21,0x25d0e7c6,0x65a40b70, + 0xbaf3cf31,0xd67f830e,0xb93ea430,0x633b3807,0x0bc96c69,0x17faa0ea }, + { 0xdf866b98,0xe6bf3482,0xa9db52d4,0x205c1ee9,0xff9ab869,0x51ef9bbd, + 0x75eeb985,0x3863dad1,0xd3cf442a,0xef216c3b,0xf9c8e321,0x3fb228e3 } }, + /* 114 */ + { { 0x0760ac07,0x94f9b70c,0x9d79bf4d,0xf3c9ccae,0xc5ffc83d,0x73cea084, + 0xdc49c38e,0xef50f943,0xbc9e7330,0xf467a2ae,0x44ea7fba,0x5ee534b6 }, + { 0x03609e7f,0x20cb6272,0x62fdc9f0,0x09844355,0x0f1457f7,0xaf5c8e58, + 0xb4b25941,0xd1f50a6c,0x2ec82395,0x77cb247c,0xda3dca33,0xa5f3e1e5 } }, + /* 115 */ + { { 0x7d85fa94,0x023489d6,0x2db9ce47,0x0ba40537,0xaed7aad1,0x0fdf7a1f, + 0x9a4ccb40,0xa57b0d73,0x5b18967c,0x48fcec99,0xb7274d24,0xf30b5b6e }, + { 0xc81c5338,0x7ccb4773,0xa3ed6bd0,0xb85639e6,0x1d56eada,0x7d9df95f, + 0x0a1607ad,0xe256d57f,0x957574d6,0x6da7ffdc,0x01c7a8c4,0x65f84046 } }, + /* 116 */ + { { 0xcba1e7f1,0x8d45d0cb,0x02b55f64,0xef0a08c0,0x17e19892,0x771ca31b, + 0x4885907e,0xe1843ecb,0x364ce16a,0x67797ebc,0x8df4b338,0x816d2b2d }, + { 0x39aa8671,0xe870b0e5,0xc102b5f5,0x9f0db3e4,0x1720c697,0x34296659, + 0x613c0d2a,0x0ad4c89e,0x418ddd61,0x1af900b2,0xd336e20e,0xe087ca72 } }, + /* 117 */ + { { 0xaba10079,0x222831ff,0x6d64fff2,0x0dc5f87b,0x3e8cb330,0x44547907, + 0x702a33fb,0xe815aaa2,0x5fba3215,0x338d6b2e,0x79f549c8,0x0f7535cb }, + { 0x2ee95923,0x471ecd97,0xc6d1c09f,0x1e868b37,0xc666ef4e,0x2bc7b8ec, + 0x808a4bfc,0xf5416589,0x3fbc4d2e,0xf23e9ee2,0x2d75125b,0x4357236c } }, + /* 118 */ + { { 0xba9cdb1b,0xfe176d95,0x2f82791e,0x45a1ca01,0x4de4cca2,0x97654af2, + 0x5cc4bcb9,0xbdbf9d0e,0xad97ac0a,0xf6a7df50,0x61359fd6,0xc52112b0 }, + { 0x4f05eae3,0x696d9ce3,0xe943ac2b,0x903adc02,0x0848be17,0xa9075347, + 0x2a3973e5,0x1e20f170,0x6feb67e9,0xe1aacc1c,0xe16bc6b9,0x2ca0ac32 } }, + /* 119 */ + { { 0xef871eb5,0xffea12e4,0xa8bf0a7a,0x94c2f25d,0x78134eaa,0x4d1e4c2a, + 0x0360fb10,0x11ed16fb,0x85fc11be,0x4029b6db,0xf4d390fa,0x5e9f7ab7 }, + { 0x30646612,0x5076d72f,0xdda1d0d8,0xa0afed1d,0x85a1d103,0x29022257, + 0x4e276bcd,0xcb499e17,0x51246c3d,0x16d1da71,0x589a0443,0xc72d56d3 } }, + /* 120 */ + { { 0xdae5bb45,0xdf5ffc74,0x261bd6dc,0x99068c4a,0xaa98ec7b,0xdc0afa7a, + 0xf121e96d,0xedd2ee00,0x1414045c,0x163cc7be,0x335af50e,0xb0b1bbce }, + { 0x01a06293,0xd440d785,0x6552e644,0xcdebab7c,0x8c757e46,0x48cb8dbc, + 0x3cabe3cb,0x81f9cf78,0xb123f59a,0xddd02611,0xeeb3784d,0x3dc7b88e } }, + /* 121 */ + { { 0xc4741456,0xe1b8d398,0x6032a121,0xa9dfa902,0x1263245b,0x1cbfc86d, + 0x5244718c,0xf411c762,0x05b0fc54,0x96521d54,0xdbaa4985,0x1afab46e }, + { 0x8674b4ad,0xa75902ba,0x5ad87d12,0x486b43ad,0x36e0d099,0x72b1c736, + 0xbb6cd6d6,0x39890e07,0x59bace4e,0x8128999c,0x7b535e33,0xd8da430b } }, + /* 122 */ + { { 0xc6b75791,0x39f65642,0x21806bfb,0x050947a6,0x1362ef84,0x0ca3e370, + 0x8c3d2391,0x9bc60aed,0x732e1ddc,0x9b488671,0xa98ee077,0x12d10d9e }, + { 0x3651b7dc,0xb6f2822d,0x80abd138,0x6345a5ba,0x472d3c84,0x62033262, + 0xacc57527,0xd54a1d40,0x424447cb,0x6ea46b3a,0x2fb1a496,0x5bc41057 } }, + /* 123 */ + { { 0xa751cd0e,0xe70c57a3,0xeba3c7d6,0x190d8419,0x9d47d55a,0xb1c3bee7, + 0xf912c6d8,0xda941266,0x407a6ad6,0x12e9aacc,0x6e838911,0xd6ce5f11 }, + { 0x70e1f2ce,0x063ca97b,0x8213d434,0xa3e47c72,0x84df810a,0xa016e241, + 0xdfd881a4,0x688ad7b0,0xa89bf0ad,0xa37d99fc,0xa23c2d23,0xd8e3f339 } }, + /* 124 */ + { { 0x750bed6f,0xbdf53163,0x83e68b0a,0x808abc32,0x5bb08a33,0x85a36627, + 0x6b0e4abe,0xf72a3a0f,0xfaf0c6ad,0xf7716d19,0x5379b25f,0x22dcc020 }, + { 0xf9a56e11,0x7400bf8d,0x56a47f21,0x6cb8bad7,0x7a6eb644,0x7c97176f, + 0xd1f5b646,0xe8fd84f7,0x44ddb054,0x98320a94,0x1dde86f5,0x07071ba3 } }, + /* 125 */ + { { 0x98f8fcb9,0x6fdfa0e5,0x94d0d70c,0x89cec8e0,0x106d20a8,0xa0899397, + 0xba8acc9c,0x915bfb9a,0x5507e01c,0x1370c94b,0x8a821ffb,0x83246a60 }, + { 0xbe3c378f,0xa8273a9f,0x35a25be9,0x7e544789,0x4dd929d7,0x6cfa4972, + 0x365bd878,0x987fed9d,0x5c29a7ae,0x4982ac94,0x5ddd7ec5,0x4589a5d7 } }, + /* 126 */ + { { 0xa95540a9,0x9fabb174,0x0162c5b0,0x7cfb886f,0xea3dee18,0x17be766b, + 0xe88e624c,0xff7da41f,0x8b919c38,0xad0b71eb,0xf31ff9a9,0x86a522e0 }, + { 0x868bc259,0xbc8e6f72,0x3ccef9e4,0x6130c638,0x9a466555,0x09f1f454, + 0x19b2bfb4,0x8e6c0f09,0x0ca7bb22,0x945c46c9,0x4dafb67b,0xacd87168 } }, + /* 127 */ + { { 0x10c53841,0x090c72ca,0x55a4fced,0xc20ae01b,0xe10234ad,0x03f7ebd5, + 0x85892064,0xb3f42a6a,0xb4a14722,0xbdbc30c0,0x8ca124cc,0x971bc437 }, + { 0x517ff2ff,0x6f79f46d,0xecba947b,0x6a9c96e2,0x62925122,0x5e79f2f4, + 0x6a4e91f1,0x30a96bb1,0x2d4c72da,0x1147c923,0x5811e4df,0x65bc311f } }, + /* 128 */ + { { 0x139b3239,0x87c7dd7d,0x4d833bae,0x8b57824e,0x9fff0015,0xbcbc4878, + 0x909eaf1a,0x8ffcef8b,0xf1443a78,0x9905f4ee,0xe15cbfed,0x020dd4a2 }, + { 0xa306d695,0xca2969ec,0xb93caf60,0xdf940cad,0x87ea6e39,0x67f7fab7, + 0xf98c4fe5,0x0d0ee10f,0xc19cb91e,0xc646879a,0x7d1d7ab4,0x4b4ea50c } }, + /* 129 */ + { { 0x7a0db57e,0x19e40945,0x9a8c9702,0xe6017cad,0x1be5cff9,0xdbf739e5, + 0xa7a938a2,0x3646b3cd,0x68350dfc,0x04511085,0x56e098b5,0xad3bd6f3 }, + { 0xee2e3e3e,0x935ebabf,0x473926cb,0xfbd01702,0x9e9fb5aa,0x7c735b02, + 0x2e3feff0,0xc52a1b85,0x046b405a,0x9199abd3,0x39039971,0xe306fcec } }, + /* 130 */ + { { 0x23e4712c,0xd6d9aec8,0xc3c198ee,0x7ca8376c,0x31bebd8a,0xe6d83187, + 0xd88bfef3,0xed57aff3,0xcf44edc7,0x72a645ee,0x5cbb1517,0xd4e63d0b }, + { 0xceee0ecf,0x98ce7a1c,0x5383ee8e,0x8f012633,0xa6b455e8,0x3b879078, + 0xc7658c06,0xcbcd3d96,0x0783336a,0x721d6fe7,0x5a677136,0xf21a7263 } }, + /* 131 */ + { { 0x9586ba11,0x19d8b3cd,0x8a5c0480,0xd9e0aeb2,0x2230ef5c,0xe4261dbf, + 0x02e6bf09,0x095a9dee,0x80dc7784,0x8963723c,0x145157b1,0x5c97dbaf }, + { 0x4bc4503e,0x97e74434,0x85a6b370,0x0fb1cb31,0xcd205d4b,0x3e8df2be, + 0xf8f765da,0x497dd1bc,0x6c988a1a,0x92ef95c7,0x64dc4cfa,0x3f924baa } }, + /* 132 */ + { { 0x7268b448,0x6bf1b8dd,0xefd79b94,0xd4c28ba1,0xe4e3551f,0x2fa1f8c8, + 0x5c9187a9,0x769e3ad4,0x40326c0d,0x28843b4d,0x50d5d669,0xfefc8094 }, + { 0x90339366,0x30c85bfd,0x5ccf6c3a,0x4eeb56f1,0x28ccd1dc,0x0e72b149, + 0xf2ce978e,0x73ee85b5,0x3165bb23,0xcdeb2bf3,0x4e410abf,0x8106c923 } }, + /* 133 */ + { { 0x7d02f4ee,0xc8df0161,0x18e21225,0x8a781547,0x6acf9e40,0x4ea895eb, + 0x6e5a633d,0x8b000cb5,0x7e981ffb,0xf31d86d5,0x4475bc32,0xf5c8029c }, + { 0x1b568973,0x764561ce,0xa62996ec,0x2f809b81,0xda085408,0x9e513d64, + 0xe61ce309,0xc27d815d,0x272999e0,0x0da6ff99,0xfead73f7,0xbd284779 } }, + /* 134 */ + { { 0x9b1cdf2b,0x6033c2f9,0xbc5fa151,0x2a99cf06,0x12177b3b,0x7d27d259, + 0xc4485483,0xb1f15273,0x102e2297,0x5fd57d81,0xc7f6acb7,0x3d43e017 }, + { 0x3a70eb28,0x41a8bb0b,0x3e80b06b,0x67de2d8e,0x70c28de5,0x09245a41, + 0xa7b26023,0xad7dbcb1,0x2cbc6c1e,0x70b08a35,0x9b33041f,0xb504fb66 } }, + /* 135 */ + { { 0xf97a27c2,0xa8e85ab5,0xc10a011b,0x6ac5ec8b,0xffbcf161,0x55745533, + 0x65790a60,0x01780e85,0x99ee75b0,0xe451bf85,0x39c29881,0x8907a63b }, + { 0x260189ed,0x76d46738,0x47bd35cb,0x284a4436,0x20cab61e,0xd74e8c40, + 0x416cf20a,0x6264bf8c,0x5fd820ce,0xfa5a6c95,0xf24bb5fc,0xfa7154d0 } }, + /* 136 */ + { { 0x9b3f5034,0x18482cec,0xcd9e68fd,0x962d445a,0x95746f23,0x266fb1d6, + 0x58c94a4b,0xc66ade5a,0xed68a5b6,0xdbbda826,0x7ab0d6ae,0x05664a4d }, + { 0x025e32fc,0xbcd4fe51,0xa96df252,0x61a5aebf,0x31592a31,0xd88a07e2, + 0x98905517,0x5d9d94de,0x5fd440e7,0x96bb4010,0xe807db4c,0x1b0c47a2 } }, + /* 137 */ + { { 0x08223878,0x5c2a6ac8,0xe65a5558,0xba08c269,0x9bbc27fd,0xd22b1b9b, + 0x72b9607d,0x919171bf,0xe588dc58,0x9ab455f9,0x23662d93,0x6d54916e }, + { 0x3b1de0c1,0x8da8e938,0x804f278f,0xa84d186a,0xd3461695,0xbf4988cc, + 0xe10eb0cb,0xf5eae3be,0xbf2a66ed,0x1ff8b68f,0xc305b570,0xa68daf67 } }, + /* 138 */ + { { 0x44b2e045,0xc1004cff,0x4b1c05d4,0x91b5e136,0x88a48a07,0x53ae4090, + 0xea11bb1a,0x73fb2995,0x3d93a4ea,0x32048570,0x3bfc8a5f,0xcce45de8 }, + { 0xc2b3106e,0xaff4a97e,0xb6848b4f,0x9069c630,0xed76241c,0xeda837a6, + 0x6cc3f6cf,0x8a0daf13,0x3da018a8,0x199d049d,0xd9093ba3,0xf867c6b1 } }, + /* 139 */ + { { 0x56527296,0xe4d42a56,0xce71178d,0xae26c73d,0x6c251664,0x70a0adac, + 0x5dc0ae1d,0x813483ae,0xdaab2daf,0x7574eacd,0xc2d55f4f,0xc56b52dc }, + { 0x95f32923,0x872bc167,0x5bdd2a89,0x4be17581,0xa7699f00,0x9b57f1e7, + 0x3ac2de02,0x5fcd9c72,0x92377739,0x83af3ba1,0xfc50b97f,0xa64d4e2b } }, + /* 140 */ + { { 0x0e552b40,0x2172dae2,0xd34d52e8,0x62f49725,0x07958f98,0x7930ee40, + 0x751fdd74,0x56da2a90,0xf53e48c3,0xf1192834,0x8e53c343,0x34d2ac26 }, + { 0x13111286,0x1073c218,0xda9d9827,0x201dac14,0xee95d378,0xec2c29db, + 0x1f3ee0b1,0x9316f119,0x544ce71c,0x7890c9f0,0x27612127,0xd77138af } }, + /* 141 */ + { { 0x3b4ad1cd,0x78045e6d,0x4aa49bc1,0xcd86b94e,0xfd677a16,0x57e51f1d, + 0xfa613697,0xd9290935,0x34f4d893,0x7a3f9593,0x5d5fcf9b,0x8c9c248b }, + { 0x6f70d4e9,0x9f23a482,0x63190ae9,0x17273454,0x5b081a48,0x4bdd7c13, + 0x28d65271,0x1e2de389,0xe5841d1f,0x0bbaaa25,0x746772e5,0xc4c18a79 } }, + /* 142 */ + { { 0x593375ac,0x10ee2681,0x7dd5e113,0x4f3288be,0x240f3538,0x9a97b2fb, + 0x1de6b1e2,0xfa11089f,0x1351bc58,0x516da562,0x2dfa85b5,0x573b6119 }, + { 0x6cba7df5,0x89e96683,0x8c28ab40,0xf299be15,0xad43fcbf,0xe91c9348, + 0x9a1cefb3,0xe9bbc7cc,0x738b2775,0xc8add876,0x775eaa01,0x6e3b1f2e } }, + /* 143 */ + { { 0xb677788b,0x0365a888,0x3fd6173c,0x634ae8c4,0x9e498dbe,0x30498761, + 0xc8f779ab,0x08c43e6d,0x4c09aca9,0x068ae384,0x2018d170,0x2380c70b }, + { 0xa297c5ec,0xcf77fbc3,0xca457948,0xdacbc853,0x336bec7e,0x3690de04, + 0x14eec461,0x26bbac64,0x1f713abf,0xd1c23c7e,0xe6fd569e,0xf08bbfcd } }, + /* 144 */ + { { 0x84770ee3,0x5f8163f4,0x744a1706,0x0e0c7f94,0xe1b2d46d,0x9c8f05f7, + 0xd01fd99a,0x417eafe7,0x11440e5b,0x2ba15df5,0x91a6fbcf,0xdc5c552a }, + { 0xa270f721,0x86271d74,0xa004485b,0x32c0a075,0x8defa075,0x9d1a87e3, + 0xbf0d20fe,0xb590a7ac,0x8feda1f5,0x430c41c2,0x58f6ec24,0x454d2879 } }, + /* 145 */ + { { 0x7c525435,0x52b7a635,0x37c4bdbc,0x3d9ef57f,0xdffcc475,0x2bb93e9e, + 0x7710f3be,0xf7b8ba98,0x21b727de,0x42ee86da,0x2e490d01,0x55ac3f19 }, + { 0xc0c1c390,0x487e3a6e,0x446cde7b,0x036fb345,0x496ae951,0x089eb276, + 0x71ed1234,0xedfed4d9,0x900f0b46,0x661b0dd5,0x8582f0d3,0x11bd6f1b } }, + /* 146 */ + { { 0x076bc9d1,0x5cf9350f,0xcf3cd2c3,0x15d903be,0x25af031c,0x21cfc8c2, + 0x8b1cc657,0xe0ad3248,0x70014e87,0xdd9fb963,0x297f1658,0xf0f3a5a1 }, + { 0xf1f703aa,0xbb908fba,0x2f6760ba,0x2f9cc420,0x66a38b51,0x00ceec66, + 0x05d645da,0x4deda330,0xf7de3394,0xb9cf5c72,0x1ad4c906,0xaeef6502 } }, + /* 147 */ + { { 0x7a19045d,0x0583c8b1,0xd052824c,0xae7c3102,0xff6cfa58,0x2a234979, + 0x62c733c0,0xfe9dffc9,0x9c0c4b09,0x3a7fa250,0x4fe21805,0x516437bb }, + { 0xc2a23ddb,0x9454e3d5,0x289c104e,0x0726d887,0x4fd15243,0x8977d918, + 0x6d7790ba,0xc559e73f,0x465af85f,0x8fd3e87d,0x5feee46b,0xa2615c74 } }, + /* 148 */ + { { 0x4335167d,0xc8d607a8,0xe0f5c887,0x8b42d804,0x398d11f9,0x5f9f13df, + 0x20740c67,0x5aaa5087,0xa3d9234b,0x83da9a6a,0x2a54bad1,0xbd3a5c4e }, + { 0x2db0f658,0xdd13914c,0x5a3f373a,0x29dcb66e,0x5245a72b,0xbfd62df5, + 0x91e40847,0x19d18023,0xb136b1ae,0xd9df74db,0x3f93bc5b,0x72a06b6b } }, + /* 149 */ + { { 0xad19d96f,0x6da19ec3,0xfb2a4099,0xb342daa4,0x662271ea,0x0e61633a, + 0xce8c054b,0x3bcece81,0x8bd62dc6,0x7cc8e061,0xee578d8b,0xae189e19 }, + { 0xdced1eed,0x73e7a25d,0x7875d3ab,0xc1257f0a,0x1cfef026,0x2cb2d5a2, + 0xb1fdf61c,0xd98ef39b,0x24e83e6c,0xcd8e6f69,0xc7b7088b,0xd71e7076 } }, + /* 150 */ + { { 0x9d4245bf,0x33936830,0x2ac2953b,0x22d96217,0x56c3c3cd,0xb3bf5a82, + 0x0d0699e8,0x50c9be91,0x8f366459,0xec094463,0x513b7c35,0x6c056dba }, + { 0x045ab0e3,0x687a6a83,0x445c9295,0x8d40b57f,0xa16f5954,0x0f345048, + 0x3d8f0a87,0x64b5c639,0x9f71c5e2,0x106353a2,0x874f0dd4,0xdd58b475 } }, + /* 151 */ + { { 0x62230c72,0x67ec084f,0x481385e3,0xf14f6cca,0x4cda7774,0xf58bb407, + 0xaa2dbb6b,0xe15011b1,0x0c035ab1,0xd488369d,0x8245f2fd,0xef83c24a }, + { 0x9fdc2538,0xfb57328f,0x191fe46a,0x79808293,0x32ede548,0xe28f5c44, + 0xea1a022c,0x1b3cda99,0x3df2ec7f,0x39e639b7,0x760e9a18,0x77b6272b } }, + /* 152 */ + { { 0xa65d56d5,0x2b1d51bd,0x7ea696e0,0x3a9b71f9,0x9904f4c4,0x95250ecc, + 0xe75774b7,0x8bc4d6eb,0xeaeeb9aa,0x0e343f8a,0x930e04cb,0xc473c1d1 }, + { 0x064cd8ae,0x282321b1,0x5562221c,0xf4b4371e,0xd1bf1221,0xc1cc81ec, + 0xe2c8082f,0xa52a07a9,0xba64a958,0x350d8e59,0x6fb32c9a,0x29e4f3de } }, + /* 153 */ + { { 0xba89aaa5,0x0aa9d56c,0xc4c6059e,0xf0208ac0,0xbd6ddca4,0x7400d9c6, + 0xf2c2f74a,0xb384e475,0xb1562dd3,0x4c1061fc,0x2e153b8d,0x3924e248 }, + { 0x849808ab,0xf38b8d98,0xa491aa36,0x29bf3260,0x88220ede,0x85159ada, + 0xbe5bc422,0x8b47915b,0xd7300967,0xa934d72e,0x2e515d0d,0xc4f30398 } }, + /* 154 */ + { { 0x1b1de38b,0xe3e9ee42,0x42636760,0xa124e25a,0x90165b1a,0x90bf73c0, + 0x146434c5,0x21802a34,0x2e1fa109,0x54aa83f2,0xed9c51e9,0x1d4bd03c }, + { 0x798751e6,0xc2d96a38,0x8c3507f5,0xed27235f,0xc8c24f88,0xb5fb80e2, + 0xd37f4f78,0xf873eefa,0xf224ba96,0x7229fd74,0x9edd7149,0x9dcd9199 } }, + /* 155 */ + { { 0x4e94f22a,0xee9f81a6,0xf71ec341,0xe5609892,0xa998284e,0x6c818ddd, + 0x3b54b098,0x9fd47295,0x0e8a7cc9,0x47a6ac03,0xb207a382,0xde684e5e }, + { 0x2b6b956b,0x4bdd1ecd,0xf01b3583,0x09084414,0x55233b14,0xe2f80b32, + 0xef5ebc5e,0x5a0fec54,0xbf8b29a2,0x74cf25e6,0x7f29e014,0x1c757fa0 } }, + /* 156 */ + { { 0xeb0fdfe4,0x1bcb5c4a,0xf0899367,0xd7c649b3,0x05bc083b,0xaef68e3f, + 0xa78aa607,0x57a06e46,0x21223a44,0xa2136ecc,0x52f5a50b,0x89bd6484 }, + { 0x4455f15a,0x724411b9,0x08a9c0fd,0x23dfa970,0x6db63bef,0x7b0da4d1, + 0xfb162443,0x6f8a7ec1,0xe98284fb,0xc1ac9cee,0x33566022,0x085a582b } }, + /* 157 */ + { { 0xec1f138a,0x15cb61f9,0x668f0c28,0x11c9a230,0xdf93f38f,0xac829729, + 0x4048848d,0xcef25698,0x2bba8fbf,0x3f686da0,0x111c619a,0xed5fea78 }, + { 0xd6d1c833,0x9b4f73bc,0x86e7bf80,0x50951606,0x042b1d51,0xa2a73508, + 0x5fb89ec2,0x9ef6ea49,0x5ef8b892,0xf1008ce9,0x9ae8568b,0x78a7e684 } }, + /* 158 */ + { { 0x10470cd8,0x3fe83a7c,0xf86df000,0x92734682,0xda9409b5,0xb5dac06b, + 0x94939c5f,0x1e7a9660,0x5cc116dc,0xdec6c150,0x66bac8cc,0x1a52b408 }, + { 0x6e864045,0x5303a365,0x9139efc1,0x45eae72a,0x6f31d54f,0x83bec646, + 0x6e958a6d,0x2fb4a86f,0x4ff44030,0x6760718e,0xe91ae0df,0x008117e3 } }, + /* 159 */ + { { 0x384310a2,0x5d5833ba,0x1fd6c9fc,0xbdfb4edc,0x849c4fb8,0xb9a4f102, + 0x581c1e1f,0xe5fb239a,0xd0a9746d,0xba44b2e7,0x3bd942b9,0x78f7b768 }, + { 0xc87607ae,0x076c8ca1,0xd5caaa7e,0x82b23c2e,0x2763e461,0x6a581f39, + 0x3886df11,0xca8a5e4a,0x264e7f22,0xc87e90cf,0x215cfcfc,0x04f74870 } }, + /* 160 */ + { { 0x141d161c,0x5285d116,0x93c4ed17,0x67cd2e0e,0x7c36187e,0x12c62a64, + 0xed2584ca,0xf5329539,0x42fbbd69,0xc4c777c4,0x1bdfc50a,0x107de776 }, + { 0xe96beebd,0x9976dcc5,0xa865a151,0xbe2aff95,0x9d8872af,0x0e0a9da1, + 0xa63c17cc,0x5e357a3d,0xe15cc67c,0xd31fdfd8,0x7970c6d8,0xc44bbefd } }, + /* 161 */ + { { 0x4c0c62f1,0x703f83e2,0x4e195572,0x9b1e28ee,0xfe26cced,0x6a82858b, + 0xc43638fa,0xd381c84b,0xa5ba43d8,0x94f72867,0x10b82743,0x3b4a783d }, + { 0x7576451e,0xee1ad7b5,0x14b6b5c8,0xc3d0b597,0xfcacc1b8,0x3dc30954, + 0x472c9d7b,0x55df110e,0x02f8a328,0x97c86ed7,0x88dc098f,0xd0433413 } }, + /* 162 */ + { { 0x2ca8f2fe,0x1a60d152,0x491bd41f,0x61640948,0x58dfe035,0x6dae29a5, + 0x278e4863,0x9a615bea,0x9ad7c8e5,0xbbdb4477,0x2ceac2fc,0x1c706630 }, + { 0x99699b4b,0x5e2b54c6,0x239e17e8,0xb509ca6d,0xea063a82,0x728165fe, + 0xb6a22e02,0x6b5e609d,0xb26ee1df,0x12813905,0x439491fa,0x07b9f722 } }, + /* 163 */ + { { 0x48ff4e49,0x1592ec14,0x6d644129,0x3e4e9f17,0x1156acc0,0x7acf8288, + 0xbb092b0b,0x5aa34ba8,0x7d38393d,0xcd0f9022,0xea4f8187,0x416724dd }, + { 0xc0139e73,0x3c4e641c,0x91e4d87d,0xe0fe46cf,0xcab61f8a,0xedb3c792, + 0xd3868753,0x4cb46de4,0x20f1098a,0xe449c21d,0xf5b8ea6e,0x5e5fd059 } }, + /* 164 */ + { { 0x75856031,0x7fcadd46,0xeaf2fbd0,0x89c7a4cd,0x7a87c480,0x1af523ce, + 0x61d9ae90,0xe5fc1095,0xbcdb95f5,0x3fb5864f,0xbb5b2c7d,0xbeb5188e }, + { 0x3ae65825,0x3d1563c3,0x0e57d641,0x116854c4,0x1942ebd3,0x11f73d34, + 0xc06955b3,0x24dc5904,0x995a0a62,0x8a0d4c83,0x5d577b7d,0xfb26b86d } }, + /* 165 */ + { { 0xc686ae17,0xc53108e7,0xd1c1da56,0x9090d739,0x9aec50ae,0x4583b013, + 0xa49a6ab2,0xdd9a088b,0xf382f850,0x28192eea,0xf5fe910e,0xcc8df756 }, + { 0x9cab7630,0x877823a3,0xfb8e7fc1,0x64984a9a,0x364bfc16,0x5448ef9c, + 0xc44e2a9a,0xbbb4f871,0x435c95e9,0x901a41ab,0xaaa50a06,0xc6c23e5f } }, + /* 166 */ + { { 0x9034d8dd,0xb78016c1,0x0b13e79b,0x856bb44b,0xb3241a05,0x85c6409a, + 0x2d78ed21,0x8d2fe19a,0x726eddf2,0xdcc7c26d,0x25104f04,0x3ccaff5f }, + { 0x6b21f843,0x397d7edc,0xe975de4c,0xda88e4dd,0x4f5ab69e,0x5273d396, + 0x9aae6cc0,0x537680e3,0x3e6f9461,0xf749cce5,0x957bffd3,0x021ddbd9 } }, + /* 167 */ + { { 0x777233cf,0x7b64585f,0x0942a6f0,0xfe6771f6,0xdfe6eef0,0x636aba7a, + 0x86038029,0x63bbeb56,0xde8fcf36,0xacee5842,0xd4a20524,0x48d9aa99 }, + { 0x0da5e57a,0xcff7a74c,0xe549d6c9,0xc232593c,0xf0f2287b,0x68504bcc, + 0xbc8360b5,0x6d7d098d,0x5b402f41,0xeac5f149,0xb87d1bf1,0x61936f11 } }, + /* 168 */ + { { 0xb8153a9d,0xaa9da167,0x9e83ecf0,0xa49fe3ac,0x1b661384,0x14c18f8e, + 0x38434de1,0x61c24dab,0x283dae96,0x3d973c3a,0x82754fc9,0xc99baa01 }, + { 0x4c26b1e3,0x477d198f,0xa7516202,0x12e8e186,0x362addfa,0x386e52f6, + 0xc3962853,0x31e8f695,0x6aaedb60,0xdec2af13,0x29cf74ac,0xfcfdb4c6 } }, + /* 169 */ + { { 0xcca40298,0x6b3ee958,0xf2f5d195,0xc3878153,0xed2eae5b,0x0c565630, + 0x3a697cf2,0xd089b37e,0xad5029ea,0xc2ed2ac7,0x0f0dda6a,0x7e5cdfad }, + { 0xd9b86202,0xf98426df,0x4335e054,0xed1960b1,0x3f14639e,0x1fdb0246, + 0x0db6c670,0x17f709c3,0x773421e1,0xbfc687ae,0x26c1a8ac,0x13fefc4a } }, + /* 170 */ + { { 0x7ffa0a5f,0xe361a198,0xc63fe109,0xf4b26102,0x6c74e111,0x264acbc5, + 0x77abebaf,0x4af445fa,0x24cddb75,0x448c4fdd,0x44506eea,0x0b13157d }, + { 0x72e9993d,0x22a6b159,0x85e5ecbe,0x2c3c57e4,0xfd83e1a1,0xa673560b, + 0xc3b8c83b,0x6be23f82,0x40bbe38e,0x40b13a96,0xad17399b,0x66eea033 } }, + /* 171 */ + { { 0xb4c6c693,0x49fc6e95,0x36af7d38,0xefc735de,0x35fe42fc,0xe053343d, + 0x6a9ab7c3,0xf0aa427c,0x4a0fcb24,0xc79f0436,0x93ebbc50,0x16287243 }, + { 0x16927e1e,0x5c3d6bd0,0x673b984c,0x40158ed2,0x4cd48b9a,0xa7f86fc8, + 0x60ea282d,0x1643eda6,0xe2a1beed,0x45b393ea,0x19571a94,0x664c839e } }, + /* 172 */ + { { 0x27eeaf94,0x57745750,0xea99e1e7,0x2875c925,0x5086adea,0xc127e7ba, + 0x86fe424f,0x765252a0,0x2b6c0281,0x1143cc6c,0xd671312d,0xc9bb2989 }, + { 0x51acb0a5,0x880c337c,0xd3c60f78,0xa3710915,0x9262b6ed,0x496113c0, + 0x9ce48182,0x5d25d9f8,0xb3813586,0x53b6ad72,0x4c0e159c,0x0ea3bebc } }, + /* 173 */ + { { 0xc5e49bea,0xcaba450a,0x7c05da59,0x684e5415,0xde7ac36c,0xa2e9cab9, + 0x2e6f957b,0x4ca79b5f,0x09b817b1,0xef7b0247,0x7d89df0f,0xeb304990 }, + { 0x46fe5096,0x508f7307,0x2e04eaaf,0x695810e8,0x3512f76c,0x88ef1bd9, + 0x3ebca06b,0x77661351,0xccf158b7,0xf7d4863a,0x94ee57da,0xb2a81e44 } }, + /* 174 */ + { { 0x6d53e6ba,0xff288e5b,0x14484ea2,0xa90de1a9,0xed33c8ec,0x2fadb60c, + 0x28b66a40,0x579d6ef3,0xec24372d,0x4f2dd6dd,0x1d66ec7d,0xe9e33fc9 }, + { 0x039eab6e,0x110899d2,0x3e97bb5e,0xa31a667a,0xcfdce68e,0x6200166d, + 0x5137d54b,0xbe83ebae,0x4800acdf,0x085f7d87,0x0c6f8c86,0xcf4ab133 } }, + /* 175 */ + { { 0x931e08fb,0x03f65845,0x1506e2c0,0x6438551e,0x9c36961f,0x5791f0dc, + 0xe3dcc916,0x68107b29,0xf495d2ca,0x83242374,0x6ee5895b,0xd8cfb663 }, + { 0xa0349b1b,0x525e0f16,0x4a0fab86,0x33cd2c6c,0x2af8dda9,0x46c12ee8, + 0x71e97ad3,0x7cc424ba,0x37621eb0,0x69766ddf,0xa5f0d390,0x95565f56 } }, + /* 176 */ + { { 0x1a0f5e94,0xe0e7bbf2,0x1d82d327,0xf771e115,0xceb111fa,0x10033e3d, + 0xd3426638,0xd269744d,0x00d01ef6,0xbdf2d9da,0xa049ceaf,0x1cb80c71 }, + { 0x9e21c677,0x17f18328,0x19c8f98b,0x6452af05,0x80b67997,0x35b9c5f7, + 0x40f8f3d4,0x5c2e1cbe,0x66d667ca,0x43f91656,0xcf9d6e79,0x9faaa059 } }, + /* 177 */ + { { 0x0a078fe6,0x8ad24618,0x464fd1dd,0xf6cc73e6,0xc3e37448,0x4d2ce34d, + 0xe3271b5f,0x624950c5,0xefc5af72,0x62910f5e,0xaa132bc6,0x8b585bf8 }, + { 0xa839327f,0x11723985,0x4aac252f,0x34e2d27d,0x6296cc4e,0x402f59ef, + 0x47053de9,0x00ae055c,0x28b4f09b,0xfc22a972,0xfa0c180e,0xa9e86264 } }, + /* 178 */ + { { 0xbc310ecc,0x0b7b6224,0x67fa14ed,0x8a1a74f1,0x7214395c,0x87dd0960, + 0xf5c91128,0xdf1b3d09,0x86b264a8,0x39ff23c6,0x3e58d4c5,0xdc2d49d0 }, + { 0xa9d6f501,0x2152b7d3,0xc04094f7,0xf4c32e24,0xd938990f,0xc6366596, + 0x94fb207f,0x084d078f,0x328594cb,0xfd99f1d7,0xcb2d96b3,0x36defa64 } }, + /* 179 */ + { { 0x13ed7cbe,0x4619b781,0x9784bd0e,0x95e50015,0x2c7705fe,0x2a32251c, + 0x5f0dd083,0xa376af99,0x0361a45b,0x55425c6c,0x1f291e7b,0x812d2cef }, + { 0x5fd94972,0xccf581a0,0xe56dc383,0x26e20e39,0x63dbfbf0,0x0093685d, + 0x36b8c575,0x1fc164cc,0x390ef5e7,0xb9c5ab81,0x26908c66,0x40086beb } }, + /* 180 */ + { { 0x37e3c115,0xe5e54f79,0xc1445a8a,0x69b8ee8c,0xb7659709,0x79aedff2, + 0x1b46fbe6,0xe288e163,0xd18d7bb7,0xdb4844f0,0x48aa6424,0xe0ea23d0 }, + { 0xf3d80a73,0x714c0e4e,0x3bd64f98,0x87a0aa9e,0x2ec63080,0x8844b8a8, + 0x255d81a3,0xe0ac9c30,0x455397fc,0x86151237,0x2f820155,0x0b979464 } }, + /* 181 */ + { { 0x4ae03080,0x127a255a,0x580a89fb,0x232306b4,0x6416f539,0x04e8cd6a, + 0x13b02a0e,0xaeb70dee,0x4c09684a,0xa3038cf8,0x28e433ee,0xa710ec3c }, + { 0x681b1f7d,0x77a72567,0x2fc28170,0x86fbce95,0xf5735ac8,0xd3408683, + 0x6bd68e93,0x3a324e2a,0xc027d155,0x7ec74353,0xd4427177,0xab60354c } }, + /* 182 */ + { { 0xef4c209d,0x32a5342a,0x08d62704,0x2ba75274,0xc825d5fe,0x4bb4af6f, + 0xd28e7ff1,0x1c3919ce,0xde0340f6,0x1dfc2fdc,0x29f33ba9,0xc6580baf }, + { 0x41d442cb,0xae121e75,0x3a4724e4,0x4c7727fd,0x524f3474,0xe556d6a4, + 0x785642a2,0x87e13cc7,0xa17845fd,0x182efbb1,0x4e144857,0xdcec0cf1 } }, + /* 183 */ + { { 0xe9539819,0x1cb89541,0x9d94dbf1,0xc8cb3b4f,0x417da578,0x1d353f63, + 0x8053a09e,0xb7a697fb,0xc35d8b78,0x8d841731,0xb656a7a9,0x85748d6f }, + { 0xc1859c5d,0x1fd03947,0x535d22a2,0x6ce965c1,0x0ca3aadc,0x1966a13e, + 0x4fb14eff,0x9802e41d,0x76dd3fcd,0xa9048cbb,0xe9455bba,0x89b182b5 } }, + /* 184 */ + { { 0x43360710,0xd777ad6a,0x55e9936b,0x841287ef,0x04a21b24,0xbaf5c670, + 0x35ad86f1,0xf2c0725f,0xc707e72e,0x338fa650,0xd8883e52,0x2bf8ed2e }, + { 0xb56e0d6a,0xb0212cf4,0x6843290c,0x50537e12,0x98b3dc6f,0xd8b184a1, + 0x0210b722,0xd2be9a35,0x559781ee,0x407406db,0x0bc18534,0x5a78d591 } }, + /* 185 */ + { { 0xd748b02c,0x4d57aa2a,0xa12b3b95,0xbe5b3451,0x64711258,0xadca7a45, + 0x322153db,0x597e091a,0x32eb1eab,0xf3271006,0x2873f301,0xbd9adcba }, + { 0x38543f7f,0xd1dc79d1,0x921b1fef,0x00022092,0x1e5df8ed,0x86db3ef5, + 0x9e6b944a,0x888cae04,0x791a32b4,0x71bd29ec,0xa6d1c13e,0xd3516206 } }, + /* 186 */ + { { 0x55924f43,0x2ef6b952,0x4f9de8d5,0xd2f401ae,0xadc68042,0xfc73e8d7, + 0x0d9d1bb4,0x627ea70c,0xbbf35679,0xc3bb3e3e,0xd882dee4,0x7e8a254a }, + { 0xb5924407,0x08906f50,0xa1ad444a,0xf14a0e61,0x65f3738e,0xaa0efa21, + 0xae71f161,0xd60c7dd6,0xf175894d,0x9e8390fa,0x149f4c00,0xd115cd20 } }, + /* 187 */ + { { 0xa52abf77,0x2f2e2c1d,0x54232568,0xc2a0dca5,0x54966dcc,0xed423ea2, + 0xcd0dd039,0xe48c93c7,0x176405c7,0x1e54a225,0x70d58f2e,0x1efb5b16 }, + { 0x94fb1471,0xa751f9d9,0x67d2941d,0xfdb31e1f,0x53733698,0xa6c74eb2, + 0x89a0f64a,0xd3155d11,0xa4b8d2b6,0x4414cfe4,0xf7a8e9e3,0x8d5a4be8 } }, + /* 188 */ + { { 0x52669e98,0x5c96b4d4,0x8fd42a03,0x4547f922,0xd285174e,0xcf5c1319, + 0x064bffa0,0x805cd1ae,0x246d27e7,0x50e8bc4f,0xd5781e11,0xf89ef98f }, + { 0xdee0b63f,0xb4ff95f6,0x222663a4,0xad850047,0x4d23ce9c,0x02691860, + 0x50019f59,0x3e5309ce,0x69a508ae,0x27e6f722,0x267ba52c,0xe9376652 } }, + /* 189 */ + { { 0xc0368708,0xa04d289c,0x5e306e1d,0xc458872f,0x33112fea,0x76fa23de, + 0x6efde42e,0x718e3974,0x1d206091,0xf0c98cdc,0x14a71987,0x5fa3ca62 }, + { 0xdcaa9f2a,0xeee8188b,0x589a860d,0x312cc732,0xc63aeb1f,0xf9808dd6, + 0x4ea62b53,0x70fd43db,0x890b6e97,0x2c2bfe34,0xfa426aa6,0x105f863c } }, + /* 190 */ + { { 0xb38059ad,0x0b29795d,0x90647ea0,0x5686b77e,0xdb473a3e,0xeff0470e, + 0xf9b6d1e2,0x278d2340,0xbd594ec7,0xebbff95b,0xd3a7f23d,0xf4b72334 }, + { 0xa5a83f0b,0x2a285980,0x9716a8b3,0x0786c41a,0x22511812,0x138901bd, + 0xe2fede6e,0xd1b55221,0xdf4eb590,0x0806e264,0x762e462e,0x6c4c897e } }, + /* 191 */ + { { 0xb4b41d9d,0xd10b905f,0x4523a65b,0x826ca466,0xb699fa37,0x535bbd13, + 0x73bc8f90,0x5b9933d7,0xcd2118ad,0x9332d61f,0xd4a65fd0,0x158c693e }, + { 0xe6806e63,0x4ddfb2a8,0xb5de651b,0xe31ed3ec,0x819bc69a,0xf9460e51, + 0x2c76b1f8,0x6229c0d6,0x901970a3,0xbb78f231,0x9cee72b8,0x31f3820f } }, + /* 192 */ + { { 0xc09e1c72,0xe931caf2,0x12990cf4,0x0715f298,0x943262d8,0x33aad81d, + 0x73048d3f,0x5d292b7a,0xdc7415f6,0xb152aaa4,0x0fd19587,0xc3d10fd9 }, + { 0x75ddadd0,0xf76b35c5,0x1e7b694c,0x9f5f4a51,0xc0663025,0x2f1ab7eb, + 0x920260b0,0x01c9cc87,0x05d39da6,0xc4b1f61a,0xeb4a9c4e,0x6dcd76c4 } }, + /* 193 */ + { { 0xfdc83f01,0x0ba0916f,0x9553e4f9,0x354c8b44,0xffc5e622,0xa6cc511a, + 0xe95be787,0xb954726a,0x75b41a62,0xcb048115,0xebfde989,0xfa2ae6cd }, + { 0x0f24659a,0x6376bbc7,0x4c289c43,0x13a999fd,0xec9abd8b,0xc7134184, + 0xa789ab04,0x28c02bf6,0xd3e526ec,0xff841ebc,0x640893a8,0x442b191e } }, + /* 194 */ + { { 0xfa2b6e20,0x4cac6c62,0xf6d69861,0x97f29e9b,0xbc96d12d,0x228ab1db, + 0x5e8e108d,0x6eb91327,0x40771245,0xd4b3d4d1,0xca8a803a,0x61b20623 }, + { 0xa6a560b1,0x2c2f3b41,0x3859fcf4,0x879e1d40,0x024dbfc3,0x7cdb5145, + 0x3bfa5315,0x55d08f15,0xaa93823a,0x2f57d773,0xc6a2c9a2,0xa97f259c } }, + /* 195 */ + { { 0xe58edbbb,0xc306317b,0x79dfdf13,0x25ade51c,0x16d83dd6,0x6b5beaf1, + 0x1dd8f925,0xe8038a44,0xb2a87b6b,0x7f00143c,0xf5b438de,0xa885d00d }, + { 0xcf9e48bd,0xe9f76790,0xa5162768,0xf0bdf9f0,0xad7b57cb,0x0436709f, + 0xf7c15db7,0x7e151c12,0x5d90ee3b,0x3514f022,0x2c361a8d,0x2e84e803 } }, + /* 196 */ + { { 0x563ec8d8,0x2277607d,0xe3934cb7,0xa661811f,0xf58fd5de,0x3ca72e7a, + 0x62294c6a,0x7989da04,0xf6bbefe9,0x88b3708b,0x53ed7c82,0x0d524cf7 }, + { 0x2f30c073,0x69f699ca,0x9dc1dcf3,0xf0fa264b,0x05f0aaf6,0x44ca4568, + 0xd19b9baf,0x0f5b23c7,0xeabd1107,0x39193f41,0x2a7c9b83,0x9e3e10ad } }, + /* 197 */ + { { 0xd4ae972f,0xa90824f0,0xc6e846e7,0x43eef02b,0x29d2160a,0x7e460612, + 0xfe604e91,0x29a178ac,0x4eb184b2,0x23056f04,0xeb54cdf4,0x4fcad55f }, + { 0xae728d15,0xa0ff96f3,0xc6a00331,0x8a2680c6,0x7ee52556,0x5f84cae0, + 0xc5a65dad,0x5e462c3a,0xe2d23f4f,0x5d2b81df,0xc5b1eb07,0x6e47301b } }, + /* 198 */ + { { 0xaf8219b9,0x77411d68,0x51b1907a,0xcb883ce6,0x101383b5,0x25c87e57, + 0x982f970d,0x9c7d9859,0x118305d2,0xaa6abca5,0x9013a5db,0x725fed2f }, + { 0xababd109,0x487cdbaf,0x87586528,0xc0f8cf56,0x8ad58254,0xa02591e6, + 0xdebbd526,0xc071b1d1,0x961e7e31,0x927dfe8b,0x9263dfe1,0x55f895f9 } }, + /* 199 */ + { { 0xb175645b,0xf899b00d,0xb65b4b92,0x51f3a627,0xb67399ef,0xa2f3ac8d, + 0xe400bc20,0xe717867f,0x1967b952,0x42cc9020,0x3ecd1de1,0x3d596751 }, + { 0xdb979775,0xd41ebcde,0x6a2e7e88,0x99ba61bc,0x321504f2,0x039149a5, + 0x27ba2fad,0xe7dc2314,0xb57d8368,0x9f556308,0x57da80a7,0x2b6d16c9 } }, + /* 200 */ + { { 0x279ad982,0x84af5e76,0x9c8b81a6,0x9bb4c92d,0x0e698e67,0xd79ad44e, + 0x265fc167,0xe8be9048,0x0c3a4ccc,0xf135f7e6,0xb8863a33,0xa0a10d38 }, + { 0xd386efd9,0xe197247c,0xb52346c2,0x0eefd3f9,0x78607bc8,0xc22415f9, + 0x508674ce,0xa2a8f862,0xc8c9d607,0xa72ad09e,0x50fa764f,0xcd9f0ede } }, + /* 201 */ + { { 0xd1a46d4d,0x063391c7,0x9eb01693,0x2df51c11,0x849e83de,0xc5849800, + 0x8ad08382,0x48fd09aa,0xaa742736,0xa405d873,0xe1f9600c,0xee49e61e }, + { 0x48c76f73,0xd76676be,0x01274b2a,0xd9c100f6,0x83f8718d,0x110bb67c, + 0x02fc0d73,0xec85a420,0x744656ad,0xc0449e1e,0x37d9939b,0x28ce7376 } }, + /* 202 */ + { { 0x44544ac7,0x97e9af72,0xba010426,0xf2c658d5,0xfb3adfbd,0x732dec39, + 0xa2df0b07,0xd12faf91,0x2171e208,0x8ac26725,0x5b24fa54,0xf820cdc8 }, + { 0x94f4cf77,0x307a6eea,0x944a33c6,0x18c783d2,0x0b741ac5,0x4b939d4c, + 0x3ffbb6e4,0x1d7acd15,0x7a255e44,0x06a24858,0xce336d50,0x14fbc494 } }, + /* 203 */ + { { 0x51584e3c,0x9b920c0c,0xf7e54027,0xc7733c59,0x88422bbe,0xe24ce139, + 0x523bd6ab,0x11ada812,0xb88e6def,0xde068800,0xfe8c582d,0x7b872671 }, + { 0x7de53510,0x4e746f28,0xf7971968,0x492f8b99,0x7d928ac2,0x1ec80bc7, + 0x432eb1b5,0xb3913e48,0x32028f6e,0xad084866,0x8fc2f38b,0x122bb835 } }, + /* 204 */ + { { 0x3b0b29c3,0x0a9f3b1e,0x4fa44151,0x837b6432,0x17b28ea7,0xb9905c92, + 0x98451750,0xf39bc937,0xce8b6da1,0xcd383c24,0x010620b2,0x299f57db }, + { 0x58afdce3,0x7b6ac396,0x3d05ef47,0xa15206b3,0xb9bb02ff,0xa0ae37e2, + 0x9db3964c,0x107760ab,0x67954bea,0xe29de9a0,0x431c3f82,0x446a1ad8 } }, + /* 205 */ + { { 0x5c6b8195,0xc6fecea0,0xf49e71b9,0xd744a7c5,0x177a7ae7,0xa8e96acc, + 0x358773a7,0x1a05746c,0x37567369,0xa4162146,0x87d1c971,0xaa0217f7 }, + { 0x77fd3226,0x61e9d158,0xe4f600be,0x0f6f2304,0x7a6dff07,0xa9c4cebc, + 0x09f12a24,0xd15afa01,0x8c863ee9,0x2bbadb22,0xe5eb8c78,0xa28290e4 } }, + /* 206 */ + { { 0x3e9de330,0x55b87fa0,0x195c145b,0x12b26066,0xa920bef0,0xe08536e0, + 0x4d195adc,0x7bff6f2c,0x945f4187,0x7f319e9d,0xf892ce47,0xf9848863 }, + { 0x4fe37657,0xd0efc1d3,0x5cf0e45a,0x3c58de82,0x8b0ccbbe,0x626ad21a, + 0xaf952fc5,0xd2a31208,0xeb437357,0x81791995,0x98e95d4f,0x5f19d30f } }, + /* 207 */ + { { 0x0e6865bb,0x72e83d9a,0xf63456a6,0x22f5af3b,0x463c8d9e,0x409e9c73, + 0xdfe6970e,0x40e9e578,0x711b91ca,0x876b6efa,0x942625a3,0x895512cf }, + { 0xcb4e462b,0x84c8eda8,0x4412e7c8,0x84c0154a,0xceb7b71f,0x04325db1, + 0x66f70877,0x1537dde3,0x1992b9ac,0xf3a09399,0xd498ae77,0xa7316606 } }, + /* 208 */ + { { 0xcad260f5,0x13990d2f,0xeec0e8c0,0x76c3be29,0x0f7bd7d5,0x7dc5bee0, + 0xefebda4b,0x9be167d2,0x9122b87e,0xcce3dde6,0x82b5415c,0x75a28b09 }, + { 0xe84607a6,0xf6810bcd,0x6f4dbf0d,0xc6d58128,0x1b4dafeb,0xfead577d, + 0x066b28eb,0x9bc440b2,0x8b17e84b,0x53f1da97,0xcda9a575,0x0459504b } }, + /* 209 */ + { { 0x329e5836,0x13e39a02,0xf717269d,0x2c9e7d51,0xf26c963b,0xc5ac58d6, + 0x79967bf5,0x3b0c6c43,0x55908d9d,0x60bbea3f,0xf07c9ad1,0xd84811e7 }, + { 0x5bd20e4a,0xfe7609a7,0x0a70baa8,0xe4325dd2,0xb3600386,0x3711f370, + 0xd0924302,0x97f9562f,0x4acc4436,0x040dc0c3,0xde79cdd4,0xfd6d725c } }, + /* 210 */ + { { 0xcf13eafb,0xb3efd0e3,0x5aa0ae5f,0x21009cbb,0x79022279,0xe480c553, + 0xb2fc9a6d,0x755cf334,0x07096ae7,0x8564a5bf,0xbd238139,0xddd649d0 }, + { 0x8a045041,0xd0de10b1,0xc957d572,0x6e05b413,0x4e0fb25c,0x5c5ff806, + 0x641162fb,0xd933179b,0xe57439f9,0x42d48485,0x8a8d72aa,0x70c5bd0a } }, + /* 211 */ + { { 0x97bdf646,0xa7671738,0xab329f7c,0xaa1485b4,0xf8f25fdf,0xce3e11d6, + 0xc6221824,0x76a3fc7e,0xf3924740,0x045f281f,0x96d13a9a,0x24557d4e }, + { 0xdd4c27cd,0x875c804b,0x0f5c7fea,0x11c5f0f4,0xdc55ff7e,0xac8c880b, + 0x1103f101,0x2acddec5,0xf99faa89,0x38341a21,0xce9d6b57,0xc7b67a2c } }, + /* 212 */ + { { 0x8e357586,0x9a0d724f,0xdf648da0,0x1d7f4ff5,0xfdee62a5,0x9c3e6c9b, + 0x0389b372,0x0499cef0,0x98eab879,0xe904050d,0x6c051617,0xe8eef1b6 }, + { 0xc37e3ca9,0xebf5bfeb,0xa4e0b91d,0x7c5e946d,0x2c4bea28,0x79097314, + 0xee67b2b7,0x81f6c109,0xdafc5ede,0xaf237d9b,0x2abb04c7,0xd2e60201 } }, + /* 213 */ + { { 0x8a4f57bf,0x6156060c,0xff11182a,0xf9758696,0x6296ef00,0x8336773c, + 0xff666899,0x9c054bce,0x719cd11c,0xd6a11611,0xdbe1acfa,0x9824a641 }, + { 0xba89fd01,0x0b7b7a5f,0x889f79d8,0xf8d3b809,0xf578285c,0xc5e1ea08, + 0xae6d8288,0x7ac74536,0x7521ef5f,0x5d37a200,0xb260a25d,0x5ecc4184 } }, + /* 214 */ + { { 0xa708c8d3,0xddcebb19,0xc63f81ec,0xe63ed04f,0x11873f95,0xd045f5a0, + 0x79f276d5,0x3b5ad544,0x425ae5b3,0x81272a3d,0x10ce1605,0x8bfeb501 }, + { 0x888228bf,0x4233809c,0xb2aff7df,0x4bd82acf,0x0cbd4a7f,0x9c68f180, + 0x6b44323d,0xfcd77124,0x891db957,0x60c0fcf6,0x04da8f7f,0xcfbb4d89 } }, + /* 215 */ + { { 0x3b26139a,0x9a6a5df9,0xb2cc7eb8,0x3e076a83,0x5a964bcd,0x47a8e82d, + 0xb9278d6b,0x8a4e2a39,0xe4443549,0x93506c98,0xf1e0d566,0x06497a8f }, + { 0x2b1efa05,0x3dee8d99,0x45393e33,0x2da63ca8,0xcf0579ad,0xa4af7277, + 0x3236d8ea,0xaf4b4639,0x32b617f5,0x6ccad95b,0xb88bb124,0xce76d8b8 } }, + /* 216 */ + { { 0x083843dc,0x63d2537a,0x1e4153b4,0x89eb3514,0xea9afc94,0x5175ebc4, + 0x8ed1aed7,0x7a652580,0xd85e8297,0x67295611,0xb584b73d,0x8dd2d68b }, + { 0x0133c3a4,0x237139e6,0x4bd278ea,0x9de838ab,0xc062fcd9,0xe829b072, + 0x63ba8706,0x70730d4f,0xd3cd05ec,0x6080483f,0x0c85f84d,0x872ab5b8 } }, + /* 217 */ + { { 0x999d4d49,0xfc0776d3,0xec3f45e7,0xa3eb59de,0x0dae1fc1,0xbc990e44, + 0xa15371ff,0x33596b1e,0x9bc7ab25,0xd447dcb2,0x35979582,0xcd5b63e9 }, + { 0x77d1ff11,0xae3366fa,0xedee6903,0x59f28f05,0xa4433bf2,0x6f43fed1, + 0xdf9ce00e,0x15409c9b,0xaca9c5dc,0x21b5cded,0x82d7bdb4,0xf9f33595 } }, + /* 218 */ + { { 0x9422c792,0x95944378,0xc958b8bf,0x239ea923,0xdf076541,0x4b61a247, + 0xbb9fc544,0x4d29ce85,0x0b424559,0x9a692a67,0x0e486900,0x6e0ca5a0 }, + { 0x85b3bece,0x6b79a782,0xc61f9892,0x41f35e39,0xae747f82,0xff82099a, + 0xd0ca59d6,0x58c8ae3f,0x99406b5f,0x4ac930e2,0x9df24243,0x2ce04eb9 } }, + /* 219 */ + { { 0x1ac37b82,0x4366b994,0x25b04d83,0xff0c728d,0x19c47b7c,0x1f551361, + 0xbeff13e7,0xdbf2d5ed,0xe12a683d,0xf78efd51,0x989cf9c4,0x82cd85b9 }, + { 0xe0cb5d37,0xe23c6db6,0x72ee1a15,0x818aeebd,0x28771b14,0x8212aafd, + 0x1def817d,0x7bc221d9,0x9445c51f,0xdac403a2,0x12c3746b,0x711b0517 } }, + /* 220 */ + { { 0x5ea99ecc,0x0ed9ed48,0xb8cab5e1,0xf799500d,0xb570cbdc,0xa8ec87dc, + 0xd35dfaec,0x52cfb2c2,0x6e4d80a4,0x8d31fae2,0xdcdeabe5,0xe6a37dc9 }, + { 0x1deca452,0x5d365a34,0x0d68b44e,0x09a5f8a5,0xa60744b1,0x59238ea5, + 0xbb4249e9,0xf2fedc0d,0xa909b2e3,0xe395c74e,0x39388250,0xe156d1a5 } }, + /* 221 */ + { { 0x47181ae9,0xd796b3d0,0x44197808,0xbaf44ba8,0x34cf3fac,0xe6933094, + 0xc3bd5c46,0x41aa6ade,0xeed947c6,0x4fda75d8,0x9ea5a525,0xacd9d412 }, + { 0xd430301b,0x65cc55a3,0x7b52ea49,0x3c9a5bcf,0x159507f0,0x22d319cf, + 0xde74a8dd,0x2ee0b9b5,0x877ac2b6,0x20c26a1e,0x92e7c314,0x387d73da } }, + /* 222 */ + { { 0x8cd3fdac,0x13c4833e,0x332e5b8e,0x76fcd473,0xe2fe1fd3,0xff671b4b, + 0x5d98d8ec,0x4d734e8b,0x514bbc11,0xb1ead3c6,0x7b390494,0xd14ca858 }, + { 0x5d2d37e9,0x95a443af,0x00464622,0x73c6ea73,0x15755044,0xa44aeb4b, + 0xfab58fee,0xba3f8575,0xdc680a6f,0x9779dbc9,0x7b37ddfc,0xe1ee5f5a } }, + /* 223 */ + { { 0x12d29f46,0xcd0b4648,0x0ed53137,0x93295b0b,0x80bef6c9,0xbfe26094, + 0x54248b00,0xa6565788,0x80e7f9c4,0x69c43fca,0xbe141ea1,0x2190837b }, + { 0xa1b26cfb,0x875e159a,0x7affe852,0x90ca9f87,0x92ca598e,0x15e6550d, + 0x1938ad11,0xe3e0945d,0x366ef937,0xef7636bb,0xb39869e5,0xb6034d0b } }, + /* 224 */ + { { 0x26d8356e,0x4d255e30,0xd314626f,0xf83666ed,0xd0c8ed64,0x421ddf61, + 0x26677b61,0x96e473c5,0x9e9b18b3,0xdad4af7e,0xa9393f75,0xfceffd4a }, + { 0x11c731d5,0x843138a1,0xb2f141d9,0x05bcb3a1,0x617b7671,0x20e1fa95, + 0x88ccec7b,0xbefce812,0x90f1b568,0x582073dc,0x1f055cb7,0xf572261a } }, + /* 225 */ + { { 0x36973088,0xf3148277,0x86a9f980,0xc008e708,0xe046c261,0x1b795947, + 0xca76bca0,0xdf1e6a7d,0x71acddf0,0xabafd886,0x1364d8f4,0xff7054d9 }, + { 0xe2260594,0x2cf63547,0xd73b277e,0x468a5372,0xef9bd35e,0xc7419e24, + 0x24043cc3,0x2b4a1c20,0x890b39cd,0xa28f047a,0x46f9a2e3,0xdca2cea1 } }, + /* 226 */ + { { 0x53277538,0xab788736,0xcf697738,0xa734e225,0x6b22e2c1,0x66ee1d1e, + 0xebe1d212,0x2c615389,0x02bb0766,0xf36cad40,0x3e64f207,0x120885c3 }, + { 0x90fbfec2,0x59e77d56,0xd7a574ae,0xf9e781aa,0x5d045e53,0x801410b0, + 0xa91b5f0e,0xd3b5f0aa,0x7fbb3521,0xb3d1df00,0xc72bee9a,0x11c4b33e } }, + /* 227 */ + { { 0x83c3a7f3,0xd32b9832,0x88d8a354,0x8083abcf,0x50f4ec5a,0xdeb16404, + 0x641e2907,0x18d747f0,0xf1bbf03e,0x4e8978ae,0x88a0cd89,0x932447dc }, + { 0xcf3d5897,0x561e0feb,0x13600e6d,0xfc3a682f,0xd16a6b73,0xc78b9d73, + 0xd29bf580,0xe713fede,0x08d69e5c,0x0a225223,0x1ff7fda4,0x3a924a57 } }, + /* 228 */ + { { 0xb4093bee,0xfb64554c,0xa58c6ec0,0xa6d65a25,0x43d0ed37,0x4126994d, + 0x55152d44,0xa5689a51,0x284caa8d,0xb8e5ea8c,0xd1f25538,0x33f05d4f }, + { 0x1b615d6e,0xe0fdfe09,0x705507da,0x2ded7e8f,0x17bbcc80,0xdd5631e5, + 0x267fd11f,0x4f87453e,0xff89d62d,0xc6da723f,0xe3cda21d,0x55cbcae2 } }, + /* 229 */ + { { 0x6b4e84f3,0x336bc94e,0x4ef72c35,0x72863031,0xeeb57f99,0x6d85fdee, + 0xa42ece1b,0x7f4e3272,0x36f0320a,0x7f86cbb5,0x923331e6,0xf09b6a2b }, + { 0x56778435,0x21d3ecf1,0x8323b2d2,0x2977ba99,0x1704bc0f,0x6a1b57fb, + 0x389f048a,0xd777cf8b,0xac6b42cd,0x9ce2174f,0x09e6c55a,0x404e2bff } }, + /* 230 */ + { { 0x204c5ddb,0x9b9b135e,0x3eff550e,0x9dbfe044,0xec3be0f6,0x35eab4bf, + 0x0a43e56f,0x8b4c3f0d,0x0e73f9b3,0x4c1c6673,0x2c78c905,0x92ed38bd }, + { 0xa386e27c,0xc7003f6a,0xaced8507,0xb9c4f46f,0x59df5464,0xea024ec8, + 0x429572ea,0x4af96152,0xe1fc1194,0x279cd5e2,0x281e358c,0xaa376a03 } }, + /* 231 */ + { { 0x3cdbc95c,0x07859223,0xef2e337a,0xaae1aa6a,0x472a8544,0xc040108d, + 0x8d037b7d,0x80c853e6,0x8c7eee24,0xd221315c,0x8ee47752,0x195d3856 }, + { 0xdacd7fbe,0xd4b1ba03,0xd3e0c52b,0x4b5ac61e,0x6aab7b52,0x68d3c052, + 0x660e3fea,0xf0d7248c,0x3145efb4,0xafdb3f89,0x8f40936d,0xa73fd9a3 } }, + /* 232 */ + { { 0xbb1b17ce,0x891b9ef3,0xc6127f31,0x14023667,0x305521fd,0x12b2e58d, + 0xe3508088,0x3a47e449,0xff751507,0xe49fc84b,0x5310d16e,0x4023f722 }, + { 0xb73399fa,0xa608e5ed,0xd532aa3e,0xf12632d8,0x845e8415,0x13a2758e, + 0x1fc2d861,0xae4b6f85,0x339d02f2,0x3879f5b1,0x80d99ebd,0x446d22a6 } }, + /* 233 */ + { { 0x4be164f1,0x0f502302,0x88b81920,0x8d09d2d6,0x984aceff,0x514056f1, + 0x75e9e80d,0xa5c4ddf0,0xdf496a93,0x38cb47e6,0x38df6bf7,0x899e1d6b }, + { 0xb59eb2a6,0x69e87e88,0x9b47f38b,0x280d9d63,0x3654e955,0x599411ea, + 0x969aa581,0xcf8dd4fd,0x530742a7,0xff5c2baf,0x1a373085,0xa4391536 } }, + /* 234 */ + { { 0xa8a4bdd2,0x6ace72a3,0xb68ef702,0xc656cdd1,0x90c4dad8,0xd4a33e7e, + 0x9d951c50,0x4aece08a,0x085d68e6,0xea8005ae,0x6f7502b8,0xfdd7a7d7 }, + { 0x98d6fa45,0xce6fb0a6,0x1104eb8c,0x228f8672,0xda09d7dc,0xd23d8787, + 0x2ae93065,0x5521428b,0xea56c366,0x95faba3d,0x0a88aca5,0xedbe5039 } }, + /* 235 */ + { { 0xbfb26c82,0xd64da0ad,0x952c2f9c,0xe5d70b3c,0xf7e77f68,0xf5e8f365, + 0x08f2d695,0x7234e002,0xd12e7be6,0xfaf900ee,0x4acf734e,0x27dc6934 }, + { 0xc260a46a,0x80e4ff5e,0x2dc31c28,0x7da5ebce,0xca69f552,0x485c5d73, + 0x69cc84c2,0xcdfb6b29,0xed6d4eca,0x031c5afe,0x22247637,0xc7bbf4c8 } }, + /* 236 */ + { { 0x49fe01b2,0x9d5b72c7,0x793a91b8,0x34785186,0xcf460438,0xa3ba3c54, + 0x3ab21b6f,0x73e8e43d,0xbe57b8ab,0x50cde8e0,0xdd204264,0x6488b3a7 }, + { 0xdddc4582,0xa9e398b3,0x5bec46fe,0x1698c1a9,0x156d3843,0x7f1446ef, + 0x770329a2,0x3fd25dd8,0x2c710668,0x05b1221a,0xa72ee6cf,0x65b2dc2a } }, + /* 237 */ + { { 0xcd021d63,0x21a885f7,0xfea61f08,0x3f344b15,0xc5cf73e6,0xad5ba6dd, + 0x227a8b23,0x154d0d8f,0xdc559311,0x9b74373c,0x98620fa1,0x4feab715 }, + { 0x7d9ec924,0x5098938e,0x6d47e550,0x84d54a5e,0x1b617506,0x1a2d1bdc, + 0x615868a4,0x99fe1782,0x3005a924,0x171da780,0x7d8f79b6,0xa70bf5ed } }, + /* 238 */ + { { 0xfe2216c5,0x0bc1250d,0x7601b351,0x2c37e250,0xd6f06b7e,0xb6300175, + 0x8bfeb9b7,0x4dde8ca1,0xb82f843d,0x4f210432,0xb1ac0afd,0x8d70e2f9 }, + { 0xaae91abb,0x25c73b78,0x863028f2,0x0230dca3,0xe5cf30b7,0x8b923ecf, + 0x5506f265,0xed754ec2,0x729a5e39,0x8e41b88c,0xbabf889b,0xee67cec2 } }, + /* 239 */ + { { 0x1be46c65,0xe183acf5,0xe7565d7a,0x9789538f,0xd9627b4e,0x87873391, + 0x9f1d9187,0xbf4ac4c1,0x4691f5c8,0x5db99f63,0x74a1fb98,0xa68df803 }, + { 0xbf92b5fa,0x3c448ed1,0x3e0bdc32,0xa098c841,0x79bf016c,0x8e74cd55, + 0x115e244d,0x5df0d09c,0x3410b66e,0x9418ad01,0x17a02130,0x8b6124cb } }, + /* 240 */ + { { 0xc26e3392,0x425ec3af,0xa1722e00,0xc07f8470,0xe2356b43,0xdcc28190, + 0xb1ef59a6,0x4ed97dff,0xc63028c1,0xc22b3ad1,0x68c18988,0x070723c2 }, + { 0x4cf49e7d,0x70da302f,0x3f12a522,0xc5e87c93,0x18594148,0x74acdd1d, + 0xca74124c,0xad5f73ab,0xd69fd478,0xe72e4a3e,0x7b117cc3,0x61593868 } }, + /* 241 */ + { { 0xa9aa0486,0x7b7b9577,0xa063d557,0x6e41fb35,0xda9047d7,0xb017d5c7, + 0x68a87ba9,0x8c748280,0xdf08ad93,0xab45fa5c,0x4c288a28,0xcd9fb217 }, + { 0x5747843d,0x59544642,0xa56111e3,0x34d64c6c,0x4bfce8d5,0x12e47ea1, + 0x6169267f,0x17740e05,0xeed03fb5,0x5c49438e,0x4fc3f513,0x9da30add } }, + /* 242 */ + { { 0xccfa5200,0xc4e85282,0x6a19b13d,0x2707608f,0xf5726e2f,0xdcb9a53d, + 0xe9427de5,0x612407c9,0xd54d582a,0x3e5a17e1,0x655ae118,0xb99877de }, + { 0x015254de,0x6f0e972b,0xf0a6f7c5,0x92a56db1,0xa656f8b2,0xd297e4e1, + 0xad981983,0x99fe0052,0x07cfed84,0xd3652d2f,0x843c1738,0xc784352e } }, + /* 243 */ + { { 0x7e9b2d8a,0x6ee90af0,0x57cf1964,0xac8d7018,0x71f28efc,0xf6ed9031, + 0x6812b20e,0x7f70d5a9,0xf1c61eee,0x27b557f4,0xc6263758,0xf1c9bd57 }, + { 0x2a1a6194,0x5cf7d014,0x1890ab84,0xdd614e0b,0x0e93c2a6,0x3ef9de10, + 0xe0cd91c5,0xf98cf575,0x14befc32,0x504ec0c6,0x6279d68c,0xd0513a66 } }, + /* 244 */ + { { 0xa859fb6a,0xa8eadbad,0xdb283666,0xcf8346e7,0x3e22e355,0x7b35e61a, + 0x99639c6b,0x293ece2c,0x56f241c8,0xfa0162e2,0xbf7a1dda,0xd2e6c7b9 }, + { 0x40075e63,0xd0de6253,0xf9ec8286,0x2405aa61,0x8fe45494,0x2237830a, + 0x364e9c8c,0x4fd01ac7,0x904ba750,0x4d9c3d21,0xaf1b520b,0xd589be14 } }, + /* 245 */ + { { 0x4662e53b,0x13576a4f,0xf9077676,0x35ec2f51,0x97c0af97,0x66297d13, + 0x9e598b58,0xed3201fe,0x5e70f604,0x49bc752a,0xbb12d951,0xb54af535 }, + { 0x212c1c76,0x36ea4c2b,0xeb250dfd,0x18f5bbc7,0x9a0a1a46,0xa0d466cc, + 0xdac2d917,0x52564da4,0x8e95fab5,0x206559f4,0x9ca67a33,0x7487c190 } }, + /* 246 */ + { { 0xdde98e9c,0x75abfe37,0x2a411199,0x99b90b26,0xdcdb1f7c,0x1b410996, + 0x8b3b5675,0xab346f11,0xf1f8ae1e,0x04852193,0x6b8b98c1,0x1ec4d227 }, + { 0x45452baa,0xba3bc926,0xacc4a572,0x387d1858,0xe51f171e,0x9478eff6, + 0x931e1c00,0xf357077d,0xe54c8ca8,0xffee77cd,0x551dc9a4,0xfb4892ff } }, + /* 247 */ + { { 0x2db8dff8,0x5b1bdad0,0x5a2285a2,0xd462f4fd,0xda00b461,0x1d6aad8e, + 0x41306d1b,0x43fbefcf,0x6a13fe19,0x428e86f3,0x17f89404,0xc8b2f118 }, + { 0xf0d51afb,0x762528aa,0x549b1d06,0xa3e2fea4,0xea3ddf66,0x86fad8f2, + 0x4fbdd206,0x0d9ccc4b,0xc189ff5a,0xcde97d4c,0x199f19a6,0xc36793d6 } }, + /* 248 */ + { { 0x51b85197,0xea38909b,0xb4c92895,0xffb17dd0,0x1ddb3f3f,0x0eb0878b, + 0xc57cf0f2,0xb05d28ff,0x1abd57e2,0xd8bde2e7,0xc40c1b20,0x7f2be28d }, + { 0x299a2d48,0x6554dca2,0x8377982d,0x5130ba2e,0x1071971a,0x8863205f, + 0x7cf2825d,0x15ee6282,0x03748f2b,0xd4b6c57f,0x430385a0,0xa9e3f4da } }, + /* 249 */ + { { 0x83fbc9c6,0x33eb7cec,0x4541777e,0x24a311c7,0x4f0767fc,0xc81377f7, + 0x4ab702da,0x12adae36,0x2a779696,0xb7fcb6db,0x01cea6ad,0x4a6fb284 }, + { 0xcdfc73de,0x5e8b1d2a,0x1b02fd32,0xd0efae8d,0xd81d8519,0x3f99c190, + 0xfc808971,0x3c18f7fa,0x51b7ae7b,0x41f713e7,0xf07fc3f8,0x0a4b3435 } }, + /* 250 */ + { { 0x019b7d2e,0x7dda3c4c,0xd4dc4b89,0x631c8d1a,0x1cdb313c,0x5489cd6e, + 0x4c07bb06,0xd44aed10,0x75f000d1,0x8f97e13a,0xdda5df4d,0x0e9ee64f }, + { 0x3e346910,0xeaa99f3b,0xfa294ad7,0x622f6921,0x0d0b2fe9,0x22aaa20d, + 0x1e5881ba,0x4fed2f99,0xc1571802,0x9af3b2d6,0xdc7ee17c,0x919e67a8 } }, + /* 251 */ + { { 0x76250533,0xc724fe4c,0x7d817ef8,0x8a2080e5,0x172c9751,0xa2afb0f4, + 0x17c0702e,0x9b10cdeb,0xc9b7e3e9,0xbf3975e3,0x1cd0cdc5,0x206117df }, + { 0xbe05ebd5,0xfb049e61,0x16c782c0,0xeb0bb55c,0xab7fed09,0x13a331b8, + 0x632863f0,0xf6c58b1d,0x4d3b6195,0x6264ef6e,0x9a53f116,0x92c51b63 } }, + /* 252 */ + { { 0x288b364d,0xa57c7bc8,0x7b41e5c4,0x4a562e08,0x698a9a11,0x699d21c6, + 0xf3f849b9,0xa4ed9581,0x9eb726ba,0xa223eef3,0xcc2884f9,0x13159c23 }, + { 0x3a3f4963,0x73931e58,0x0ada6a81,0x96500389,0x5ab2950b,0x3ee8a1c6, + 0x775fab52,0xeedf4949,0x4f2671b6,0x63d652e1,0x3c4e2f55,0xfed4491c } }, + /* 253 */ + { { 0xf4eb453e,0x335eadc3,0xcadd1a5b,0x5ff74b63,0x5d84a91a,0x6933d0d7, + 0xb49ba337,0x9ca3eeb9,0xc04c15b8,0x1f6facce,0xdc09a7e4,0x4ef19326 }, + { 0x3dca3233,0x53d2d324,0xa2259d4b,0x0ee40590,0x5546f002,0x18c22edb, + 0x09ea6b71,0x92429801,0xb0e91e61,0xaada0add,0x99963c50,0x5fe53ef4 } }, + /* 254 */ + { { 0x90c28c65,0x372dd06b,0x119ce47d,0x1765242c,0x6b22fc82,0xc041fb80, + 0xb0a7ccc1,0x667edf07,0x1261bece,0xc79599e7,0x19cff22a,0xbc69d9ba }, + { 0x13c06819,0x009d77cd,0xe282b79d,0x635a66ae,0x225b1be8,0x4edac4a6, + 0x524008f9,0x57d4f4e4,0xb056af84,0xee299ac5,0x3a0bc386,0xcc38444c } }, + /* 255 */ + { { 0xcd4c2356,0x490643b1,0x750547be,0x740a4851,0xd4944c04,0x643eaf29, + 0x299a98a0,0xba572479,0xee05fdf9,0x48b29f16,0x089b2d7b,0x33fb4f61 }, + { 0xa950f955,0x86704902,0xfedc3ddf,0x97e1034d,0x05fbb6a2,0x211320b6, + 0x432299bb,0x23d7b93f,0x8590e4a3,0x1fe1a057,0xf58c0ce6,0x8e1d0586 } }, +}; + +/* 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. + * 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_12(sp_point_384* r, const sp_digit* k, + int map, void* heap) +{ + return sp_384_ecc_mulmod_stripe_12(r, &p384_base, p384_table, + k, map, heap); +} + +#endif + +/* Multiply the base point of P384 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_384(mp_int* km, ecc_point* r, int map, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 p; + sp_digit kd[12]; +#endif + sp_point_384* point; + sp_digit* k = NULL; + int err = MP_OKAY; + + err = sp_384_point_new_12(heap, p, point); +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 12, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + } +#else + k = kd; +#endif + if (err == MP_OKAY) { + sp_384_from_mp(k, 12, km); + + err = sp_384_ecc_mulmod_base_12(point, k, map, heap); + } + if (err == MP_OKAY) { + err = sp_384_point_to_ecc_point_12(point, r); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + 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. + * Implementation is constant time. + * + * a Number to check. + * returns 1 if the number is zero and 0 otherwise. + */ +static int sp_384_iszero_12(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]) == 0; +} + +#endif /* WOLFSSL_VALIDATE_ECC_KEYGEN || HAVE_ECC_SIGN || HAVE_ECC_VERIFY */ +/* Add 1 to a. (a = a + 1) + * + * a A single precision integer. + */ +SP_NOINLINE static void sp_384_add_one_12(sp_digit* a) +{ + __asm__ __volatile__ ( + "mov r2, #1\n\t" + "ldr r1, [%[a], #0]\n\t" + "adds r1, r1, r2\n\t" + "mov r2, #0\n\t" + "str r1, [%[a], #0]\n\t" + "ldr r1, [%[a], #4]\n\t" + "adcs r1, r1, r2\n\t" + "str r1, [%[a], #4]\n\t" + "ldr r1, [%[a], #8]\n\t" + "adcs r1, r1, r2\n\t" + "str r1, [%[a], #8]\n\t" + "ldr r1, [%[a], #12]\n\t" + "adcs r1, r1, r2\n\t" + "str r1, [%[a], #12]\n\t" + "ldr r1, [%[a], #16]\n\t" + "adcs r1, r1, r2\n\t" + "str r1, [%[a], #16]\n\t" + "ldr r1, [%[a], #20]\n\t" + "adcs r1, r1, r2\n\t" + "str r1, [%[a], #20]\n\t" + "ldr r1, [%[a], #24]\n\t" + "adcs r1, r1, r2\n\t" + "str r1, [%[a], #24]\n\t" + "ldr r1, [%[a], #28]\n\t" + "adcs r1, r1, r2\n\t" + "str r1, [%[a], #28]\n\t" + "ldr r1, [%[a], #32]\n\t" + "adcs r1, r1, r2\n\t" + "str r1, [%[a], #32]\n\t" + "ldr r1, [%[a], #36]\n\t" + "adcs r1, r1, r2\n\t" + "str r1, [%[a], #36]\n\t" + "ldr r1, [%[a], #40]\n\t" + "adcs r1, r1, r2\n\t" + "str r1, [%[a], #40]\n\t" + "ldr r1, [%[a], #44]\n\t" + "adcs r1, r1, r2\n\t" + "str r1, [%[a], #44]\n\t" + : + : [a] "r" (a) + : "memory", "r1", "r2" + ); +} + +/* 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_384_from_bin(sp_digit* r, int size, const byte* a, int n) +{ + int i, 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; + } +} + +/* Generates a scalar that is in the range 1..order-1. + * + * rng Random number generator. + * k Scalar value. + * returns RNG failures, MEMORY_E when memory allocation fails and + * MP_OKAY on success. + */ +static int sp_384_ecc_gen_k_12(WC_RNG* rng, sp_digit* k) +{ + int err; + byte buf[48]; + + do { + err = wc_RNG_GenerateBlock(rng, buf, sizeof(buf)); + if (err == 0) { + sp_384_from_bin(k, 12, buf, (int)sizeof(buf)); + if (sp_384_cmp_12(k, p384_order2) < 0) { + sp_384_add_one_12(k); + break; + } + } + } + while (err == 0); + + return err; +} + +/* Makes a random EC key pair. + * + * rng Random number generator. + * priv Generated private value. + * pub Generated public point. + * heap Heap to use for allocation. + * returns ECC_INF_E when the point does not have the correct order, RNG + * failures, MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_make_key_384(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 p; + sp_digit kd[12]; +#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN + sp_point_384 inf; +#endif +#endif + sp_point_384* point; + sp_digit* k = NULL; +#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN + sp_point_384* infinity; +#endif + int err; + + (void)heap; + + err = sp_384_point_new_12(heap, p, point); +#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN + if (err == MP_OKAY) { + err = sp_384_point_new_12(heap, inf, infinity); + } +#endif +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 12, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + } +#else + k = kd; +#endif + + if (err == MP_OKAY) { + err = sp_384_ecc_gen_k_12(rng, k); + } + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_base_12(point, k, 1, NULL); + } + +#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_12(infinity, point, p384_order, 1, NULL); + } + if (err == MP_OKAY) { + if ((sp_384_iszero_12(point->x) == 0) || (sp_384_iszero_12(point->y) == 0)) { + err = ECC_INF_E; + } + } +#endif + + if (err == MP_OKAY) { + err = sp_384_to_mp(k, priv); + } + if (err == MP_OKAY) { + err = sp_384_point_to_ecc_point_12(point, pub); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif +#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN + sp_384_point_free_12(infinity, 1, heap); +#endif + sp_384_point_free_12(point, 1, heap); + + return err; +} + +#ifdef HAVE_ECC_DHE +/* Write r as big endian to byte array. + * Fixed length number of bytes written: 48 + * + * r A single precision integer. + * a Byte array. + */ +static void sp_384_to_bin(sp_digit* r, byte* a) +{ + int i, j, s = 0, b; + + j = 384 / 8 - 1; + a[j] = 0; + for (i=0; i<12 && j>=0; i++) { + b = 0; + /* lint allow cast of mismatch sp_digit and int */ + a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ + if (j < 0) { + break; + } + while (b < 32) { + a[j--] = r[i] >> b; b += 8; + if (j < 0) { + break; + } + } + s = 8 - (b - 32); + if (j >= 0) { + a[j] = 0; + } + if (s != 0) { + j++; + } + } +} + +/* Multiply the point by the scalar and serialize the X ordinate. + * The number is 0 padded to maximum size on output. + * + * priv Scalar to multiply the point by. + * pub Point to multiply. + * out Buffer to hold X ordinate. + * outLen On entry, size of the buffer in bytes. + * On exit, length of data in buffer in bytes. + * heap Heap to use for allocation. + * 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, + word32* outLen, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 p; + sp_digit kd[12]; +#endif + sp_point_384* point = NULL; + sp_digit* k = NULL; + int err = MP_OKAY; + + if (*outLen < 48U) { + err = BUFFER_E; + } + + if (err == MP_OKAY) { + err = sp_384_point_new_12(heap, p, point); + } +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 12, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) + err = MEMORY_E; + } +#else + k = kd; +#endif + + if (err == MP_OKAY) { + sp_384_from_mp(k, 12, priv); + sp_384_point_from_ecc_point_12(point, pub); + err = sp_384_ecc_mulmod_12(point, point, k, 1, heap); + } + if (err == MP_OKAY) { + sp_384_to_bin(point->x, out); + *outLen = 48; + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_12(point, 0, heap); + + return err; +} +#endif /* HAVE_ECC_DHE */ + +#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) +#endif +#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) +#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_384_sub_in_place_12(sp_digit* a, + const sp_digit* b) +{ + sp_digit c = 0; + __asm__ __volatile__ ( + "mov r8, %[a]\n\t" + "add r8, r8, #48\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" + "bne 1b\n\t" + : [c] "+r" (c), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r3", "r4", "r5", "r6", "r8" + ); + + 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_in_place_12(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" + "sbc %[c], %[c], %[c]\n\t" + : [c] "+r" (c), [a] "+r" (a), [b] "+r" (b) + : + : "memory", "r3", "r4", "r5", "r6" + ); + + 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_384_mul_d_12(sp_digit* r, const sp_digit* a, + sp_digit b) +{ + __asm__ __volatile__ ( + "add r9, %[a], #48\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" + "blt 1b\n\t" + "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_384_word_12(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_384_mask_12(sp_digit* r, const sp_digit* a, sp_digit m) +{ +#ifdef WOLFSSL_SP_SMALL + int i; + + for (i=0; i<12; 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; + r[8] = a[8] & m; + r[9] = a[9] & m; + r[10] = a[10] & m; + r[11] = a[11] & m; +#endif +} + +/* 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 Nmber 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_384_div_12(const sp_digit* a, const sp_digit* d, sp_digit* m, + sp_digit* r) +{ + sp_digit t1[24], t2[13]; + sp_digit div, r1; + int i; + + (void)m; + + div = d[11]; + XMEMCPY(t1, a, sizeof(*t1) * 2 * 12); + for (i=11; i>=0; i--) { + r1 = div_384_word_12(t1[12 + i], t1[12 + i - 1], div); + + sp_384_mul_d_12(t2, d, r1); + t1[12 + i] += sp_384_sub_in_place_12(&t1[i], t2); + t1[12 + i] -= t2[12]; + sp_384_mask_12(t2, d, t1[12 + i]); + t1[12 + i] += sp_384_add_12(&t1[i], &t1[i], t2); + sp_384_mask_12(t2, d, t1[12 + i]); + t1[12 + i] += sp_384_add_12(&t1[i], &t1[i], t2); + } + + r1 = sp_384_cmp_12(t1, d) >= 0; + sp_384_cond_sub_12(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_384_mod_12(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + return sp_384_div_12(a, m, NULL, r); +} + +#endif +#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) +#ifdef WOLFSSL_SP_SMALL +/* Order-2 for the P384 curve. */ +static const uint32_t p384_order_minus_2[12] = { + 0xccc52971U,0xecec196aU,0x48b0a77aU,0x581a0db2U,0xf4372ddfU,0xc7634d81U, + 0xffffffffU,0xffffffffU,0xffffffffU,0xffffffffU,0xffffffffU,0xffffffffU +}; +#else +/* 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 */ + +/* Multiply two number mod the order of P384 curve. (r = a * b mod order) + * + * r Result of the multiplication. + * a First operand of the multiplication. + * b Second operand of the multiplication. + */ +static void sp_384_mont_mul_order_12(sp_digit* r, const sp_digit* a, const sp_digit* b) +{ + sp_384_mul_12(r, a, b); + sp_384_mont_reduce_order_12(r, p384_order, p384_mp_order); +} + +/* Square number mod the order of P384 curve. (r = a * a mod order) + * + * r Result of the squaring. + * a Number to square. + */ +static void sp_384_mont_sqr_order_12(sp_digit* r, const sp_digit* a) +{ + sp_384_sqr_12(r, a); + sp_384_mont_reduce_order_12(r, p384_order, p384_mp_order); +} + +#ifndef WOLFSSL_SP_SMALL +/* Square number mod the order of P384 curve a number of times. + * (r = a ^ n mod order) + * + * r Result of the squaring. + * a Number to square. + */ +static void sp_384_mont_sqr_n_order_12(sp_digit* r, const sp_digit* a, int n) +{ + int i; + + sp_384_mont_sqr_order_12(r, a); + for (i=1; i=0; i--) { + sp_384_mont_sqr_order_12(t, t); + if ((p384_order_minus_2[i / 32] & ((sp_int_digit)1 << (i % 32))) != 0) { + sp_384_mont_mul_order_12(t, t, a); + } + } + XMEMCPY(r, t, sizeof(sp_digit) * 12U); +#else + sp_digit* t = td; + sp_digit* t2 = td + 2 * 12; + sp_digit* t3 = td + 4 * 12; + int i; + + /* t = a^2 */ + sp_384_mont_sqr_order_12(t, a); + /* t = a^3 = t * a */ + sp_384_mont_mul_order_12(t, t, a); + /* t2= a^c = t ^ 2 ^ 2 */ + sp_384_mont_sqr_n_order_12(t2, t, 2); + /* t = a^f = t2 * t */ + sp_384_mont_mul_order_12(t, t2, t); + /* t2= a^f0 = t ^ 2 ^ 4 */ + sp_384_mont_sqr_n_order_12(t2, t, 4); + /* t = a^ff = t2 * t */ + sp_384_mont_mul_order_12(t, t2, t); + /* t2= a^ff00 = t ^ 2 ^ 8 */ + sp_384_mont_sqr_n_order_12(t2, t, 8); + /* t3= a^ffff = t2 * t */ + sp_384_mont_mul_order_12(t3, t2, t); + /* t2= a^ffff0000 = t3 ^ 2 ^ 16 */ + sp_384_mont_sqr_n_order_12(t2, t3, 16); + /* t = a^ffffffff = t2 * t3 */ + sp_384_mont_mul_order_12(t, t2, t3); + /* t2= a^ffffffff0000 = t ^ 2 ^ 16 */ + sp_384_mont_sqr_n_order_12(t2, t, 16); + /* t = a^ffffffffffff = t2 * t3 */ + sp_384_mont_mul_order_12(t, t2, t3); + /* t2= a^ffffffffffff000000000000 = t ^ 2 ^ 48 */ + sp_384_mont_sqr_n_order_12(t2, t, 48); + /* t= a^fffffffffffffffffffffffff = t2 * t */ + sp_384_mont_mul_order_12(t, t2, t); + /* t2= a^ffffffffffffffffffffffff000000000000000000000000 */ + sp_384_mont_sqr_n_order_12(t2, t, 96); + /* t2= a^ffffffffffffffffffffffffffffffffffffffffffffffff = t2 * t */ + 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) { + sp_384_mont_mul_order_12(t2, t2, a); + } + } + sp_384_mont_sqr_order_12(t2, t2); + sp_384_mont_mul_order_12(r, t2, a); +#endif /* WOLFSSL_SP_SMALL */ +} + +#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 + +/* Sign the hash using the private key. + * e = [hash, 384 bits] from binary + * r = (k.G)->x mod order + * s = (r * x + e) / k mod order + * The hash is truncated to the first 384 bits. + * + * hash Hash to sign. + * hashLen Length of the hash data. + * rng Random number generator. + * priv Private part of key - scalar. + * 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. + */ +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) +{ +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_digit* d = NULL; +#else + sp_digit ed[2*12]; + sp_digit xd[2*12]; + sp_digit kd[2*12]; + sp_digit rd[2*12]; + sp_digit td[3 * 2*12]; + sp_point_384 p; +#endif + sp_digit* e = NULL; + sp_digit* x = NULL; + sp_digit* k = NULL; + 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 i; + + (void)heap; + + err = sp_384_point_new_12(heap, p, point); +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7 * 2 * 12, heap, + DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + e = d + 0 * 12; + x = d + 2 * 12; + k = d + 4 * 12; + r = d + 6 * 12; + tmp = d + 8 * 12; +#else + e = ed; + x = xd; + k = kd; + r = rd; + tmp = td; +#endif + s = e; + kInv = k; + + if (hashLen > 48U) { + hashLen = 48U; + } + + sp_384_from_bin(e, 12, hash, (int)hashLen); + } + + 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); + } + else { + sp_384_from_mp(k, 12, km); + mp_zero(km); + } + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_base_12(point, k, 1, NULL); + } + + if (err == MP_OKAY) { + /* r = point->x mod order */ + XMEMCPY(r, point->x, sizeof(sp_digit) * 12U); + sp_384_norm_12(r); + c = sp_384_cmp_12(r, p384_order); + 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); + 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); + + /* Check that signature is usable. */ + if (sp_384_iszero_12(s) == 0) { + break; + } + } + } + + if (i == 0) { + err = RNG_FAILURE_E; + } + + if (err == MP_OKAY) { + err = sp_384_to_mp(r, rm); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(s, sm); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (d != NULL) { + XMEMSET(d, 0, sizeof(sp_digit) * 8 * 12); + XFREE(d, heap, DYNAMIC_TYPE_ECC); + } +#else + XMEMSET(e, 0, sizeof(sp_digit) * 2U * 12U); + 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); + + return err; +} +#endif /* HAVE_ECC_SIGN */ + +#ifdef HAVE_ECC_VERIFY +/* Verify the signature values with the hash and public key. + * e = Truncate(hash, 384) + * u1 = e/s mod order + * u2 = r/s mod order + * r == (u1.G + u2.Q)->x mod order + * Optimization: Leave point in projective form. + * (x, y, 1) == (x' / z'*z', y' / z'*z'*z', z' / z') + * (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' + * The hash is truncated to the first 384 bits. + * + * hash Hash to sign. + * hashLen Length of the hash data. + * rng Random number generator. + * priv Private part of key - scalar. + * 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. + */ +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) +{ +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_digit* d = NULL; +#else + sp_digit u1d[2*12]; + sp_digit u2d[2*12]; + sp_digit sd[2*12]; + sp_digit tmpd[2*12 * 5]; + sp_point_384 p1d; + sp_point_384 p2d; +#endif + sp_digit* u1 = NULL; + sp_digit* u2 = NULL; + sp_digit* s = NULL; + sp_digit* tmp = NULL; + sp_point_384* p1; + sp_point_384* p2 = NULL; + sp_digit carry; + int32_t c; + int err; + + err = sp_384_point_new_12(heap, p1d, p1); + if (err == MP_OKAY) { + err = sp_384_point_new_12(heap, p2d, p2); + } +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 12, heap, + DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + u1 = d + 0 * 12; + u2 = d + 2 * 12; + s = d + 4 * 12; + tmp = d + 6 * 12; +#else + u1 = u1d; + u2 = u2d; + s = sd; + tmp = tmpd; +#endif + + if (hashLen > 48U) { + hashLen = 48U; + } + + sp_384_from_bin(u1, 12, hash, (int)hashLen); + sp_384_from_mp(u2, 12, r); + sp_384_from_mp(s, 12, sm); + sp_384_from_mp(p2->x, 12, pX); + sp_384_from_mp(p2->y, 12, pY); + sp_384_from_mp(p2->z, 12, pZ); + + { + 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); + { + 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); + } + + err = sp_384_ecc_mulmod_base_12(p1, u1, 0, heap); + } + if (err == MP_OKAY) { + err = sp_384_ecc_mulmod_12(p2, p2, u2, 0, heap); + } + + 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); + err = sp_384_mod_mul_norm_12(u2, u2, p384_mod); + } + + if (err == MP_OKAY) { + /* u1 = r.z'.z' mod prime */ + sp_384_mont_sqr_12(p1->z, p1->z, p384_mod, p384_mp_mod); + 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) { + /* Reload r and add order. */ + sp_384_from_mp(u2, 12, r); + carry = sp_384_add_12(u2, u2, p384_order); + /* Carry means result is greater than mod and is not valid. */ + if (carry == 0) { + sp_384_norm_12(u2); + + /* 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 defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (d != NULL) + XFREE(d, heap, DYNAMIC_TYPE_ECC); +#endif + sp_384_point_free_12(p1, 0, heap); + sp_384_point_free_12(p2, 0, heap); + + return err; +} +#endif /* HAVE_ECC_VERIFY */ + +#ifdef HAVE_ECC_CHECK_KEY +/* 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_384_ecc_is_point_12(sp_point_384* point, void* heap) +{ +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_digit* d = NULL; +#else + sp_digit t1d[2*12]; + sp_digit t2d[2*12]; +#endif + sp_digit* t1; + sp_digit* t2; + int err = MP_OKAY; + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 12 * 4, heap, DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + t1 = d + 0 * 12; + t2 = d + 2 * 12; +#else + (void)heap; + + t1 = t1d; + t2 = t2d; +#endif + + sp_384_sqr_12(t1, point->y); + (void)sp_384_mod_12(t1, t1, p384_mod); + sp_384_sqr_12(t2, point->x); + (void)sp_384_mod_12(t2, t2, p384_mod); + sp_384_mul_12(t2, t2, point->x); + (void)sp_384_mod_12(t2, t2, p384_mod); + (void)sp_384_sub_12(t2, p384_mod, t2); + sp_384_mont_add_12(t1, t1, t2, p384_mod); + + sp_384_mont_add_12(t1, t1, point->x, p384_mod); + sp_384_mont_add_12(t1, t1, point->x, p384_mod); + sp_384_mont_add_12(t1, t1, point->x, p384_mod); + + if (sp_384_cmp_12(t1, p384_b) != 0) { + err = MP_VAL; + } + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + 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_384(mp_int* pX, mp_int* pY) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 pubd; +#endif + sp_point_384* pub; + byte one[1] = { 1 }; + int err; + + err = sp_384_point_new_12(NULL, pubd, pub); + if (err == MP_OKAY) { + sp_384_from_mp(pub->x, 12, pX); + sp_384_from_mp(pub->y, 12, pY); + sp_384_from_bin(pub->z, 12, one, (int)sizeof(one)); + + err = sp_384_ecc_is_point_12(pub, NULL); + } + + sp_384_point_free_12(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_384(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_digit privd[12]; + sp_point_384 pubd; + sp_point_384 pd; +#endif + sp_digit* priv = NULL; + sp_point_384* pub; + sp_point_384* p = NULL; + byte one[1] = { 1 }; + int err; + + err = sp_384_point_new_12(heap, pubd, pub); + if (err == MP_OKAY) { + err = sp_384_point_new_12(heap, pd, p); + } +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + priv = (sp_digit*)XMALLOC(sizeof(sp_digit) * 12, heap, + DYNAMIC_TYPE_ECC); + if (priv == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if !(defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) + priv = privd; +#endif + + sp_384_from_mp(pub->x, 12, pX); + sp_384_from_mp(pub->y, 12, pY); + sp_384_from_bin(pub->z, 12, one, (int)sizeof(one)); + sp_384_from_mp(priv, 12, privm); + + /* Check point at infinitiy. */ + if ((sp_384_iszero_12(pub->x) != 0) && + (sp_384_iszero_12(pub->y) != 0)) { + err = ECC_INF_E; + } + } + + 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; + } + } + + if (err == MP_OKAY) { + /* Check point is on curve */ + err = sp_384_ecc_is_point_12(pub, heap); + } + + if (err == MP_OKAY) { + /* Point * order = infinity */ + err = sp_384_ecc_mulmod_12(p, pub, p384_order, 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; + } + } + + if (err == MP_OKAY) { + /* Base * private = point */ + err = sp_384_ecc_mulmod_base_12(p, priv, 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; + } + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (priv != NULL) { + XFREE(priv, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_12(p, 0, heap); + sp_384_point_free_12(pub, 0, heap); + + return err; +} +#endif +#ifdef WOLFSSL_PUBLIC_ECC_ADD_DBL +/* Add two projective EC points together. + * (pX, pY, pZ) + (qX, qY, qZ) = (rX, rY, rZ) + * + * pX First EC point's X ordinate. + * pY First EC point's Y ordinate. + * pZ First EC point's Z ordinate. + * qX Second EC point's X ordinate. + * qY Second EC point's Y ordinate. + * qZ Second EC point's Z ordinate. + * rX Resultant EC point's X ordinate. + * rY Resultant EC point's Y ordinate. + * rZ Resultant EC point's Z ordinate. + * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise. + */ +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) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_digit tmpd[2 * 12 * 5]; + sp_point_384 pd; + sp_point_384 qd; +#endif + sp_digit* tmp; + sp_point_384* p; + sp_point_384* q = NULL; + int err; + + err = sp_384_point_new_12(NULL, pd, p); + if (err == MP_OKAY) { + err = sp_384_point_new_12(NULL, qd, q); + } +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 12 * 5, NULL, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) { + err = MEMORY_E; + } + } +#else + tmp = tmpd; +#endif + + if (err == MP_OKAY) { + sp_384_from_mp(p->x, 12, pX); + sp_384_from_mp(p->y, 12, pY); + sp_384_from_mp(p->z, 12, pZ); + sp_384_from_mp(q->x, 12, qX); + sp_384_from_mp(q->y, 12, qY); + sp_384_from_mp(q->z, 12, qZ); + + sp_384_proj_point_add_12(p, p, q, tmp); + } + + if (err == MP_OKAY) { + err = sp_384_to_mp(p->x, rX); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->y, rY); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->z, rZ); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (tmp != NULL) { + XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_12(q, 0, NULL); + sp_384_point_free_12(p, 0, NULL); + + return err; +} + +/* Double a projective EC point. + * (pX, pY, pZ) + (pX, pY, pZ) = (rX, rY, rZ) + * + * pX EC point's X ordinate. + * pY EC point's Y ordinate. + * pZ EC point's Z ordinate. + * rX Resultant EC point's X ordinate. + * rY Resultant EC point's Y ordinate. + * rZ Resultant EC point's Z ordinate. + * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise. + */ +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) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_digit tmpd[2 * 12 * 2]; + sp_point_384 pd; +#endif + sp_digit* tmp; + sp_point_384* p; + int err; + + err = sp_384_point_new_12(NULL, pd, p); +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 12 * 2, NULL, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) { + err = MEMORY_E; + } + } +#else + tmp = tmpd; +#endif + + if (err == MP_OKAY) { + sp_384_from_mp(p->x, 12, pX); + sp_384_from_mp(p->y, 12, pY); + sp_384_from_mp(p->z, 12, pZ); + + sp_384_proj_point_dbl_12(p, p, tmp); + } + + if (err == MP_OKAY) { + err = sp_384_to_mp(p->x, rX); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->y, rY); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->z, rZ); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (tmp != NULL) { + XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_12(p, 0, NULL); + + return err; +} + +/* Map a projective EC point to affine in place. + * pZ will be one. + * + * pX EC point's X ordinate. + * pY EC point's Y ordinate. + * pZ EC point's Z ordinate. + * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise. + */ +int sp_ecc_map_384(mp_int* pX, mp_int* pY, mp_int* pZ) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_digit tmpd[2 * 12 * 6]; + sp_point_384 pd; +#endif + sp_digit* tmp; + sp_point_384* p; + int err; + + err = sp_384_point_new_12(NULL, pd, p); +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 12 * 6, NULL, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) { + err = MEMORY_E; + } + } +#else + tmp = tmpd; +#endif + if (err == MP_OKAY) { + sp_384_from_mp(p->x, 12, pX); + sp_384_from_mp(p->y, 12, pY); + sp_384_from_mp(p->z, 12, pZ); + + sp_384_map_12(p, p, tmp); + } + + if (err == MP_OKAY) { + err = sp_384_to_mp(p->x, pX); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->y, pY); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->z, pZ); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (tmp != NULL) { + XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_12(p, 0, NULL); + + return err; +} +#endif /* WOLFSSL_PUBLIC_ECC_ADD_DBL */ +#ifdef HAVE_COMP_KEY +/* Find the square root of a number mod the prime of the curve. + * + * y The number to operate on and the result. + * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise. + */ +static int sp_384_mont_sqrt_12(sp_digit* y) +{ +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_digit* d; +#else + sp_digit t1d[2 * 12]; + sp_digit t2d[2 * 12]; + sp_digit t3d[2 * 12]; + sp_digit t4d[2 * 12]; + sp_digit t5d[2 * 12]; +#endif + sp_digit* t1; + sp_digit* t2; + sp_digit* t3; + sp_digit* t4; + sp_digit* t5; + int err = MP_OKAY; + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 5 * 2 * 12, NULL, DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + t1 = d + 0 * 12; + t2 = d + 2 * 12; + t3 = d + 4 * 12; + t4 = d + 6 * 12; + t5 = d + 8 * 12; +#else + t1 = t1d; + t2 = t2d; + t3 = t3d; + t4 = t4d; + t5 = t5d; +#endif + + { + /* t2 = y ^ 0x2 */ + sp_384_mont_sqr_12(t2, y, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x3 */ + sp_384_mont_mul_12(t1, t2, y, p384_mod, p384_mp_mod); + /* t5 = y ^ 0xc */ + sp_384_mont_sqr_n_12(t5, t1, 2, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xf */ + sp_384_mont_mul_12(t1, t1, t5, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x1e */ + sp_384_mont_sqr_12(t2, t1, p384_mod, p384_mp_mod); + /* t3 = y ^ 0x1f */ + sp_384_mont_mul_12(t3, t2, y, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3e0 */ + sp_384_mont_sqr_n_12(t2, t3, 5, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x3ff */ + sp_384_mont_mul_12(t1, t3, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x7fe0 */ + sp_384_mont_sqr_n_12(t2, t1, 5, p384_mod, p384_mp_mod); + /* t3 = y ^ 0x7fff */ + sp_384_mont_mul_12(t3, t3, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3fff800 */ + sp_384_mont_sqr_n_12(t2, t3, 15, p384_mod, p384_mp_mod); + /* t4 = y ^ 0x3ffffff */ + sp_384_mont_mul_12(t4, t3, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0xffffffc000000 */ + sp_384_mont_sqr_n_12(t2, t4, 30, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xfffffffffffff */ + sp_384_mont_mul_12(t1, t4, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0xfffffffffffffff000000000000000 */ + sp_384_mont_sqr_n_12(t2, t1, 60, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xffffffffffffffffffffffffffffff */ + sp_384_mont_mul_12(t1, t1, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0xffffffffffffffffffffffffffffff000000000000000000000000000000 */ + sp_384_mont_sqr_n_12(t2, t1, 120, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */ + sp_384_mont_mul_12(t1, t1, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000 */ + sp_384_mont_sqr_n_12(t2, t1, 15, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */ + sp_384_mont_mul_12(t1, t3, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000 */ + sp_384_mont_sqr_n_12(t2, t1, 31, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffff */ + sp_384_mont_mul_12(t1, t4, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffff0 */ + sp_384_mont_sqr_n_12(t2, t1, 4, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffc */ + sp_384_mont_mul_12(t1, t5, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000 */ + sp_384_mont_sqr_n_12(t2, t1, 62, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000001 */ + sp_384_mont_mul_12(t1, y, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffc00000000000000040000000 */ + sp_384_mont_sqr_n_12(y, t1, 30, p384_mod, p384_mp_mod); + } + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (d != NULL) { + XFREE(d, NULL, DYNAMIC_TYPE_ECC); + } +#endif + + return err; +} + + +/* Uncompress the point given the X ordinate. + * + * xm X ordinate. + * odd Whether the Y ordinate is odd. + * ym Calculated Y ordinate. + * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise. + */ +int sp_ecc_uncompress_384(mp_int* xm, int odd, mp_int* ym) +{ +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_digit* d; +#else + sp_digit xd[2 * 12]; + sp_digit yd[2 * 12]; +#endif + sp_digit* x = NULL; + sp_digit* y = NULL; + int err = MP_OKAY; + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4 * 12, NULL, DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + x = d + 0 * 12; + y = d + 2 * 12; +#else + x = xd; + y = yd; +#endif + + sp_384_from_mp(x, 12, xm); + err = sp_384_mod_mul_norm_12(x, x, p384_mod); + } + if (err == MP_OKAY) { + /* y = x^3 */ + { + sp_384_mont_sqr_12(y, x, p384_mod, p384_mp_mod); + sp_384_mont_mul_12(y, y, x, p384_mod, p384_mp_mod); + } + /* y = x^3 - 3x */ + sp_384_mont_sub_12(y, y, x, p384_mod); + sp_384_mont_sub_12(y, y, x, p384_mod); + sp_384_mont_sub_12(y, y, x, p384_mod); + /* y = x^3 - 3x + b */ + err = sp_384_mod_mul_norm_12(x, p384_b, p384_mod); + } + if (err == MP_OKAY) { + sp_384_mont_add_12(y, y, x, p384_mod); + /* y = sqrt(x^3 - 3x + b) */ + err = sp_384_mont_sqrt_12(y); + } + if (err == MP_OKAY) { + XMEMSET(y + 12, 0, 12U * sizeof(sp_digit)); + sp_384_mont_reduce_12(y, p384_mod, p384_mp_mod); + if ((((word32)y[0] ^ (word32)odd) & 1U) != 0U) { + sp_384_mont_sub_12(y, p384_mod, y, p384_mod); + } + + err = sp_384_to_mp(y, ym); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (d != NULL) { + XFREE(d, NULL, DYNAMIC_TYPE_ECC); + } +#endif + + return err; +} +#endif +#endif /* WOLFSSL_SP_384 */ #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 */ diff --git a/wolfcrypt/src/sp_int.c b/wolfcrypt/src/sp_int.c index 92f877b76..5c6642457 100644 --- a/wolfcrypt/src/sp_int.c +++ b/wolfcrypt/src/sp_int.c @@ -157,37 +157,37 @@ int sp_unsigned_bin_size(sp_int* a) int sp_read_unsigned_bin(sp_int* a, const byte* in, int inSz) { int err = MP_OKAY; - int i, j = 0, s = 0; + int i, j = 0, k; if (inSz > SP_INT_DIGITS * (int)sizeof(a->dp[0])) { err = MP_VAL; } if (err == MP_OKAY) { - a->dp[0] = 0; - for (i = inSz-1; i >= 0; i--) { - a->dp[j] |= ((sp_int_digit)in[i]) << s; - if (s == DIGIT_BIT - 8) { - a->dp[++j] = 0; - s = 0; - } - else if (s > DIGIT_BIT - 8) { - s = DIGIT_BIT - s; - if (j + 1 >= a->size) - break; - a->dp[++j] = in[i] >> s; - s = 8 - s; - } - else - s += 8; + for (i = inSz-1; i >= (SP_WORD_SIZE/8); i -= (SP_WORD_SIZE/8), j++) { + a->dp[j] = (((sp_int_digit)in[i-0]) << (0*8)) + | (((sp_int_digit)in[i-1]) << (1*8)) + | (((sp_int_digit)in[i-2]) << (2*8)) + | (((sp_int_digit)in[i-3]) << (3*8)); + #if SP_WORD_SIZE == 64 + a->dp[j] |= (((sp_int_digit)in[i-4]) << (4*8)) + | (((sp_int_digit)in[i-5]) << (5*8)) + | (((sp_int_digit)in[i-6]) << (6*8)) + | (((sp_int_digit)in[i-7]) << (7*8)); + #endif } - - a->used = j + 1; - sp_clamp(a); - for (j++; j < a->size; j++) + if (i >= 0) { a->dp[j] = 0; + for (k = 0; k <= i; k++) { + a->dp[j] <<= 8; + a->dp[j] |= in[k]; + } + } + a->used = j + 1; } + sp_clamp(a); + return err; } @@ -239,7 +239,7 @@ int sp_read_radix(sp_int* a, const char* in, int radix) } if (j == DIGIT_BIT) a->dp[++k] = 0; - j &= DIGIT_BIT - 1; + j &= SP_WORD_SIZE - 1; } } @@ -359,13 +359,17 @@ int sp_leading_bit(sp_int* a) int sp_to_unsigned_bin(sp_int* a, byte* out) { int i, j, b; + sp_int_digit d; j = sp_unsigned_bin_size(a) - 1; for (i=0; j>=0; i++) { - for (b = 0; b < SP_WORD_SIZE; b += 8) { - out[j--] = a->dp[i] >> b; - if (j < 0) + d = a->dp[i]; + for (b = 0; b < SP_WORD_SIZE / 8; b++) { + out[j] = d; + if (--j < 0) { break; + } + d >>= 8; } } diff --git a/wolfcrypt/src/sp_x86_64.c b/wolfcrypt/src/sp_x86_64.c index 142340860..c1ec7a3a0 100644 --- a/wolfcrypt/src/sp_x86_64.c +++ b/wolfcrypt/src/sp_x86_64.c @@ -4294,6 +4294,7 @@ SP_NOINLINE static void sp_4096_mul_64(sp_digit* r, const sp_digit* a, sp_4096_add_64(r + 64, r + 64, z2); } +extern sp_digit sp_2048_dbl_32(sp_digit* r, const sp_digit* a); /* Square a and put result in r. (r = a * a) * * r A single precision integer. @@ -5693,12 +5694,12 @@ int sp_DhExp_4096(mp_int* base, const byte* exp, word32 expLen, #ifndef WOLFSSL_SP_NO_256 /* Point structure to use. */ -typedef struct sp_point { +typedef struct sp_point_256 { sp_digit x[2 * 4]; sp_digit y[2 * 4]; sp_digit z[2 * 4]; int infinity; -} sp_point; +} sp_point_256; /* The modulus (prime) of the curve P256. */ static const sp_digit p256_mod[4] = { @@ -5738,21 +5739,24 @@ static const sp_digit p256_mp_order = 0xccd1c8aaee00bc4fL; #endif #ifdef WOLFSSL_SP_SMALL /* The base point of curve P256. */ -static const sp_point p256_base = { +static const sp_point_256 p256_base = { /* X ordinate */ { 0xf4a13945d898c296L,0x77037d812deb33a0L,0xf8bce6e563a440f2L, - 0x6b17d1f2e12c4247L, 0L, 0L, 0L, 0L + 0x6b17d1f2e12c4247L, + 0L, 0L, 0L, 0L }, /* Y ordinate */ { 0xcbb6406837bf51f5L,0x2bce33576b315eceL,0x8ee7eb4a7c0f9e16L, - 0x4fe342e2fe1a7f9bL, 0L, 0L, 0L, 0L + 0x4fe342e2fe1a7f9bL, + 0L, 0L, 0L, 0L }, /* Z ordinate */ { 0x0000000000000001L,0x0000000000000000L,0x0000000000000000L, - 0x0000000000000000L, 0L, 0L, 0L, 0L + 0x0000000000000000L, + 0L, 0L, 0L, 0L }, /* infinity */ 0 @@ -5765,34 +5769,32 @@ static const sp_digit p256_b[4] = { }; #endif -static int sp_ecc_point_new_ex(void* heap, sp_point* sp, sp_point** p) +static int sp_256_point_new_ex_4(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) + (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; } - else { - #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - *p = (sp_point*)XMALLOC(sizeof(sp_point), heap, DYNAMIC_TYPE_ECC); - (void)sp; - #else - *p = sp; - (void)heap; - #endif - } return ret; } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) /* Allocate memory for point and return error. */ -#define sp_ecc_point_new(heap, sp, p) sp_ecc_point_new_ex((heap), NULL, &(p)) +#define sp_256_point_new_4(heap, sp, p) sp_256_point_new_ex_4((heap), NULL, &(p)) #else /* Set pointer to data and return no error. */ -#define sp_ecc_point_new(heap, sp, p) sp_ecc_point_new_ex((heap), &(sp), &(p)) +#define sp_256_point_new_4(heap, sp, p) sp_256_point_new_ex_4((heap), &(sp), &(p)) #endif -static void sp_ecc_point_free(sp_point* p, int clear, void* heap) +static void sp_256_point_free_4(sp_point_256* p, int clear, void* heap) { #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) /* If valid pointer then clear point data if requested and free data. */ @@ -5960,12 +5962,12 @@ static void sp_256_from_mp(sp_digit* r, int size, const mp_int* a) #endif } -/* Convert a point of type ecc_point to type sp_point. +/* Convert a point of type ecc_point to type sp_point_256. * - * p Point of type sp_point (result). + * 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* 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)); @@ -6040,14 +6042,14 @@ static int sp_256_to_mp(const sp_digit* a, mp_int* r) return err; } -/* Convert a point of type sp_point to type ecc_point. +/* Convert a point of type sp_point_256 to type ecc_point. * - * p Point of type sp_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_4(const sp_point* p, ecc_point* pm) +static int sp_256_point_to_ecc_point_4(const sp_point_256* p, ecc_point* pm) { int err; @@ -6063,18 +6065,6 @@ static int sp_256_point_to_ecc_point_4(const sp_point* p, ecc_point* pm) } extern void sp_256_cond_copy_4(sp_digit* r, const sp_digit* a, sp_digit m); -extern int64_t sp_256_cmp_4(const sp_digit* a, const sp_digit* b); -/* Normalize the values in each word to 64. - * - * a Array of sp_digit to normalize. - */ -#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); extern void sp_256_mont_mul_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_4(sp_digit* r, const sp_digit* a, const sp_digit* m, sp_digit mp); #if !defined(WOLFSSL_SP_SMALL) || defined(HAVE_COMP_KEY) @@ -6098,7 +6088,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 */ #ifdef WOLFSSL_SP_SMALL /* Mod-2 for the P256 curve. */ -static const uint64_t p256_mod_2[4] = { +static const uint64_t p256_mod_minus_2[4] = { 0xfffffffffffffffdU,0x00000000ffffffffU,0x0000000000000000U, 0xffffffff00000001U }; @@ -6120,71 +6110,78 @@ static void sp_256_mont_inv_4(sp_digit* r, const sp_digit* a, sp_digit* td) XMEMCPY(t, a, sizeof(sp_digit) * 4); for (i=254; i>=0; i--) { sp_256_mont_sqr_4(t, t, p256_mod, p256_mp_mod); - if (p256_mod_2[i / 64] & ((sp_digit)1 << (i % 64))) + if (p256_mod_minus_2[i / 64] & ((sp_digit)1 << (i % 64))) sp_256_mont_mul_4(t, t, a, p256_mod, p256_mp_mod); } XMEMCPY(r, t, sizeof(sp_digit) * 4); #else - sp_digit* t = td; + sp_digit* t1 = td; sp_digit* t2 = td + 2 * 4; sp_digit* t3 = td + 4 * 4; - - /* t = a^2 */ - sp_256_mont_sqr_4(t, a, p256_mod, p256_mp_mod); - /* t = a^3 = t * a */ - sp_256_mont_mul_4(t, t, a, p256_mod, p256_mp_mod); - /* t2= a^c = t ^ 2 ^ 2 */ - sp_256_mont_sqr_n_4(t2, t, 2, p256_mod, p256_mp_mod); - /* t3= a^d = t2 * a */ - sp_256_mont_mul_4(t3, t2, a, p256_mod, p256_mp_mod); - /* t = a^f = t2 * t */ - sp_256_mont_mul_4(t, t2, t, p256_mod, p256_mp_mod); - /* t2= a^f0 = t ^ 2 ^ 4 */ - sp_256_mont_sqr_n_4(t2, t, 4, p256_mod, p256_mp_mod); - /* t3= a^fd = t2 * t3 */ - sp_256_mont_mul_4(t3, t2, t3, p256_mod, p256_mp_mod); - /* t = a^ff = t2 * t */ - sp_256_mont_mul_4(t, t2, t, p256_mod, p256_mp_mod); - /* t2= a^ff00 = t ^ 2 ^ 8 */ - sp_256_mont_sqr_n_4(t2, t, 8, p256_mod, p256_mp_mod); - /* t3= a^fffd = t2 * t3 */ - sp_256_mont_mul_4(t3, t2, t3, p256_mod, p256_mp_mod); - /* t = a^ffff = t2 * t */ - sp_256_mont_mul_4(t, t2, t, p256_mod, p256_mp_mod); - /* t2= a^ffff0000 = t ^ 2 ^ 16 */ - sp_256_mont_sqr_n_4(t2, t, 16, p256_mod, p256_mp_mod); - /* t3= a^fffffffd = t2 * t3 */ - sp_256_mont_mul_4(t3, t2, t3, p256_mod, p256_mp_mod); - /* t = a^ffffffff = t2 * t */ - sp_256_mont_mul_4(t, t2, t, p256_mod, p256_mp_mod); - /* t = a^ffffffff00000000 = t ^ 2 ^ 32 */ - sp_256_mont_sqr_n_4(t2, t, 32, p256_mod, p256_mp_mod); - /* t2= a^ffffffffffffffff = t2 * t */ - sp_256_mont_mul_4(t, t2, t, p256_mod, p256_mp_mod); - /* t2= a^ffffffff00000001 = t2 * a */ - sp_256_mont_mul_4(t2, t2, a, p256_mod, p256_mp_mod); - /* t2= a^ffffffff000000010000000000000000000000000000000000000000 - * = t2 ^ 2 ^ 160 */ - sp_256_mont_sqr_n_4(t2, t2, 160, p256_mod, p256_mp_mod); - /* t2= a^ffffffff00000001000000000000000000000000ffffffffffffffff - * = t2 * t */ - sp_256_mont_mul_4(t2, t2, t, p256_mod, p256_mp_mod); - /* t2= a^ffffffff00000001000000000000000000000000ffffffffffffffff00000000 - * = t2 ^ 2 ^ 32 */ - sp_256_mont_sqr_n_4(t2, t2, 32, p256_mod, p256_mp_mod); - /* r = a^ffffffff00000001000000000000000000000000fffffffffffffffffffffffd - * = t2 * t3 */ - sp_256_mont_mul_4(r, t2, t3, p256_mod, p256_mp_mod); + /* 0x2 */ + sp_256_mont_sqr_4(t1, a, p256_mod, p256_mp_mod); + /* 0x3 */ + sp_256_mont_mul_4(t2, t1, a, p256_mod, p256_mp_mod); + /* 0xc */ + sp_256_mont_sqr_n_4(t1, t2, 2, p256_mod, p256_mp_mod); + /* 0xd */ + sp_256_mont_mul_4(t3, t1, a, p256_mod, p256_mp_mod); + /* 0xf */ + sp_256_mont_mul_4(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xf0 */ + sp_256_mont_sqr_n_4(t1, t2, 4, p256_mod, p256_mp_mod); + /* 0xfd */ + sp_256_mont_mul_4(t3, t3, t1, p256_mod, p256_mp_mod); + /* 0xff */ + sp_256_mont_mul_4(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xff00 */ + sp_256_mont_sqr_n_4(t1, t2, 8, p256_mod, p256_mp_mod); + /* 0xfffd */ + sp_256_mont_mul_4(t3, t3, t1, p256_mod, p256_mp_mod); + /* 0xffff */ + sp_256_mont_mul_4(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xffff0000 */ + sp_256_mont_sqr_n_4(t1, t2, 16, p256_mod, p256_mp_mod); + /* 0xfffffffd */ + sp_256_mont_mul_4(t3, t3, t1, p256_mod, p256_mp_mod); + /* 0xffffffff */ + sp_256_mont_mul_4(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xffffffff00000000 */ + sp_256_mont_sqr_n_4(t1, t2, 32, p256_mod, p256_mp_mod); + /* 0xffffffffffffffff */ + sp_256_mont_mul_4(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xffffffff00000001 */ + sp_256_mont_mul_4(r, t1, a, p256_mod, p256_mp_mod); + /* 0xffffffff000000010000000000000000000000000000000000000000 */ + sp_256_mont_sqr_n_4(r, r, 160, p256_mod, p256_mp_mod); + /* 0xffffffff00000001000000000000000000000000ffffffffffffffff */ + sp_256_mont_mul_4(r, r, t2, p256_mod, p256_mp_mod); + /* 0xffffffff00000001000000000000000000000000ffffffffffffffff00000000 */ + sp_256_mont_sqr_n_4(r, r, 32, p256_mod, p256_mp_mod); + /* 0xffffffff00000001000000000000000000000000fffffffffffffffffffffffd */ + sp_256_mont_mul_4(r, r, t3, p256_mod, p256_mp_mod); #endif /* WOLFSSL_SP_SMALL */ } +extern int64_t sp_256_cmp_4(const sp_digit* a, const sp_digit* b); +/* Normalize the values in each word to 64. + * + * a Array of sp_digit to normalize. + */ +#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); /* 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_4(sp_point* r, const sp_point* 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; @@ -6231,9 +6228,9 @@ extern void sp_256_div2_4(sp_digit* r, const sp_digit* a, const sp_digit* m); * p Point to double. * t Temporary ordinate data. */ -static void sp_256_proj_point_dbl_4(sp_point* r, const sp_point* p, sp_digit* t) +static void sp_256_proj_point_dbl_4(sp_point_256* r, const sp_point_256* p, sp_digit* t) { - sp_point* rp[2]; + sp_point_256* rp[2]; sp_digit* t1 = t; sp_digit* t2 = t + 2*4; sp_digit* x; @@ -6245,8 +6242,8 @@ static void sp_256_proj_point_dbl_4(sp_point* r, const sp_point* p, sp_digit* t) rp[0] = r; /*lint allow cast to different type of pointer*/ - rp[1] = (sp_point*)t; /*lint !e9087 !e740*/ - XMEMSET(rp[1], 0, sizeof(sp_point)); + rp[1] = (sp_point_256*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_256)); x = rp[p->infinity]->x; y = rp[p->infinity]->y; z = rp[p->infinity]->z; @@ -6310,10 +6307,10 @@ static void sp_256_proj_point_dbl_4(sp_point* r, const sp_point* p, sp_digit* t) * n Number of times to double * t Temporary ordinate data. */ -static void sp_256_proj_point_dbl_n_4(sp_point* r, const sp_point* p, int n, +static void sp_256_proj_point_dbl_n_4(sp_point_256* r, const sp_point_256* p, int n, sp_digit* t) { - sp_point* rp[2]; + sp_point_256* rp[2]; sp_digit* w = t; sp_digit* a = t + 2*4; sp_digit* b = t + 4*4; @@ -6327,8 +6324,8 @@ static void sp_256_proj_point_dbl_n_4(sp_point* r, const sp_point* p, int n, rp[0] = r; /*lint allow cast to different type of pointer*/ - rp[1] = (sp_point*)t; /*lint !e9087 !e740*/ - XMEMSET(rp[1], 0, sizeof(sp_point)); + rp[1] = (sp_point_256*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_256)); x = rp[p->infinity]->x; y = rp[p->infinity]->y; z = rp[p->infinity]->z; @@ -6399,11 +6396,11 @@ static int sp_256_cmp_equal_4(const sp_digit* a, const sp_digit* b) * q Second point to add. * t Temporary ordinate data. */ -static void sp_256_proj_point_add_4(sp_point* r, const sp_point* p, const sp_point* q, +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* ap[2]; - sp_point* rp[2]; + const sp_point_256* ap[2]; + sp_point_256* rp[2]; sp_digit* t1 = t; sp_digit* t2 = t + 2*4; sp_digit* t3 = t + 4*4; @@ -6416,7 +6413,7 @@ static void sp_256_proj_point_add_4(sp_point* r, const sp_point* p, const sp_poi /* Ensure only the first point is the same as the result. */ if (q == r) { - const sp_point* a = p; + const sp_point_256* a = p; p = q; q = a; } @@ -6432,8 +6429,8 @@ static void sp_256_proj_point_add_4(sp_point* r, const sp_point* p, const sp_poi rp[0] = r; /*lint allow cast to different type of pointer*/ - rp[1] = (sp_point*)t; /*lint !e9087 !e740*/ - XMEMSET(rp[1], 0, sizeof(sp_point)); + rp[1] = (sp_point_256*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_256)); x = rp[p->infinity | q->infinity]->x; y = rp[p->infinity | q->infinity]->y; z = rp[p->infinity | q->infinity]->z; @@ -6493,7 +6490,7 @@ static void sp_256_proj_point_add_4(sp_point* r, const sp_point* p, const sp_poi * n Number of times to double * t Temporary ordinate data. */ -static void sp_256_proj_point_dbl_n_store_4(sp_point* r, const sp_point* p, +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; @@ -6563,8 +6560,8 @@ static void sp_256_proj_point_dbl_n_store_4(sp_point* r, const sp_point* p, * q Second point to add. * t Temporary ordinate data. */ -static void sp_256_proj_point_add_sub_4(sp_point* ra, sp_point* rs, - const sp_point* p, const sp_point* q, sp_digit* t) +static void sp_256_proj_point_add_sub_4(sp_point_256* ra, sp_point_256* rs, + const sp_point_256* p, const sp_point_256* q, sp_digit* t) { sp_digit* t1 = t; sp_digit* t2 = t + 2*4; @@ -6634,12 +6631,12 @@ static void sp_256_proj_point_add_sub_4(sp_point* ra, sp_point* rs, } /* Structure used to describe recoding of scalar multiplication. */ -typedef struct ecc_recode { +typedef struct ecc_recode_256 { /* Index into pre-computation table. */ uint8_t i; /* Use the negative of the point. */ uint8_t neg; -} ecc_recode; +} ecc_recode_256; /* The index into pre-computation table to use. */ static const uint8_t recode_index_4_6[66] = { @@ -6665,7 +6662,7 @@ static const uint8_t recode_neg_4_6[66] = { * k Scalar to multiply by. * v Vector of operations to perform. */ -static void sp_256_ecc_recode_6_4(const sp_digit* k, ecc_recode* v) +static void sp_256_ecc_recode_6_4(const sp_digit* k, ecc_recode_256* v) { int i, j; uint8_t y; @@ -6713,30 +6710,30 @@ static void sp_256_ecc_recode_6_4(const sp_digit* k, ecc_recode* v) * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_win_add_sub_4(sp_point* r, const sp_point* g, +static int sp_256_ecc_mulmod_win_add_sub_4(sp_point_256* r, const sp_point_256* g, const sp_digit* k, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point td[33]; - sp_point rtd, pd; + sp_point_256 td[33]; + sp_point_256 rtd, pd; sp_digit tmpd[2 * 4 * 6]; #endif - sp_point* t; - sp_point* rt; - sp_point* p = NULL; + sp_point_256* t; + sp_point_256* rt; + sp_point_256* p = NULL; sp_digit* tmp; sp_digit* negy; int i; - ecc_recode v[43]; + ecc_recode_256 v[43]; int err; (void)heap; - err = sp_ecc_point_new(heap, rtd, rt); + err = sp_256_point_new_4(heap, rtd, rt); if (err == MP_OKAY) - err = sp_ecc_point_new(heap, pd, p); + err = sp_256_point_new_4(heap, pd, p); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - t = (sp_point*)XMALLOC(sizeof(sp_point) * 33, heap, DYNAMIC_TYPE_ECC); + t = (sp_point_256*)XMALLOC(sizeof(sp_point_256) * 33, heap, DYNAMIC_TYPE_ECC); if (t == NULL) err = MEMORY_E; tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 4 * 6, heap, @@ -6792,11 +6789,11 @@ static int sp_256_ecc_mulmod_win_add_sub_4(sp_point* r, const sp_point* g, sp_256_ecc_recode_6_4(k, v); i = 42; - XMEMCPY(rt, &t[v[i].i], sizeof(sp_point)); + XMEMCPY(rt, &t[v[i].i], sizeof(sp_point_256)); for (--i; i>=0; i--) { sp_256_proj_point_dbl_n_4(rt, rt, 6, tmp); - XMEMCPY(p, &t[v[i].i], sizeof(sp_point)); + XMEMCPY(p, &t[v[i].i], sizeof(sp_point_256)); sp_256_sub_4(negy, p256_mod, p->y); sp_256_cond_copy_4(p->y, negy, (sp_digit)0 - v[i].neg); sp_256_proj_point_add_4(rt, rt, p, tmp); @@ -6806,7 +6803,7 @@ static int sp_256_ecc_mulmod_win_add_sub_4(sp_point* r, const sp_point* g, sp_256_map_4(r, rt, tmp); } else { - XMEMCPY(r, rt, sizeof(sp_point)); + XMEMCPY(r, rt, sizeof(sp_point_256)); } } @@ -6816,8 +6813,8 @@ static int sp_256_ecc_mulmod_win_add_sub_4(sp_point* r, const sp_point* g, if (tmp != NULL) XFREE(tmp, heap, DYNAMIC_TYPE_ECC); #endif - sp_ecc_point_free(p, 0, heap); - sp_ecc_point_free(rt, 0, heap); + sp_256_point_free_4(p, 0, heap); + sp_256_point_free_4(rt, 0, heap); return err; } @@ -6861,61 +6858,56 @@ static void sp_256_mont_inv_avx2_4(sp_digit* r, const sp_digit* a, sp_digit* td) XMEMCPY(t, a, sizeof(sp_digit) * 4); for (i=254; i>=0; i--) { sp_256_mont_sqr_avx2_4(t, t, p256_mod, p256_mp_mod); - if (p256_mod_2[i / 64] & ((sp_digit)1 << (i % 64))) + if (p256_mod_minus_2[i / 64] & ((sp_digit)1 << (i % 64))) sp_256_mont_mul_avx2_4(t, t, a, p256_mod, p256_mp_mod); } XMEMCPY(r, t, sizeof(sp_digit) * 4); #else - sp_digit* t = td; + sp_digit* t1 = td; sp_digit* t2 = td + 2 * 4; sp_digit* t3 = td + 4 * 4; - - /* t = a^2 */ - sp_256_mont_sqr_avx2_4(t, a, p256_mod, p256_mp_mod); - /* t = a^3 = t * a */ - sp_256_mont_mul_avx2_4(t, t, a, p256_mod, p256_mp_mod); - /* t2= a^c = t ^ 2 ^ 2 */ - sp_256_mont_sqr_n_avx2_4(t2, t, 2, p256_mod, p256_mp_mod); - /* t3= a^d = t2 * a */ - sp_256_mont_mul_avx2_4(t3, t2, a, p256_mod, p256_mp_mod); - /* t = a^f = t2 * t */ - sp_256_mont_mul_avx2_4(t, t2, t, p256_mod, p256_mp_mod); - /* t2= a^f0 = t ^ 2 ^ 4 */ - sp_256_mont_sqr_n_avx2_4(t2, t, 4, p256_mod, p256_mp_mod); - /* t3= a^fd = t2 * t3 */ - sp_256_mont_mul_avx2_4(t3, t2, t3, p256_mod, p256_mp_mod); - /* t = a^ff = t2 * t */ - sp_256_mont_mul_avx2_4(t, t2, t, p256_mod, p256_mp_mod); - /* t2= a^ff00 = t ^ 2 ^ 8 */ - sp_256_mont_sqr_n_avx2_4(t2, t, 8, p256_mod, p256_mp_mod); - /* t3= a^fffd = t2 * t3 */ - sp_256_mont_mul_avx2_4(t3, t2, t3, p256_mod, p256_mp_mod); - /* t = a^ffff = t2 * t */ - sp_256_mont_mul_avx2_4(t, t2, t, p256_mod, p256_mp_mod); - /* t2= a^ffff0000 = t ^ 2 ^ 16 */ - sp_256_mont_sqr_n_avx2_4(t2, t, 16, p256_mod, p256_mp_mod); - /* t3= a^fffffffd = t2 * t3 */ - sp_256_mont_mul_avx2_4(t3, t2, t3, p256_mod, p256_mp_mod); - /* t = a^ffffffff = t2 * t */ - sp_256_mont_mul_avx2_4(t, t2, t, p256_mod, p256_mp_mod); - /* t = a^ffffffff00000000 = t ^ 2 ^ 32 */ - sp_256_mont_sqr_n_avx2_4(t2, t, 32, p256_mod, p256_mp_mod); - /* t2= a^ffffffffffffffff = t2 * t */ - sp_256_mont_mul_avx2_4(t, t2, t, p256_mod, p256_mp_mod); - /* t2= a^ffffffff00000001 = t2 * a */ - sp_256_mont_mul_avx2_4(t2, t2, a, p256_mod, p256_mp_mod); - /* t2= a^ffffffff000000010000000000000000000000000000000000000000 - * = t2 ^ 2 ^ 160 */ - sp_256_mont_sqr_n_avx2_4(t2, t2, 160, p256_mod, p256_mp_mod); - /* t2= a^ffffffff00000001000000000000000000000000ffffffffffffffff - * = t2 * t */ - sp_256_mont_mul_avx2_4(t2, t2, t, p256_mod, p256_mp_mod); - /* t2= a^ffffffff00000001000000000000000000000000ffffffffffffffff00000000 - * = t2 ^ 2 ^ 32 */ - sp_256_mont_sqr_n_avx2_4(t2, t2, 32, p256_mod, p256_mp_mod); - /* r = a^ffffffff00000001000000000000000000000000fffffffffffffffffffffffd - * = t2 * t3 */ - sp_256_mont_mul_avx2_4(r, t2, t3, p256_mod, p256_mp_mod); + /* 0x2 */ + sp_256_mont_sqr_avx2_4(t1, a, p256_mod, p256_mp_mod); + /* 0x3 */ + sp_256_mont_mul_avx2_4(t2, t1, a, p256_mod, p256_mp_mod); + /* 0xc */ + sp_256_mont_sqr_n_avx2_4(t1, t2, 2, p256_mod, p256_mp_mod); + /* 0xd */ + sp_256_mont_mul_avx2_4(t3, t1, a, p256_mod, p256_mp_mod); + /* 0xf */ + sp_256_mont_mul_avx2_4(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xf0 */ + sp_256_mont_sqr_n_avx2_4(t1, t2, 4, p256_mod, p256_mp_mod); + /* 0xfd */ + sp_256_mont_mul_avx2_4(t3, t3, t1, p256_mod, p256_mp_mod); + /* 0xff */ + sp_256_mont_mul_avx2_4(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xff00 */ + sp_256_mont_sqr_n_avx2_4(t1, t2, 8, p256_mod, p256_mp_mod); + /* 0xfffd */ + sp_256_mont_mul_avx2_4(t3, t3, t1, p256_mod, p256_mp_mod); + /* 0xffff */ + sp_256_mont_mul_avx2_4(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xffff0000 */ + sp_256_mont_sqr_n_avx2_4(t1, t2, 16, p256_mod, p256_mp_mod); + /* 0xfffffffd */ + sp_256_mont_mul_avx2_4(t3, t3, t1, p256_mod, p256_mp_mod); + /* 0xffffffff */ + sp_256_mont_mul_avx2_4(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xffffffff00000000 */ + sp_256_mont_sqr_n_avx2_4(t1, t2, 32, p256_mod, p256_mp_mod); + /* 0xffffffffffffffff */ + sp_256_mont_mul_avx2_4(t2, t2, t1, p256_mod, p256_mp_mod); + /* 0xffffffff00000001 */ + sp_256_mont_mul_avx2_4(r, t1, a, p256_mod, p256_mp_mod); + /* 0xffffffff000000010000000000000000000000000000000000000000 */ + sp_256_mont_sqr_n_avx2_4(r, r, 160, p256_mod, p256_mp_mod); + /* 0xffffffff00000001000000000000000000000000ffffffffffffffff */ + sp_256_mont_mul_avx2_4(r, r, t2, p256_mod, p256_mp_mod); + /* 0xffffffff00000001000000000000000000000000ffffffffffffffff00000000 */ + sp_256_mont_sqr_n_avx2_4(r, r, 32, p256_mod, p256_mp_mod); + /* 0xffffffff00000001000000000000000000000000fffffffffffffffffffffffd */ + sp_256_mont_mul_avx2_4(r, r, t3, p256_mod, p256_mp_mod); #endif /* WOLFSSL_SP_SMALL */ } @@ -6925,7 +6917,7 @@ static void sp_256_mont_inv_avx2_4(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_avx2_4(sp_point* r, const sp_point* 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; @@ -6967,9 +6959,9 @@ static void sp_256_map_avx2_4(sp_point* r, const sp_point* p, sp_digit* t) * p Point to double. * t Temporary ordinate data. */ -static void sp_256_proj_point_dbl_avx2_4(sp_point* r, const sp_point* p, sp_digit* t) +static void sp_256_proj_point_dbl_avx2_4(sp_point_256* r, const sp_point_256* p, sp_digit* t) { - sp_point* rp[2]; + sp_point_256* rp[2]; sp_digit* t1 = t; sp_digit* t2 = t + 2*4; sp_digit* x; @@ -6981,8 +6973,8 @@ static void sp_256_proj_point_dbl_avx2_4(sp_point* r, const sp_point* p, sp_digi rp[0] = r; /*lint allow cast to different type of pointer*/ - rp[1] = (sp_point*)t; /*lint !e9087 !e740*/ - XMEMSET(rp[1], 0, sizeof(sp_point)); + rp[1] = (sp_point_256*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_256)); x = rp[p->infinity]->x; y = rp[p->infinity]->y; z = rp[p->infinity]->z; @@ -7046,10 +7038,10 @@ static void sp_256_proj_point_dbl_avx2_4(sp_point* r, const sp_point* p, sp_digi * n Number of times to double * t Temporary ordinate data. */ -static void sp_256_proj_point_dbl_n_avx2_4(sp_point* r, const sp_point* p, int n, +static void sp_256_proj_point_dbl_n_avx2_4(sp_point_256* r, const sp_point_256* p, int n, sp_digit* t) { - sp_point* rp[2]; + sp_point_256* rp[2]; sp_digit* w = t; sp_digit* a = t + 2*4; sp_digit* b = t + 4*4; @@ -7063,8 +7055,8 @@ static void sp_256_proj_point_dbl_n_avx2_4(sp_point* r, const sp_point* p, int n rp[0] = r; /*lint allow cast to different type of pointer*/ - rp[1] = (sp_point*)t; /*lint !e9087 !e740*/ - XMEMSET(rp[1], 0, sizeof(sp_point)); + rp[1] = (sp_point_256*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_256)); x = rp[p->infinity]->x; y = rp[p->infinity]->y; z = rp[p->infinity]->z; @@ -7123,11 +7115,11 @@ static void sp_256_proj_point_dbl_n_avx2_4(sp_point* r, const sp_point* p, int n * q Second point to add. * t Temporary ordinate data. */ -static void sp_256_proj_point_add_avx2_4(sp_point* r, const sp_point* p, const sp_point* q, +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* ap[2]; - sp_point* rp[2]; + const sp_point_256* ap[2]; + sp_point_256* rp[2]; sp_digit* t1 = t; sp_digit* t2 = t + 2*4; sp_digit* t3 = t + 4*4; @@ -7140,7 +7132,7 @@ static void sp_256_proj_point_add_avx2_4(sp_point* r, const sp_point* p, const s /* Ensure only the first point is the same as the result. */ if (q == r) { - const sp_point* a = p; + const sp_point_256* a = p; p = q; q = a; } @@ -7156,8 +7148,8 @@ static void sp_256_proj_point_add_avx2_4(sp_point* r, const sp_point* p, const s rp[0] = r; /*lint allow cast to different type of pointer*/ - rp[1] = (sp_point*)t; /*lint !e9087 !e740*/ - XMEMSET(rp[1], 0, sizeof(sp_point)); + rp[1] = (sp_point_256*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_256)); x = rp[p->infinity | q->infinity]->x; y = rp[p->infinity | q->infinity]->y; z = rp[p->infinity | q->infinity]->z; @@ -7217,7 +7209,7 @@ static void sp_256_proj_point_add_avx2_4(sp_point* r, const sp_point* p, const s * n Number of times to double * t Temporary ordinate data. */ -static void sp_256_proj_point_dbl_n_store_avx2_4(sp_point* r, const sp_point* p, +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; @@ -7287,8 +7279,8 @@ static void sp_256_proj_point_dbl_n_store_avx2_4(sp_point* r, const sp_point* p, * q Second point to add. * t Temporary ordinate data. */ -static void sp_256_proj_point_add_sub_avx2_4(sp_point* ra, sp_point* rs, - const sp_point* p, const sp_point* q, sp_digit* t) +static void sp_256_proj_point_add_sub_avx2_4(sp_point_256* ra, sp_point_256* rs, + const sp_point_256* p, const sp_point_256* q, sp_digit* t) { sp_digit* t1 = t; sp_digit* t2 = t + 2*4; @@ -7367,30 +7359,30 @@ static void sp_256_proj_point_add_sub_avx2_4(sp_point* ra, sp_point* rs, * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_win_add_sub_avx2_4(sp_point* r, const sp_point* g, +static int sp_256_ecc_mulmod_win_add_sub_avx2_4(sp_point_256* r, const sp_point_256* g, const sp_digit* k, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point td[33]; - sp_point rtd, pd; + sp_point_256 td[33]; + sp_point_256 rtd, pd; sp_digit tmpd[2 * 4 * 6]; #endif - sp_point* t; - sp_point* rt; - sp_point* p = NULL; + sp_point_256* t; + sp_point_256* rt; + sp_point_256* p = NULL; sp_digit* tmp; sp_digit* negy; int i; - ecc_recode v[43]; + ecc_recode_256 v[43]; int err; (void)heap; - err = sp_ecc_point_new(heap, rtd, rt); + err = sp_256_point_new_4(heap, rtd, rt); if (err == MP_OKAY) - err = sp_ecc_point_new(heap, pd, p); + err = sp_256_point_new_4(heap, pd, p); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - t = (sp_point*)XMALLOC(sizeof(sp_point) * 33, heap, DYNAMIC_TYPE_ECC); + t = (sp_point_256*)XMALLOC(sizeof(sp_point_256) * 33, heap, DYNAMIC_TYPE_ECC); if (t == NULL) err = MEMORY_E; tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 4 * 6, heap, @@ -7446,11 +7438,11 @@ static int sp_256_ecc_mulmod_win_add_sub_avx2_4(sp_point* r, const sp_point* g, sp_256_ecc_recode_6_4(k, v); i = 42; - XMEMCPY(rt, &t[v[i].i], sizeof(sp_point)); + XMEMCPY(rt, &t[v[i].i], sizeof(sp_point_256)); for (--i; i>=0; i--) { sp_256_proj_point_dbl_n_avx2_4(rt, rt, 6, tmp); - XMEMCPY(p, &t[v[i].i], sizeof(sp_point)); + XMEMCPY(p, &t[v[i].i], sizeof(sp_point_256)); sp_256_sub_4(negy, p256_mod, p->y); 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); @@ -7460,7 +7452,7 @@ static int sp_256_ecc_mulmod_win_add_sub_avx2_4(sp_point* r, const sp_point* g, sp_256_map_avx2_4(r, rt, tmp); } else { - XMEMCPY(r, rt, sizeof(sp_point)); + XMEMCPY(r, rt, sizeof(sp_point_256)); } } @@ -7470,18 +7462,18 @@ static int sp_256_ecc_mulmod_win_add_sub_avx2_4(sp_point* r, const sp_point* g, if (tmp != NULL) XFREE(tmp, heap, DYNAMIC_TYPE_ECC); #endif - sp_ecc_point_free(p, 0, heap); - sp_ecc_point_free(rt, 0, heap); + sp_256_point_free_4(p, 0, heap); + sp_256_point_free_4(rt, 0, heap); return err; } #endif /* HAVE_INTEL_AVX2 */ /* A table entry for pre-computed points. */ -typedef struct sp_table_entry { +typedef struct sp_table_entry_256 { sp_digit x[4]; sp_digit y[4]; -} sp_table_entry; +} sp_table_entry_256; #if defined(FP_ECC) || defined(WOLFSSL_SP_SMALL) #endif /* FP_ECC || WOLFSSL_SP_SMALL */ @@ -7494,11 +7486,11 @@ typedef struct sp_table_entry { * q Second point to add. * t Temporary ordinate data. */ -static void sp_256_proj_point_add_qz1_4(sp_point* r, const sp_point* p, - const sp_point* q, sp_digit* t) +static void sp_256_proj_point_add_qz1_4(sp_point_256* r, const sp_point_256* p, + const sp_point_256* q, sp_digit* t) { - const sp_point* ap[2]; - sp_point* rp[2]; + const sp_point_256* ap[2]; + sp_point_256* rp[2]; sp_digit* t1 = t; sp_digit* t2 = t + 2*4; sp_digit* t3 = t + 4*4; @@ -7520,8 +7512,8 @@ static void sp_256_proj_point_add_qz1_4(sp_point* r, const sp_point* p, rp[0] = r; /*lint allow cast to different type of pointer*/ - rp[1] = (sp_point*)t; /*lint !e9087 !e740*/ - XMEMSET(rp[1], 0, sizeof(sp_point)); + rp[1] = (sp_point_256*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_256)); x = rp[p->infinity | q->infinity]->x; y = rp[p->infinity | q->infinity]->y; z = rp[p->infinity | q->infinity]->z; @@ -7574,7 +7566,7 @@ static void sp_256_proj_point_add_qz1_4(sp_point* r, const sp_point* p, * a Point to convert. * t Temporary data. */ -static void sp_256_proj_to_affine_4(sp_point* a, sp_digit* t) +static void sp_256_proj_to_affine_4(sp_point_256* a, sp_digit* t) { sp_digit* t1 = t; sp_digit* t2 = t + 2 * 4; @@ -7597,26 +7589,26 @@ static void sp_256_proj_to_affine_4(sp_point* a, sp_digit* t) * tmp Temporary data. * heap Heap to use for allocation. */ -static int sp_256_gen_stripe_table_4(const sp_point* a, - sp_table_entry* table, sp_digit* tmp, void* heap) +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) - sp_point td, s1d, s2d; + sp_point_256 td, s1d, s2d; #endif - sp_point* t; - sp_point* s1 = NULL; - sp_point* s2 = NULL; + sp_point_256* t; + sp_point_256* s1 = NULL; + sp_point_256* s2 = NULL; int i, j; int err; (void)heap; - err = sp_ecc_point_new(heap, td, t); + err = sp_256_point_new_4(heap, td, t); if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, s1d, s1); + err = sp_256_point_new_4(heap, s1d, s1); } if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, s2d, s2); + err = sp_256_point_new_4(heap, s2d, s2); } if (err == MP_OKAY) { @@ -7638,7 +7630,7 @@ static int sp_256_gen_stripe_table_4(const sp_point* a, s2->infinity = 0; /* table[0] = {0, 0, infinity} */ - XMEMSET(&table[0], 0, sizeof(sp_table_entry)); + XMEMSET(&table[0], 0, sizeof(sp_table_entry_256)); /* 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)); @@ -7664,9 +7656,9 @@ static int sp_256_gen_stripe_table_4(const sp_point* a, } } - sp_ecc_point_free(s2, 0, heap); - sp_ecc_point_free(s1, 0, heap); - sp_ecc_point_free( t, 0, heap); + sp_256_point_free_4(s2, 0, heap); + sp_256_point_free_4(s1, 0, heap); + sp_256_point_free_4( t, 0, heap); return err; } @@ -7682,16 +7674,16 @@ static int sp_256_gen_stripe_table_4(const sp_point* a, * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_stripe_4(sp_point* r, const sp_point* g, - const sp_table_entry* table, const sp_digit* k, int map, void* heap) +static int sp_256_ecc_mulmod_stripe_4(sp_point_256* r, const sp_point_256* g, + const sp_table_entry_256* table, const sp_digit* k, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point rtd; - sp_point pd; + sp_point_256 rtd; + sp_point_256 pd; sp_digit td[2 * 4 * 5]; #endif - sp_point* rt; - sp_point* p = NULL; + sp_point_256* rt; + sp_point_256* p = NULL; sp_digit* t; int i, j; int y, x; @@ -7700,9 +7692,10 @@ static int sp_256_ecc_mulmod_stripe_4(sp_point* r, const sp_point* g, (void)g; (void)heap; - err = sp_ecc_point_new(heap, rtd, rt); + + err = sp_256_point_new_4(heap, rtd, rt); if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, pd, p); + err = sp_256_point_new_4(heap, pd, p); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 4 * 5, heap, @@ -7742,7 +7735,7 @@ static int sp_256_ecc_mulmod_stripe_4(sp_point* r, const sp_point* g, sp_256_map_4(r, rt, t); } else { - XMEMCPY(r, rt, sizeof(sp_point)); + XMEMCPY(r, rt, sizeof(sp_point_256)); } } @@ -7751,8 +7744,8 @@ static int sp_256_ecc_mulmod_stripe_4(sp_point* r, const sp_point* g, XFREE(t, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(p, 0, heap); - sp_ecc_point_free(rt, 0, heap); + sp_256_point_free_4(p, 0, heap); + sp_256_point_free_4(rt, 0, heap); return err; } @@ -7763,43 +7756,43 @@ static int sp_256_ecc_mulmod_stripe_4(sp_point* r, const sp_point* g, #define FP_ENTRIES 16 #endif -typedef struct sp_cache_t { +typedef struct sp_cache_256_t { sp_digit x[4]; sp_digit y[4]; - sp_table_entry table[256]; + sp_table_entry_256 table[256]; uint32_t cnt; int set; -} sp_cache_t; +} sp_cache_256_t; -static THREAD_LS_T sp_cache_t sp_cache[FP_ENTRIES]; -static THREAD_LS_T int sp_cache_last = -1; -static THREAD_LS_T int sp_cache_inited = 0; +static THREAD_LS_T sp_cache_256_t sp_cache_256[FP_ENTRIES]; +static THREAD_LS_T int sp_cache_256_last = -1; +static THREAD_LS_T int sp_cache_256_inited = 0; #ifndef HAVE_THREAD_LS - static volatile int initCacheMutex = 0; - static wolfSSL_Mutex sp_cache_lock; + static volatile int initCacheMutex_256 = 0; + static wolfSSL_Mutex sp_cache_256_lock; #endif -static void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache) +static void sp_ecc_get_cache_256(const sp_point_256* g, sp_cache_256_t** cache) { int i, j; uint32_t least; - if (sp_cache_inited == 0) { + if (sp_cache_256_inited == 0) { for (i=0; ix, sp_cache[i].x) & - sp_256_cmp_equal_4(g->y, sp_cache[i].y)) { - sp_cache[i].cnt++; + if (sp_256_cmp_equal_4(g->x, sp_cache_256[i].x) & + sp_256_cmp_equal_4(g->y, sp_cache_256[i].y)) { + sp_cache_256[i].cnt++; break; } } @@ -7807,32 +7800,32 @@ static void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache) /* No match. */ if (i == FP_ENTRIES) { /* Find empty entry. */ - i = (sp_cache_last + 1) % FP_ENTRIES; - for (; i != sp_cache_last; i=(i+1)%FP_ENTRIES) { - if (!sp_cache[i].set) { + i = (sp_cache_256_last + 1) % FP_ENTRIES; + for (; i != sp_cache_256_last; i=(i+1)%FP_ENTRIES) { + if (!sp_cache_256[i].set) { break; } } /* Evict least used. */ - if (i == sp_cache_last) { - least = sp_cache[0].cnt; + if (i == sp_cache_256_last) { + least = sp_cache_256[0].cnt; for (j=1; jx, sizeof(sp_cache[i].x)); - XMEMCPY(sp_cache[i].y, g->y, sizeof(sp_cache[i].y)); - sp_cache[i].set = 1; - sp_cache[i].cnt = 1; + XMEMCPY(sp_cache_256[i].x, g->x, sizeof(sp_cache_256[i].x)); + XMEMCPY(sp_cache_256[i].y, g->y, sizeof(sp_cache_256[i].y)); + sp_cache_256[i].set = 1; + sp_cache_256[i].cnt = 1; } - *cache = &sp_cache[i]; - sp_cache_last = i; + *cache = &sp_cache_256[i]; + sp_cache_256_last = i; } #endif /* FP_ECC */ @@ -7846,32 +7839,32 @@ static void sp_ecc_get_cache(const sp_point* g, sp_cache_t** cache) * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_4(sp_point* r, const sp_point* g, const sp_digit* k, +static int sp_256_ecc_mulmod_4(sp_point_256* r, const sp_point_256* g, const sp_digit* k, int map, void* heap) { #ifndef FP_ECC return sp_256_ecc_mulmod_win_add_sub_4(r, g, k, map, heap); #else sp_digit tmp[2 * 4 * 5]; - sp_cache_t* cache; + sp_cache_256_t* cache; int err = MP_OKAY; #ifndef HAVE_THREAD_LS - if (initCacheMutex == 0) { - wc_InitMutex(&sp_cache_lock); - initCacheMutex = 1; + if (initCacheMutex_256 == 0) { + wc_InitMutex(&sp_cache_256_lock); + initCacheMutex_256 = 1; } - if (wc_LockMutex(&sp_cache_lock) != 0) + if (wc_LockMutex(&sp_cache_256_lock) != 0) err = BAD_MUTEX_E; #endif /* HAVE_THREAD_LS */ if (err == MP_OKAY) { - sp_ecc_get_cache(g, &cache); + sp_ecc_get_cache_256(g, &cache); if (cache->cnt == 2) sp_256_gen_stripe_table_4(g, cache->table, tmp, heap); #ifndef HAVE_THREAD_LS - wc_UnLockMutex(&sp_cache_lock); + wc_UnLockMutex(&sp_cache_256_lock); #endif /* HAVE_THREAD_LS */ if (cache->cnt < 2) { @@ -7899,11 +7892,11 @@ static int sp_256_ecc_mulmod_4(sp_point* r, const sp_point* g, const sp_digit* k * q Second point to add. * t Temporary ordinate data. */ -static void sp_256_proj_point_add_qz1_avx2_4(sp_point* r, const sp_point* p, - const sp_point* q, sp_digit* t) +static void sp_256_proj_point_add_qz1_avx2_4(sp_point_256* r, const sp_point_256* p, + const sp_point_256* q, sp_digit* t) { - const sp_point* ap[2]; - sp_point* rp[2]; + const sp_point_256* ap[2]; + sp_point_256* rp[2]; sp_digit* t1 = t; sp_digit* t2 = t + 2*4; sp_digit* t3 = t + 4*4; @@ -7925,8 +7918,8 @@ static void sp_256_proj_point_add_qz1_avx2_4(sp_point* r, const sp_point* p, rp[0] = r; /*lint allow cast to different type of pointer*/ - rp[1] = (sp_point*)t; /*lint !e9087 !e740*/ - XMEMSET(rp[1], 0, sizeof(sp_point)); + rp[1] = (sp_point_256*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_256)); x = rp[p->infinity | q->infinity]->x; y = rp[p->infinity | q->infinity]->y; z = rp[p->infinity | q->infinity]->z; @@ -7979,7 +7972,7 @@ static void sp_256_proj_point_add_qz1_avx2_4(sp_point* r, const sp_point* p, * a Point to convert. * t Temporary data. */ -static void sp_256_proj_to_affine_avx2_4(sp_point* a, sp_digit* t) +static void sp_256_proj_to_affine_avx2_4(sp_point_256* a, sp_digit* t) { sp_digit* t1 = t; sp_digit* t2 = t + 2 * 4; @@ -8002,26 +7995,26 @@ static void sp_256_proj_to_affine_avx2_4(sp_point* a, sp_digit* t) * tmp Temporary data. * heap Heap to use for allocation. */ -static int sp_256_gen_stripe_table_avx2_4(const sp_point* a, - sp_table_entry* table, sp_digit* tmp, void* heap) +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) - sp_point td, s1d, s2d; + sp_point_256 td, s1d, s2d; #endif - sp_point* t; - sp_point* s1 = NULL; - sp_point* s2 = NULL; + sp_point_256* t; + sp_point_256* s1 = NULL; + sp_point_256* s2 = NULL; int i, j; int err; (void)heap; - err = sp_ecc_point_new(heap, td, t); + err = sp_256_point_new_4(heap, td, t); if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, s1d, s1); + err = sp_256_point_new_4(heap, s1d, s1); } if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, s2d, s2); + err = sp_256_point_new_4(heap, s2d, s2); } if (err == MP_OKAY) { @@ -8043,7 +8036,7 @@ static int sp_256_gen_stripe_table_avx2_4(const sp_point* a, s2->infinity = 0; /* table[0] = {0, 0, infinity} */ - XMEMSET(&table[0], 0, sizeof(sp_table_entry)); + XMEMSET(&table[0], 0, sizeof(sp_table_entry_256)); /* 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)); @@ -8069,9 +8062,9 @@ static int sp_256_gen_stripe_table_avx2_4(const sp_point* a, } } - sp_ecc_point_free(s2, 0, heap); - sp_ecc_point_free(s1, 0, heap); - sp_ecc_point_free( t, 0, heap); + sp_256_point_free_4(s2, 0, heap); + sp_256_point_free_4(s1, 0, heap); + sp_256_point_free_4( t, 0, heap); return err; } @@ -8087,16 +8080,16 @@ static int sp_256_gen_stripe_table_avx2_4(const sp_point* a, * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_stripe_avx2_4(sp_point* r, const sp_point* g, - const sp_table_entry* table, const sp_digit* k, int map, void* heap) +static int sp_256_ecc_mulmod_stripe_avx2_4(sp_point_256* r, const sp_point_256* g, + const sp_table_entry_256* table, const sp_digit* k, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point rtd; - sp_point pd; + sp_point_256 rtd; + sp_point_256 pd; sp_digit td[2 * 4 * 5]; #endif - sp_point* rt; - sp_point* p = NULL; + sp_point_256* rt; + sp_point_256* p = NULL; sp_digit* t; int i, j; int y, x; @@ -8105,9 +8098,10 @@ static int sp_256_ecc_mulmod_stripe_avx2_4(sp_point* r, const sp_point* g, (void)g; (void)heap; - err = sp_ecc_point_new(heap, rtd, rt); + + err = sp_256_point_new_4(heap, rtd, rt); if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, pd, p); + err = sp_256_point_new_4(heap, pd, p); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) t = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 4 * 5, heap, @@ -8147,7 +8141,7 @@ static int sp_256_ecc_mulmod_stripe_avx2_4(sp_point* r, const sp_point* g, sp_256_map_avx2_4(r, rt, t); } else { - XMEMCPY(r, rt, sizeof(sp_point)); + XMEMCPY(r, rt, sizeof(sp_point_256)); } } @@ -8156,8 +8150,8 @@ static int sp_256_ecc_mulmod_stripe_avx2_4(sp_point* r, const sp_point* g, XFREE(t, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(p, 0, heap); - sp_ecc_point_free(rt, 0, heap); + sp_256_point_free_4(p, 0, heap); + sp_256_point_free_4(rt, 0, heap); return err; } @@ -8173,32 +8167,32 @@ static int sp_256_ecc_mulmod_stripe_avx2_4(sp_point* r, const sp_point* g, * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_avx2_4(sp_point* r, const sp_point* g, const sp_digit* k, +static int sp_256_ecc_mulmod_avx2_4(sp_point_256* r, const sp_point_256* g, const sp_digit* k, int map, void* heap) { #ifndef FP_ECC return sp_256_ecc_mulmod_win_add_sub_avx2_4(r, g, k, map, heap); #else sp_digit tmp[2 * 4 * 5]; - sp_cache_t* cache; + sp_cache_256_t* cache; int err = MP_OKAY; #ifndef HAVE_THREAD_LS - if (initCacheMutex == 0) { - wc_InitMutex(&sp_cache_lock); - initCacheMutex = 1; + if (initCacheMutex_256 == 0) { + wc_InitMutex(&sp_cache_256_lock); + initCacheMutex_256 = 1; } - if (wc_LockMutex(&sp_cache_lock) != 0) + if (wc_LockMutex(&sp_cache_256_lock) != 0) err = BAD_MUTEX_E; #endif /* HAVE_THREAD_LS */ if (err == MP_OKAY) { - sp_ecc_get_cache(g, &cache); + sp_ecc_get_cache_256(g, &cache); if (cache->cnt == 2) sp_256_gen_stripe_table_avx2_4(g, cache->table, tmp, heap); #ifndef HAVE_THREAD_LS - wc_UnLockMutex(&sp_cache_lock); + wc_UnLockMutex(&sp_cache_256_lock); #endif /* HAVE_THREAD_LS */ if (cache->cnt < 2) { @@ -8229,18 +8223,17 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point p; - sp_digit k[4]; -#else - sp_digit* k = NULL; + sp_point_256 p; + sp_digit kd[4]; #endif - sp_point* point; - int err; + sp_point_256* point; + sp_digit* k = NULL; + int err = MP_OKAY; #ifdef HAVE_INTEL_AVX2 word32 cpuid_flags = cpuid_get_flags(); #endif - err = sp_ecc_point_new(heap, p, point); + err = sp_256_point_new_4(heap, p, point); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4, heap, @@ -8248,6 +8241,8 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, if (k == NULL) err = MEMORY_E; } +#else + k = kd; #endif if (err == MP_OKAY) { sp_256_from_mp(k, 4, km); @@ -8269,13 +8264,13 @@ int sp_ecc_mulmod_256(mp_int* km, ecc_point* gm, ecc_point* r, int map, XFREE(k, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(point, 0, heap); + sp_256_point_free_4(point, 0, heap); return err; } #ifdef WOLFSSL_SP_SMALL -static const sp_table_entry p256_table[256] = { +static const sp_table_entry_256 p256_table[256] = { /* 0 */ { { 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00 } }, @@ -9565,7 +9560,7 @@ static const sp_table_entry p256_table[256] = { * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_base_4(sp_point* r, const sp_digit* k, +static int sp_256_ecc_mulmod_base_4(sp_point_256* r, const sp_digit* k, int map, void* heap) { return sp_256_ecc_mulmod_stripe_4(r, &p256_base, p256_table, @@ -9582,7 +9577,7 @@ static int sp_256_ecc_mulmod_base_4(sp_point* r, const sp_digit* k, * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_base_avx2_4(sp_point* r, const sp_digit* k, +static int sp_256_ecc_mulmod_base_avx2_4(sp_point_256* r, const sp_digit* k, int map, void* heap) { return sp_256_ecc_mulmod_stripe_avx2_4(r, &p256_base, p256_table, @@ -9623,7 +9618,7 @@ static const uint8_t recode_neg_4_7[130] = { * k Scalar to multiply by. * v Vector of operations to perform. */ -static void sp_256_ecc_recode_7_4(const sp_digit* k, ecc_recode* v) +static void sp_256_ecc_recode_7_4(const sp_digit* k, ecc_recode_256* v) { int i, j; uint8_t y; @@ -9661,7 +9656,7 @@ static void sp_256_ecc_recode_7_4(const sp_digit* k, ecc_recode* v) } } -static const sp_table_entry p256_table[2405] = { +static const sp_table_entry_256 p256_table[2405] = { /* 0 << 0 */ { { 0x00, 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x00, 0x00 } }, @@ -21624,28 +21619,28 @@ static const sp_table_entry p256_table[2405] = { * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_add_only_4(sp_point* r, const sp_point* g, - const sp_table_entry* table, const sp_digit* k, int map, void* heap) +static int sp_256_ecc_mulmod_add_only_4(sp_point_256* r, const sp_point_256* g, + const sp_table_entry_256* table, const sp_digit* k, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point rtd; - sp_point pd; + sp_point_256 rtd; + sp_point_256 pd; sp_digit tmpd[2 * 4 * 5]; #endif - sp_point* rt; - sp_point* p = NULL; + sp_point_256* rt; + sp_point_256* p = NULL; sp_digit* tmp; sp_digit* negy; int i; - ecc_recode v[37]; + ecc_recode_256 v[37]; int err; (void)g; (void)heap; - err = sp_ecc_point_new(heap, rtd, rt); + err = sp_256_point_new_4(heap, rtd, rt); if (err == MP_OKAY) - err = sp_ecc_point_new(heap, pd, p); + err = sp_256_point_new_4(heap, pd, p); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 4 * 5, heap, DYNAMIC_TYPE_ECC); @@ -21678,7 +21673,7 @@ static int sp_256_ecc_mulmod_add_only_4(sp_point* r, const sp_point* g, sp_256_map_4(r, rt, tmp); } else { - XMEMCPY(r, rt, sizeof(sp_point)); + XMEMCPY(r, rt, sizeof(sp_point_256)); } } @@ -21690,8 +21685,8 @@ static int sp_256_ecc_mulmod_add_only_4(sp_point* r, const sp_point* g, #else ForceZero(tmp, sizeof(sp_digit) * 2 * 4 * 5); #endif - sp_ecc_point_free(p, 0, heap); - sp_ecc_point_free(rt, 0, heap); + sp_256_point_free_4(p, 0, heap); + sp_256_point_free_4(rt, 0, heap); return MP_OKAY; } @@ -21705,7 +21700,7 @@ static int sp_256_ecc_mulmod_add_only_4(sp_point* r, const sp_point* g, * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_base_4(sp_point* r, const sp_digit* k, +static int sp_256_ecc_mulmod_base_4(sp_point_256* r, const sp_digit* k, int map, void* heap) { return sp_256_ecc_mulmod_add_only_4(r, NULL, p256_table, @@ -21722,28 +21717,28 @@ static int sp_256_ecc_mulmod_base_4(sp_point* r, const sp_digit* k, * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_add_only_avx2_4(sp_point* r, const sp_point* g, - const sp_table_entry* table, const sp_digit* k, int map, void* heap) +static int sp_256_ecc_mulmod_add_only_avx2_4(sp_point_256* r, const sp_point_256* g, + const sp_table_entry_256* table, const sp_digit* k, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point rtd; - sp_point pd; + sp_point_256 rtd; + sp_point_256 pd; sp_digit tmpd[2 * 4 * 5]; #endif - sp_point* rt; - sp_point* p = NULL; + sp_point_256* rt; + sp_point_256* p = NULL; sp_digit* tmp; sp_digit* negy; int i; - ecc_recode v[37]; + ecc_recode_256 v[37]; int err; (void)g; (void)heap; - err = sp_ecc_point_new(heap, rtd, rt); + err = sp_256_point_new_4(heap, rtd, rt); if (err == MP_OKAY) - err = sp_ecc_point_new(heap, pd, p); + err = sp_256_point_new_4(heap, pd, p); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 4 * 5, heap, DYNAMIC_TYPE_ECC); @@ -21776,7 +21771,7 @@ static int sp_256_ecc_mulmod_add_only_avx2_4(sp_point* r, const sp_point* g, sp_256_map_avx2_4(r, rt, tmp); } else { - XMEMCPY(r, rt, sizeof(sp_point)); + XMEMCPY(r, rt, sizeof(sp_point_256)); } } @@ -21788,8 +21783,8 @@ static int sp_256_ecc_mulmod_add_only_avx2_4(sp_point* r, const sp_point* g, #else ForceZero(tmp, sizeof(sp_digit) * 2 * 4 * 5); #endif - sp_ecc_point_free(p, 0, heap); - sp_ecc_point_free(rt, 0, heap); + sp_256_point_free_4(p, 0, heap); + sp_256_point_free_4(rt, 0, heap); return MP_OKAY; } @@ -21803,7 +21798,7 @@ static int sp_256_ecc_mulmod_add_only_avx2_4(sp_point* r, const sp_point* g, * heap Heap to use for allocation. * returns MEMORY_E when memory allocation fails and MP_OKAY on success. */ -static int sp_256_ecc_mulmod_base_avx2_4(sp_point* r, const sp_digit* k, +static int sp_256_ecc_mulmod_base_avx2_4(sp_point_256* r, const sp_digit* k, int map, void* heap) { return sp_256_ecc_mulmod_add_only_avx2_4(r, NULL, p256_table, @@ -21824,18 +21819,17 @@ static int sp_256_ecc_mulmod_base_avx2_4(sp_point* r, const sp_digit* k, int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point p; - sp_digit k[4]; -#else - sp_digit* k = NULL; + sp_point_256 p; + sp_digit kd[4]; #endif - sp_point* point; - int err; + sp_point_256* point; + sp_digit* k = NULL; + int err = MP_OKAY; #ifdef HAVE_INTEL_AVX2 word32 cpuid_flags = cpuid_get_flags(); #endif - err = sp_ecc_point_new(heap, p, point); + err = sp_256_point_new_4(heap, p, point); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4, heap, @@ -21844,6 +21838,8 @@ int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) err = MEMORY_E; } } +#else + k = kd; #endif if (err == MP_OKAY) { sp_256_from_mp(k, 4, km); @@ -21864,7 +21860,7 @@ int sp_ecc_mulmod_base_256(mp_int* km, ecc_point* r, int map, void* heap) XFREE(k, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(point, 0, heap); + sp_256_point_free_4(point, 0, heap); return err; } @@ -21924,17 +21920,16 @@ static int sp_256_ecc_gen_k_4(WC_RNG* rng, sp_digit* k) int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point p; - sp_digit k[4]; + sp_point_256 p; + sp_digit kd[4]; #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN - sp_point inf; + sp_point_256 inf; #endif -#else +#endif + sp_point_256* point; sp_digit* k = NULL; -#endif - sp_point* point; #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN - sp_point* infinity; + sp_point_256* infinity; #endif int err; #ifdef HAVE_INTEL_AVX2 @@ -21943,10 +21938,10 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) (void)heap; - err = sp_ecc_point_new(heap, p, point); + err = sp_256_point_new_4(heap, p, point); #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, inf, infinity); + err = sp_256_point_new_4(heap, inf, infinity); } #endif #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) @@ -21957,6 +21952,8 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) err = MEMORY_E; } } +#else + k = kd; #endif if (err == MP_OKAY) { @@ -22002,9 +21999,9 @@ int sp_ecc_make_key_256(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) } #endif #ifdef WOLFSSL_VALIDATE_ECC_KEYGEN - sp_ecc_point_free(infinity, 1, heap); + sp_256_point_free_4(infinity, 1, heap); #endif - sp_ecc_point_free(point, 1, heap); + sp_256_point_free_4(point, 1, heap); return err; } @@ -22027,12 +22024,11 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, word32* outLen, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point p; - sp_digit k[4]; -#else - sp_digit* k = NULL; + sp_point_256 p; + sp_digit kd[4]; #endif - sp_point* point = NULL; + sp_point_256* point = NULL; + sp_digit* k = NULL; int err = MP_OKAY; #ifdef HAVE_INTEL_AVX2 word32 cpuid_flags = cpuid_get_flags(); @@ -22043,7 +22039,7 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, } if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, p, point); + err = sp_256_point_new_4(heap, p, point); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { @@ -22052,6 +22048,8 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, if (k == NULL) err = MEMORY_E; } +#else + k = kd; #endif if (err == MP_OKAY) { @@ -22074,7 +22072,7 @@ int sp_ecc_secret_gen_256(mp_int* priv, ecc_point* pub, byte* out, XFREE(k, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(point, 0, heap); + sp_256_point_free_4(point, 0, heap); return err; } @@ -22203,7 +22201,7 @@ static WC_INLINE int sp_256_mod_4(sp_digit* r, const sp_digit* a, const sp_digit 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_2[4] = { +static const uint64_t p256_order_minus_2[4] = { 0xf3b9cac2fc63254fU,0xbce6faada7179e84U,0xffffffffffffffffU, 0xffffffff00000000U }; @@ -22272,7 +22270,7 @@ static void sp_256_mont_inv_order_4(sp_digit* r, const sp_digit* a, XMEMCPY(t, a, sizeof(sp_digit) * 4); for (i=254; i>=0; i--) { sp_256_mont_sqr_order_4(t, t); - if ((p256_order_2[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) { + if ((p256_order_minus_2[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) { sp_256_mont_mul_order_4(t, t, a); } } @@ -22418,7 +22416,7 @@ static void sp_256_mont_inv_order_avx2_4(sp_digit* r, const sp_digit* a, XMEMCPY(t, a, sizeof(sp_digit) * 4); for (i=254; i>=0; i--) { sp_256_mont_sqr_order_avx2_4(t, t); - if ((p256_order_2[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) { + if ((p256_order_minus_2[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) { sp_256_mont_mul_order_avx2_4(t, t, a); } } @@ -22535,18 +22533,18 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, sp_digit kd[2*4]; sp_digit rd[2*4]; sp_digit td[3 * 2*4]; - sp_point p; + sp_point_256 p; #endif sp_digit* e = NULL; sp_digit* x = NULL; sp_digit* k = NULL; sp_digit* r = NULL; sp_digit* tmp = NULL; - sp_point* point = NULL; + sp_point_256* point = NULL; sp_digit carry; sp_digit* s = NULL; sp_digit* kInv = NULL; - int err; + int err = MP_OKAY; int64_t c; int i; #ifdef HAVE_INTEL_AVX2 @@ -22555,7 +22553,7 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, (void)heap; - err = sp_ecc_point_new(heap, p, point); + err = sp_256_point_new_4(heap, p, point); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7 * 2 * 4, heap, @@ -22696,7 +22694,7 @@ int sp_ecc_sign_256(const byte* hash, word32 hashLen, WC_RNG* rng, mp_int* priv, XMEMSET(r, 0, sizeof(sp_digit) * 2U * 4U); XMEMSET(tmp, 0, sizeof(sp_digit) * 3U * 2U * 4U); #endif - sp_ecc_point_free(point, 1, heap); + sp_256_point_free_4(point, 1, heap); return err; } @@ -22733,15 +22731,15 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, sp_digit u2d[2*4]; sp_digit sd[2*4]; sp_digit tmpd[2*4 * 5]; - sp_point p1d; - sp_point p2d; + sp_point_256 p1d; + sp_point_256 p2d; #endif sp_digit* u1 = NULL; sp_digit* u2 = NULL; sp_digit* s = NULL; sp_digit* tmp = NULL; - sp_point* p1; - sp_point* p2 = NULL; + sp_point_256* p1; + sp_point_256* p2 = NULL; sp_digit carry; int64_t c; int err; @@ -22749,9 +22747,9 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, word32 cpuid_flags = cpuid_get_flags(); #endif - err = sp_ecc_point_new(heap, p1d, p1); + err = sp_256_point_new_4(heap, p1d, p1); if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, p2d, p2); + err = sp_256_point_new_4(heap, p2d, p2); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { @@ -22906,8 +22904,8 @@ int sp_ecc_verify_256(const byte* hash, word32 hashLen, mp_int* pX, if (d != NULL) XFREE(d, heap, DYNAMIC_TYPE_ECC); #endif - sp_ecc_point_free(p1, 0, heap); - sp_ecc_point_free(p2, 0, heap); + sp_256_point_free_4(p1, 0, heap); + sp_256_point_free_4(p2, 0, heap); return err; } @@ -22921,10 +22919,10 @@ 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* point, void* heap) +static int sp_256_ecc_is_point_4(sp_point_256* point, void* heap) { #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - sp_digit* d; + sp_digit* d = NULL; #else sp_digit t1d[2*4]; sp_digit t2d[2*4]; @@ -22988,13 +22986,13 @@ static int sp_256_ecc_is_point_4(sp_point* point, void* heap) int sp_ecc_is_point_256(mp_int* pX, mp_int* pY) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point pubd; + sp_point_256 pubd; #endif - sp_point* pub; + sp_point_256* pub; byte one[1] = { 1 }; int err; - err = sp_ecc_point_new(NULL, pubd, pub); + err = sp_256_point_new_4(NULL, pubd, pub); if (err == MP_OKAY) { sp_256_from_mp(pub->x, 4, pX); sp_256_from_mp(pub->y, 4, pY); @@ -23003,7 +23001,7 @@ int sp_ecc_is_point_256(mp_int* pX, mp_int* pY) err = sp_256_ecc_is_point_4(pub, NULL); } - sp_ecc_point_free(pub, 0, NULL); + sp_256_point_free_4(pub, 0, NULL); return err; } @@ -23023,21 +23021,21 @@ int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_digit privd[4]; - sp_point pubd; - sp_point pd; + sp_point_256 pubd; + sp_point_256 pd; #endif sp_digit* priv = NULL; - sp_point* pub; - sp_point* p = NULL; + sp_point_256* pub; + sp_point_256* p = NULL; byte one[1] = { 1 }; int err; #ifdef HAVE_INTEL_AVX2 word32 cpuid_flags = cpuid_get_flags(); #endif - err = sp_ecc_point_new(heap, pubd, pub); + err = sp_256_point_new_4(heap, pubd, pub); if (err == MP_OKAY) { - err = sp_ecc_point_new(heap, pd, p); + err = sp_256_point_new_4(heap, pd, p); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { @@ -23118,8 +23116,8 @@ int sp_ecc_check_key_256(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) XFREE(priv, heap, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(p, 0, heap); - sp_ecc_point_free(pub, 0, heap); + sp_256_point_free_4(p, 0, heap); + sp_256_point_free_4(pub, 0, heap); return err; } @@ -23145,20 +23143,20 @@ int sp_ecc_proj_add_point_256(mp_int* pX, mp_int* pY, mp_int* pZ, { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_digit tmpd[2 * 4 * 5]; - sp_point pd; - sp_point qd; + sp_point_256 pd; + sp_point_256 qd; #endif sp_digit* tmp; - sp_point* p; - sp_point* q = NULL; + sp_point_256* p; + sp_point_256* q = NULL; int err; #ifdef HAVE_INTEL_AVX2 word32 cpuid_flags = cpuid_get_flags(); #endif - err = sp_ecc_point_new(NULL, pd, p); + err = sp_256_point_new_4(NULL, pd, p); if (err == MP_OKAY) { - err = sp_ecc_point_new(NULL, qd, q); + err = sp_256_point_new_4(NULL, qd, q); } #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { @@ -23203,8 +23201,8 @@ int sp_ecc_proj_add_point_256(mp_int* pX, mp_int* pY, mp_int* pZ, XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(q, 0, NULL); - sp_ecc_point_free(p, 0, NULL); + sp_256_point_free_4(q, 0, NULL); + sp_256_point_free_4(p, 0, NULL); return err; } @@ -23225,16 +23223,16 @@ int sp_ecc_proj_dbl_point_256(mp_int* pX, mp_int* pY, mp_int* pZ, { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_digit tmpd[2 * 4 * 2]; - sp_point pd; + sp_point_256 pd; #endif sp_digit* tmp; - sp_point* p; + sp_point_256* p; int err; #ifdef HAVE_INTEL_AVX2 word32 cpuid_flags = cpuid_get_flags(); #endif - err = sp_ecc_point_new(NULL, pd, p); + err = sp_256_point_new_4(NULL, pd, p); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 4 * 2, NULL, @@ -23275,7 +23273,7 @@ int sp_ecc_proj_dbl_point_256(mp_int* pX, mp_int* pY, mp_int* pZ, XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(p, 0, NULL); + sp_256_point_free_4(p, 0, NULL); return err; } @@ -23292,13 +23290,13 @@ int sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) sp_digit tmpd[2 * 4 * 4]; - sp_point pd; + sp_point_256 pd; #endif sp_digit* tmp; - sp_point* p; + sp_point_256* p; int err; - err = sp_ecc_point_new(NULL, pd, p); + err = sp_256_point_new_4(NULL, pd, p); #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) if (err == MP_OKAY) { tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 4 * 4, NULL, @@ -23333,7 +23331,7 @@ int sp_ecc_map_256(mp_int* pX, mp_int* pY, mp_int* pZ) XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); } #endif - sp_ecc_point_free(p, 0, NULL); + sp_256_point_free_4(p, 0, NULL); return err; } @@ -23451,6 +23449,7 @@ static int sp_256_mont_sqrt_4(sp_digit* y) return err; } + /* Uncompress the point given the X ordinate. * * xm X ordinate. @@ -23537,6 +23536,5869 @@ int sp_ecc_uncompress_256(mp_int* xm, int odd, mp_int* ym) } #endif #endif /* !WOLFSSL_SP_NO_256 */ +#ifdef WOLFSSL_SP_384 + +/* Point structure to use. */ +typedef struct sp_point_384 { + sp_digit x[2 * 6]; + sp_digit y[2 * 6]; + sp_digit z[2 * 6]; + int infinity; +} sp_point_384; + +/* The modulus (prime) of the curve P384. */ +static const sp_digit p384_mod[6] = { + 0x00000000ffffffffL,0xffffffff00000000L,0xfffffffffffffffeL, + 0xffffffffffffffffL,0xffffffffffffffffL,0xffffffffffffffffL +}; +/* The Montogmery normalizer for modulus of the curve P384. */ +static const sp_digit p384_norm_mod[6] = { + 0xffffffff00000001L,0x00000000ffffffffL,0x0000000000000001L, + 0x0000000000000000L,0x0000000000000000L,0x0000000000000000L +}; +/* The Montogmery multiplier for modulus of the curve P384. */ +static sp_digit p384_mp_mod = 0x0000000100000001; +#if defined(WOLFSSL_VALIDATE_ECC_KEYGEN) || defined(HAVE_ECC_SIGN) || \ + defined(HAVE_ECC_VERIFY) +/* The order of the curve P384. */ +static const sp_digit p384_order[6] = { + 0xecec196accc52973L,0x581a0db248b0a77aL,0xc7634d81f4372ddfL, + 0xffffffffffffffffL,0xffffffffffffffffL,0xffffffffffffffffL +}; +#endif +/* The order of the curve P384 minus 2. */ +static const sp_digit p384_order2[6] = { + 0xecec196accc52971L,0x581a0db248b0a77aL,0xc7634d81f4372ddfL, + 0xffffffffffffffffL,0xffffffffffffffffL,0xffffffffffffffffL +}; +#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[6] = { + 0x1313e695333ad68dL,0xa7e5f24db74f5885L,0x389cb27e0bc8d220L, + 0x0000000000000000L,0x0000000000000000L,0x0000000000000000L +}; +#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; +#endif +/* The base point of curve P384. */ +static const sp_point_384 p384_base = { + /* X ordinate */ + { + 0x3a545e3872760ab7L,0x5502f25dbf55296cL,0x59f741e082542a38L, + 0x6e1d3b628ba79b98L,0x8eb1c71ef320ad74L,0xaa87ca22be8b0537L, + 0L, 0L, 0L, 0L, 0L, 0L + }, + /* Y ordinate */ + { + 0x7a431d7c90ea0e5fL,0x0a60b1ce1d7e819dL,0xe9da3113b5f0b8c0L, + 0xf8f41dbd289a147cL,0x5d9e98bf9292dc29L,0x3617de4a96262c6fL, + 0L, 0L, 0L, 0L, 0L, 0L + }, + /* Z ordinate */ + { + 0x0000000000000001L,0x0000000000000000L,0x0000000000000000L, + 0x0000000000000000L,0x0000000000000000L,0x0000000000000000L, + 0L, 0L, 0L, 0L, 0L, 0L + }, + /* infinity */ + 0 +}; +#if defined(HAVE_ECC_CHECK_KEY) || defined(HAVE_COMP_KEY) +static const sp_digit p384_b[6] = { + 0x2a85c8edd3ec2aefL,0xc656398d8a2ed19dL,0x0314088f5013875aL, + 0x181d9c6efe814112L,0x988e056be3f82d19L,0xb3312fa7e23ee7e4L +}; +#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) + (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) +/* 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) +/* 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) + 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) + 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) + 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) + 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] |= a[i] << s; + r->dp[j] &= (1L << DIGIT_BIT) - 1; + s = DIGIT_BIT - s; + r->dp[++j] = 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] = 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; +} + +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); +/* 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); +} + +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. + * a Number to square in Montogmery form. + * 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) +{ + sp_384_sqr_6(r, a); + sp_384_mont_reduce_6(r, m, mp); +} + +#if !defined(WOLFSSL_SP_SMALL) || defined(HAVE_COMP_KEY) +/* Square the Montgomery form number a number of times. (r = a ^ n mod m) + * + * r Result of squaring. + * a Number to square in Montogmery form. + * n Number of times to square. + * m Modulus (prime). + * mp Montogmery mulitplier. + */ +static void sp_384_mont_sqr_n_6(sp_digit* r, const sp_digit* a, int n, + const sp_digit* m, sp_digit mp) +{ + sp_384_mont_sqr_6(r, a, m, mp); + for (; n > 1; n--) { + sp_384_mont_sqr_6(r, r, m, mp); + } +} + +#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] = { + 0x00000000fffffffdU,0xffffffff00000000U,0xfffffffffffffffeU, + 0xffffffffffffffffU,0xffffffffffffffffU,0xffffffffffffffffU +}; +#endif /* !WOLFSSL_SP_SMALL */ + +/* Invert the number, in Montgomery form, modulo the modulus (prime) of the + * P384 curve. (r = 1 / a mod m) + * + * r Inverse result. + * a Number to invert. + * td Temporary data. + */ +static void sp_384_mont_inv_6(sp_digit* r, const sp_digit* a, sp_digit* td) +{ +#ifdef WOLFSSL_SP_SMALL + sp_digit* t = td; + int i; + + XMEMCPY(t, a, sizeof(sp_digit) * 6); + for (i=382; i>=0; i--) { + sp_384_mont_sqr_6(t, t, p384_mod, p384_mp_mod); + if (p384_mod_minus_2[i / 64] & ((sp_digit)1 << (i % 64))) + sp_384_mont_mul_6(t, t, a, p384_mod, p384_mp_mod); + } + XMEMCPY(r, t, sizeof(sp_digit) * 6); +#else + sp_digit* t1 = td; + sp_digit* t2 = td + 2 * 6; + sp_digit* t3 = td + 4 * 6; + sp_digit* t4 = td + 6 * 6; + sp_digit* t5 = td + 8 * 6; + + /* 0x2 */ + sp_384_mont_sqr_6(t1, a, p384_mod, p384_mp_mod); + /* 0x3 */ + sp_384_mont_mul_6(t5, t1, a, p384_mod, p384_mp_mod); + /* 0xc */ + sp_384_mont_sqr_n_6(t1, t5, 2, p384_mod, p384_mp_mod); + /* 0xf */ + sp_384_mont_mul_6(t2, t5, t1, p384_mod, p384_mp_mod); + /* 0x1e */ + sp_384_mont_sqr_6(t1, t2, p384_mod, p384_mp_mod); + /* 0x1f */ + sp_384_mont_mul_6(t4, t1, a, p384_mod, p384_mp_mod); + /* 0x3e0 */ + sp_384_mont_sqr_n_6(t1, t4, 5, p384_mod, p384_mp_mod); + /* 0x3ff */ + sp_384_mont_mul_6(t2, t4, t1, p384_mod, p384_mp_mod); + /* 0x7fe0 */ + sp_384_mont_sqr_n_6(t1, t2, 5, p384_mod, p384_mp_mod); + /* 0x7fff */ + sp_384_mont_mul_6(t4, t4, t1, p384_mod, p384_mp_mod); + /* 0x3fff8000 */ + sp_384_mont_sqr_n_6(t1, t4, 15, p384_mod, p384_mp_mod); + /* 0x3fffffff */ + sp_384_mont_mul_6(t2, t4, t1, p384_mod, p384_mp_mod); + /* 0xfffffffc */ + sp_384_mont_sqr_n_6(t3, t2, 2, p384_mod, p384_mp_mod); + /* 0xfffffffd */ + sp_384_mont_mul_6(r, t3, a, p384_mod, p384_mp_mod); + /* 0xffffffff */ + sp_384_mont_mul_6(t3, t5, t3, p384_mod, p384_mp_mod); + /* 0xfffffffc0000000 */ + sp_384_mont_sqr_n_6(t1, t2, 30, p384_mod, p384_mp_mod); + /* 0xfffffffffffffff */ + sp_384_mont_mul_6(t2, t2, t1, p384_mod, p384_mp_mod); + /* 0xfffffffffffffff000000000000000 */ + sp_384_mont_sqr_n_6(t1, t2, 60, p384_mod, p384_mp_mod); + /* 0xffffffffffffffffffffffffffffff */ + sp_384_mont_mul_6(t2, t2, t1, p384_mod, p384_mp_mod); + /* 0xffffffffffffffffffffffffffffff000000000000000000000000000000 */ + sp_384_mont_sqr_n_6(t1, t2, 120, p384_mod, p384_mp_mod); + /* 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */ + sp_384_mont_mul_6(t2, t2, t1, p384_mod, p384_mp_mod); + /* 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000 */ + sp_384_mont_sqr_n_6(t1, t2, 15, p384_mod, p384_mp_mod); + /* 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */ + sp_384_mont_mul_6(t2, t4, t1, p384_mod, p384_mp_mod); + /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00000000 */ + sp_384_mont_sqr_n_6(t1, t2, 33, p384_mod, p384_mp_mod); + /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff */ + sp_384_mont_mul_6(t2, t3, t1, p384_mod, p384_mp_mod); + /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff000000000000000000000000 */ + sp_384_mont_sqr_n_6(t1, t2, 96, p384_mod, p384_mp_mod); + /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffd */ + sp_384_mont_mul_6(r, r, t1, p384_mod, p384_mp_mod); + +#endif /* WOLFSSL_SP_SMALL */ +} + +extern int64_t sp_384_cmp_6(const sp_digit* a, const sp_digit* b); +/* Normalize the values in each word to 64. + * + * a Array of sp_digit to normalize. + */ +#define sp_384_norm_6(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_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; + int64_t n; + + sp_384_mont_inv_6(t1, p->z, t + 2*6); + + sp_384_mont_sqr_6(t2, t1, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(t1, t2, t1, p384_mod, p384_mp_mod); + + /* x /= z^2 */ + sp_384_mont_mul_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); + /* 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) ? + (sp_digit)1 : (sp_digit)0)); + sp_384_norm_6(r->x); + + /* y /= z^3 */ + sp_384_mont_mul_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); + /* 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_digit)1 : (sp_digit)0)); + sp_384_norm_6(r->y); + + XMEMSET(r->z, 0, sizeof(r->z)); + r->z[0] = 1; + +} + +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. + * a First number to add in Montogmery form. + * b Second number to add in Montogmery form. + * m Modulus (prime). + */ +static void sp_384_mont_add_6(sp_digit* r, const sp_digit* a, const sp_digit* b, + const sp_digit* m) +{ + sp_digit o; + + o = sp_384_add_6(r, a, b); + sp_384_cond_sub_6(r, r, m, 0 - o); +} + +extern sp_digit sp_384_dbl_6(sp_digit* r, const sp_digit* a); +/* 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_384_mont_dbl_6(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + sp_digit o; + + o = sp_384_dbl_6(r, a); + sp_384_cond_sub_6(r, r, m, 0 - o); +} + +/* 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_384_mont_tpl_6(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + sp_digit o; + + o = sp_384_dbl_6(r, a); + sp_384_cond_sub_6(r, r, m, 0 - o); + o = sp_384_add_6(r, r, a); + 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). + * + * 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_384_mont_sub_6(sp_digit* r, const sp_digit* a, const sp_digit* b, + const sp_digit* m) +{ + sp_digit o; + + o = sp_384_sub_6(r, a, b); + sp_384_cond_add_6(r, r, m, o); +} + +extern void sp_384_div2_6(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. + */ +static void sp_384_proj_point_dbl_6(sp_point_384* r, const sp_point_384* p, sp_digit* t) +{ + sp_point_384* rp[2]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*6; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + /* When infinity don't double point passed in - constant time. */ + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_384*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_384)); + x = rp[p->infinity]->x; + y = rp[p->infinity]->y; + z = rp[p->infinity]->z; + /* Put point to double into result - good for infinity. */ + if (r != p) { + for (i=0; i<6; i++) { + r->x[i] = p->x[i]; + } + for (i=0; i<6; i++) { + r->y[i] = p->y[i]; + } + for (i=0; i<6; i++) { + r->z[i] = p->z[i]; + } + r->infinity = p->infinity; + } + + /* T1 = Z * Z */ + sp_384_mont_sqr_6(t1, z, p384_mod, p384_mp_mod); + /* Z = Y * Z */ + sp_384_mont_mul_6(z, y, z, p384_mod, p384_mp_mod); + /* Z = 2Z */ + sp_384_mont_dbl_6(z, z, p384_mod); + /* T2 = X - T1 */ + sp_384_mont_sub_6(t2, x, t1, p384_mod); + /* T1 = X + T1 */ + sp_384_mont_add_6(t1, x, t1, p384_mod); + /* T2 = T1 * T2 */ + sp_384_mont_mul_6(t2, t1, t2, p384_mod, p384_mp_mod); + /* T1 = 3T2 */ + sp_384_mont_tpl_6(t1, t2, p384_mod); + /* Y = 2Y */ + sp_384_mont_dbl_6(y, y, p384_mod); + /* Y = Y * Y */ + sp_384_mont_sqr_6(y, y, p384_mod, p384_mp_mod); + /* T2 = Y * Y */ + sp_384_mont_sqr_6(t2, y, p384_mod, p384_mp_mod); + /* T2 = T2/2 */ + sp_384_div2_6(t2, t2, p384_mod); + /* Y = Y * X */ + sp_384_mont_mul_6(y, y, x, p384_mod, p384_mp_mod); + /* X = T1 * T1 */ + sp_384_mont_mul_6(x, t1, t1, p384_mod, p384_mp_mod); + /* X = X - Y */ + sp_384_mont_sub_6(x, x, y, p384_mod); + /* X = X - Y */ + sp_384_mont_sub_6(x, x, y, p384_mod); + /* Y = Y - X */ + sp_384_mont_sub_6(y, y, x, p384_mod); + /* Y = Y * T1 */ + sp_384_mont_mul_6(y, y, t1, p384_mod, p384_mp_mod); + /* Y = Y - T2 */ + sp_384_mont_sub_6(y, y, t2, p384_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_384_proj_point_dbl_n_6(sp_point_384* r, const sp_point_384* p, int n, + sp_digit* t) +{ + sp_point_384* rp[2]; + sp_digit* w = t; + sp_digit* a = t + 2*6; + sp_digit* b = t + 4*6; + sp_digit* t1 = t + 6*6; + sp_digit* t2 = t + 8*6; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_384*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_384)); + x = rp[p->infinity]->x; + y = rp[p->infinity]->y; + z = rp[p->infinity]->z; + if (r != p) { + for (i=0; i<6; i++) { + r->x[i] = p->x[i]; + } + for (i=0; i<6; i++) { + r->y[i] = p->y[i]; + } + for (i=0; i<6; i++) { + r->z[i] = p->z[i]; + } + r->infinity = p->infinity; + } + + /* Y = 2*Y */ + sp_384_mont_dbl_6(y, y, p384_mod); + /* 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); + while (n-- > 0) { + /* 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); + sp_384_mont_tpl_6(a, t1, p384_mod); + /* 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 = A^2 - 2B */ + sp_384_mont_sqr_6(x, a, p384_mod, p384_mp_mod); + sp_384_mont_dbl_6(t1, b, p384_mod); + sp_384_mont_sub_6(x, x, t1, p384_mod); + /* Z = Z*Y */ + sp_384_mont_mul_6(z, z, y, p384_mod, p384_mp_mod); + /* t2 = Y^4 */ + sp_384_mont_sqr_6(t2, t2, p384_mod, p384_mp_mod); + if (n != 0) { + /* W = W*Y^4 */ + sp_384_mont_mul_6(w, w, t2, 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_mul_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, t2, p384_mod); + } + /* Y = Y/2 */ + sp_384_div2_6(y, y, p384_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_384_cmp_equal_6(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])) == 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. + */ +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]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*6; + sp_digit* t3 = t + 4*6; + sp_digit* t4 = t + 6*6; + sp_digit* t5 = t + 8*6; + 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_384* a = p; + p = q; + q = a; + } + + /* Check double */ + (void)sp_384_sub_6(t1, p384_mod, q->y); + 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); + } + else { + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_384*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_384)); + 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<6; i++) { + r->x[i] = ap[p->infinity]->x[i]; + } + for (i=0; i<6; i++) { + r->y[i] = ap[p->infinity]->y[i]; + } + for (i=0; i<6; i++) { + r->z[i] = ap[p->infinity]->z[i]; + } + r->infinity = ap[p->infinity]->infinity; + + /* U1 = X1*Z2^2 */ + sp_384_mont_sqr_6(t1, q->z, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(t3, t1, q->z, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(t1, t1, x, p384_mod, p384_mp_mod); + /* U2 = X2*Z1^2 */ + sp_384_mont_sqr_6(t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(t4, t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(t2, t2, q->x, p384_mod, p384_mp_mod); + /* S1 = Y1*Z2^3 */ + sp_384_mont_mul_6(t3, t3, y, p384_mod, p384_mp_mod); + /* S2 = Y2*Z1^3 */ + sp_384_mont_mul_6(t4, t4, q->y, p384_mod, p384_mp_mod); + /* H = U2 - U1 */ + sp_384_mont_sub_6(t2, t2, t1, p384_mod); + /* R = S2 - S1 */ + sp_384_mont_sub_6(t4, t4, t3, p384_mod); + /* Z3 = H*Z1*Z2 */ + sp_384_mont_mul_6(z, z, q->z, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(z, z, t2, p384_mod, p384_mp_mod); + /* X3 = R^2 - H^3 - 2*U1*H^2 */ + sp_384_mont_sqr_6(x, t4, p384_mod, p384_mp_mod); + sp_384_mont_sqr_6(t5, t2, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(y, t1, t5, p384_mod, p384_mp_mod); + sp_384_mont_mul_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); + /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */ + sp_384_mont_sub_6(y, y, x, p384_mod); + sp_384_mont_mul_6(y, y, t4, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(t5, t5, t3, p384_mod, p384_mp_mod); + sp_384_mont_sub_6(y, y, t5, p384_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_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; + sp_digit* b = t + 4*6; + sp_digit* t1 = t + 6*6; + sp_digit* t2 = t + 8*6; + sp_digit* x = r[2*m].x; + sp_digit* y = r[(1<x[i]; + } + for (i=0; i<6; i++) { + y[i] = p->y[i]; + } + for (i=0; i<6; i++) { + z[i] = p->z[i]; + } + + /* Y = 2*Y */ + sp_384_mont_dbl_6(y, y, p384_mod); + /* 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); + for (i=1; i<=n; i++) { + /* 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); + sp_384_mont_tpl_6(a, t1, p384_mod); + /* 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<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_384_mont_sqr_6(t1, q->z, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(t3, t1, q->z, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(t1, t1, x, p384_mod, p384_mp_mod); + /* U2 = X2*Z1^2 */ + sp_384_mont_sqr_6(t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(t4, t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(t2, t2, q->x, p384_mod, p384_mp_mod); + /* S1 = Y1*Z2^3 */ + sp_384_mont_mul_6(t3, t3, y, p384_mod, p384_mp_mod); + /* S2 = Y2*Z1^3 */ + sp_384_mont_mul_6(t4, t4, q->y, p384_mod, p384_mp_mod); + /* H = U2 - U1 */ + sp_384_mont_sub_6(t2, t2, t1, p384_mod); + /* RS = S2 + S1 */ + sp_384_mont_add_6(t6, t4, t3, p384_mod); + /* R = S2 - S1 */ + sp_384_mont_sub_6(t4, t4, t3, p384_mod); + /* Z3 = H*Z1*Z2 */ + /* ZS = H*Z1*Z2 */ + sp_384_mont_mul_6(z, z, q->z, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(z, z, t2, p384_mod, p384_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_384_mont_sqr_6(x, t4, p384_mod, p384_mp_mod); + sp_384_mont_sqr_6(xs, t6, p384_mod, p384_mp_mod); + sp_384_mont_sqr_6(t5, t2, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(y, t1, t5, p384_mod, p384_mp_mod); + sp_384_mont_mul_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); + /* 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_mul_6(y, y, t4, p384_mod, p384_mp_mod); + sp_384_sub_6(t6, p384_mod, t6); + sp_384_mont_mul_6(ys, ys, t6, p384_mod, p384_mp_mod); + sp_384_mont_mul_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); +} + +/* Structure used to describe recoding of scalar multiplication. */ +typedef struct ecc_recode_384 { + /* Index into pre-computation table. */ + uint8_t i; + /* Use the negative of the point. */ + uint8_t neg; +} ecc_recode_384; + +/* The index into pre-computation table to use. */ +static const uint8_t recode_index_6_6[66] = { + 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, 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_6[66] = { + 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, + 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_6_6(const sp_digit* k, ecc_recode_384* v) +{ + int i, j; + uint8_t y; + int carry = 0; + int o; + sp_digit n; + + j = 0; + n = k[j]; + o = 0; + for (i=0; i<65; i++) { + y = n; + if (o + 6 < 64) { + y &= 0x3f; + n >>= 6; + o += 6; + } + else if (o + 6 == 64) { + n >>= 6; + if (++j < 6) + n = k[j]; + o = 0; + } + else if (++j < 6) { + n = k[j]; + y |= (n << (64 - o)) & 0x3f; + o -= 58; + n >>= o; + } + + y += carry; + v[i].i = recode_index_6_6[y]; + v[i].neg = recode_neg_6_6[y]; + carry = (y >> 6) + v[i].neg; + } +} + +/* Multiply the point 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. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_ecc_mulmod_win_add_sub_6(sp_point_384* r, const sp_point_384* g, + const sp_digit* k, int map, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 td[33]; + sp_point_384 rtd, pd; + sp_digit tmpd[2 * 6 * 6]; +#endif + sp_point_384* t; + sp_point_384* rt; + sp_point_384* p = NULL; + sp_digit* tmp; + sp_digit* negy; + int i; + ecc_recode_384 v[65]; + int err; + + (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) + t = (sp_point_384*)XMALLOC(sizeof(sp_point_384) * 33, heap, DYNAMIC_TYPE_ECC); + if (t == NULL) + err = MEMORY_E; + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 6 * 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_384_mod_mul_norm_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); + } + if (err == MP_OKAY) { + err = sp_384_mod_mul_norm_6(t[1].z, g->z, p384_mod); + } + + if (err == MP_OKAY) { + t[1].infinity = 0; + /* t[2] ... t[32] */ + sp_384_proj_point_dbl_n_store_6(t, &t[ 1], 5, 1, tmp); + sp_384_proj_point_add_6(&t[ 3], &t[ 2], &t[ 1], tmp); + sp_384_proj_point_dbl_6(&t[ 6], &t[ 3], tmp); + sp_384_proj_point_add_sub_6(&t[ 7], &t[ 5], &t[ 6], &t[ 1], tmp); + sp_384_proj_point_dbl_6(&t[10], &t[ 5], tmp); + sp_384_proj_point_add_sub_6(&t[11], &t[ 9], &t[10], &t[ 1], tmp); + sp_384_proj_point_dbl_6(&t[12], &t[ 6], tmp); + sp_384_proj_point_dbl_6(&t[14], &t[ 7], tmp); + sp_384_proj_point_add_sub_6(&t[15], &t[13], &t[14], &t[ 1], tmp); + sp_384_proj_point_dbl_6(&t[18], &t[ 9], tmp); + sp_384_proj_point_add_sub_6(&t[19], &t[17], &t[18], &t[ 1], tmp); + sp_384_proj_point_dbl_6(&t[20], &t[10], tmp); + sp_384_proj_point_dbl_6(&t[22], &t[11], tmp); + sp_384_proj_point_add_sub_6(&t[23], &t[21], &t[22], &t[ 1], tmp); + sp_384_proj_point_dbl_6(&t[24], &t[12], tmp); + sp_384_proj_point_dbl_6(&t[26], &t[13], tmp); + sp_384_proj_point_add_sub_6(&t[27], &t[25], &t[26], &t[ 1], tmp); + sp_384_proj_point_dbl_6(&t[28], &t[14], tmp); + sp_384_proj_point_dbl_6(&t[30], &t[15], tmp); + sp_384_proj_point_add_sub_6(&t[31], &t[29], &t[30], &t[ 1], tmp); + + negy = t[0].y; + + sp_384_ecc_recode_6_6(k, v); + + i = 64; + XMEMCPY(rt, &t[v[i].i], sizeof(sp_point_384)); + for (--i; i>=0; i--) { + sp_384_proj_point_dbl_n_6(rt, rt, 6, tmp); + + XMEMCPY(p, &t[v[i].i], sizeof(sp_point_384)); + sp_384_sub_6(negy, p384_mod, p->y); + sp_384_cond_copy_6(p->y, negy, (sp_digit)0 - v[i].neg); + sp_384_proj_point_add_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) + if (t != NULL) + XFREE(t, heap, DYNAMIC_TYPE_ECC); + if (tmp != NULL) + XFREE(tmp, heap, DYNAMIC_TYPE_ECC); +#endif + sp_384_point_free_6(p, 0, heap); + sp_384_point_free_6(rt, 0, heap); + + return err; +} + +#ifdef HAVE_INTEL_AVX2 +#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 +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_mont_reduce_order_avx2_6(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_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); +} + +#endif /* HAVE_INTEL_AVX2 */ +#ifdef HAVE_INTEL_AVX2 +extern void sp_384_sqr_avx2_6(sp_digit* r, const sp_digit* a); +/* 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_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); +} + +#endif /* HAVE_INTEL_AVX2 */ +#if !defined(WOLFSSL_SP_SMALL) || defined(HAVE_COMP_KEY) +/* Square the Montgomery form number a number of times. (r = a ^ n mod m) + * + * r Result of squaring. + * a Number to square in Montogmery form. + * n Number of times to square. + * m Modulus (prime). + * mp Montogmery mulitplier. + */ +static void sp_384_mont_sqr_n_avx2_6(sp_digit* r, const sp_digit* a, int n, + const sp_digit* m, sp_digit mp) +{ + sp_384_mont_sqr_avx2_6(r, a, m, mp); + for (; n > 1; n--) { + sp_384_mont_sqr_avx2_6(r, r, m, mp); + } +} + +#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) + * + * r Inverse result. + * a Number to invert. + * td Temporary data. + */ +static void sp_384_mont_inv_avx2_6(sp_digit* r, const sp_digit* a, sp_digit* td) +{ +#ifdef WOLFSSL_SP_SMALL + sp_digit* t = td; + int i; + + XMEMCPY(t, a, sizeof(sp_digit) * 6); + for (i=382; i>=0; i--) { + sp_384_mont_sqr_avx2_6(t, t, p384_mod, p384_mp_mod); + if (p384_mod_minus_2[i / 64] & ((sp_digit)1 << (i % 64))) + sp_384_mont_mul_avx2_6(t, t, a, p384_mod, p384_mp_mod); + } + XMEMCPY(r, t, sizeof(sp_digit) * 6); +#else + sp_digit* t1 = td; + sp_digit* t2 = td + 2 * 6; + sp_digit* t3 = td + 4 * 6; + sp_digit* t4 = td + 6 * 6; + sp_digit* t5 = td + 8 * 6; + + /* 0x2 */ + sp_384_mont_sqr_avx2_6(t1, a, p384_mod, p384_mp_mod); + /* 0x3 */ + sp_384_mont_mul_avx2_6(t5, t1, a, p384_mod, p384_mp_mod); + /* 0xc */ + sp_384_mont_sqr_n_avx2_6(t1, t5, 2, p384_mod, p384_mp_mod); + /* 0xf */ + sp_384_mont_mul_avx2_6(t2, t5, t1, p384_mod, p384_mp_mod); + /* 0x1e */ + sp_384_mont_sqr_avx2_6(t1, t2, p384_mod, p384_mp_mod); + /* 0x1f */ + sp_384_mont_mul_avx2_6(t4, t1, a, p384_mod, p384_mp_mod); + /* 0x3e0 */ + sp_384_mont_sqr_n_avx2_6(t1, t4, 5, p384_mod, p384_mp_mod); + /* 0x3ff */ + sp_384_mont_mul_avx2_6(t2, t4, t1, p384_mod, p384_mp_mod); + /* 0x7fe0 */ + sp_384_mont_sqr_n_avx2_6(t1, t2, 5, p384_mod, p384_mp_mod); + /* 0x7fff */ + sp_384_mont_mul_avx2_6(t4, t4, t1, p384_mod, p384_mp_mod); + /* 0x3fff8000 */ + sp_384_mont_sqr_n_avx2_6(t1, t4, 15, p384_mod, p384_mp_mod); + /* 0x3fffffff */ + sp_384_mont_mul_avx2_6(t2, t4, t1, p384_mod, p384_mp_mod); + /* 0xfffffffc */ + sp_384_mont_sqr_n_avx2_6(t3, t2, 2, p384_mod, p384_mp_mod); + /* 0xfffffffd */ + sp_384_mont_mul_avx2_6(r, t3, a, p384_mod, p384_mp_mod); + /* 0xffffffff */ + sp_384_mont_mul_avx2_6(t3, t5, t3, p384_mod, p384_mp_mod); + /* 0xfffffffc0000000 */ + sp_384_mont_sqr_n_avx2_6(t1, t2, 30, p384_mod, p384_mp_mod); + /* 0xfffffffffffffff */ + sp_384_mont_mul_avx2_6(t2, t2, t1, p384_mod, p384_mp_mod); + /* 0xfffffffffffffff000000000000000 */ + sp_384_mont_sqr_n_avx2_6(t1, t2, 60, p384_mod, p384_mp_mod); + /* 0xffffffffffffffffffffffffffffff */ + sp_384_mont_mul_avx2_6(t2, t2, t1, p384_mod, p384_mp_mod); + /* 0xffffffffffffffffffffffffffffff000000000000000000000000000000 */ + sp_384_mont_sqr_n_avx2_6(t1, t2, 120, p384_mod, p384_mp_mod); + /* 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */ + sp_384_mont_mul_avx2_6(t2, t2, t1, p384_mod, p384_mp_mod); + /* 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000 */ + sp_384_mont_sqr_n_avx2_6(t1, t2, 15, p384_mod, p384_mp_mod); + /* 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */ + sp_384_mont_mul_avx2_6(t2, t4, t1, p384_mod, p384_mp_mod); + /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe00000000 */ + sp_384_mont_sqr_n_avx2_6(t1, t2, 33, p384_mod, p384_mp_mod); + /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff */ + sp_384_mont_mul_avx2_6(t2, t3, t1, p384_mod, p384_mp_mod); + /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff000000000000000000000000 */ + sp_384_mont_sqr_n_avx2_6(t1, t2, 96, p384_mod, p384_mp_mod); + /* 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000fffffffd */ + sp_384_mont_mul_avx2_6(r, r, t1, p384_mod, p384_mp_mod); + +#endif /* WOLFSSL_SP_SMALL */ +} + +#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. + */ +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); +} + +#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_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); +} + +#endif /* HAVE_INTEL_AVX2_ */ +/* 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) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2*6; + int64_t n; + + sp_384_mont_inv_avx2_6(t1, p->z, t + 2*6); + + sp_384_mont_sqr_avx2_6(t2, t1, p384_mod, p384_mp_mod); + sp_384_mont_mul_avx2_6(t1, t2, t1, p384_mod, p384_mp_mod); + + /* 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); + /* 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) ? + (sp_digit)1 : (sp_digit)0)); + sp_384_norm_6(r->x); + + /* 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); + /* 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_digit)1 : (sp_digit)0)); + sp_384_norm_6(r->y); + + XMEMSET(r->z, 0, sizeof(r->z)); + r->z[0] = 1; + +} + +/* Double the Montgomery form projective point p. + * + * r Result of doubling point. + * p Point to double. + * t Temporary ordinate data. + */ +static void sp_384_proj_point_dbl_avx2_6(sp_point_384* r, const sp_point_384* p, sp_digit* t) +{ + sp_point_384* rp[2]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*6; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + /* When infinity don't double point passed in - constant time. */ + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_384*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_384)); + x = rp[p->infinity]->x; + y = rp[p->infinity]->y; + z = rp[p->infinity]->z; + /* Put point to double into result - good for infinity. */ + if (r != p) { + for (i=0; i<6; i++) { + r->x[i] = p->x[i]; + } + for (i=0; i<6; i++) { + r->y[i] = p->y[i]; + } + for (i=0; i<6; i++) { + r->z[i] = p->z[i]; + } + r->infinity = p->infinity; + } + + /* T1 = Z * Z */ + sp_384_mont_sqr_avx2_6(t1, z, p384_mod, p384_mp_mod); + /* Z = Y * Z */ + sp_384_mont_mul_avx2_6(z, y, z, p384_mod, p384_mp_mod); + /* Z = 2Z */ + sp_384_mont_dbl_6(z, z, p384_mod); + /* T2 = X - T1 */ + sp_384_mont_sub_6(t2, x, t1, p384_mod); + /* T1 = X + T1 */ + sp_384_mont_add_6(t1, 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); + /* Y = 2Y */ + sp_384_mont_dbl_6(y, 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); + /* Y = Y * X */ + sp_384_mont_mul_avx2_6(y, y, x, p384_mod, p384_mp_mod); + /* X = T1 * T1 */ + sp_384_mont_mul_avx2_6(x, t1, t1, p384_mod, p384_mp_mod); + /* X = X - Y */ + sp_384_mont_sub_6(x, x, y, p384_mod); + /* X = X - Y */ + sp_384_mont_sub_6(x, x, y, p384_mod); + /* Y = Y - X */ + sp_384_mont_sub_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); + +} + +/* 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_384_proj_point_dbl_n_avx2_6(sp_point_384* r, const sp_point_384* p, int n, + sp_digit* t) +{ + sp_point_384* rp[2]; + sp_digit* w = t; + sp_digit* a = t + 2*6; + sp_digit* b = t + 4*6; + sp_digit* t1 = t + 6*6; + sp_digit* t2 = t + 8*6; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_384*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_384)); + x = rp[p->infinity]->x; + y = rp[p->infinity]->y; + z = rp[p->infinity]->z; + if (r != p) { + for (i=0; i<6; i++) { + r->x[i] = p->x[i]; + } + for (i=0; i<6; i++) { + r->y[i] = p->y[i]; + } + for (i=0; i<6; i++) { + r->z[i] = p->z[i]; + } + r->infinity = p->infinity; + } + + /* Y = 2*Y */ + sp_384_mont_dbl_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); + while (n-- > 0) { + /* 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); + /* 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 = A^2 - 2B */ + sp_384_mont_sqr_avx2_6(x, a, p384_mod, p384_mp_mod); + sp_384_mont_dbl_6(t1, b, p384_mod); + sp_384_mont_sub_6(x, x, t1, 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(t2, t2, p384_mod, p384_mp_mod); + if (n != 0) { + /* W = W*Y^4 */ + sp_384_mont_mul_avx2_6(w, w, t2, 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_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, t2, p384_mod); + } + /* Y = Y/2 */ + sp_384_div2_6(y, y, p384_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. + */ +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]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*6; + sp_digit* t3 = t + 4*6; + sp_digit* t4 = t + 6*6; + sp_digit* t5 = t + 8*6; + 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_384* a = p; + p = q; + q = a; + } + + /* Check double */ + (void)sp_384_sub_6(t1, p384_mod, q->y); + 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); + } + else { + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_384*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_384)); + 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<6; i++) { + r->x[i] = ap[p->infinity]->x[i]; + } + for (i=0; i<6; i++) { + r->y[i] = ap[p->infinity]->y[i]; + } + for (i=0; i<6; i++) { + r->z[i] = ap[p->infinity]->z[i]; + } + r->infinity = ap[p->infinity]->infinity; + + /* U1 = X1*Z2^2 */ + sp_384_mont_sqr_avx2_6(t1, q->z, p384_mod, p384_mp_mod); + sp_384_mont_mul_avx2_6(t3, t1, q->z, p384_mod, p384_mp_mod); + sp_384_mont_mul_avx2_6(t1, t1, x, p384_mod, p384_mp_mod); + /* U2 = X2*Z1^2 */ + sp_384_mont_sqr_avx2_6(t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_avx2_6(t4, t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_avx2_6(t2, t2, q->x, p384_mod, p384_mp_mod); + /* S1 = Y1*Z2^3 */ + sp_384_mont_mul_avx2_6(t3, t3, y, p384_mod, p384_mp_mod); + /* 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); + /* R = S2 - S1 */ + sp_384_mont_sub_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); + /* X3 = R^2 - H^3 - 2*U1*H^2 */ + sp_384_mont_sqr_avx2_6(x, t4, p384_mod, p384_mp_mod); + 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); + /* Y3 = R*(U1*H^2 - X3) - S1*H^3 */ + sp_384_mont_sub_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); + } +} + +/* 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_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; + sp_digit* b = t + 4*6; + sp_digit* t1 = t + 6*6; + sp_digit* t2 = t + 8*6; + sp_digit* x = r[2*m].x; + sp_digit* y = r[(1<x[i]; + } + for (i=0; i<6; i++) { + y[i] = p->y[i]; + } + for (i=0; i<6; i++) { + z[i] = p->z[i]; + } + + /* Y = 2*Y */ + sp_384_mont_dbl_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); + for (i=1; i<=n; i++) { + /* 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); + /* 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<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_384_mont_sqr_avx2_6(t1, q->z, p384_mod, p384_mp_mod); + sp_384_mont_mul_avx2_6(t3, t1, q->z, p384_mod, p384_mp_mod); + sp_384_mont_mul_avx2_6(t1, t1, x, p384_mod, p384_mp_mod); + /* U2 = X2*Z1^2 */ + sp_384_mont_sqr_avx2_6(t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_avx2_6(t4, t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_avx2_6(t2, t2, q->x, p384_mod, p384_mp_mod); + /* S1 = Y1*Z2^3 */ + sp_384_mont_mul_avx2_6(t3, t3, y, p384_mod, p384_mp_mod); + /* 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); + /* RS = S2 + S1 */ + sp_384_mont_add_6(t6, t4, t3, p384_mod); + /* R = S2 - S1 */ + sp_384_mont_sub_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); + sp_384_mont_mul_avx2_6(z, z, t2, p384_mod, p384_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_384_mont_sqr_avx2_6(x, t4, p384_mod, p384_mp_mod); + sp_384_mont_sqr_avx2_6(xs, t6, p384_mod, p384_mp_mod); + 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); + /* 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_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); +} + +/* Multiply the point 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. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_ecc_mulmod_win_add_sub_avx2_6(sp_point_384* r, const sp_point_384* g, + const sp_digit* k, int map, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 td[33]; + sp_point_384 rtd, pd; + sp_digit tmpd[2 * 6 * 6]; +#endif + sp_point_384* t; + sp_point_384* rt; + sp_point_384* p = NULL; + sp_digit* tmp; + sp_digit* negy; + int i; + ecc_recode_384 v[65]; + int err; + + (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) + t = (sp_point_384*)XMALLOC(sizeof(sp_point_384) * 33, heap, DYNAMIC_TYPE_ECC); + if (t == NULL) + err = MEMORY_E; + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 6 * 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_384_mod_mul_norm_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); + } + if (err == MP_OKAY) { + err = sp_384_mod_mul_norm_6(t[1].z, g->z, p384_mod); + } + + if (err == MP_OKAY) { + t[1].infinity = 0; + /* t[2] ... t[32] */ + sp_384_proj_point_dbl_n_store_avx2_6(t, &t[ 1], 5, 1, tmp); + sp_384_proj_point_add_avx2_6(&t[ 3], &t[ 2], &t[ 1], tmp); + sp_384_proj_point_dbl_avx2_6(&t[ 6], &t[ 3], tmp); + sp_384_proj_point_add_sub_avx2_6(&t[ 7], &t[ 5], &t[ 6], &t[ 1], tmp); + sp_384_proj_point_dbl_avx2_6(&t[10], &t[ 5], tmp); + sp_384_proj_point_add_sub_avx2_6(&t[11], &t[ 9], &t[10], &t[ 1], tmp); + sp_384_proj_point_dbl_avx2_6(&t[12], &t[ 6], tmp); + sp_384_proj_point_dbl_avx2_6(&t[14], &t[ 7], tmp); + sp_384_proj_point_add_sub_avx2_6(&t[15], &t[13], &t[14], &t[ 1], tmp); + sp_384_proj_point_dbl_avx2_6(&t[18], &t[ 9], tmp); + sp_384_proj_point_add_sub_avx2_6(&t[19], &t[17], &t[18], &t[ 1], tmp); + sp_384_proj_point_dbl_avx2_6(&t[20], &t[10], tmp); + sp_384_proj_point_dbl_avx2_6(&t[22], &t[11], tmp); + sp_384_proj_point_add_sub_avx2_6(&t[23], &t[21], &t[22], &t[ 1], tmp); + sp_384_proj_point_dbl_avx2_6(&t[24], &t[12], tmp); + sp_384_proj_point_dbl_avx2_6(&t[26], &t[13], tmp); + sp_384_proj_point_add_sub_avx2_6(&t[27], &t[25], &t[26], &t[ 1], tmp); + sp_384_proj_point_dbl_avx2_6(&t[28], &t[14], tmp); + sp_384_proj_point_dbl_avx2_6(&t[30], &t[15], tmp); + sp_384_proj_point_add_sub_avx2_6(&t[31], &t[29], &t[30], &t[ 1], tmp); + + negy = t[0].y; + + sp_384_ecc_recode_6_6(k, v); + + i = 64; + XMEMCPY(rt, &t[v[i].i], sizeof(sp_point_384)); + for (--i; i>=0; i--) { + sp_384_proj_point_dbl_n_avx2_6(rt, rt, 6, tmp); + + XMEMCPY(p, &t[v[i].i], sizeof(sp_point_384)); + sp_384_sub_6(negy, p384_mod, p->y); + 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); + } + + 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) + if (t != NULL) + XFREE(t, heap, DYNAMIC_TYPE_ECC); + if (tmp != NULL) + XFREE(tmp, heap, DYNAMIC_TYPE_ECC); +#endif + sp_384_point_free_6(p, 0, heap); + sp_384_point_free_6(rt, 0, heap); + + return err; +} + +#endif /* HAVE_INTEL_AVX2 */ +/* 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 */ +/* 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_384_proj_point_add_qz1_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]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*6; + sp_digit* t3 = t + 4*6; + sp_digit* t4 = t + 6*6; + sp_digit* t5 = t + 8*6; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + /* Check double */ + (void)sp_384_sub_6(t1, p384_mod, q->y); + 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); + } + else { + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_384*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_384)); + 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<6; i++) { + r->x[i] = ap[p->infinity]->x[i]; + } + for (i=0; i<6; i++) { + r->y[i] = ap[p->infinity]->y[i]; + } + for (i=0; i<6; i++) { + r->z[i] = ap[p->infinity]->z[i]; + } + r->infinity = ap[p->infinity]->infinity; + + /* U2 = X2*Z1^2 */ + sp_384_mont_sqr_6(t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(t4, t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(t2, t2, q->x, p384_mod, p384_mp_mod); + /* S2 = Y2*Z1^3 */ + sp_384_mont_mul_6(t4, t4, q->y, p384_mod, p384_mp_mod); + /* H = U2 - X1 */ + sp_384_mont_sub_6(t2, t2, x, p384_mod); + /* R = S2 - Y1 */ + sp_384_mont_sub_6(t4, t4, y, p384_mod); + /* Z3 = H*Z1 */ + sp_384_mont_mul_6(z, z, t2, p384_mod, p384_mp_mod); + /* X3 = R^2 - H^3 - 2*X1*H^2 */ + sp_384_mont_sqr_6(t1, t4, p384_mod, p384_mp_mod); + sp_384_mont_sqr_6(t5, t2, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(t3, x, t5, p384_mod, p384_mp_mod); + sp_384_mont_mul_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); + /* Y3 = R*(X1*H^2 - X3) - Y1*H^3 */ + sp_384_mont_sub_6(t3, t3, x, p384_mod); + sp_384_mont_mul_6(t3, t3, t4, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(t5, t5, y, p384_mod, p384_mp_mod); + sp_384_mont_sub_6(y, t3, t5, p384_mod); + } +} + +#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_6(sp_point_384* a, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 6; + sp_digit* tmp = t + 4 * 6; + + sp_384_mont_inv_6(t1, a->z, tmp); + + sp_384_mont_sqr_6(t2, t1, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(t1, t2, t1, p384_mod, p384_mp_mod); + + sp_384_mont_mul_6(a->x, a->x, t2, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(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. + * + * 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) + sp_point_384 td, s1d, s2d; +#endif + sp_point_384* t; + sp_point_384* s1 = NULL; + sp_point_384* s2 = NULL; + int i, 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, 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 */ +/* Multiply the point 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_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, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + 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, j; + int y, x; + int err; + + (void)g; + (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) + 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; + for (j=0,x=47; j<8; j++,x+=48) { + y |= ((k[x / 64] >> (x % 64)) & 1) << j; + } + 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; + for (j=0,x=i; j<8; j++,x+=48) { + y |= ((k[x / 64] >> (x % 64)) & 1) << j; + } + + sp_384_proj_point_dbl_6(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_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) + 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; +} + +#ifdef FP_ECC +#ifndef FP_ENTRIES + #define FP_ENTRIES 16 +#endif + +typedef struct sp_cache_384_t { + sp_digit x[6]; + sp_digit y[6]; + sp_table_entry_384 table[256]; + uint32_t cnt; + int set; +} sp_cache_384_t; + +static THREAD_LS_T sp_cache_384_t sp_cache_384[FP_ENTRIES]; +static THREAD_LS_T int sp_cache_384_last = -1; +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 + +static void sp_ecc_get_cache_384(const sp_point_384* g, sp_cache_384_t** cache) +{ + int i, 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. + * 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, void* heap) +{ +#ifndef FP_ECC + return sp_384_ecc_mulmod_win_add_sub_6(r, g, k, map, 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, heap); + } + else { + err = sp_384_ecc_mulmod_stripe_6(r, g, cache->table, k, + map, 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_384_proj_point_add_qz1_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]; + sp_digit* t1 = t; + sp_digit* t2 = t + 2*6; + sp_digit* t3 = t + 4*6; + sp_digit* t4 = t + 6*6; + sp_digit* t5 = t + 8*6; + sp_digit* x; + sp_digit* y; + sp_digit* z; + int i; + + /* Check double */ + (void)sp_384_sub_6(t1, p384_mod, q->y); + 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); + } + else { + rp[0] = r; + + /*lint allow cast to different type of pointer*/ + rp[1] = (sp_point_384*)t; /*lint !e9087 !e740*/ + XMEMSET(rp[1], 0, sizeof(sp_point_384)); + 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<6; i++) { + r->x[i] = ap[p->infinity]->x[i]; + } + for (i=0; i<6; i++) { + r->y[i] = ap[p->infinity]->y[i]; + } + for (i=0; i<6; i++) { + r->z[i] = ap[p->infinity]->z[i]; + } + r->infinity = ap[p->infinity]->infinity; + + /* U2 = X2*Z1^2 */ + sp_384_mont_sqr_avx2_6(t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_avx2_6(t4, t2, z, p384_mod, p384_mp_mod); + sp_384_mont_mul_avx2_6(t2, t2, q->x, p384_mod, p384_mp_mod); + /* 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); + /* R = S2 - Y1 */ + sp_384_mont_sub_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 */ + sp_384_mont_sqr_avx2_6(t1, t4, p384_mod, p384_mp_mod); + 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); + /* Y3 = R*(X1*H^2 - X3) - Y1*H^3 */ + sp_384_mont_sub_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); + } +} + +#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_avx2_6(sp_point_384* a, sp_digit* t) +{ + sp_digit* t1 = t; + sp_digit* t2 = t + 2 * 6; + sp_digit* tmp = t + 4 * 6; + + sp_384_mont_inv_avx2_6(t1, a->z, tmp); + + sp_384_mont_sqr_avx2_6(t2, t1, p384_mod, p384_mp_mod); + sp_384_mont_mul_avx2_6(t1, t2, t1, p384_mod, p384_mp_mod); + + sp_384_mont_mul_avx2_6(a->x, a->x, t2, p384_mod, p384_mp_mod); + sp_384_mont_mul_avx2_6(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. + * + * 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_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) + sp_point_384 td, s1d, s2d; +#endif + sp_point_384* t; + sp_point_384* s1 = NULL; + sp_point_384* s2 = NULL; + int i, 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_avx2_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_avx2_6(t, t, 48, 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++) { + 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_avx2_6(t, s1, s2, tmp); + sp_384_proj_to_affine_avx2_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 */ +/* Multiply the point 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_384_ecc_mulmod_stripe_avx2_6(sp_point_384* r, const sp_point_384* g, + const sp_table_entry_384* table, const sp_digit* k, int map, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + 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, j; + int y, x; + int err; + + (void)g; + (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) + 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; + for (j=0,x=47; j<8; j++,x+=48) { + y |= ((k[x / 64] >> (x % 64)) & 1) << j; + } + 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; + for (j=0,x=i; j<8; j++,x+=48) { + y |= ((k[x / 64] >> (x % 64)) & 1) << j; + } + + sp_384_proj_point_dbl_avx2_6(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_384_proj_point_add_qz1_avx2_6(rt, rt, p, t); + } + + if (map != 0) { + sp_384_map_avx2_6(r, rt, t); + } + else { + XMEMCPY(r, rt, sizeof(sp_point_384)); + } + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + 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; +} + +/* 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. + * heap Heap to use for allocation. + * returns MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +static int sp_384_ecc_mulmod_avx2_6(sp_point_384* r, const sp_point_384* g, const sp_digit* k, + int map, void* heap) +{ +#ifndef FP_ECC + return sp_384_ecc_mulmod_win_add_sub_avx2_6(r, g, k, map, 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_avx2_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_avx2_6(r, g, k, map, heap); + } + else { + err = sp_384_ecc_mulmod_stripe_avx2_6(r, g, cache->table, k, + map, 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_384(mp_int* km, ecc_point* gm, ecc_point* r, int map, + void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 p; + sp_digit kd[6]; +#endif + sp_point_384* point; + 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 defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 6, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) + err = MEMORY_E; + } +#else + k = kd; +#endif + if (err == MP_OKAY) { + sp_384_from_mp(k, 6, km); + sp_384_point_from_ecc_point_6(point, gm); + +#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, map, heap); + else +#endif + err = sp_384_ecc_mulmod_6(point, point, k, map, heap); + } + if (err == MP_OKAY) { + err = sp_384_point_to_ecc_point_6(point, r); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_6(point, 0, heap); + + return err; +} + +static const sp_table_entry_384 p384_table[256] = { + /* 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 */ + { { 0x298647532b0c535bL,0x90dd695370506296L,0x038cd6b4216ab9acL, + 0x3df9b7b7be12d76aL,0x13f4d9785f347bdbL,0x222c5c9c13e94489L }, + { 0x5f8e796f2680dc64L,0x120e7cb758352417L,0x254b5d8ad10740b8L, + 0xc38b8efb5337dee6L,0xf688c2e194f02247L,0x7b5c75f36c25bc4cL } }, + /* 3 */ + { { 0xe26a3cc39edffea5L,0x35bbfd1c37d7e9fcL,0xf0e7700d9bde3ef6L, + 0x0380eb471a538f5aL,0x2e9da8bb05bf9eb3L,0xdbb93c731a460c3eL }, + { 0x37dba260f526b605L,0x95d4978efd785537L,0x24ed793aed72a04aL, + 0x2694837776005b1aL,0x99f557b99e681f82L,0xae5f9557d64954efL } }, + /* 4 */ + { { 0x24480c57f26feef9L,0xc31a26943a0e1240L,0x735002c3273e2bc7L, + 0x8c42e9c53ef1ed4cL,0x028babf67f4948e8L,0x6a502f438a978632L }, + { 0xf5f13a46b74536feL,0x1d218babd8a9f0ebL,0x30f36bcc37232768L, + 0xc5317b31576e8c18L,0xef1d57a69bbcb766L,0x917c4930b3e3d4dcL } }, + /* 5 */ + { { 0x11426e2ee349ddd0L,0x9f117ef99b2fc250L,0xff36b480ec0174a6L, + 0x4f4bde7618458466L,0x2f2edb6d05806049L,0x8adc75d119dfca92L }, + { 0xa619d097b7d5a7ceL,0x874275e5a34411e9L,0x5403e0470da4b4efL, + 0x2ebaafd977901d8fL,0x5e63ebcea747170fL,0x12a369447f9d8036L } }, + /* 6 */ + { { 0x28f9c07a4fc52870L,0xce0b37481a53a961L,0xd550fa180e1828d9L, + 0xa24abaf76adb225aL,0xd11ed0a56e58a348L,0xf3d811e6948acb62L }, + { 0x8618dd774c61ed22L,0x0bb747f980b47c9dL,0x22bf796fde6b8559L, + 0xfdfd1c6d680a21e9L,0xc0db15772af2c9ddL,0xa09379e6c1e90f3dL } }, + /* 7 */ + { { 0x386c66efe085c629L,0x5fc2a461095bc89aL,0x1353d631203f4b41L, + 0x7ca1972b7e4bd8f5L,0xb077380aa7df8ce9L,0xd8a90389ee7e4ea3L }, + { 0x1bc74dc7e7b14461L,0xdc2cb0140c9c4f78L,0x52b4b3a684ef0a10L, + 0xbde6ea5d20327fe2L,0xb71ec435660f9615L,0xeede5a04b8ad8173L } }, + /* 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 */ + { { 0x73ade4da2341c342L,0xdd326e54ea704422L,0x336c7d983741cef3L, + 0x1eafa00d59e61549L,0xcd3ed892bd9a3efdL,0x03faf26cc5c6c7e4L }, + { 0x087e2fcf3045f8acL,0x14a65532174f1e73L,0x2cf84f28fe0af9a7L, + 0xddfd7a842cdc935bL,0x4c0f117b6929c895L,0x356572d64c8bcfccL } }, + /* 18 */ + { { 0x7ecbac017d8c1bbaL,0x6058f9c390b0f3d5L,0xaee116e3f6197d0fL, + 0xc4dd70684033b128L,0xf084dba6c209b983L,0x97c7c2cf831dbc4aL }, + { 0x2f4e61ddf96010e8L,0xd97e4e20529faa17L,0x4ee6666069d37f20L, + 0xccc139ed3d366d72L,0x690b6ee213488e0fL,0x7cad1dc5f3a6d533L } }, + /* 19 */ + { { 0x660a9a81da57a41fL,0xe74a0412ec0039b6L,0x42343c6b5e1dad15L, + 0x284f3ff546681d4cL,0xb51087f163749e89L,0x070f23cc6f9f2f13L }, + { 0x542211da5d186e14L,0x84748f37fddb0dffL,0x41a3aab4db1f4180L, + 0x25ed667ba6402d0eL,0x2f2924a902f58355L,0x5844ee7cfa44a689L } }, + /* 20 */ + { { 0xfab086073f3b236fL,0x19e9d41d81e221daL,0xf3f6571e3927b428L, + 0x4348a9337550f1f6L,0x7167b996a85e62f0L,0x62d437597f5452bfL }, + { 0xd85feb9ef2955926L,0x440a561f6df78353L,0x389668ec9ca36b59L, + 0x052bf1a1a22da016L,0xbdfbff72f6093254L,0x94e50f28e22209f3L } }, + /* 21 */ + { { 0x90b2e5b33062e8afL,0xa8572375e8a3d369L,0x3fe1b00b201db7b1L, + 0xe926def0ee651aa2L,0x6542c9beb9b10ad7L,0x098e309ba2fcbe74L }, + { 0x779deeb3fff1d63fL,0x23d0e80a20bfd374L,0x8452bb3b8768f797L, + 0xcf75bb4d1f952856L,0x8fe6b40029ea3faaL,0x12bd3e4081373a53L } }, + /* 22 */ + { { 0xc023780d104cbba5L,0x6207e747fa35dd4cL,0x35c239281ca9b6a3L, + 0x4ff19be897987b10L,0xb8476bbf8022eee8L,0xaa0a4a14d3bbe74dL }, + { 0x20f94331187d4543L,0x3215387079f6e066L,0x83b0f74eac7e82e1L, + 0xa7748ba2828f06abL,0xc5f0298ac26ef35fL,0x0f0c50708e9a7dbdL } }, + /* 23 */ + { { 0x0c5c244cdef029ddL,0x3dabc687850661b8L,0x9992b865fe11d981L, + 0xe9801b8f6274dbadL,0xe54e6319098da242L,0x9929a91a91a53d08L }, + { 0x37bffd7235285887L,0xbc759425f1418102L,0x9280cc35fd2e6e20L, + 0x735c600cfbc42ee5L,0xb7ad28648837619aL,0xa3627231a778c57bL } }, + /* 24 */ + { { 0xae799b5c91361ed8L,0x47d71b756c63366cL,0x54cdd5211b265a6aL, + 0xe0215a5998d77b74L,0x4424d9b7bab29db0L,0x8b0ffacc7fd9e536L }, + { 0x46d85d1237b5d9efL,0x5b106d62bfa91747L,0xed0479f85f99ba2dL, + 0x0e6f39231d104de4L,0x83a84c8425e8983fL,0xa9507e0af8105a70L } }, + /* 25 */ + { { 0xf6c68a6e14cf381cL,0xaf9d27bdc22e31ccL,0x23568d4daa8a5ccbL, + 0xe431eec0e338e4d2L,0xf1a828fe8f52ad1fL,0xdb6a0579e86acd80L }, + { 0x2885672e4507832aL,0x73fc275f887e5289L,0x65f8027805610d08L, + 0x8d9b4554075ff5b0L,0x3a8e8fb109f712b5L,0x39f0ac862ebe9cf2L } }, + /* 26 */ + { { 0xd8fabf784c52edf5L,0xdcd737e5a589ae53L,0x94918bf0d791ab17L, + 0xb5fbd956bcff06c9L,0xf6d3032edca46d45L,0x2cdff7e141a3e486L }, + { 0x6674b3ba61f47ec8L,0x8a882163eef84608L,0xa257c7054c687f90L, + 0xe30cb2edf6cdf227L,0x2c4c64ca7f6ea846L,0x186fa17ccc6bcd3cL } }, + /* 27 */ + { { 0x48a3f5361dfcb91eL,0x83595e13646d358aL,0xbd15827b91128798L, + 0x3ce612b82187757aL,0x873150a161bd7372L,0xf4684530b662f568L }, + { 0x8833950b401896f6L,0xe11cb89a77f3e090L,0xb2f12cac48e7f4a5L, + 0x313dd769f606677eL,0xfdcf08b316579f93L,0x6429cec946b8f22bL } }, + /* 28 */ + { { 0x4984dd54bb75f9a4L,0x4aef06b929d3b570L,0xb5f84ca23d6e4c1eL, + 0x24c61c11b083ef35L,0xce4a7392392ca9ffL,0x865d65176730a800L }, + { 0xca3dfe76722b4a2bL,0x12c04bf97b083e0eL,0x803ce5b51b86b8a5L, + 0x3fc7632d6a7e3e0cL,0xc89970c2c81adbe4L,0x3cbcd3ad120e16b1L } }, + /* 29 */ + { { 0xfbfb4cc7ec30ce93L,0x10ed6c7db72720a2L,0xec675bf747b55500L, + 0x90725903333ff7c3L,0xc7c3973e5075bfc0L,0xb049ecb007acf31bL }, + { 0xb4076eaf4f58839cL,0x101896daa2b05e4fL,0x3f6033b0ab40c66eL, + 0x19ee9eebc8d864baL,0xeb6cf15547bf6d2aL,0x8e5a9663f826477dL } }, + /* 30 */ + { { 0x69e62fddf7fbd5e1L,0x38ecfe5476912b1dL,0x845a3d56d1da3bfbL, + 0x0494950e1c86f0d4L,0x83cadbf93bc36ce8L,0x41fce5724fccc8d1L }, + { 0x05f939c28332c144L,0xb17f248b0871e46eL,0x3d8534e266e8aff6L, + 0x1d06f1dc3b85c629L,0xdb06a32ea3131b73L,0xf295184d8b3f64e5L } }, + /* 31 */ + { { 0xd9653ff736ddc103L,0x25f43e3795ef606fL,0x09e301fcfe06dce8L, + 0x85af234130b6eebfL,0x79b12b530ff56b20L,0x9b4fb499fe9a3c6bL }, + { 0x0154f89251d27ac2L,0xd33167e356ca5389L,0x7828ec1fafc065a6L, + 0x0959a2587f746c9bL,0xb18f1be30c44f837L,0xa7946117c4132fdbL } }, + /* 32 */ + { { 0xc0426b775e3c647bL,0xbfcbd9398cf05348L,0x31d312e3172c0d3dL, + 0x5f49fde6ee754737L,0x895530f06da7ee61L,0xcf281b0ae8b3a5fbL }, + { 0xfd14973541b8a543L,0x41a625a73080dd30L,0xe2baae07653908cfL, + 0xc3d01436ba02a278L,0xa0d0222e7b21b8f8L,0xfdc270e9d7ec1297L } }, + /* 33 */ + { { 0x00873c0cbc7f41d6L,0xd976113e1b7ad641L,0x2a536ff4238443fbL, + 0x030d00e241e62e45L,0x532e98675f545fc6L,0xcd0331088e91208cL }, + { 0xd1a04c999797612cL,0xd4393e02eea674e2L,0xd56fa69ee19742a1L, + 0xdd2ab48085f0590eL,0xa5cefc5248a2243dL,0x48cc67b654383f41L } }, + /* 34 */ + { { 0x4e50430efc14ab48L,0x195b7f4f26706a74L,0x2fe8a228cc881ff6L, + 0xb1b968e2d945013dL,0x936aa5794b92162bL,0x4fb766b7364e754aL }, + { 0x13f93bca31e1ff7fL,0x696eb5cace4f2691L,0xff754bf8a2b09e02L, + 0x58f13c9ce58e3ff8L,0xb757346f1678c0b0L,0xd54200dba86692b3L } }, + /* 35 */ + { { 0x9a030bbd6dda1265L,0xf7b4f3fce89718ddL,0xa6a4931f936065b8L, + 0xbce72d875f72241cL,0x6cbb51cb65775857L,0xc71618154e993675L }, + { 0xe81a0f792ee32189L,0xef2fab26277dc0b2L,0x9e64f6feb71f469fL, + 0xb448ce33dfdaf859L,0x3f5c1c4cbe6b5df1L,0xfb8dfb001de45f7bL } }, + /* 36 */ + { { 0xc7345fa74d5bb921L,0x5c7e04be4d2b667eL,0x47ed3a80282d7a3eL, + 0x5c2777f87e47b2a4L,0x89b3b10008488e2eL,0x9aad77c2b2eb5b45L }, + { 0xd681bca7daac34aeL,0x2452e4e526afb326L,0x0c88792441a1ee14L, + 0x743b04d4c2407adeL,0xcb5e999bfc17a2acL,0x4dca2f824a701a06L } }, + /* 37 */ + { { 0x68e31ca61127bc1aL,0xa3edd59b17ead3beL,0x67b6b645e25f5a15L, + 0x76221794a420e15eL,0x794fd83b4b1e872eL,0x7cab3f03b2dece1bL }, + { 0x7119bf15ca9b3586L,0xa55459244d250bd7L,0x173633eacc6bcf24L, + 0x9bd308c2b1b6f884L,0x3bae06f5447d38c3L,0x54dcc135f341fe1cL } }, + /* 38 */ + { { 0x56d3598d943caf0dL,0xce044ea9225ff133L,0x9edf6a7c563fadeaL, + 0x632eb94473e8dc27L,0x814b467e3190dcabL,0x2d4f4f316dbb1e31L }, + { 0x8d69811ca143b7caL,0x4ec1ac32de7cf950L,0x223ab5fd37b5fe82L, + 0xe82616e49390f1d9L,0xabff4b2075804610L,0x11b9be15875b08f0L } }, + /* 39 */ + { { 0x4ae31a3d3bbe682cL,0xbc7c5d2674eef2ddL,0x92afd10a3c47dd40L, + 0xec7e0a3bc14ab9e1L,0x6a6c3dd1b2e495e4L,0x085ee5e9309bcd85L }, + { 0xf381a9088c2e67fdL,0x32083a80e261eaf2L,0x0fcd6a4996deee15L, + 0xe3b8fb035e524c79L,0x8dc360d91d5b08b9L,0x3a06e2c87f26719fL } }, + /* 40 */ + { { 0x5cd9f5a87237cac0L,0x93f0b59d43586794L,0x4384a764e94f6c4eL, + 0x8304ed2bb62782d3L,0x0b8db8b3cde06015L,0x4336dd535dbe190fL }, + { 0x5744355392ab473aL,0x031c7275be5ed046L,0x3e78678c21909aa4L, + 0x4ab7e04f99202ddbL,0x2648d2066977e635L,0xd427d184093198beL } }, + /* 41 */ + { { 0x822848f50f9b5a31L,0xbb003468baadb62aL,0x233a04723357559cL, + 0x49ef688079aee843L,0xa89867a0aeb9e1e3L,0xc151931b1f6f9a55L }, + { 0xd264eb0bad74251eL,0x37b9b2634abf295eL,0xb600921b04960d10L, + 0x0de53dbc4da77dc0L,0x01d9bab3d2b18697L,0xad54ec7af7156ddfL } }, + /* 42 */ + { { 0x8e74dc3579efdc58L,0x456bd3694ff68ddbL,0x724e74ccd32096a5L, + 0xe41cff42386783d0L,0xa04c7f217c70d8a4L,0x41199d2fe61a19a2L }, + { 0xd389a3e029c05dd2L,0x535f2a6be7e3fda9L,0x26ecf72d7c2b4df8L, + 0x678275f4fe745294L,0x6319c9cc9d23f519L,0x1e05a02d88048fc4L } }, + /* 43 */ + { { 0x75cc8e2ed4d5ffe8L,0xf8bb4896dbea17f2L,0x35059790cee3cb4aL, + 0x4c06ee85a47c6165L,0xf98fff2592935d2fL,0x34c4a57232ffd7c7L }, + { 0xc4b14806ea0376a2L,0x2ea5e7504f115e02L,0x532d76e21e55d7c0L, + 0x68dc9411f31044daL,0x9272e46571b77993L,0xadaa38bb93a8cfd5L } }, + /* 44 */ + { { 0x4bf0c7127d4ed72aL,0xda0e9264ba1f79a3L,0x48c0258bf4c39ea4L, + 0xa5394ed82a715138L,0x4af511cebf06c660L,0xfcebceefec5c37cdL }, + { 0xf23b75aa779ae8c1L,0xdeff59ccad1e606eL,0xf3f526fd22755c82L, + 0x64c5ab44bb32cefdL,0xa96e11a2915bdefdL,0xab19746a1143813eL } }, + /* 45 */ + { { 0x43c78585ec837d7dL,0xca5b6fbcb8ee0ba4L,0x34e924d9d5dbb5eeL, + 0x3f4fa104bb4f1ca5L,0x15458b72398640f7L,0x4231faa9d7f407eaL }, + { 0x53e0661ef96e6896L,0x554e4c69d03b0f9dL,0xd4fcb07b9c7858d1L, + 0x7e95279352cb04faL,0x5f5f15748974e7f7L,0x2e3fa5586b6d57c8L } }, + /* 46 */ + { { 0x42cd48036a9951a8L,0xa8b15b8842792ad0L,0x18e8bcf9abb29a73L, + 0xbfd9a092409933e8L,0x760a3594efb88dc4L,0x1441886340724458L }, + { 0x162a56ee99caedc7L,0x8fb12ecd91d101c9L,0xea671967393202daL, + 0x1aac8c4aa4ccd796L,0x7db050361cf185a8L,0x0c9f86cd8cfd095aL } }, + /* 47 */ + { { 0x9a72814710b2a556L,0x767ca964327b70b2L,0x04ed9e125e3799b7L, + 0x6781d2dc22a3eb2aL,0x5bd116eb0d9450acL,0xeccac1fca7ebe08aL }, + { 0xde68444fdc2d6e94L,0x3621f42935ecf21bL,0x14e2d54329e03a2cL, + 0x53e42cd57d3e7f0aL,0xbba26c0973ed00b9L,0x00297c39c57d2272L } }, + /* 48 */ + { { 0x3aaaab10b8243a7dL,0x6eeef93e8fa58c5bL,0xf866fca39ae7f764L, + 0x64105a2661ab04d3L,0xa3578d8a03945d66L,0xb08cd3e4791b848cL }, + { 0x45edc5f8756d2411L,0xd4a790d9a755128cL,0xc2cf096349e5f6a0L, + 0xc66d267df649beaaL,0x3ce6d9688467039eL,0x50046c6b42f7816fL } }, + /* 49 */ + { { 0x92ae160266425043L,0x1ff66afdf08db890L,0x386f5a7f8f162ce5L, + 0x18d2dea0fcf5598fL,0x78372b3a1a8ca18eL,0xdf0d20eb8cd0e6f7L }, + { 0x7edd5e1d75bb4045L,0x252a47ceb96d94b7L,0xbdb293582c626776L, + 0x853c394340dd1031L,0x9dc9becf7d5f47fdL,0x27c2302fbae4044aL } }, + /* 50 */ + { { 0x2d1d208a8f2d49ceL,0x0d91aa02162df0a2L,0x9c5cce8709a07f65L, + 0xdf07238b84339012L,0x5028e2c8419442cdL,0x2dcbd35872062abaL }, + { 0xb5fbc3cbe4680967L,0x2a7bc6459f92d72cL,0x806c76e1116c369dL, + 0x5c50677a3177e8d8L,0x753739eb4569df57L,0x2d481ef636c3f40bL } }, + /* 51 */ + { { 0x1a2d39fdfea1103eL,0xeaae559295f81b17L,0xdbd0aa18f59b264aL, + 0x90c39c1acb592ee0L,0xdf62f80d9750cca3L,0xda4d8283df97cc6cL }, + { 0x0a6dd3461e201067L,0x1531f85969fb1f6bL,0x4895e5521d60121fL, + 0x0b21aab04c041c91L,0x9d896c46bcc1ccf8L,0xd24da3b33141bde7L } }, + /* 52 */ + { { 0x575a053753b0a354L,0x392ff2f40c6ddcd8L,0x0b8e8cff56157b94L, + 0x073e57bd3b1b80d1L,0x2a75e0f03fedee15L,0x752380e4aa8e6f19L }, + { 0x1f4e227c6558ffe9L,0x3a34861819ec5415L,0xab382d5ef7997085L, + 0x5e6deaffddc46ac2L,0xe5144078fc8d094cL,0xf674fe51f60e37c6L } }, + /* 53 */ + { { 0x6fb87ae5af63408fL,0xa39c36a9cd75a737L,0x7833313fcf4c618dL, + 0xfbcd4482f034c88dL,0x4469a76139b35288L,0x77a711c566b5d9c9L }, + { 0x4a695dc7944f8d65L,0xe6da5f65161aaba8L,0x8654e9c324601669L, + 0xbc8b93f528ae7491L,0x5f1d1e838f5580d8L,0x8ccf9a1acea32cc8L } }, + /* 54 */ + { { 0x28ab110c7196fee2L,0x75799d63874c8945L,0xa262934829aedaddL, + 0x9714cc7b2be88ff4L,0xf71293cfd58d60d6L,0xda6b6cb332a564e9L }, + { 0xf43fddb13dd821c2L,0xf2f2785f90dd323dL,0x91246419048489f8L, + 0x61660f26d24c6749L,0x961d9e8cc803c15cL,0x631c6158faadc4c9L } }, + /* 55 */ + { { 0xacf2ebe0fd752366L,0xb93c340e139be88bL,0x98f664850f20179eL, + 0x14820254ff1da785L,0x5278e2764f85c16eL,0xa246ee457aab1913L }, + { 0x43861eb453763b33L,0xc49f03fc45c0bc0dL,0xafff16bcad6b1ea1L, + 0xce33908b6fd49c99L,0x5c51e9bff7fde8c3L,0x076a7a39ff142c5eL } }, + /* 56 */ + { { 0x04639dfe9e338d10L,0x8ee6996ff42b411bL,0x960461d1a875cef2L, + 0x1057b6d695b4d0baL,0x27639252a906e0bcL,0x2c19f09ae1c20f8aL }, + { 0x5b8fc3f0eef4c43dL,0xe2e1b1a807a84aa9L,0x5f455528835d2bdbL, + 0x0f4aee4d207132ddL,0xe9f8338c3907f675L,0x7a874dc90e0531f0L } }, + /* 57 */ + { { 0x84b22d4597c27050L,0xbd0b8df759e70bf8L,0xb4d6740579738b9bL, + 0x47f4d5f5cd917c4fL,0x9099c4ce13ce6e33L,0x942bfd39521d0f8bL }, + { 0x5028f0f6a43b566dL,0xaf6e866921bff7deL,0x83f6f856c44232cdL, + 0x65680579f915069aL,0xd12095a2ecfecb85L,0xcf7f06aedb01ba16L } }, + /* 58 */ + { { 0x0f56e3c48ef96c80L,0xd521f2b33ddb609cL,0x2be941027dc1450dL, + 0x2d21a07102a91fe2L,0x2e6f74fa1efa37deL,0x9a9a90b8156c28a1L }, + { 0xc54ea9ea9dc7dfcbL,0xc74e66fc2c2c1d62L,0x9f23f96749d3e067L, + 0x1c7c3a4654dd38adL,0xc70058845946cee3L,0x8985636845cc045dL } }, + /* 59 */ + { { 0x29da7cd4fce73946L,0x8f697db523168563L,0x8e235e9ccba92ec6L, + 0x55d4655f9f91d3eaL,0xf3689f23aa50a6cdL,0xdcf21c2621e6a1a0L }, + { 0xcffbc82e61b818bfL,0xc74a2f96da47a243L,0x234e980a8bc1a0cfL, + 0xf35fd6b57929cb6dL,0x81468e12efe17d6cL,0xddea6ae558b2dafbL } }, + /* 60 */ + { { 0x294de8877e787b2eL,0x258acc1f39a9310dL,0x92d9714aac14265dL, + 0x18b5591c708b48a0L,0x27cc6bb0e1abbf71L,0xc0581fa3568307b9L }, + { 0x9e0f58a3f24d4d58L,0xfebe9bb8e0ce2327L,0x91fd6a419d1be702L, + 0x9a7d8a45facac993L,0xabc0a08c9e50d66dL,0x02c342f706498201L } }, + /* 61 */ + { { 0xccd71407157bdbc2L,0x72fa89c6ad0e1605L,0xb1d3da2bb92a015fL, + 0x8ad9e7cda0a3fe56L,0x160edcbd24f06737L,0x79d4db3361275be6L }, + { 0xd3d31fd95f3497c4L,0x8cafeaee04192fb0L,0xe13ca74513a50af3L, + 0x188261678c85aae5L,0xce06cea89eb556ffL,0x2eef1995bdb549f3L } }, + /* 62 */ + { { 0x8ed7d3eb50596edcL,0xaa359362905243a2L,0xa212c2c2a4b6d02bL, + 0x611fd727c4fbec68L,0x8a0b8ff7b84f733dL,0xd85a6b905f0daf0eL }, + { 0x60e899f5d4091cf7L,0x4fef2b672eff2768L,0xc1f195cb10c33964L, + 0x8275d36993626a8fL,0xc77904f40d6c840aL,0x88d8b7fd7a868acdL } }, + /* 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 } }, +}; + +/* 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. + * 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, void* heap) +{ + return sp_384_ecc_mulmod_stripe_6(r, &p384_base, p384_table, + k, map, heap); +} + +#ifdef HAVE_INTEL_AVX2 +/* 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. + * 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, void* heap) +{ + return sp_384_ecc_mulmod_stripe_avx2_6(r, &p384_base, p384_table, + k, map, heap); +} + +#endif /* HAVE_INTEL_AVX2 */ +/* Multiply the base point of P384 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_384(mp_int* km, ecc_point* r, int map, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 p; + sp_digit kd[6]; +#endif + sp_point_384* point; + 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 defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 6, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + } +#else + k = kd; +#endif + if (err == MP_OKAY) { + sp_384_from_mp(k, 6, km); + +#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, map, heap); + else +#endif + err = sp_384_ecc_mulmod_base_6(point, k, map, heap); + } + if (err == MP_OKAY) { + err = sp_384_point_to_ecc_point_6(point, r); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + 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. + * Implementation is constant time. + * + * a Number to check. + * returns 1 if the number is zero and 0 otherwise. + */ +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 */ +extern void sp_384_add_one_6(sp_digit* a); +extern void sp_384_from_bin(sp_digit* r, int size, const byte* a, int n); +/* Generates a scalar that is in the range 1..order-1. + * + * rng Random number generator. + * k Scalar value. + * returns RNG failures, MEMORY_E when memory allocation fails and + * MP_OKAY on success. + */ +static int sp_384_ecc_gen_k_6(WC_RNG* rng, sp_digit* k) +{ + int err; + byte buf[48]; + + do { + err = wc_RNG_GenerateBlock(rng, buf, sizeof(buf)); + if (err == 0) { + sp_384_from_bin(k, 6, buf, (int)sizeof(buf)); + if (sp_384_cmp_6(k, p384_order2) < 0) { + sp_384_add_one_6(k); + break; + } + } + } + while (err == 0); + + return err; +} + +/* Makes a random EC key pair. + * + * rng Random number generator. + * priv Generated private value. + * pub Generated public point. + * heap Heap to use for allocation. + * returns ECC_INF_E when the point does not have the correct order, RNG + * failures, MEMORY_E when memory allocation fails and MP_OKAY on success. + */ +int sp_ecc_make_key_384(WC_RNG* rng, mp_int* priv, ecc_point* pub, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 p; + sp_digit kd[6]; +#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN + sp_point_384 inf; +#endif +#endif + sp_point_384* point; + sp_digit* k = NULL; +#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN + sp_point_384* infinity; +#endif + int err; +#ifdef HAVE_INTEL_AVX2 + word32 cpuid_flags = cpuid_get_flags(); +#endif + + (void)heap; + + err = sp_384_point_new_6(heap, p, point); +#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN + if (err == MP_OKAY) { + err = sp_384_point_new_6(heap, inf, infinity); + } +#endif +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 6, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) { + err = MEMORY_E; + } + } +#else + k = kd; +#endif + + if (err == MP_OKAY) { + err = sp_384_ecc_gen_k_6(rng, k); + } + 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, 1, NULL); + else +#endif + err = sp_384_ecc_mulmod_base_6(point, k, 1, NULL); + } + +#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN + 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(infinity, point, p384_order, 1, + NULL); + } + else +#endif + err = sp_384_ecc_mulmod_6(infinity, point, p384_order, 1, NULL); + } + if (err == MP_OKAY) { + if ((sp_384_iszero_6(point->x) == 0) || (sp_384_iszero_6(point->y) == 0)) { + err = ECC_INF_E; + } + } +#endif + + if (err == MP_OKAY) { + err = sp_384_to_mp(k, priv); + } + if (err == MP_OKAY) { + err = sp_384_point_to_ecc_point_6(point, pub); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif +#ifdef WOLFSSL_VALIDATE_ECC_KEYGEN + sp_384_point_free_6(infinity, 1, heap); +#endif + sp_384_point_free_6(point, 1, heap); + + return err; +} + +#ifdef HAVE_ECC_DHE +extern void sp_384_to_bin(sp_digit* r, byte* a); +/* Multiply the point by the scalar and serialize the X ordinate. + * The number is 0 padded to maximum size on output. + * + * priv Scalar to multiply the point by. + * pub Point to multiply. + * out Buffer to hold X ordinate. + * outLen On entry, size of the buffer in bytes. + * On exit, length of data in buffer in bytes. + * heap Heap to use for allocation. + * 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, + word32* outLen, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 p; + sp_digit kd[6]; +#endif + sp_point_384* point = NULL; + sp_digit* k = NULL; + int err = MP_OKAY; +#ifdef HAVE_INTEL_AVX2 + word32 cpuid_flags = cpuid_get_flags(); +#endif + + if (*outLen < 48U) { + err = BUFFER_E; + } + + if (err == MP_OKAY) { + err = sp_384_point_new_6(heap, p, point); + } +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + k = (sp_digit*)XMALLOC(sizeof(sp_digit) * 6, heap, + DYNAMIC_TYPE_ECC); + if (k == NULL) + err = MEMORY_E; + } +#else + k = kd; +#endif + + if (err == MP_OKAY) { + sp_384_from_mp(k, 6, priv); + sp_384_point_from_ecc_point_6(point, pub); +#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, 1, heap); + else +#endif + err = sp_384_ecc_mulmod_6(point, point, k, 1, heap); + } + if (err == MP_OKAY) { + sp_384_to_bin(point->x, out); + *outLen = 48; + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (k != NULL) { + XFREE(k, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_6(point, 0, heap); + + return err; +} +#endif /* HAVE_ECC_DHE */ + +#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) +#ifdef HAVE_INTEL_AVX2 +#endif /* HAVE_INTEL_AVX2 */ +#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 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); +/* 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) +{ + register sp_digit r asm("rax"); + __asm__ __volatile__ ( + "divq %3" + : "=a" (r) + : "d" (d1), "a" (d0), "r" (div) + : + ); + 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_384_mask_6(sp_digit* r, const sp_digit* a, sp_digit m) +{ +#ifdef WOLFSSL_SP_SMALL + int i; + + for (i=0; i<6; 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; +#endif +} + +/* 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 Nmber 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_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; + int i; +#ifdef HAVE_INTEL_AVX2 + word32 cpuid_flags = cpuid_get_flags(); +#endif + + (void)m; + + div = d[5]; + XMEMCPY(t1, a, sizeof(*t1) * 2 * 6); + for (i=5; i>=0; i--) { + r1 = div_384_word_6(t1[6 + i], t1[6 + i - 1], div); + +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_384_mul_d_avx2_6(t2, d, r1); + else +#endif + sp_384_mul_d_6(t2, d, r1); + t1[6 + i] += sp_384_sub_in_place_6(&t1[i], t2); + t1[6 + i] -= t2[6]; + sp_384_mask_6(t2, d, t1[6 + i]); + t1[6 + i] += sp_384_add_6(&t1[i], &t1[i], t2); + sp_384_mask_6(t2, d, t1[6 + i]); + t1[6 + i] += sp_384_add_6(&t1[i], &t1[i], t2); + } + + r1 = sp_384_cmp_6(t1, d) >= 0; +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_384_cond_sub_avx2_6(r, t1, d, (sp_digit)0 - r1); + else +#endif + sp_384_cond_sub_6(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_384_mod_6(sp_digit* r, const sp_digit* a, const sp_digit* m) +{ + return sp_384_div_6(a, m, NULL, r); +} + +#endif +#if defined(HAVE_ECC_SIGN) || defined(HAVE_ECC_VERIFY) +#ifdef WOLFSSL_SP_SMALL +/* Order-2 for the P384 curve. */ +static const uint64_t p384_order_minus_2[6] = { + 0xecec196accc52971U,0x581a0db248b0a77aU,0xc7634d81f4372ddfU, + 0xffffffffffffffffU,0xffffffffffffffffU,0xffffffffffffffffU +}; +#else +/* 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 */ + +/* Multiply two number mod the order of P384 curve. (r = a * b mod order) + * + * r Result of the multiplication. + * a First operand of the multiplication. + * b Second operand of the multiplication. + */ +static void sp_384_mont_mul_order_6(sp_digit* r, const sp_digit* a, const sp_digit* b) +{ + sp_384_mul_6(r, a, b); + sp_384_mont_reduce_order_6(r, p384_order, p384_mp_order); +} + +/* Square number mod the order of P384 curve. (r = a * a mod order) + * + * r Result of the squaring. + * a Number to square. + */ +static void sp_384_mont_sqr_order_6(sp_digit* r, const sp_digit* a) +{ + sp_384_sqr_6(r, a); + sp_384_mont_reduce_order_6(r, p384_order, p384_mp_order); +} + +#ifndef WOLFSSL_SP_SMALL +/* Square number mod the order of P384 curve a number of times. + * (r = a ^ n mod order) + * + * r Result of the squaring. + * a Number to square. + */ +static void sp_384_mont_sqr_n_order_6(sp_digit* r, const sp_digit* a, int n) +{ + int i; + + sp_384_mont_sqr_order_6(r, a); + for (i=1; i=0; i--) { + sp_384_mont_sqr_order_6(t, t); + if ((p384_order_minus_2[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) { + sp_384_mont_mul_order_6(t, t, a); + } + } + XMEMCPY(r, t, sizeof(sp_digit) * 6U); +#else + sp_digit* t = td; + sp_digit* t2 = td + 2 * 6; + sp_digit* t3 = td + 4 * 6; + int i; + + /* t = a^2 */ + sp_384_mont_sqr_order_6(t, a); + /* t = a^3 = t * a */ + sp_384_mont_mul_order_6(t, t, a); + /* t2= a^c = t ^ 2 ^ 2 */ + sp_384_mont_sqr_n_order_6(t2, t, 2); + /* t = a^f = t2 * t */ + sp_384_mont_mul_order_6(t, t2, t); + /* t2= a^f0 = t ^ 2 ^ 4 */ + sp_384_mont_sqr_n_order_6(t2, t, 4); + /* t = a^ff = t2 * t */ + sp_384_mont_mul_order_6(t, t2, t); + /* t2= a^ff00 = t ^ 2 ^ 8 */ + sp_384_mont_sqr_n_order_6(t2, t, 8); + /* t3= a^ffff = t2 * t */ + sp_384_mont_mul_order_6(t3, t2, t); + /* t2= a^ffff0000 = t3 ^ 2 ^ 16 */ + sp_384_mont_sqr_n_order_6(t2, t3, 16); + /* t = a^ffffffff = t2 * t3 */ + sp_384_mont_mul_order_6(t, t2, t3); + /* t2= a^ffffffff0000 = t ^ 2 ^ 16 */ + sp_384_mont_sqr_n_order_6(t2, t, 16); + /* t = a^ffffffffffff = t2 * t3 */ + sp_384_mont_mul_order_6(t, t2, t3); + /* t2= a^ffffffffffff000000000000 = t ^ 2 ^ 48 */ + sp_384_mont_sqr_n_order_6(t2, t, 48); + /* t= a^fffffffffffffffffffffffff = t2 * t */ + sp_384_mont_mul_order_6(t, t2, t); + /* t2= a^ffffffffffffffffffffffff000000000000000000000000 */ + sp_384_mont_sqr_n_order_6(t2, t, 96); + /* t2= a^ffffffffffffffffffffffffffffffffffffffffffffffff = t2 * t */ + 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) { + sp_384_mont_mul_order_6(t2, t2, a); + } + } + sp_384_mont_sqr_order_6(t2, t2); + sp_384_mont_mul_order_6(r, t2, a); +#endif /* WOLFSSL_SP_SMALL */ +} + +#ifdef HAVE_INTEL_AVX2 +/* Multiply two number mod the order of P384 curve. (r = a * b mod order) + * + * r Result of the multiplication. + * a First operand of the multiplication. + * b Second operand of the multiplication. + */ +static void sp_384_mont_mul_order_avx2_6(sp_digit* r, const sp_digit* a, const sp_digit* b) +{ + sp_384_mul_avx2_6(r, a, b); + sp_384_mont_reduce_order_avx2_6(r, p384_order, p384_mp_order); +} + +/* Square number mod the order of P384 curve. (r = a * a mod order) + * + * r Result of the squaring. + * a Number to square. + */ +static void sp_384_mont_sqr_order_avx2_6(sp_digit* r, const sp_digit* a) +{ + sp_384_sqr_avx2_6(r, a); + sp_384_mont_reduce_order_avx2_6(r, p384_order, p384_mp_order); +} + +#ifndef WOLFSSL_SP_SMALL +/* Square number mod the order of P384 curve a number of times. + * (r = a ^ n mod order) + * + * r Result of the squaring. + * a Number to square. + */ +static void sp_384_mont_sqr_n_order_avx2_6(sp_digit* r, const sp_digit* a, int n) +{ + int i; + + sp_384_mont_sqr_order_avx2_6(r, a); + for (i=1; i=0; i--) { + sp_384_mont_sqr_order_avx2_6(t, t); + if ((p384_order_minus_2[i / 64] & ((sp_int_digit)1 << (i % 64))) != 0) { + sp_384_mont_mul_order_avx2_6(t, t, a); + } + } + XMEMCPY(r, t, sizeof(sp_digit) * 6U); +#else + sp_digit* t = td; + sp_digit* t2 = td + 2 * 6; + sp_digit* t3 = td + 4 * 6; + int i; + + /* t = a^2 */ + sp_384_mont_sqr_order_avx2_6(t, a); + /* t = a^3 = t * a */ + sp_384_mont_mul_order_avx2_6(t, t, a); + /* t2= a^c = t ^ 2 ^ 2 */ + sp_384_mont_sqr_n_order_avx2_6(t2, t, 2); + /* t = a^f = t2 * t */ + sp_384_mont_mul_order_avx2_6(t, t2, t); + /* t2= a^f0 = t ^ 2 ^ 4 */ + sp_384_mont_sqr_n_order_avx2_6(t2, t, 4); + /* t = a^ff = t2 * t */ + sp_384_mont_mul_order_avx2_6(t, t2, t); + /* t2= a^ff00 = t ^ 2 ^ 8 */ + sp_384_mont_sqr_n_order_avx2_6(t2, t, 8); + /* t3= a^ffff = t2 * t */ + sp_384_mont_mul_order_avx2_6(t3, t2, t); + /* t2= a^ffff0000 = t3 ^ 2 ^ 16 */ + sp_384_mont_sqr_n_order_avx2_6(t2, t3, 16); + /* t = a^ffffffff = t2 * t3 */ + sp_384_mont_mul_order_avx2_6(t, t2, t3); + /* t2= a^ffffffff0000 = t ^ 2 ^ 16 */ + sp_384_mont_sqr_n_order_avx2_6(t2, t, 16); + /* t = a^ffffffffffff = t2 * t3 */ + sp_384_mont_mul_order_avx2_6(t, t2, t3); + /* t2= a^ffffffffffff000000000000 = t ^ 2 ^ 48 */ + sp_384_mont_sqr_n_order_avx2_6(t2, t, 48); + /* t= a^fffffffffffffffffffffffff = t2 * t */ + sp_384_mont_mul_order_avx2_6(t, t2, t); + /* t2= a^ffffffffffffffffffffffff000000000000000000000000 */ + sp_384_mont_sqr_n_order_avx2_6(t2, t, 96); + /* t2= a^ffffffffffffffffffffffffffffffffffffffffffffffff = t2 * t */ + 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) { + sp_384_mont_mul_order_avx2_6(t2, t2, a); + } + } + sp_384_mont_sqr_order_avx2_6(t2, t2); + sp_384_mont_mul_order_avx2_6(r, t2, a); +#endif /* WOLFSSL_SP_SMALL */ +} + +#endif /* HAVE_INTEL_AVX2 */ +#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 + +/* Sign the hash using the private key. + * e = [hash, 384 bits] from binary + * r = (k.G)->x mod order + * s = (r * x + e) / k mod order + * The hash is truncated to the first 384 bits. + * + * hash Hash to sign. + * hashLen Length of the hash data. + * rng Random number generator. + * priv Private part of key - scalar. + * 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. + */ +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) +{ +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_digit* d = NULL; +#else + sp_digit ed[2*6]; + sp_digit xd[2*6]; + sp_digit kd[2*6]; + sp_digit rd[2*6]; + sp_digit td[3 * 2*6]; + sp_point_384 p; +#endif + sp_digit* e = NULL; + sp_digit* x = NULL; + sp_digit* k = NULL; + 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 i; +#ifdef HAVE_INTEL_AVX2 + word32 cpuid_flags = cpuid_get_flags(); +#endif + + (void)heap; + + err = sp_384_point_new_6(heap, p, point); +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 7 * 2 * 6, heap, + DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + e = d + 0 * 6; + x = d + 2 * 6; + k = d + 4 * 6; + r = d + 6 * 6; + tmp = d + 8 * 6; +#else + e = ed; + x = xd; + k = kd; + r = rd; + tmp = td; +#endif + s = e; + kInv = k; + + if (hashLen > 48U) { + hashLen = 48U; + } + + sp_384_from_bin(e, 6, hash, (int)hashLen); + } + + 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); + } + else { + sp_384_from_mp(k, 6, km); + mp_zero(km); + } + 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, 1, heap); + else +#endif + err = sp_384_ecc_mulmod_base_6(point, k, 1, NULL); + } + + if (err == MP_OKAY) { + /* r = point->x mod order */ + XMEMCPY(r, point->x, sizeof(sp_digit) * 6U); + sp_384_norm_6(r); + c = sp_384_cmp_6(r, p384_order); + 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); + 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); + + /* Check that signature is usable. */ + if (sp_384_iszero_6(s) == 0) { + break; + } + } + } + + if (i == 0) { + err = RNG_FAILURE_E; + } + + if (err == MP_OKAY) { + err = sp_384_to_mp(r, rm); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(s, sm); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (d != NULL) { + XMEMSET(d, 0, sizeof(sp_digit) * 8 * 6); + XFREE(d, heap, DYNAMIC_TYPE_ECC); + } +#else + XMEMSET(e, 0, sizeof(sp_digit) * 2U * 6U); + 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); + + return err; +} +#endif /* HAVE_ECC_SIGN */ + +#ifdef HAVE_ECC_VERIFY +/* Verify the signature values with the hash and public key. + * e = Truncate(hash, 384) + * u1 = e/s mod order + * u2 = r/s mod order + * r == (u1.G + u2.Q)->x mod order + * Optimization: Leave point in projective form. + * (x, y, 1) == (x' / z'*z', y' / z'*z'*z', z' / z') + * (r + n*order).z'.z' mod prime == (u1.G + u2.Q)->x' + * The hash is truncated to the first 384 bits. + * + * hash Hash to sign. + * hashLen Length of the hash data. + * rng Random number generator. + * priv Private part of key - scalar. + * 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. + */ +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) +{ +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_digit* d = NULL; +#else + sp_digit u1d[2*6]; + sp_digit u2d[2*6]; + sp_digit sd[2*6]; + sp_digit tmpd[2*6 * 5]; + sp_point_384 p1d; + sp_point_384 p2d; +#endif + sp_digit* u1 = NULL; + sp_digit* u2 = NULL; + sp_digit* s = NULL; + sp_digit* tmp = NULL; + sp_point_384* p1; + sp_point_384* p2 = NULL; + sp_digit carry; + int64_t c; + 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) { + err = sp_384_point_new_6(heap, p2d, p2); + } +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 16 * 6, heap, + DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + u1 = d + 0 * 6; + u2 = d + 2 * 6; + s = d + 4 * 6; + tmp = d + 6 * 6; +#else + u1 = u1d; + u2 = u2d; + s = sd; + tmp = tmpd; +#endif + + if (hashLen > 48U) { + hashLen = 48U; + } + + sp_384_from_bin(u1, 6, hash, (int)hashLen); + sp_384_from_mp(u2, 6, r); + sp_384_from_mp(s, 6, sm); + sp_384_from_mp(p2->x, 6, pX); + sp_384_from_mp(p2->y, 6, pY); + sp_384_from_mp(p2->z, 6, pZ); + +#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 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); + } + +#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, heap); + else +#endif + err = sp_384_ecc_mulmod_base_6(p1, u1, 0, heap); + } + 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, heap); + else +#endif + err = sp_384_ecc_mulmod_6(p2, p2, u2, 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(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); + err = sp_384_mod_mul_norm_6(u2, u2, p384_mod); + } + + if (err == MP_OKAY) { + /* u1 = r.z'.z' mod prime */ + sp_384_mont_sqr_6(p1->z, p1->z, p384_mod, p384_mp_mod); + 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) { + /* Reload r and add order. */ + sp_384_from_mp(u2, 6, r); + carry = sp_384_add_6(u2, u2, p384_order); + /* Carry means result is greater than mod and is not valid. */ + if (carry == 0) { + sp_384_norm_6(u2); + + /* 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 defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (d != NULL) + XFREE(d, heap, DYNAMIC_TYPE_ECC); +#endif + sp_384_point_free_6(p1, 0, heap); + sp_384_point_free_6(p2, 0, heap); + + return err; +} +#endif /* HAVE_ECC_VERIFY */ + +#ifdef HAVE_ECC_CHECK_KEY +/* 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_384_ecc_is_point_6(sp_point_384* point, void* heap) +{ +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_digit* d = NULL; +#else + sp_digit t1d[2*6]; + sp_digit t2d[2*6]; +#endif + sp_digit* t1; + sp_digit* t2; + int err = MP_OKAY; + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 6 * 4, heap, DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + t1 = d + 0 * 6; + t2 = d + 2 * 6; +#else + (void)heap; + + t1 = t1d; + t2 = t2d; +#endif + + sp_384_sqr_6(t1, point->y); + (void)sp_384_mod_6(t1, t1, p384_mod); + sp_384_sqr_6(t2, point->x); + (void)sp_384_mod_6(t2, t2, p384_mod); + sp_384_mul_6(t2, t2, point->x); + (void)sp_384_mod_6(t2, t2, p384_mod); + (void)sp_384_sub_6(t2, p384_mod, t2); + sp_384_mont_add_6(t1, t1, t2, p384_mod); + + sp_384_mont_add_6(t1, t1, point->x, p384_mod); + sp_384_mont_add_6(t1, t1, point->x, p384_mod); + sp_384_mont_add_6(t1, t1, point->x, p384_mod); + + if (sp_384_cmp_6(t1, p384_b) != 0) { + err = MP_VAL; + } + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + 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_384(mp_int* pX, mp_int* pY) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_point_384 pubd; +#endif + sp_point_384* pub; + byte one[1] = { 1 }; + int err; + + err = sp_384_point_new_6(NULL, pubd, pub); + if (err == MP_OKAY) { + sp_384_from_mp(pub->x, 6, pX); + sp_384_from_mp(pub->y, 6, pY); + sp_384_from_bin(pub->z, 6, one, (int)sizeof(one)); + + err = sp_384_ecc_is_point_6(pub, NULL); + } + + sp_384_point_free_6(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_384(mp_int* pX, mp_int* pY, mp_int* privm, void* heap) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_digit privd[6]; + sp_point_384 pubd; + sp_point_384 pd; +#endif + sp_digit* priv = NULL; + sp_point_384* pub; + sp_point_384* p = NULL; + byte one[1] = { 1 }; + int err; +#ifdef HAVE_INTEL_AVX2 + word32 cpuid_flags = cpuid_get_flags(); +#endif + + err = sp_384_point_new_6(heap, pubd, pub); + if (err == MP_OKAY) { + err = sp_384_point_new_6(heap, pd, p); + } +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + priv = (sp_digit*)XMALLOC(sizeof(sp_digit) * 6, heap, + DYNAMIC_TYPE_ECC); + if (priv == NULL) { + err = MEMORY_E; + } + } +#endif + + if (err == MP_OKAY) { +#if !(defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK)) + priv = privd; +#endif + + sp_384_from_mp(pub->x, 6, pX); + sp_384_from_mp(pub->y, 6, pY); + sp_384_from_bin(pub->z, 6, one, (int)sizeof(one)); + sp_384_from_mp(priv, 6, privm); + + /* Check point at infinitiy. */ + if ((sp_384_iszero_6(pub->x) != 0) && + (sp_384_iszero_6(pub->y) != 0)) { + err = ECC_INF_E; + } + } + + 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; + } + } + + if (err == MP_OKAY) { + /* Check point is on curve */ + err = sp_384_ecc_is_point_6(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_384_ecc_mulmod_avx2_6(p, pub, p384_order, 1, heap); + else +#endif + err = sp_384_ecc_mulmod_6(p, pub, p384_order, 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; + } + } + + if (err == MP_OKAY) { + /* Base * private = point */ +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + err = sp_384_ecc_mulmod_base_avx2_6(p, priv, 1, heap); + else +#endif + err = sp_384_ecc_mulmod_base_6(p, priv, 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; + } + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (priv != NULL) { + XFREE(priv, heap, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_6(p, 0, heap); + sp_384_point_free_6(pub, 0, heap); + + return err; +} +#endif +#ifdef WOLFSSL_PUBLIC_ECC_ADD_DBL +/* Add two projective EC points together. + * (pX, pY, pZ) + (qX, qY, qZ) = (rX, rY, rZ) + * + * pX First EC point's X ordinate. + * pY First EC point's Y ordinate. + * pZ First EC point's Z ordinate. + * qX Second EC point's X ordinate. + * qY Second EC point's Y ordinate. + * qZ Second EC point's Z ordinate. + * rX Resultant EC point's X ordinate. + * rY Resultant EC point's Y ordinate. + * rZ Resultant EC point's Z ordinate. + * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise. + */ +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) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_digit tmpd[2 * 6 * 5]; + sp_point_384 pd; + sp_point_384 qd; +#endif + sp_digit* tmp; + sp_point_384* p; + sp_point_384* q = NULL; + int err; +#ifdef HAVE_INTEL_AVX2 + word32 cpuid_flags = cpuid_get_flags(); +#endif + + err = sp_384_point_new_6(NULL, pd, p); + if (err == MP_OKAY) { + err = sp_384_point_new_6(NULL, qd, q); + } +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 6 * 5, NULL, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) { + err = MEMORY_E; + } + } +#else + tmp = tmpd; +#endif + + if (err == MP_OKAY) { + sp_384_from_mp(p->x, 6, pX); + sp_384_from_mp(p->y, 6, pY); + sp_384_from_mp(p->z, 6, pZ); + sp_384_from_mp(q->x, 6, qX); + sp_384_from_mp(q->y, 6, qY); + sp_384_from_mp(q->z, 6, qZ); + +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_384_proj_point_add_avx2_6(p, p, q, tmp); + else +#endif + sp_384_proj_point_add_6(p, p, q, tmp); + } + + if (err == MP_OKAY) { + err = sp_384_to_mp(p->x, rX); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->y, rY); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->z, rZ); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (tmp != NULL) { + XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_6(q, 0, NULL); + sp_384_point_free_6(p, 0, NULL); + + return err; +} + +/* Double a projective EC point. + * (pX, pY, pZ) + (pX, pY, pZ) = (rX, rY, rZ) + * + * pX EC point's X ordinate. + * pY EC point's Y ordinate. + * pZ EC point's Z ordinate. + * rX Resultant EC point's X ordinate. + * rY Resultant EC point's Y ordinate. + * rZ Resultant EC point's Z ordinate. + * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise. + */ +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) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_digit tmpd[2 * 6 * 2]; + sp_point_384 pd; +#endif + sp_digit* tmp; + 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) + if (err == MP_OKAY) { + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 6 * 2, NULL, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) { + err = MEMORY_E; + } + } +#else + tmp = tmpd; +#endif + + if (err == MP_OKAY) { + sp_384_from_mp(p->x, 6, pX); + sp_384_from_mp(p->y, 6, pY); + sp_384_from_mp(p->z, 6, pZ); + +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_384_proj_point_dbl_avx2_6(p, p, tmp); + else +#endif + sp_384_proj_point_dbl_6(p, p, tmp); + } + + if (err == MP_OKAY) { + err = sp_384_to_mp(p->x, rX); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->y, rY); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->z, rZ); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (tmp != NULL) { + XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_6(p, 0, NULL); + + return err; +} + +/* Map a projective EC point to affine in place. + * pZ will be one. + * + * pX EC point's X ordinate. + * pY EC point's Y ordinate. + * pZ EC point's Z ordinate. + * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise. + */ +int sp_ecc_map_384(mp_int* pX, mp_int* pY, mp_int* pZ) +{ +#if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) + sp_digit tmpd[2 * 6 * 6]; + sp_point_384 pd; +#endif + sp_digit* tmp; + sp_point_384* p; + int err; + + err = sp_384_point_new_6(NULL, pd, p); +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (err == MP_OKAY) { + tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 6 * 6, NULL, + DYNAMIC_TYPE_ECC); + if (tmp == NULL) { + err = MEMORY_E; + } + } +#else + tmp = tmpd; +#endif + if (err == MP_OKAY) { + sp_384_from_mp(p->x, 6, pX); + sp_384_from_mp(p->y, 6, pY); + sp_384_from_mp(p->z, 6, pZ); + + sp_384_map_6(p, p, tmp); + } + + if (err == MP_OKAY) { + err = sp_384_to_mp(p->x, pX); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->y, pY); + } + if (err == MP_OKAY) { + err = sp_384_to_mp(p->z, pZ); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (tmp != NULL) { + XFREE(tmp, NULL, DYNAMIC_TYPE_ECC); + } +#endif + sp_384_point_free_6(p, 0, NULL); + + return err; +} +#endif /* WOLFSSL_PUBLIC_ECC_ADD_DBL */ +#ifdef HAVE_COMP_KEY +/* Find the square root of a number mod the prime of the curve. + * + * y The number to operate on and the result. + * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise. + */ +static int sp_384_mont_sqrt_6(sp_digit* y) +{ +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_digit* d; +#else + sp_digit t1d[2 * 6]; + sp_digit t2d[2 * 6]; + sp_digit t3d[2 * 6]; + sp_digit t4d[2 * 6]; + sp_digit t5d[2 * 6]; +#endif + sp_digit* t1; + sp_digit* t2; + sp_digit* t3; + sp_digit* t4; + sp_digit* t5; + int err = MP_OKAY; +#ifdef HAVE_INTEL_AVX2 + word32 cpuid_flags = cpuid_get_flags(); +#endif + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 5 * 2 * 6, NULL, DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + t1 = d + 0 * 6; + t2 = d + 2 * 6; + t3 = d + 4 * 6; + t4 = d + 6 * 6; + t5 = d + 8 * 6; +#else + t1 = t1d; + t2 = t2d; + t3 = t3d; + t4 = t4d; + t5 = t5d; +#endif + +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) { + /* t2 = y ^ 0x2 */ + sp_384_mont_sqr_avx2_6(t2, y, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x3 */ + sp_384_mont_mul_avx2_6(t1, t2, y, p384_mod, p384_mp_mod); + /* t5 = y ^ 0xc */ + sp_384_mont_sqr_n_avx2_6(t5, t1, 2, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xf */ + sp_384_mont_mul_avx2_6(t1, t1, t5, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x1e */ + sp_384_mont_sqr_avx2_6(t2, t1, p384_mod, p384_mp_mod); + /* t3 = y ^ 0x1f */ + sp_384_mont_mul_avx2_6(t3, t2, y, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3e0 */ + sp_384_mont_sqr_n_avx2_6(t2, t3, 5, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x3ff */ + sp_384_mont_mul_avx2_6(t1, t3, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x7fe0 */ + sp_384_mont_sqr_n_avx2_6(t2, t1, 5, p384_mod, p384_mp_mod); + /* t3 = y ^ 0x7fff */ + sp_384_mont_mul_avx2_6(t3, t3, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3fff800 */ + sp_384_mont_sqr_n_avx2_6(t2, t3, 15, p384_mod, p384_mp_mod); + /* t4 = y ^ 0x3ffffff */ + sp_384_mont_mul_avx2_6(t4, t3, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0xffffffc000000 */ + sp_384_mont_sqr_n_avx2_6(t2, t4, 30, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xfffffffffffff */ + sp_384_mont_mul_avx2_6(t1, t4, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0xfffffffffffffff000000000000000 */ + sp_384_mont_sqr_n_avx2_6(t2, t1, 60, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xffffffffffffffffffffffffffffff */ + sp_384_mont_mul_avx2_6(t1, t1, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0xffffffffffffffffffffffffffffff000000000000000000000000000000 */ + sp_384_mont_sqr_n_avx2_6(t2, t1, 120, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */ + sp_384_mont_mul_avx2_6(t1, t1, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000 */ + sp_384_mont_sqr_n_avx2_6(t2, t1, 15, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */ + sp_384_mont_mul_avx2_6(t1, t3, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000 */ + sp_384_mont_sqr_n_avx2_6(t2, t1, 31, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffff */ + sp_384_mont_mul_avx2_6(t1, t4, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffff0 */ + sp_384_mont_sqr_n_avx2_6(t2, t1, 4, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffc */ + sp_384_mont_mul_avx2_6(t1, t5, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000 */ + sp_384_mont_sqr_n_avx2_6(t2, t1, 62, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000001 */ + sp_384_mont_mul_avx2_6(t1, y, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffc00000000000000040000000 */ + sp_384_mont_sqr_n_avx2_6(y, t1, 30, p384_mod, p384_mp_mod); + } + else +#endif + { + /* t2 = y ^ 0x2 */ + sp_384_mont_sqr_6(t2, y, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x3 */ + sp_384_mont_mul_6(t1, t2, y, p384_mod, p384_mp_mod); + /* t5 = y ^ 0xc */ + sp_384_mont_sqr_n_6(t5, t1, 2, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xf */ + sp_384_mont_mul_6(t1, t1, t5, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x1e */ + sp_384_mont_sqr_6(t2, t1, p384_mod, p384_mp_mod); + /* t3 = y ^ 0x1f */ + sp_384_mont_mul_6(t3, t2, y, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3e0 */ + sp_384_mont_sqr_n_6(t2, t3, 5, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x3ff */ + sp_384_mont_mul_6(t1, t3, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x7fe0 */ + sp_384_mont_sqr_n_6(t2, t1, 5, p384_mod, p384_mp_mod); + /* t3 = y ^ 0x7fff */ + sp_384_mont_mul_6(t3, t3, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3fff800 */ + sp_384_mont_sqr_n_6(t2, t3, 15, p384_mod, p384_mp_mod); + /* t4 = y ^ 0x3ffffff */ + sp_384_mont_mul_6(t4, t3, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0xffffffc000000 */ + sp_384_mont_sqr_n_6(t2, t4, 30, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xfffffffffffff */ + sp_384_mont_mul_6(t1, t4, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0xfffffffffffffff000000000000000 */ + sp_384_mont_sqr_n_6(t2, t1, 60, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xffffffffffffffffffffffffffffff */ + sp_384_mont_mul_6(t1, t1, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0xffffffffffffffffffffffffffffff000000000000000000000000000000 */ + sp_384_mont_sqr_n_6(t2, t1, 120, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */ + sp_384_mont_mul_6(t1, t1, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000 */ + sp_384_mont_sqr_n_6(t2, t1, 15, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff */ + sp_384_mont_mul_6(t1, t3, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000000 */ + sp_384_mont_sqr_n_6(t2, t1, 31, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffff */ + sp_384_mont_mul_6(t1, t4, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffff0 */ + sp_384_mont_sqr_n_6(t2, t1, 4, p384_mod, p384_mp_mod); + /* t1 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffc */ + sp_384_mont_mul_6(t1, t5, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000 */ + sp_384_mont_sqr_n_6(t2, t1, 62, p384_mod, p384_mp_mod); + /* t1 = y ^ 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000001 */ + sp_384_mont_mul_6(t1, y, t2, p384_mod, p384_mp_mod); + /* t2 = y ^ 0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffc00000000000000040000000 */ + sp_384_mont_sqr_n_6(y, t1, 30, p384_mod, p384_mp_mod); + } + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (d != NULL) { + XFREE(d, NULL, DYNAMIC_TYPE_ECC); + } +#endif + + return err; +} + + +/* Uncompress the point given the X ordinate. + * + * xm X ordinate. + * odd Whether the Y ordinate is odd. + * ym Calculated Y ordinate. + * returns MEMORY_E if dynamic memory allocation fails and MP_OKAY otherwise. + */ +int sp_ecc_uncompress_384(mp_int* xm, int odd, mp_int* ym) +{ +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + sp_digit* d; +#else + sp_digit xd[2 * 6]; + sp_digit yd[2 * 6]; +#endif + sp_digit* x = NULL; + sp_digit* y = NULL; + int err = MP_OKAY; +#ifdef HAVE_INTEL_AVX2 + word32 cpuid_flags = cpuid_get_flags(); +#endif + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + d = (sp_digit*)XMALLOC(sizeof(sp_digit) * 4 * 6, NULL, DYNAMIC_TYPE_ECC); + if (d == NULL) { + err = MEMORY_E; + } +#endif + + if (err == MP_OKAY) { +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + x = d + 0 * 6; + y = d + 2 * 6; +#else + x = xd; + y = yd; +#endif + + sp_384_from_mp(x, 6, xm); + err = sp_384_mod_mul_norm_6(x, x, p384_mod); + } + if (err == MP_OKAY) { + /* y = x^3 */ +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) { + sp_384_mont_sqr_avx2_6(y, x, p384_mod, p384_mp_mod); + sp_384_mont_mul_avx2_6(y, y, x, p384_mod, p384_mp_mod); + } + else +#endif + { + sp_384_mont_sqr_6(y, x, p384_mod, p384_mp_mod); + sp_384_mont_mul_6(y, y, x, p384_mod, p384_mp_mod); + } + /* y = x^3 - 3x */ + sp_384_mont_sub_6(y, y, x, p384_mod); + sp_384_mont_sub_6(y, y, x, p384_mod); + sp_384_mont_sub_6(y, y, x, p384_mod); + /* y = x^3 - 3x + b */ + err = sp_384_mod_mul_norm_6(x, p384_b, p384_mod); + } + if (err == MP_OKAY) { + sp_384_mont_add_6(y, y, x, p384_mod); + /* y = sqrt(x^3 - 3x + b) */ + err = sp_384_mont_sqrt_6(y); + } + if (err == MP_OKAY) { + XMEMSET(y + 6, 0, 6U * sizeof(sp_digit)); + sp_384_mont_reduce_6(y, p384_mod, p384_mp_mod); + if ((((word32)y[0] ^ (word32)odd) & 1U) != 0U) { + sp_384_mont_sub_6(y, p384_mod, y, p384_mod); + } + + err = sp_384_to_mp(y, ym); + } + +#if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) + if (d != NULL) { + XFREE(d, NULL, DYNAMIC_TYPE_ECC); + } +#endif + + return err; +} +#endif +#endif /* WOLFSSL_SP_384 */ #endif /* WOLFSSL_HAVE_SP_ECC */ #endif /* WOLFSSL_SP_X86_64_ASM */ #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 1591e62a3..e73399f21 100644 --- a/wolfcrypt/src/sp_x86_64_asm.S +++ b/wolfcrypt/src/sp_x86_64_asm.S @@ -21,6 +21,7 @@ #define HAVE_INTEL_AVX2 #ifndef WOLFSSL_SP_NO_2048 +#ifndef WOLFSSL_SP_NO_2048 /* Read big endian unsigned byte array into r. * * r A single precision integer. @@ -6245,7 +6246,7 @@ _sp_2048_mul_d_32: movq %r8, 240(%rdi) adcq %rdx, %r9 adcq $0, %r10 - # # A[31] * B + # A[31] * B movq %rcx, %rax mulq 248(%rsi) addq %rax, %r9 @@ -6485,7 +6486,7 @@ _sp_2048_mont_reduce_16: push %r15 movq %rdx, %rcx xorq %r15, %r15 - # i = 0 + # i = 16 movq $16, %r8 movq (%rdi), %r13 movq 8(%rdi), %r14 @@ -6649,7 +6650,7 @@ L_mont_loop_16: movq %r12, 120(%rdi) adcq %rdx, 128(%rdi) adcq $0, %r15 - # i += 1 + # i -= 1 addq $8, %rdi decq %r8 jnz L_mont_loop_16 @@ -6659,7 +6660,6 @@ L_mont_loop_16: movq %r15, %rcx movq %rsi, %rdx movq %rdi, %rsi - movq %rdi, %rdi subq $128, %rdi #ifndef __APPLE__ callq sp_2048_cond_sub_16@plt @@ -6914,7 +6914,7 @@ _sp_2048_mul_d_16: movq %r10, 112(%rdi) adcq %rdx, %r8 adcq $0, %r9 - # # A[15] * B + # A[15] * B movq %rcx, %rax mulq 120(%rsi) addq %rax, %r8 @@ -7219,7 +7219,7 @@ _sp_2048_mont_reduce_avx2_16: push %r14 movq %rdx, %rax xorq %r14, %r14 - # i = 0 + # i = 16 movq $16, %r9 movq (%rdi), %r13 xorq %r12, %r12 @@ -7324,10 +7324,10 @@ L_mont_loop_avx2_16: movq %r11, 120(%rdi) adcxq %r14, %r10 movq %r12, %r14 + movq %r10, 128(%rdi) adoxq %r12, %r14 adcxq %r12, %r14 - movq %r10, 128(%rdi) - # i += 1 + # i -= 1 addq $8, %rdi decq %r9 jnz L_mont_loop_avx2_16 @@ -7336,7 +7336,6 @@ L_mont_loop_avx2_16: movq %r14, %rcx movq %rsi, %rdx movq %rdi, %rsi - movq %rdi, %rdi subq $128, %rdi #ifndef __APPLE__ callq sp_2048_cond_sub_avx2_16@plt @@ -7623,7 +7622,7 @@ _sp_2048_mont_reduce_32: push %r15 movq %rdx, %rcx xorq %r15, %r15 - # i = 0 + # i = 32 movq $32, %r8 movq (%rdi), %r13 movq 8(%rdi), %r14 @@ -7947,7 +7946,7 @@ L_mont_loop_32: movq %r12, 248(%rdi) adcq %rdx, 256(%rdi) adcq $0, %r15 - # i += 1 + # i -= 1 addq $8, %rdi decq %r8 jnz L_mont_loop_32 @@ -7957,7 +7956,6 @@ L_mont_loop_32: movq %r15, %rcx movq %rsi, %rdx movq %rdi, %rsi - movq %rdi, %rdi subq $256, %rdi #ifndef __APPLE__ callq sp_2048_cond_sub_32@plt @@ -8668,103 +8666,103 @@ sp_2048_sub_32: .p2align 4 _sp_2048_sub_32: #endif /* __APPLE__ */ - movq (%rsi), %r8 + movq (%rsi), %rcx xorq %rax, %rax - subq (%rdx), %r8 - movq 8(%rsi), %r9 - movq %r8, (%rdi) - sbbq 8(%rdx), %r9 - movq 16(%rsi), %r8 - movq %r9, 8(%rdi) - sbbq 16(%rdx), %r8 - movq 24(%rsi), %r9 - movq %r8, 16(%rdi) - sbbq 24(%rdx), %r9 - movq 32(%rsi), %r8 - movq %r9, 24(%rdi) - sbbq 32(%rdx), %r8 - movq 40(%rsi), %r9 - movq %r8, 32(%rdi) - sbbq 40(%rdx), %r9 - movq 48(%rsi), %r8 - movq %r9, 40(%rdi) - sbbq 48(%rdx), %r8 - movq 56(%rsi), %r9 - movq %r8, 48(%rdi) - sbbq 56(%rdx), %r9 - movq 64(%rsi), %r8 - movq %r9, 56(%rdi) - sbbq 64(%rdx), %r8 - movq 72(%rsi), %r9 - movq %r8, 64(%rdi) - sbbq 72(%rdx), %r9 - movq 80(%rsi), %r8 - movq %r9, 72(%rdi) - sbbq 80(%rdx), %r8 - movq 88(%rsi), %r9 - movq %r8, 80(%rdi) - sbbq 88(%rdx), %r9 - movq 96(%rsi), %r8 - movq %r9, 88(%rdi) - sbbq 96(%rdx), %r8 - movq 104(%rsi), %r9 - movq %r8, 96(%rdi) - sbbq 104(%rdx), %r9 - movq 112(%rsi), %r8 - movq %r9, 104(%rdi) - sbbq 112(%rdx), %r8 - movq 120(%rsi), %r9 - movq %r8, 112(%rdi) - sbbq 120(%rdx), %r9 - movq 128(%rsi), %r8 - movq %r9, 120(%rdi) - sbbq 128(%rdx), %r8 - movq 136(%rsi), %r9 - movq %r8, 128(%rdi) - sbbq 136(%rdx), %r9 - movq 144(%rsi), %r8 - movq %r9, 136(%rdi) - sbbq 144(%rdx), %r8 - movq 152(%rsi), %r9 - movq %r8, 144(%rdi) - sbbq 152(%rdx), %r9 - movq 160(%rsi), %r8 - movq %r9, 152(%rdi) - sbbq 160(%rdx), %r8 - movq 168(%rsi), %r9 - movq %r8, 160(%rdi) - sbbq 168(%rdx), %r9 - movq 176(%rsi), %r8 - movq %r9, 168(%rdi) - sbbq 176(%rdx), %r8 - movq 184(%rsi), %r9 - movq %r8, 176(%rdi) - sbbq 184(%rdx), %r9 - movq 192(%rsi), %r8 - movq %r9, 184(%rdi) - sbbq 192(%rdx), %r8 - movq 200(%rsi), %r9 - movq %r8, 192(%rdi) - sbbq 200(%rdx), %r9 - movq 208(%rsi), %r8 - movq %r9, 200(%rdi) - sbbq 208(%rdx), %r8 - movq 216(%rsi), %r9 - movq %r8, 208(%rdi) - sbbq 216(%rdx), %r9 - movq 224(%rsi), %r8 - movq %r9, 216(%rdi) - sbbq 224(%rdx), %r8 - movq 232(%rsi), %r9 - movq %r8, 224(%rdi) - sbbq 232(%rdx), %r9 - movq 240(%rsi), %r8 - movq %r9, 232(%rdi) - sbbq 240(%rdx), %r8 - movq 248(%rsi), %r9 - movq %r8, 240(%rdi) - sbbq 248(%rdx), %r9 - movq %r9, 248(%rdi) + 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 128(%rsi), %rcx + movq %r8, 120(%rdi) + sbbq 128(%rdx), %rcx + movq 136(%rsi), %r8 + movq %rcx, 128(%rdi) + sbbq 136(%rdx), %r8 + movq 144(%rsi), %rcx + movq %r8, 136(%rdi) + sbbq 144(%rdx), %rcx + movq 152(%rsi), %r8 + movq %rcx, 144(%rdi) + sbbq 152(%rdx), %r8 + movq 160(%rsi), %rcx + movq %r8, 152(%rdi) + sbbq 160(%rdx), %rcx + movq 168(%rsi), %r8 + movq %rcx, 160(%rdi) + sbbq 168(%rdx), %r8 + movq 176(%rsi), %rcx + movq %r8, 168(%rdi) + sbbq 176(%rdx), %rcx + movq 184(%rsi), %r8 + movq %rcx, 176(%rdi) + sbbq 184(%rdx), %r8 + movq 192(%rsi), %rcx + movq %r8, 184(%rdi) + sbbq 192(%rdx), %rcx + movq 200(%rsi), %r8 + movq %rcx, 192(%rdi) + sbbq 200(%rdx), %r8 + movq 208(%rsi), %rcx + movq %r8, 200(%rdi) + sbbq 208(%rdx), %rcx + movq 216(%rsi), %r8 + movq %rcx, 208(%rdi) + sbbq 216(%rdx), %r8 + movq 224(%rsi), %rcx + movq %r8, 216(%rdi) + sbbq 224(%rdx), %rcx + movq 232(%rsi), %r8 + movq %rcx, 224(%rdi) + sbbq 232(%rdx), %r8 + movq 240(%rsi), %rcx + movq %r8, 232(%rdi) + sbbq 240(%rdx), %rcx + movq 248(%rsi), %r8 + movq %rcx, 240(%rdi) + sbbq 248(%rdx), %r8 + movq %r8, 248(%rdi) sbbq $0, %rax repz retq #ifndef __APPLE__ @@ -8792,7 +8790,7 @@ _sp_2048_mont_reduce_avx2_32: push %r14 movq %rdx, %rax xorq %r14, %r14 - # i = 0 + # i = 32 movq $32, %r9 movq (%rdi), %r13 xorq %r12, %r12 @@ -8993,10 +8991,10 @@ L_mont_loop_avx2_32: movq %r11, 248(%rdi) adcxq %r14, %r10 movq %r12, %r14 + movq %r10, 256(%rdi) adoxq %r12, %r14 adcxq %r12, %r14 - movq %r10, 256(%rdi) - # i += 1 + # i -= 1 addq $8, %rdi decq %r9 jnz L_mont_loop_avx2_32 @@ -9005,7 +9003,6 @@ L_mont_loop_avx2_32: movq %r14, %rcx movq %rsi, %rdx movq %rdi, %rsi - movq %rdi, %rdi subq $256, %rdi #ifndef __APPLE__ callq sp_2048_cond_sub_avx2_32@plt @@ -9138,6 +9135,8 @@ _sp_2048_lshift_32: movq %r11, 24(%rdi) repz retq #endif /* !WOLFSSL_SP_NO_2048 */ +#endif /* !WOLFSSL_SP_NO_2048 */ +#ifndef WOLFSSL_SP_NO_3072 #ifndef WOLFSSL_SP_NO_3072 /* Read big endian unsigned byte array into r. * @@ -21797,7 +21796,7 @@ _sp_3072_mul_d_48: movq %r9, 368(%rdi) adcq %rdx, %r10 adcq $0, %r8 - # # A[47] * B + # A[47] * B movq %rcx, %rax mulq 376(%rsi) addq %rax, %r10 @@ -22117,7 +22116,7 @@ _sp_3072_mont_reduce_24: push %r15 movq %rdx, %rcx xorq %r15, %r15 - # i = 0 + # i = 24 movq $24, %r8 movq (%rdi), %r13 movq 8(%rdi), %r14 @@ -22361,7 +22360,7 @@ L_mont_loop_24: movq %r12, 184(%rdi) adcq %rdx, 192(%rdi) adcq $0, %r15 - # i += 1 + # i -= 1 addq $8, %rdi decq %r8 jnz L_mont_loop_24 @@ -22371,7 +22370,6 @@ L_mont_loop_24: movq %r15, %rcx movq %rsi, %rdx movq %rdi, %rsi - movq %rdi, %rdi subq $192, %rdi #ifndef __APPLE__ callq sp_3072_cond_sub_24@plt @@ -22730,7 +22728,7 @@ _sp_3072_mul_d_24: movq %r9, 176(%rdi) adcq %rdx, %r10 adcq $0, %r8 - # # A[23] * B + # A[23] * B movq %rcx, %rax mulq 184(%rsi) addq %rax, %r10 @@ -23147,7 +23145,7 @@ _sp_3072_mont_reduce_avx2_24: push %r14 movq %rdx, %rax xorq %r14, %r14 - # i = 0 + # i = 24 movq $24, %r9 movq (%rdi), %r13 xorq %r12, %r12 @@ -23300,10 +23298,10 @@ L_mont_loop_avx2_24: movq %r11, 184(%rdi) adcxq %r14, %r10 movq %r12, %r14 + movq %r10, 192(%rdi) adoxq %r12, %r14 adcxq %r12, %r14 - movq %r10, 192(%rdi) - # i += 1 + # i -= 1 addq $8, %rdi decq %r9 jnz L_mont_loop_avx2_24 @@ -23312,7 +23310,6 @@ L_mont_loop_avx2_24: movq %r14, %rcx movq %rsi, %rdx movq %rdi, %rsi - movq %rdi, %rdi subq $192, %rdi #ifndef __APPLE__ callq sp_3072_cond_sub_avx2_24@plt @@ -23711,7 +23708,7 @@ _sp_3072_mont_reduce_48: push %r15 movq %rdx, %rcx xorq %r15, %r15 - # i = 0 + # i = 48 movq $48, %r8 movq (%rdi), %r13 movq 8(%rdi), %r14 @@ -24195,7 +24192,7 @@ L_mont_loop_48: movq %r12, 376(%rdi) adcq %rdx, 384(%rdi) adcq $0, %r15 - # i += 1 + # i -= 1 addq $8, %rdi decq %r8 jnz L_mont_loop_48 @@ -24205,7 +24202,6 @@ L_mont_loop_48: movq %r15, %rcx movq %rsi, %rdx movq %rdi, %rsi - movq %rdi, %rdi subq $384, %rdi #ifndef __APPLE__ callq sp_3072_cond_sub_48@plt @@ -25220,151 +25216,151 @@ sp_3072_sub_48: .p2align 4 _sp_3072_sub_48: #endif /* __APPLE__ */ - movq (%rsi), %r8 + movq (%rsi), %rcx xorq %rax, %rax - subq (%rdx), %r8 - movq 8(%rsi), %r9 - movq %r8, (%rdi) - sbbq 8(%rdx), %r9 - movq 16(%rsi), %r8 - movq %r9, 8(%rdi) - sbbq 16(%rdx), %r8 - movq 24(%rsi), %r9 - movq %r8, 16(%rdi) - sbbq 24(%rdx), %r9 - movq 32(%rsi), %r8 - movq %r9, 24(%rdi) - sbbq 32(%rdx), %r8 - movq 40(%rsi), %r9 - movq %r8, 32(%rdi) - sbbq 40(%rdx), %r9 - movq 48(%rsi), %r8 - movq %r9, 40(%rdi) - sbbq 48(%rdx), %r8 - movq 56(%rsi), %r9 - movq %r8, 48(%rdi) - sbbq 56(%rdx), %r9 - movq 64(%rsi), %r8 - movq %r9, 56(%rdi) - sbbq 64(%rdx), %r8 - movq 72(%rsi), %r9 - movq %r8, 64(%rdi) - sbbq 72(%rdx), %r9 - movq 80(%rsi), %r8 - movq %r9, 72(%rdi) - sbbq 80(%rdx), %r8 - movq 88(%rsi), %r9 - movq %r8, 80(%rdi) - sbbq 88(%rdx), %r9 - movq 96(%rsi), %r8 - movq %r9, 88(%rdi) - sbbq 96(%rdx), %r8 - movq 104(%rsi), %r9 - movq %r8, 96(%rdi) - sbbq 104(%rdx), %r9 - movq 112(%rsi), %r8 - movq %r9, 104(%rdi) - sbbq 112(%rdx), %r8 - movq 120(%rsi), %r9 - movq %r8, 112(%rdi) - sbbq 120(%rdx), %r9 - movq 128(%rsi), %r8 - movq %r9, 120(%rdi) - sbbq 128(%rdx), %r8 - movq 136(%rsi), %r9 - movq %r8, 128(%rdi) - sbbq 136(%rdx), %r9 - movq 144(%rsi), %r8 - movq %r9, 136(%rdi) - sbbq 144(%rdx), %r8 - movq 152(%rsi), %r9 - movq %r8, 144(%rdi) - sbbq 152(%rdx), %r9 - movq 160(%rsi), %r8 - movq %r9, 152(%rdi) - sbbq 160(%rdx), %r8 - movq 168(%rsi), %r9 - movq %r8, 160(%rdi) - sbbq 168(%rdx), %r9 - movq 176(%rsi), %r8 - movq %r9, 168(%rdi) - sbbq 176(%rdx), %r8 - movq 184(%rsi), %r9 - movq %r8, 176(%rdi) - sbbq 184(%rdx), %r9 - movq 192(%rsi), %r8 - movq %r9, 184(%rdi) - sbbq 192(%rdx), %r8 - movq 200(%rsi), %r9 - movq %r8, 192(%rdi) - sbbq 200(%rdx), %r9 - movq 208(%rsi), %r8 - movq %r9, 200(%rdi) - sbbq 208(%rdx), %r8 - movq 216(%rsi), %r9 - movq %r8, 208(%rdi) - sbbq 216(%rdx), %r9 - movq 224(%rsi), %r8 - movq %r9, 216(%rdi) - sbbq 224(%rdx), %r8 - movq 232(%rsi), %r9 - movq %r8, 224(%rdi) - sbbq 232(%rdx), %r9 - movq 240(%rsi), %r8 - movq %r9, 232(%rdi) - sbbq 240(%rdx), %r8 - movq 248(%rsi), %r9 - movq %r8, 240(%rdi) - sbbq 248(%rdx), %r9 - movq 256(%rsi), %r8 - movq %r9, 248(%rdi) - sbbq 256(%rdx), %r8 - movq 264(%rsi), %r9 - movq %r8, 256(%rdi) - sbbq 264(%rdx), %r9 - movq 272(%rsi), %r8 - movq %r9, 264(%rdi) - sbbq 272(%rdx), %r8 - movq 280(%rsi), %r9 - movq %r8, 272(%rdi) - sbbq 280(%rdx), %r9 - movq 288(%rsi), %r8 - movq %r9, 280(%rdi) - sbbq 288(%rdx), %r8 - movq 296(%rsi), %r9 - movq %r8, 288(%rdi) - sbbq 296(%rdx), %r9 - movq 304(%rsi), %r8 - movq %r9, 296(%rdi) - sbbq 304(%rdx), %r8 - movq 312(%rsi), %r9 - movq %r8, 304(%rdi) - sbbq 312(%rdx), %r9 - movq 320(%rsi), %r8 - movq %r9, 312(%rdi) - sbbq 320(%rdx), %r8 - movq 328(%rsi), %r9 - movq %r8, 320(%rdi) - sbbq 328(%rdx), %r9 - movq 336(%rsi), %r8 - movq %r9, 328(%rdi) - sbbq 336(%rdx), %r8 - movq 344(%rsi), %r9 - movq %r8, 336(%rdi) - sbbq 344(%rdx), %r9 - movq 352(%rsi), %r8 - movq %r9, 344(%rdi) - sbbq 352(%rdx), %r8 - movq 360(%rsi), %r9 - movq %r8, 352(%rdi) - sbbq 360(%rdx), %r9 - movq 368(%rsi), %r8 - movq %r9, 360(%rdi) - sbbq 368(%rdx), %r8 - movq 376(%rsi), %r9 - movq %r8, 368(%rdi) - sbbq 376(%rdx), %r9 - movq %r9, 376(%rdi) + 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 128(%rsi), %rcx + movq %r8, 120(%rdi) + sbbq 128(%rdx), %rcx + movq 136(%rsi), %r8 + movq %rcx, 128(%rdi) + sbbq 136(%rdx), %r8 + movq 144(%rsi), %rcx + movq %r8, 136(%rdi) + sbbq 144(%rdx), %rcx + movq 152(%rsi), %r8 + movq %rcx, 144(%rdi) + sbbq 152(%rdx), %r8 + movq 160(%rsi), %rcx + movq %r8, 152(%rdi) + sbbq 160(%rdx), %rcx + movq 168(%rsi), %r8 + movq %rcx, 160(%rdi) + sbbq 168(%rdx), %r8 + movq 176(%rsi), %rcx + movq %r8, 168(%rdi) + sbbq 176(%rdx), %rcx + movq 184(%rsi), %r8 + movq %rcx, 176(%rdi) + sbbq 184(%rdx), %r8 + movq 192(%rsi), %rcx + movq %r8, 184(%rdi) + sbbq 192(%rdx), %rcx + movq 200(%rsi), %r8 + movq %rcx, 192(%rdi) + sbbq 200(%rdx), %r8 + movq 208(%rsi), %rcx + movq %r8, 200(%rdi) + sbbq 208(%rdx), %rcx + movq 216(%rsi), %r8 + movq %rcx, 208(%rdi) + sbbq 216(%rdx), %r8 + movq 224(%rsi), %rcx + movq %r8, 216(%rdi) + sbbq 224(%rdx), %rcx + movq 232(%rsi), %r8 + movq %rcx, 224(%rdi) + sbbq 232(%rdx), %r8 + movq 240(%rsi), %rcx + movq %r8, 232(%rdi) + sbbq 240(%rdx), %rcx + movq 248(%rsi), %r8 + movq %rcx, 240(%rdi) + sbbq 248(%rdx), %r8 + movq 256(%rsi), %rcx + movq %r8, 248(%rdi) + sbbq 256(%rdx), %rcx + movq 264(%rsi), %r8 + movq %rcx, 256(%rdi) + sbbq 264(%rdx), %r8 + movq 272(%rsi), %rcx + movq %r8, 264(%rdi) + sbbq 272(%rdx), %rcx + movq 280(%rsi), %r8 + movq %rcx, 272(%rdi) + sbbq 280(%rdx), %r8 + movq 288(%rsi), %rcx + movq %r8, 280(%rdi) + sbbq 288(%rdx), %rcx + movq 296(%rsi), %r8 + movq %rcx, 288(%rdi) + sbbq 296(%rdx), %r8 + movq 304(%rsi), %rcx + movq %r8, 296(%rdi) + sbbq 304(%rdx), %rcx + movq 312(%rsi), %r8 + movq %rcx, 304(%rdi) + sbbq 312(%rdx), %r8 + movq 320(%rsi), %rcx + movq %r8, 312(%rdi) + sbbq 320(%rdx), %rcx + movq 328(%rsi), %r8 + movq %rcx, 320(%rdi) + sbbq 328(%rdx), %r8 + movq 336(%rsi), %rcx + movq %r8, 328(%rdi) + sbbq 336(%rdx), %rcx + movq 344(%rsi), %r8 + movq %rcx, 336(%rdi) + sbbq 344(%rdx), %r8 + movq 352(%rsi), %rcx + movq %r8, 344(%rdi) + sbbq 352(%rdx), %rcx + movq 360(%rsi), %r8 + movq %rcx, 352(%rdi) + sbbq 360(%rdx), %r8 + movq 368(%rsi), %rcx + movq %r8, 360(%rdi) + sbbq 368(%rdx), %rcx + movq 376(%rsi), %r8 + movq %rcx, 368(%rdi) + sbbq 376(%rdx), %r8 + movq %r8, 376(%rdi) sbbq $0, %rax repz retq #ifndef __APPLE__ @@ -25392,7 +25388,7 @@ _sp_3072_mont_reduce_avx2_48: push %r14 movq %rdx, %rax xorq %r14, %r14 - # i = 0 + # i = 48 movq $48, %r9 movq (%rdi), %r13 xorq %r12, %r12 @@ -25689,10 +25685,10 @@ L_mont_loop_avx2_48: movq %r11, 376(%rdi) adcxq %r14, %r10 movq %r12, %r14 + movq %r10, 384(%rdi) adoxq %r12, %r14 adcxq %r12, %r14 - movq %r10, 384(%rdi) - # i += 1 + # i -= 1 addq $8, %rdi decq %r9 jnz L_mont_loop_avx2_48 @@ -25701,7 +25697,6 @@ L_mont_loop_avx2_48: movq %r14, %rcx movq %rsi, %rdx movq %rdi, %rsi - movq %rdi, %rdi subq $384, %rdi #ifndef __APPLE__ callq sp_3072_cond_sub_avx2_48@plt @@ -25882,6 +25877,8 @@ _sp_3072_lshift_48: movq %r11, 24(%rdi) repz retq #endif /* !WOLFSSL_SP_NO_3072 */ +#endif /* !WOLFSSL_SP_NO_3072 */ +#ifdef WOLFSSL_SP_4096 #ifdef WOLFSSL_SP_4096 /* Read big endian unsigned byte array into r. * @@ -26540,6 +26537,123 @@ _sp_4096_add_64: #ifndef __APPLE__ .size sp_4096_add_64,.-sp_4096_add_64 #endif /* __APPLE__ */ +/* Add a to a into r. (r = a + a) + * + * r A single precision integer. + * a A single precision integer. + */ +#ifndef __APPLE__ +.globl sp_2048_dbl_32 +.type sp_2048_dbl_32,@function +.align 16 +sp_2048_dbl_32: +#else +.globl _sp_2048_dbl_32 +.p2align 4 +_sp_2048_dbl_32: +#endif /* __APPLE__ */ + movq (%rsi), %rdx + xorq %rax, %rax + addq %rdx, %rdx + movq 8(%rsi), %rcx + movq %rdx, (%rdi) + adcq %rcx, %rcx + movq 16(%rsi), %rdx + movq %rcx, 8(%rdi) + adcq %rdx, %rdx + movq 24(%rsi), %rcx + movq %rdx, 16(%rdi) + adcq %rcx, %rcx + movq 32(%rsi), %rdx + movq %rcx, 24(%rdi) + adcq %rdx, %rdx + movq 40(%rsi), %rcx + movq %rdx, 32(%rdi) + adcq %rcx, %rcx + movq 48(%rsi), %rdx + movq %rcx, 40(%rdi) + adcq %rdx, %rdx + movq 56(%rsi), %rcx + movq %rdx, 48(%rdi) + adcq %rcx, %rcx + movq 64(%rsi), %rdx + movq %rcx, 56(%rdi) + adcq %rdx, %rdx + movq 72(%rsi), %rcx + movq %rdx, 64(%rdi) + adcq %rcx, %rcx + movq 80(%rsi), %rdx + movq %rcx, 72(%rdi) + adcq %rdx, %rdx + movq 88(%rsi), %rcx + movq %rdx, 80(%rdi) + adcq %rcx, %rcx + movq 96(%rsi), %rdx + movq %rcx, 88(%rdi) + adcq %rdx, %rdx + movq 104(%rsi), %rcx + movq %rdx, 96(%rdi) + adcq %rcx, %rcx + movq 112(%rsi), %rdx + movq %rcx, 104(%rdi) + adcq %rdx, %rdx + movq 120(%rsi), %rcx + movq %rdx, 112(%rdi) + adcq %rcx, %rcx + movq 128(%rsi), %rdx + movq %rcx, 120(%rdi) + adcq %rdx, %rdx + movq 136(%rsi), %rcx + movq %rdx, 128(%rdi) + adcq %rcx, %rcx + movq 144(%rsi), %rdx + movq %rcx, 136(%rdi) + adcq %rdx, %rdx + movq 152(%rsi), %rcx + movq %rdx, 144(%rdi) + adcq %rcx, %rcx + movq 160(%rsi), %rdx + movq %rcx, 152(%rdi) + adcq %rdx, %rdx + movq 168(%rsi), %rcx + movq %rdx, 160(%rdi) + adcq %rcx, %rcx + movq 176(%rsi), %rdx + movq %rcx, 168(%rdi) + adcq %rdx, %rdx + movq 184(%rsi), %rcx + movq %rdx, 176(%rdi) + adcq %rcx, %rcx + movq 192(%rsi), %rdx + movq %rcx, 184(%rdi) + adcq %rdx, %rdx + movq 200(%rsi), %rcx + movq %rdx, 192(%rdi) + adcq %rcx, %rcx + movq 208(%rsi), %rdx + movq %rcx, 200(%rdi) + adcq %rdx, %rdx + movq 216(%rsi), %rcx + movq %rdx, 208(%rdi) + adcq %rcx, %rcx + movq 224(%rsi), %rdx + movq %rcx, 216(%rdi) + adcq %rdx, %rdx + movq 232(%rsi), %rcx + movq %rdx, 224(%rdi) + adcq %rcx, %rcx + movq 240(%rsi), %rdx + movq %rcx, 232(%rdi) + adcq %rdx, %rdx + movq 248(%rsi), %rcx + movq %rdx, 240(%rdi) + adcq %rcx, %rcx + movq %rcx, 248(%rdi) + adcq $0, %rax + repz retq +#ifndef __APPLE__ +.size sp_2048_dbl_32,.-sp_2048_dbl_32 +#endif /* __APPLE__ */ /* Mul a by digit b into r. (r = a * b) * * r A single precision integer. @@ -27060,7 +27174,7 @@ _sp_4096_mul_d_64: movq %r10, 496(%rdi) adcq %rdx, %r8 adcq $0, %r9 - # # A[63] * B + # A[63] * B movq %rcx, %rax mulq 504(%rsi) addq %rax, %r8 @@ -27567,7 +27681,7 @@ _sp_4096_mont_reduce_64: push %r15 movq %rdx, %rcx xorq %r15, %r15 - # i = 0 + # i = 64 movq $64, %r8 movq (%rdi), %r13 movq 8(%rdi), %r14 @@ -28211,7 +28325,7 @@ L_mont_loop_64: movq %r12, 504(%rdi) adcq %rdx, 512(%rdi) adcq $0, %r15 - # i += 1 + # i -= 1 addq $8, %rdi decq %r8 jnz L_mont_loop_64 @@ -28221,7 +28335,6 @@ L_mont_loop_64: movq %r15, %rcx movq %rsi, %rdx movq %rdi, %rsi - movq %rdi, %rdi subq $512, %rdi #ifndef __APPLE__ callq sp_4096_cond_sub_64@plt @@ -29540,199 +29653,199 @@ sp_4096_sub_64: .p2align 4 _sp_4096_sub_64: #endif /* __APPLE__ */ - movq (%rsi), %r8 + movq (%rsi), %rcx xorq %rax, %rax - subq (%rdx), %r8 - movq 8(%rsi), %r9 - movq %r8, (%rdi) - sbbq 8(%rdx), %r9 - movq 16(%rsi), %r8 - movq %r9, 8(%rdi) - sbbq 16(%rdx), %r8 - movq 24(%rsi), %r9 - movq %r8, 16(%rdi) - sbbq 24(%rdx), %r9 - movq 32(%rsi), %r8 - movq %r9, 24(%rdi) - sbbq 32(%rdx), %r8 - movq 40(%rsi), %r9 - movq %r8, 32(%rdi) - sbbq 40(%rdx), %r9 - movq 48(%rsi), %r8 - movq %r9, 40(%rdi) - sbbq 48(%rdx), %r8 - movq 56(%rsi), %r9 - movq %r8, 48(%rdi) - sbbq 56(%rdx), %r9 - movq 64(%rsi), %r8 - movq %r9, 56(%rdi) - sbbq 64(%rdx), %r8 - movq 72(%rsi), %r9 - movq %r8, 64(%rdi) - sbbq 72(%rdx), %r9 - movq 80(%rsi), %r8 - movq %r9, 72(%rdi) - sbbq 80(%rdx), %r8 - movq 88(%rsi), %r9 - movq %r8, 80(%rdi) - sbbq 88(%rdx), %r9 - movq 96(%rsi), %r8 - movq %r9, 88(%rdi) - sbbq 96(%rdx), %r8 - movq 104(%rsi), %r9 - movq %r8, 96(%rdi) - sbbq 104(%rdx), %r9 - movq 112(%rsi), %r8 - movq %r9, 104(%rdi) - sbbq 112(%rdx), %r8 - movq 120(%rsi), %r9 - movq %r8, 112(%rdi) - sbbq 120(%rdx), %r9 - movq 128(%rsi), %r8 - movq %r9, 120(%rdi) - sbbq 128(%rdx), %r8 - movq 136(%rsi), %r9 - movq %r8, 128(%rdi) - sbbq 136(%rdx), %r9 - movq 144(%rsi), %r8 - movq %r9, 136(%rdi) - sbbq 144(%rdx), %r8 - movq 152(%rsi), %r9 - movq %r8, 144(%rdi) - sbbq 152(%rdx), %r9 - movq 160(%rsi), %r8 - movq %r9, 152(%rdi) - sbbq 160(%rdx), %r8 - movq 168(%rsi), %r9 - movq %r8, 160(%rdi) - sbbq 168(%rdx), %r9 - movq 176(%rsi), %r8 - movq %r9, 168(%rdi) - sbbq 176(%rdx), %r8 - movq 184(%rsi), %r9 - movq %r8, 176(%rdi) - sbbq 184(%rdx), %r9 - movq 192(%rsi), %r8 - movq %r9, 184(%rdi) - sbbq 192(%rdx), %r8 - movq 200(%rsi), %r9 - movq %r8, 192(%rdi) - sbbq 200(%rdx), %r9 - movq 208(%rsi), %r8 - movq %r9, 200(%rdi) - sbbq 208(%rdx), %r8 - movq 216(%rsi), %r9 - movq %r8, 208(%rdi) - sbbq 216(%rdx), %r9 - movq 224(%rsi), %r8 - movq %r9, 216(%rdi) - sbbq 224(%rdx), %r8 - movq 232(%rsi), %r9 - movq %r8, 224(%rdi) - sbbq 232(%rdx), %r9 - movq 240(%rsi), %r8 - movq %r9, 232(%rdi) - sbbq 240(%rdx), %r8 - movq 248(%rsi), %r9 - movq %r8, 240(%rdi) - sbbq 248(%rdx), %r9 - movq 256(%rsi), %r8 - movq %r9, 248(%rdi) - sbbq 256(%rdx), %r8 - movq 264(%rsi), %r9 - movq %r8, 256(%rdi) - sbbq 264(%rdx), %r9 - movq 272(%rsi), %r8 - movq %r9, 264(%rdi) - sbbq 272(%rdx), %r8 - movq 280(%rsi), %r9 - movq %r8, 272(%rdi) - sbbq 280(%rdx), %r9 - movq 288(%rsi), %r8 - movq %r9, 280(%rdi) - sbbq 288(%rdx), %r8 - movq 296(%rsi), %r9 - movq %r8, 288(%rdi) - sbbq 296(%rdx), %r9 - movq 304(%rsi), %r8 - movq %r9, 296(%rdi) - sbbq 304(%rdx), %r8 - movq 312(%rsi), %r9 - movq %r8, 304(%rdi) - sbbq 312(%rdx), %r9 - movq 320(%rsi), %r8 - movq %r9, 312(%rdi) - sbbq 320(%rdx), %r8 - movq 328(%rsi), %r9 - movq %r8, 320(%rdi) - sbbq 328(%rdx), %r9 - movq 336(%rsi), %r8 - movq %r9, 328(%rdi) - sbbq 336(%rdx), %r8 - movq 344(%rsi), %r9 - movq %r8, 336(%rdi) - sbbq 344(%rdx), %r9 - movq 352(%rsi), %r8 - movq %r9, 344(%rdi) - sbbq 352(%rdx), %r8 - movq 360(%rsi), %r9 - movq %r8, 352(%rdi) - sbbq 360(%rdx), %r9 - movq 368(%rsi), %r8 - movq %r9, 360(%rdi) - sbbq 368(%rdx), %r8 - movq 376(%rsi), %r9 - movq %r8, 368(%rdi) - sbbq 376(%rdx), %r9 - movq 384(%rsi), %r8 - movq %r9, 376(%rdi) - sbbq 384(%rdx), %r8 - movq 392(%rsi), %r9 - movq %r8, 384(%rdi) - sbbq 392(%rdx), %r9 - movq 400(%rsi), %r8 - movq %r9, 392(%rdi) - sbbq 400(%rdx), %r8 - movq 408(%rsi), %r9 - movq %r8, 400(%rdi) - sbbq 408(%rdx), %r9 - movq 416(%rsi), %r8 - movq %r9, 408(%rdi) - sbbq 416(%rdx), %r8 - movq 424(%rsi), %r9 - movq %r8, 416(%rdi) - sbbq 424(%rdx), %r9 - movq 432(%rsi), %r8 - movq %r9, 424(%rdi) - sbbq 432(%rdx), %r8 - movq 440(%rsi), %r9 - movq %r8, 432(%rdi) - sbbq 440(%rdx), %r9 - movq 448(%rsi), %r8 - movq %r9, 440(%rdi) - sbbq 448(%rdx), %r8 - movq 456(%rsi), %r9 - movq %r8, 448(%rdi) - sbbq 456(%rdx), %r9 - movq 464(%rsi), %r8 - movq %r9, 456(%rdi) - sbbq 464(%rdx), %r8 - movq 472(%rsi), %r9 - movq %r8, 464(%rdi) - sbbq 472(%rdx), %r9 - movq 480(%rsi), %r8 - movq %r9, 472(%rdi) - sbbq 480(%rdx), %r8 - movq 488(%rsi), %r9 - movq %r8, 480(%rdi) - sbbq 488(%rdx), %r9 - movq 496(%rsi), %r8 - movq %r9, 488(%rdi) - sbbq 496(%rdx), %r8 - movq 504(%rsi), %r9 - movq %r8, 496(%rdi) - sbbq 504(%rdx), %r9 - movq %r9, 504(%rdi) + 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 128(%rsi), %rcx + movq %r8, 120(%rdi) + sbbq 128(%rdx), %rcx + movq 136(%rsi), %r8 + movq %rcx, 128(%rdi) + sbbq 136(%rdx), %r8 + movq 144(%rsi), %rcx + movq %r8, 136(%rdi) + sbbq 144(%rdx), %rcx + movq 152(%rsi), %r8 + movq %rcx, 144(%rdi) + sbbq 152(%rdx), %r8 + movq 160(%rsi), %rcx + movq %r8, 152(%rdi) + sbbq 160(%rdx), %rcx + movq 168(%rsi), %r8 + movq %rcx, 160(%rdi) + sbbq 168(%rdx), %r8 + movq 176(%rsi), %rcx + movq %r8, 168(%rdi) + sbbq 176(%rdx), %rcx + movq 184(%rsi), %r8 + movq %rcx, 176(%rdi) + sbbq 184(%rdx), %r8 + movq 192(%rsi), %rcx + movq %r8, 184(%rdi) + sbbq 192(%rdx), %rcx + movq 200(%rsi), %r8 + movq %rcx, 192(%rdi) + sbbq 200(%rdx), %r8 + movq 208(%rsi), %rcx + movq %r8, 200(%rdi) + sbbq 208(%rdx), %rcx + movq 216(%rsi), %r8 + movq %rcx, 208(%rdi) + sbbq 216(%rdx), %r8 + movq 224(%rsi), %rcx + movq %r8, 216(%rdi) + sbbq 224(%rdx), %rcx + movq 232(%rsi), %r8 + movq %rcx, 224(%rdi) + sbbq 232(%rdx), %r8 + movq 240(%rsi), %rcx + movq %r8, 232(%rdi) + sbbq 240(%rdx), %rcx + movq 248(%rsi), %r8 + movq %rcx, 240(%rdi) + sbbq 248(%rdx), %r8 + movq 256(%rsi), %rcx + movq %r8, 248(%rdi) + sbbq 256(%rdx), %rcx + movq 264(%rsi), %r8 + movq %rcx, 256(%rdi) + sbbq 264(%rdx), %r8 + movq 272(%rsi), %rcx + movq %r8, 264(%rdi) + sbbq 272(%rdx), %rcx + movq 280(%rsi), %r8 + movq %rcx, 272(%rdi) + sbbq 280(%rdx), %r8 + movq 288(%rsi), %rcx + movq %r8, 280(%rdi) + sbbq 288(%rdx), %rcx + movq 296(%rsi), %r8 + movq %rcx, 288(%rdi) + sbbq 296(%rdx), %r8 + movq 304(%rsi), %rcx + movq %r8, 296(%rdi) + sbbq 304(%rdx), %rcx + movq 312(%rsi), %r8 + movq %rcx, 304(%rdi) + sbbq 312(%rdx), %r8 + movq 320(%rsi), %rcx + movq %r8, 312(%rdi) + sbbq 320(%rdx), %rcx + movq 328(%rsi), %r8 + movq %rcx, 320(%rdi) + sbbq 328(%rdx), %r8 + movq 336(%rsi), %rcx + movq %r8, 328(%rdi) + sbbq 336(%rdx), %rcx + movq 344(%rsi), %r8 + movq %rcx, 336(%rdi) + sbbq 344(%rdx), %r8 + movq 352(%rsi), %rcx + movq %r8, 344(%rdi) + sbbq 352(%rdx), %rcx + movq 360(%rsi), %r8 + movq %rcx, 352(%rdi) + sbbq 360(%rdx), %r8 + movq 368(%rsi), %rcx + movq %r8, 360(%rdi) + sbbq 368(%rdx), %rcx + movq 376(%rsi), %r8 + movq %rcx, 368(%rdi) + sbbq 376(%rdx), %r8 + movq 384(%rsi), %rcx + movq %r8, 376(%rdi) + sbbq 384(%rdx), %rcx + movq 392(%rsi), %r8 + movq %rcx, 384(%rdi) + sbbq 392(%rdx), %r8 + movq 400(%rsi), %rcx + movq %r8, 392(%rdi) + sbbq 400(%rdx), %rcx + movq 408(%rsi), %r8 + movq %rcx, 400(%rdi) + sbbq 408(%rdx), %r8 + movq 416(%rsi), %rcx + movq %r8, 408(%rdi) + sbbq 416(%rdx), %rcx + movq 424(%rsi), %r8 + movq %rcx, 416(%rdi) + sbbq 424(%rdx), %r8 + movq 432(%rsi), %rcx + movq %r8, 424(%rdi) + sbbq 432(%rdx), %rcx + movq 440(%rsi), %r8 + movq %rcx, 432(%rdi) + sbbq 440(%rdx), %r8 + movq 448(%rsi), %rcx + movq %r8, 440(%rdi) + sbbq 448(%rdx), %rcx + movq 456(%rsi), %r8 + movq %rcx, 448(%rdi) + sbbq 456(%rdx), %r8 + movq 464(%rsi), %rcx + movq %r8, 456(%rdi) + sbbq 464(%rdx), %rcx + movq 472(%rsi), %r8 + movq %rcx, 464(%rdi) + sbbq 472(%rdx), %r8 + movq 480(%rsi), %rcx + movq %r8, 472(%rdi) + sbbq 480(%rdx), %rcx + movq 488(%rsi), %r8 + movq %rcx, 480(%rdi) + sbbq 488(%rdx), %r8 + movq 496(%rsi), %rcx + movq %r8, 488(%rdi) + sbbq 496(%rdx), %rcx + movq 504(%rsi), %r8 + movq %rcx, 496(%rdi) + sbbq 504(%rdx), %r8 + movq %r8, 504(%rdi) sbbq $0, %rax repz retq #ifndef __APPLE__ @@ -29760,7 +29873,7 @@ _sp_4096_mont_reduce_avx2_64: push %r14 movq %rdx, %rax xorq %r14, %r14 - # i = 0 + # i = 64 movq $64, %r9 movq (%rdi), %r13 xorq %r12, %r12 @@ -30153,10 +30266,10 @@ L_mont_loop_avx2_64: movq %r11, 504(%rdi) adcxq %r14, %r10 movq %r12, %r14 + movq %r10, 512(%rdi) adoxq %r12, %r14 adcxq %r12, %r14 - movq %r10, 512(%rdi) - # i += 1 + # i -= 1 addq $8, %rdi decq %r9 jnz L_mont_loop_avx2_64 @@ -30165,7 +30278,6 @@ L_mont_loop_avx2_64: movq %r14, %rcx movq %rsi, %rdx movq %rdi, %rsi - movq %rdi, %rdi subq $512, %rdi #ifndef __APPLE__ callq sp_4096_cond_sub_avx2_64@plt @@ -30394,6 +30506,8 @@ _sp_4096_lshift_64: movq %r11, 24(%rdi) repz retq #endif /* WOLFSSL_SP_4096 */ +#endif /* WOLFSSL_SP_4096 */ +#ifndef WOLFSSL_SP_NO_256 /* Conditionally copy a into r using the mask m. * m is -1 to copy and 0 when not. * @@ -30431,268 +30545,6 @@ _sp_256_cond_copy_4: #ifndef __APPLE__ .size sp_256_cond_copy_4,.-sp_256_cond_copy_4 #endif /* __APPLE__ */ -/* 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__ -.globl sp_256_cmp_4 -.type sp_256_cmp_4,@function -.align 16 -sp_256_cmp_4: -#else -.globl _sp_256_cmp_4 -.p2align 4 -_sp_256_cmp_4: -#endif /* __APPLE__ */ - xorq %rcx, %rcx - movq $-1, %rdx - movq $-1, %rax - movq $1, %r8 - 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_256_cmp_4,.-sp_256_cmp_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__ -.globl sp_256_cond_sub_4 -.type sp_256_cond_sub_4,@function -.align 16 -sp_256_cond_sub_4: -#else -.globl _sp_256_cond_sub_4 -.p2align 4 -_sp_256_cond_sub_4: -#endif /* __APPLE__ */ - push %r12 - push %r13 - push %r14 - push %r15 - movq $0, %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 $0, %rax - pop %r15 - pop %r14 - pop %r13 - pop %r12 - repz retq -#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__ -.globl sp_256_sub_4 -.type sp_256_sub_4,@function -.align 16 -sp_256_sub_4: -#else -.globl _sp_256_sub_4 -.p2align 4 -_sp_256_sub_4: -#endif /* __APPLE__ */ - push %r12 - push %r13 - push %r14 - push %r15 - xorq %rax, %rax - movq (%rsi), %r8 - movq 8(%rsi), %r9 - movq 16(%rsi), %r10 - movq 24(%rsi), %r11 - movq (%rdx), %r12 - movq 8(%rdx), %r13 - movq 16(%rdx), %r14 - movq 24(%rdx), %r15 - 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 $0, %rax - pop %r15 - pop %r14 - pop %r13 - pop %r12 - 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. - * m The single precision number representing the modulus. - * mp The digit representing the negative inverse of m mod 2^n. - */ -#ifndef __APPLE__ -.globl sp_256_mont_reduce_4 -.type sp_256_mont_reduce_4,@function -.align 16 -sp_256_mont_reduce_4: -#else -.globl _sp_256_mont_reduce_4 -.p2align 4 -_sp_256_mont_reduce_4: -#endif /* __APPLE__ */ - push %r12 - push %r13 - push %r14 - push %r15 - movq %rdx, %rcx - # i = 0 - xorq %r14, %r14 - movq $4, %r8 - movq %rdi, %r13 -L_mont_loop_4: - # mu = a[i] * mp - movq (%r13), %r12 - imulq %rcx, %r12 - # a[i+0] += m[0] * mu - movq (%rsi), %rax - movq 8(%rsi), %r10 - mulq %r12 - movq (%r13), %r15 - addq %rax, %r15 - movq %rdx, %r9 - movq %r15, (%r13) - adcq $0, %r9 - # a[i+1] += m[1] * mu - movq %r10, %rax - mulq %r12 - movq 16(%rsi), %r10 - movq 8(%r13), %r15 - addq %r9, %rax - movq %rdx, %r11 - adcq $0, %r11 - addq %rax, %r15 - movq %r15, 8(%r13) - adcq $0, %r11 - # a[i+2] += m[2] * mu - movq %r10, %rax - mulq %r12 - movq 24(%rsi), %r10 - movq 16(%r13), %r15 - addq %r11, %rax - movq %rdx, %r9 - adcq $0, %r9 - addq %rax, %r15 - movq %r15, 16(%r13) - adcq $0, %r9 - # a[i+3] += m[3] * mu - movq %r10, %rax - mulq %r12 - movq 24(%r13), %r15 - addq %r9, %rax - adcq %r14, %rdx - movq $0, %r14 - adcq $0, %r14 - addq %rax, %r15 - movq %r15, 24(%r13) - adcq %rdx, 32(%r13) - adcq $0, %r14 - # i += 1 - addq $8, %r13 - decq %r8 - jnz L_mont_loop_4 - xorq %rax, %rax - movq 32(%rdi), %rdx - movq 40(%rdi), %r8 - movq 48(%rdi), %r15 - movq 56(%rdi), %r9 - subq %r14, %rax - movq (%rsi), %r10 - movq 8(%rsi), %r11 - movq 16(%rsi), %r12 - movq 24(%rsi), %r13 - andq %rax, %r10 - andq %rax, %r11 - andq %rax, %r12 - andq %rax, %r13 - subq %r10, %rdx - sbbq %r11, %r8 - sbbq %r12, %r15 - sbbq %r13, %r9 - movq %rdx, (%rdi) - movq %r8, 8(%rdi) - movq %r15, 16(%rdi) - movq %r9, 24(%rdi) - pop %r15 - pop %r14 - pop %r13 - pop %r12 - repz retq -#ifndef __APPLE__ -.size sp_256_mont_reduce_4,.-sp_256_mont_reduce_4 -#endif /* __APPLE__ */ /* Multiply two Montogmery form numbers mod the modulus (prime). * (r = a * b mod m) * @@ -31075,6 +30927,256 @@ _sp_256_mont_sqr_4: #ifndef __APPLE__ .size sp_256_mont_sqr_4,.-sp_256_mont_sqr_4 #endif /* __APPLE__ */ +/* 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__ +.globl sp_256_cmp_4 +.type sp_256_cmp_4,@function +.align 16 +sp_256_cmp_4: +#else +.globl _sp_256_cmp_4 +.p2align 4 +_sp_256_cmp_4: +#endif /* __APPLE__ */ + xorq %rcx, %rcx + movq $-1, %rdx + movq $-1, %rax + movq $1, %r8 + 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_256_cmp_4,.-sp_256_cmp_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__ +.globl sp_256_cond_sub_4 +.type sp_256_cond_sub_4,@function +.align 16 +sp_256_cond_sub_4: +#else +.globl _sp_256_cond_sub_4 +.p2align 4 +_sp_256_cond_sub_4: +#endif /* __APPLE__ */ + push %r12 + push %r13 + push %r14 + push %r15 + movq $0, %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 $0, %rax + pop %r15 + pop %r14 + pop %r13 + pop %r12 + repz retq +#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__ +.globl sp_256_sub_4 +.type sp_256_sub_4,@function +.align 16 +sp_256_sub_4: +#else +.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 $0, %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. + * m The single precision number representing the modulus. + * mp The digit representing the negative inverse of m mod 2^n. + */ +#ifndef __APPLE__ +.globl sp_256_mont_reduce_4 +.type sp_256_mont_reduce_4,@function +.align 16 +sp_256_mont_reduce_4: +#else +.globl _sp_256_mont_reduce_4 +.p2align 4 +_sp_256_mont_reduce_4: +#endif /* __APPLE__ */ + push %r12 + push %r13 + push %r14 + push %r15 + movq %rdx, %rcx + # i = 0 + xorq %r14, %r14 + movq $4, %r8 + movq %rdi, %r13 +L_mont_loop_4: + # mu = a[i] * mp + movq (%r13), %r12 + imulq %rcx, %r12 + # a[i+0] += m[0] * mu + movq (%rsi), %rax + movq 8(%rsi), %r10 + mulq %r12 + movq (%r13), %r15 + addq %rax, %r15 + movq %rdx, %r9 + movq %r15, (%r13) + adcq $0, %r9 + # a[i+1] += m[1] * mu + movq %r10, %rax + mulq %r12 + movq 16(%rsi), %r10 + movq 8(%r13), %r15 + addq %r9, %rax + movq %rdx, %r11 + adcq $0, %r11 + addq %rax, %r15 + movq %r15, 8(%r13) + adcq $0, %r11 + # a[i+2] += m[2] * mu + movq %r10, %rax + mulq %r12 + movq 24(%rsi), %r10 + movq 16(%r13), %r15 + addq %r11, %rax + movq %rdx, %r9 + adcq $0, %r9 + addq %rax, %r15 + movq %r15, 16(%r13) + adcq $0, %r9 + # a[i+3] += m[3] * mu + movq %r10, %rax + mulq %r12 + movq 24(%r13), %r15 + addq %r9, %rax + adcq %r14, %rdx + movq $0, %r14 + adcq $0, %r14 + addq %rax, %r15 + movq %r15, 24(%r13) + adcq %rdx, 32(%r13) + adcq $0, %r14 + # i += 1 + addq $8, %r13 + decq %r8 + jnz L_mont_loop_4 + xorq %rax, %rax + movq 32(%rdi), %rdx + movq 40(%rdi), %r8 + movq 48(%rdi), %r15 + movq 56(%rdi), %r9 + subq %r14, %rax + movq (%rsi), %r10 + movq 8(%rsi), %r11 + movq 16(%rsi), %r12 + movq 24(%rsi), %r13 + andq %rax, %r10 + andq %rax, %r11 + andq %rax, %r12 + andq %rax, %r13 + subq %r10, %rdx + sbbq %r11, %r8 + sbbq %r12, %r15 + sbbq %r13, %r9 + movq %rdx, (%rdi) + movq %r8, 8(%rdi) + movq %r15, 16(%rdi) + movq %r9, 24(%rdi) + pop %r15 + pop %r14 + pop %r13 + pop %r12 + repz retq +#ifndef __APPLE__ +.size sp_256_mont_reduce_4,.-sp_256_mont_reduce_4 +#endif /* __APPLE__ */ /* Add two Montgomery form numbers (r = a + b % m). * * r Result of addition. @@ -31535,6 +31637,7 @@ _sp_256_mont_sqr_avx2_4: adcxq %r8, %r13 adcxq %r15, %r14 # Double with Carry Flag + xorq %r15, %r15 # A[0] * A[0] movq (%rsi), %rdx mulxq %rdx, %r8, %rax @@ -32182,7 +32285,7 @@ _sp_256_mul_d_4: movq %r10, 16(%rdi) adcq %rdx, %r8 adcq $0, %r9 - # # A[3] * B + # A[3] * B movq %rcx, %rax mulq 24(%rsi) addq %rax, %r8 @@ -32592,7 +32695,6 @@ _sp_256_mont_reduce_avx2_4: movq $18446744069414584320, %rdx andq %r11, %r8 andq %r11, %r9 - movq %r11, %r11 andq %r11, %rdx subq %r8, %rbx sbbq %r9, %r12 @@ -32612,3 +32714,2068 @@ _sp_256_mont_reduce_avx2_4: .size sp_256_mont_reduce_avx2_4,.-sp_256_mont_reduce_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__ +.globl sp_384_cond_copy_6 +.type sp_384_cond_copy_6,@function +.align 16 +sp_384_cond_copy_6: +#else +.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. + * a A single precision integer. + * b A single precision integer. + */ +#ifndef __APPLE__ +.globl sp_384_mul_6 +.type sp_384_mul_6,@function +.align 16 +sp_384_mul_6: +#else +.globl _sp_384_mul_6 +.p2align 4 +_sp_384_mul_6: +#endif /* __APPLE__ */ + movq %rdx, %rcx + subq $48, %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 $0, %r8 + # A[1] * B[0] + movq (%rcx), %rax + mulq 8(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0, %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 $0, %r9 + # A[1] * B[1] + movq 8(%rcx), %rax + mulq 8(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0, %r9 + # A[2] * B[0] + movq (%rcx), %rax + mulq 16(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0, %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 $0, %r10 + # A[1] * B[2] + movq 16(%rcx), %rax + mulq 8(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0, %r10 + # A[2] * B[1] + movq 8(%rcx), %rax + mulq 16(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0, %r10 + # A[3] * B[0] + movq (%rcx), %rax + mulq 24(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0, %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 $0, %r8 + # A[1] * B[3] + movq 24(%rcx), %rax + mulq 8(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0, %r8 + # A[2] * B[2] + movq 16(%rcx), %rax + mulq 16(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0, %r8 + # A[3] * B[1] + movq 8(%rcx), %rax + mulq 24(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0, %r8 + # A[4] * B[0] + movq (%rcx), %rax + mulq 32(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0, %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 $0, %r9 + # A[1] * B[4] + movq 32(%rcx), %rax + mulq 8(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0, %r9 + # A[2] * B[3] + movq 24(%rcx), %rax + mulq 16(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0, %r9 + # A[3] * B[2] + movq 16(%rcx), %rax + mulq 24(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0, %r9 + # A[4] * B[1] + movq 8(%rcx), %rax + mulq 32(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0, %r9 + # A[5] * B[0] + movq (%rcx), %rax + mulq 40(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0, %r9 + movq %r10, 40(%rsp) + # A[1] * B[5] + movq 40(%rcx), %rax + mulq 8(%rsi) + xorq %r10, %r10 + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0, %r10 + # A[2] * B[4] + movq 32(%rcx), %rax + mulq 16(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0, %r10 + # A[3] * B[3] + movq 24(%rcx), %rax + mulq 24(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0, %r10 + # A[4] * B[2] + movq 16(%rcx), %rax + mulq 32(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0, %r10 + # A[5] * B[1] + movq 8(%rcx), %rax + mulq 40(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0, %r10 + movq %r8, 48(%rdi) + # A[2] * B[5] + movq 40(%rcx), %rax + mulq 16(%rsi) + xorq %r8, %r8 + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0, %r8 + # A[3] * B[4] + movq 32(%rcx), %rax + mulq 24(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0, %r8 + # A[4] * B[3] + movq 24(%rcx), %rax + mulq 32(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0, %r8 + # A[5] * B[2] + movq 16(%rcx), %rax + mulq 40(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + adcq $0, %r8 + movq %r9, 56(%rdi) + # A[3] * B[5] + movq 40(%rcx), %rax + mulq 24(%rsi) + xorq %r9, %r9 + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0, %r9 + # A[4] * B[4] + movq 32(%rcx), %rax + mulq 32(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0, %r9 + # A[5] * B[3] + movq 24(%rcx), %rax + mulq 40(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + adcq $0, %r9 + movq %r10, 64(%rdi) + # A[4] * B[5] + movq 40(%rcx), %rax + mulq 32(%rsi) + xorq %r10, %r10 + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0, %r10 + # A[5] * B[4] + movq 32(%rcx), %rax + mulq 40(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0, %r10 + movq %r8, 72(%rdi) + # A[5] * B[5] + movq 40(%rcx), %rax + mulq 40(%rsi) + addq %rax, %r9 + adcq %rdx, %r10 + movq %r9, 80(%rdi) + movq %r10, 88(%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 %rax, 32(%rdi) + movq %rdx, 40(%rdi) + addq $48, %rsp + repz retq +#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__ +.globl sp_384_cond_sub_6 +.type sp_384_cond_sub_6,@function +.align 16 +sp_384_cond_sub_6: +#else +.globl _sp_384_cond_sub_6 +.p2align 4 +_sp_384_cond_sub_6: +#endif /* __APPLE__ */ + subq $48, %rsp + movq $0, %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 $0, %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__ +.globl sp_384_mont_reduce_6 +.type sp_384_mont_reduce_6,@function +.align 16 +sp_384_mont_reduce_6: +#else +.globl _sp_384_mont_reduce_6 +.p2align 4 +_sp_384_mont_reduce_6: +#endif /* __APPLE__ */ + push %r12 + push %r13 + push %r14 + push %r15 + push %rbx + push %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 $0, %r14 + adcq $0, %r15 + adcq $0, %rsi + adcq %rdx, %rbx + adcq %rax, %rbp + adcq $0, %r10 + addq %rax, %rcx + adcq %rdx, %r8 + adcq %rax, %r9 + movq $0, %rax + adcq $0, %rax + subq %r8, %r13 + sbbq %r9, %r14 + sbbq %rax, %r15 + sbbq $0, %rsi + sbbq $0, %rbx + sbbq $0, %rbp + sbbq $0, %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 $0, %r12 + movq $0, %r10 + adcq $0, %r10 + addq %rcx, %r13 + adcq %r8, %r14 + adcq %r9, %r15 + adcq $0, %rsi + adcq $0, %rbx + adcq $0, %rbp + adcq %rdx, %r11 + adcq %rax, %r12 + adcq $0, %r10 + addq %rax, %rcx + adcq %rdx, %r8 + adcq %rax, %r9 + movq $0, %rax + adcq $0, %rax + subq %r8, %r15 + sbbq %r9, %rsi + sbbq %rax, %rbx + sbbq $0, %rbp + sbbq $0, %r11 + sbbq $0, %r12 + sbbq $0, %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 $0, %r14 + movq $0, %r10 + adcq $0, %r10 + addq %rcx, %r15 + adcq %r8, %rsi + adcq %r9, %rbx + adcq $0, %rbp + adcq $0, %r11 + adcq $0, %r12 + adcq %rdx, %r13 + adcq %rax, %r14 + adcq $0, %r10 + addq %rax, %rcx + adcq %rdx, %r8 + adcq %rax, %r9 + movq $0, %rax + adcq $0, %rax + subq %r8, %rbx + sbbq %r9, %rbp + sbbq %rax, %r11 + sbbq $0, %r12 + sbbq $0, %r13 + sbbq $0, %r14 + sbbq $0, %r10 + # Subtract mod if carry + negq %r10 + movq $18446744073709551614, %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) + pop %rbp + pop %rbx + pop %r15 + pop %r14 + pop %r13 + pop %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__ +.globl sp_384_mont_reduce_order_6 +.type sp_384_mont_reduce_order_6,@function +.align 16 +sp_384_mont_reduce_order_6: +#else +.globl _sp_384_mont_reduce_order_6 +.p2align 4 +_sp_384_mont_reduce_order_6: +#endif /* __APPLE__ */ + push %r12 + push %r13 + push %r14 + push %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 $0, %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 $0, %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 $0, %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 $0, %r10 + # a[i+5] += m[5] * mu + movq %r11, %rax + mulq 40(%rsi) + movq 40(%rdi), %r12 + addq %rax, %r10 + adcq %r15, %rdx + movq $0, %r15 + adcq $0, %r15 + addq %r10, %r12 + movq %r12, 40(%rdi) + adcq %rdx, 48(%rdi) + adcq $0, %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 + subq $48, %rdi +#ifndef __APPLE__ + callq sp_384_cond_sub_6@plt +#else + callq _sp_384_cond_sub_6 +#endif /* __APPLE__ */ + pop %r15 + pop %r14 + pop %r13 + pop %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. + * a A single precision integer. + */ +#ifndef __APPLE__ +.globl sp_384_sqr_6 +.type sp_384_sqr_6,@function +.align 16 +sp_384_sqr_6: +#else +.globl _sp_384_sqr_6 +.p2align 4 +_sp_384_sqr_6: +#endif /* __APPLE__ */ + push %r12 + subq $48, %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 $0, %rcx + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0, %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 $0, %r8 + addq %rax, %r9 + adcq %rdx, %rcx + adcq $0, %r8 + # A[1] * A[1] + movq 8(%rsi), %rax + mulq %rax + addq %rax, %r9 + adcq %rdx, %rcx + adcq $0, %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 $0, %r9 + addq %rax, %rcx + adcq %rdx, %r8 + adcq $0, %r9 + # A[1] * A[2] + movq 16(%rsi), %rax + mulq 8(%rsi) + addq %rax, %rcx + adcq %rdx, %r8 + adcq $0, %r9 + addq %rax, %rcx + adcq %rdx, %r8 + adcq $0, %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 $0, %rcx + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0, %rcx + # A[1] * A[3] + movq 24(%rsi), %rax + mulq 8(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0, %rcx + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0, %rcx + # A[2] * A[2] + movq 16(%rsi), %rax + mulq %rax + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0, %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 $0, %r12 + # A[2] * A[3] + movq 24(%rsi), %rax + mulq 16(%rsi) + addq %rax, %r10 + adcq %rdx, %r11 + adcq $0, %r12 + addq %r10, %r10 + adcq %r11, %r11 + adcq %r12, %r12 + addq %r10, %r9 + adcq %r11, %rcx + adcq %r12, %r8 + movq %r9, 40(%rsp) + # A[1] * A[5] + movq 40(%rsi), %rax + mulq 8(%rsi) + xorq %r9, %r9 + addq %rax, %rcx + adcq %rdx, %r8 + adcq $0, %r9 + addq %rax, %rcx + adcq %rdx, %r8 + adcq $0, %r9 + # A[2] * A[4] + movq 32(%rsi), %rax + mulq 16(%rsi) + addq %rax, %rcx + adcq %rdx, %r8 + adcq $0, %r9 + addq %rax, %rcx + adcq %rdx, %r8 + adcq $0, %r9 + # A[3] * A[3] + movq 24(%rsi), %rax + mulq %rax + addq %rax, %rcx + adcq %rdx, %r8 + adcq $0, %r9 + movq %rcx, 48(%rdi) + # A[2] * A[5] + movq 40(%rsi), %rax + mulq 16(%rsi) + xorq %rcx, %rcx + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0, %rcx + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0, %rcx + # A[3] * A[4] + movq 32(%rsi), %rax + mulq 24(%rsi) + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0, %rcx + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0, %rcx + movq %r8, 56(%rdi) + # A[3] * A[5] + movq 40(%rsi), %rax + mulq 24(%rsi) + xorq %r8, %r8 + addq %rax, %r9 + adcq %rdx, %rcx + adcq $0, %r8 + addq %rax, %r9 + adcq %rdx, %rcx + adcq $0, %r8 + # A[4] * A[4] + movq 32(%rsi), %rax + mulq %rax + addq %rax, %r9 + adcq %rdx, %rcx + adcq $0, %r8 + movq %r9, 64(%rdi) + # A[4] * A[5] + movq 40(%rsi), %rax + mulq 32(%rsi) + xorq %r9, %r9 + addq %rax, %rcx + adcq %rdx, %r8 + adcq $0, %r9 + addq %rax, %rcx + adcq %rdx, %r8 + adcq $0, %r9 + movq %rcx, 72(%rdi) + # A[5] * A[5] + movq 40(%rsi), %rax + mulq %rax + addq %rax, %r8 + adcq %rdx, %r9 + movq %r8, 80(%rdi) + movq %r9, 88(%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 %rax, 32(%rdi) + movq %rdx, 40(%rdi) + addq $48, %rsp + pop %r12 + repz retq +#ifndef __APPLE__ +.size sp_384_sqr_6,.-sp_384_sqr_6 +#endif /* __APPLE__ */ +/* 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__ +.globl sp_384_cmp_6 +.type sp_384_cmp_6,@function +.align 16 +sp_384_cmp_6: +#else +.globl _sp_384_cmp_6 +.p2align 4 +_sp_384_cmp_6: +#endif /* __APPLE__ */ + xorq %rcx, %rcx + movq $-1, %rdx + movq $-1, %rax + movq $1, %r8 + 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_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__ +.globl sp_384_add_6 +.type sp_384_add_6,@function +.align 16 +sp_384_add_6: +#else +.globl _sp_384_add_6 +.p2align 4 +_sp_384_add_6: +#endif /* __APPLE__ */ + 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 $0, %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. + * a A single precision integer. + */ +#ifndef __APPLE__ +.globl sp_384_dbl_6 +.type sp_384_dbl_6,@function +.align 16 +sp_384_dbl_6: +#else +.globl _sp_384_dbl_6 +.p2align 4 +_sp_384_dbl_6: +#endif /* __APPLE__ */ + movq (%rsi), %rdx + xorq %rax, %rax + addq %rdx, %rdx + movq 8(%rsi), %rcx + movq %rdx, (%rdi) + adcq %rcx, %rcx + movq 16(%rsi), %rdx + movq %rcx, 8(%rdi) + adcq %rdx, %rdx + movq 24(%rsi), %rcx + movq %rdx, 16(%rdi) + adcq %rcx, %rcx + movq 32(%rsi), %rdx + movq %rcx, 24(%rdi) + adcq %rdx, %rdx + movq 40(%rsi), %rcx + movq %rdx, 32(%rdi) + adcq %rcx, %rcx + movq %rcx, 40(%rdi) + adcq $0, %rax + repz retq +#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__ +.globl sp_384_sub_6 +.type sp_384_sub_6,@function +.align 16 +sp_384_sub_6: +#else +.globl _sp_384_sub_6 +.p2align 4 +_sp_384_sub_6: +#endif /* __APPLE__ */ + push %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 $0, %rax + pop %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. + * + * 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. + */ +#ifndef __APPLE__ +.globl sp_384_cond_add_6 +.type sp_384_cond_add_6,@function +.align 16 +sp_384_cond_add_6: +#else +.globl _sp_384_cond_add_6 +.p2align 4 +_sp_384_cond_add_6: +#endif /* __APPLE__ */ + subq $48, %rsp + movq $0, %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 + addq %rdx, %r8 + movq 8(%rsi), %r9 + movq 8(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, (%rdi) + movq 16(%rsi), %r8 + movq 16(%rsp), %rdx + adcq %rdx, %r8 + movq %r9, 8(%rdi) + movq 24(%rsi), %r9 + movq 24(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, 16(%rdi) + movq 32(%rsi), %r8 + movq 32(%rsp), %rdx + adcq %rdx, %r8 + movq %r9, 24(%rdi) + movq 40(%rsi), %r9 + movq 40(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, 32(%rdi) + movq %r9, 40(%rdi) + adcq $0, %rax + addq $48, %rsp + repz retq +#ifndef __APPLE__ +.size sp_384_cond_add_6,.-sp_384_cond_add_6 +#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__ +.globl sp_384_div2_6 +.type sp_384_div2_6,@function +.align 16 +sp_384_div2_6: +#else +.globl _sp_384_div2_6 +.p2align 4 +_sp_384_div2_6: +#endif /* __APPLE__ */ + subq $48, %rsp + movq (%rsi), %rax + movq %rax, %r11 + andq $1, %r11 + negq %r11 + xorq %r10, %r10 + 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) + 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) + adcq $0, %r10 + movq (%rsp), %rax + movq 8(%rsp), %rcx + shrdq $1, %rcx, %rax + movq %rax, (%rdi) + movq 16(%rsp), %rax + shrdq $1, %rax, %rcx + movq %rcx, 8(%rdi) + movq 24(%rsp), %rcx + shrdq $1, %rcx, %rax + movq %rax, 16(%rdi) + movq 32(%rsp), %rax + shrdq $1, %rax, %rcx + movq %rcx, 24(%rdi) + movq 40(%rsp), %rcx + shrdq $1, %rcx, %rax + movq %rax, 32(%rdi) + shrdq $1, %r10, %rcx + movq %rcx, 40(%rdi) + addq $48, %rsp + repz retq +#ifndef __APPLE__ +.size sp_384_div2_6,.-sp_384_div2_6 +#endif /* __APPLE__ */ +/* 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__ +.globl sp_384_mul_avx2_6 +.type sp_384_mul_avx2_6,@function +.align 16 +sp_384_mul_avx2_6: +#else +.globl _sp_384_mul_avx2_6 +.p2align 4 +_sp_384_mul_avx2_6: +#endif /* __APPLE__ */ + push %r12 + push %r13 + push %r14 + push %r15 + push %rbx + movq %rdx, %rax + subq $40, %rsp + xorq %rbx, %rbx + movq (%rsi), %rdx + # A[0] * B[0] + mulxq (%rax), %r9, %r10 + # A[0] * B[1] + mulxq 8(%rax), %rcx, %r11 + adcxq %rcx, %r10 + # A[0] * B[2] + mulxq 16(%rax), %rcx, %r12 + adcxq %rcx, %r11 + # A[0] * B[3] + mulxq 24(%rax), %rcx, %r13 + adcxq %rcx, %r12 + # A[0] * B[4] + mulxq 32(%rax), %rcx, %r14 + adcxq %rcx, %r13 + # A[0] * B[5] + mulxq 40(%rax), %rcx, %r15 + adcxq %rcx, %r14 + adcxq %rbx, %r15 + movq %r9, (%rsp) + movq $0, %r9 + adcxq %rbx, %r9 + xorq %rbx, %rbx + movq 8(%rsi), %rdx + # A[1] * B[0] + mulxq (%rax), %rcx, %r8 + adcxq %rcx, %r10 + adoxq %r8, %r11 + # A[1] * B[1] + mulxq 8(%rax), %rcx, %r8 + adcxq %rcx, %r11 + adoxq %r8, %r12 + # A[1] * B[2] + mulxq 16(%rax), %rcx, %r8 + adcxq %rcx, %r12 + adoxq %r8, %r13 + # A[1] * B[3] + mulxq 24(%rax), %rcx, %r8 + adcxq %rcx, %r13 + adoxq %r8, %r14 + # A[1] * B[4] + mulxq 32(%rax), %rcx, %r8 + adcxq %rcx, %r14 + adoxq %r8, %r15 + # A[1] * B[5] + mulxq 40(%rax), %rcx, %r8 + adcxq %rcx, %r15 + adoxq %r8, %r9 + adcxq %rbx, %r9 + movq %r10, 8(%rsp) + movq $0, %r10 + adcxq %rbx, %r10 + adoxq %rbx, %r10 + xorq %rbx, %rbx + movq 16(%rsi), %rdx + # A[2] * B[0] + mulxq (%rax), %rcx, %r8 + adcxq %rcx, %r11 + adoxq %r8, %r12 + # A[2] * B[1] + mulxq 8(%rax), %rcx, %r8 + adcxq %rcx, %r12 + adoxq %r8, %r13 + # A[2] * B[2] + mulxq 16(%rax), %rcx, %r8 + adcxq %rcx, %r13 + adoxq %r8, %r14 + # A[2] * B[3] + mulxq 24(%rax), %rcx, %r8 + adcxq %rcx, %r14 + adoxq %r8, %r15 + # A[2] * B[4] + mulxq 32(%rax), %rcx, %r8 + adcxq %rcx, %r15 + adoxq %r8, %r9 + # A[2] * B[5] + mulxq 40(%rax), %rcx, %r8 + adcxq %rcx, %r9 + adoxq %r8, %r10 + adcxq %rbx, %r10 + movq %r11, 16(%rsp) + movq $0, %r11 + adcxq %rbx, %r11 + adoxq %rbx, %r11 + xorq %rbx, %rbx + movq 24(%rsi), %rdx + # A[3] * B[0] + mulxq (%rax), %rcx, %r8 + adcxq %rcx, %r12 + adoxq %r8, %r13 + # A[3] * B[1] + mulxq 8(%rax), %rcx, %r8 + adcxq %rcx, %r13 + adoxq %r8, %r14 + # A[3] * B[2] + mulxq 16(%rax), %rcx, %r8 + adcxq %rcx, %r14 + adoxq %r8, %r15 + # A[3] * B[3] + mulxq 24(%rax), %rcx, %r8 + adcxq %rcx, %r15 + adoxq %r8, %r9 + # A[3] * B[4] + mulxq 32(%rax), %rcx, %r8 + adcxq %rcx, %r9 + adoxq %r8, %r10 + # A[3] * B[5] + mulxq 40(%rax), %rcx, %r8 + adcxq %rcx, %r10 + adoxq %r8, %r11 + adcxq %rbx, %r11 + movq %r12, 24(%rsp) + movq $0, %r12 + adcxq %rbx, %r12 + adoxq %rbx, %r12 + xorq %rbx, %rbx + movq 32(%rsi), %rdx + # A[4] * B[0] + mulxq (%rax), %rcx, %r8 + adcxq %rcx, %r13 + adoxq %r8, %r14 + # A[4] * B[1] + mulxq 8(%rax), %rcx, %r8 + adcxq %rcx, %r14 + adoxq %r8, %r15 + # A[4] * B[2] + mulxq 16(%rax), %rcx, %r8 + adcxq %rcx, %r15 + adoxq %r8, %r9 + # A[4] * B[3] + mulxq 24(%rax), %rcx, %r8 + adcxq %rcx, %r9 + adoxq %r8, %r10 + # A[4] * B[4] + mulxq 32(%rax), %rcx, %r8 + adcxq %rcx, %r10 + adoxq %r8, %r11 + # A[4] * B[5] + mulxq 40(%rax), %rcx, %r8 + adcxq %rcx, %r11 + adoxq %r8, %r12 + adcxq %rbx, %r12 + movq %r13, 32(%rsp) + movq 40(%rsi), %rdx + # A[5] * B[0] + mulxq (%rax), %rcx, %r8 + adcxq %rcx, %r14 + adoxq %r8, %r15 + # A[5] * B[1] + mulxq 8(%rax), %rcx, %r8 + adcxq %rcx, %r15 + adoxq %r8, %r9 + # A[5] * B[2] + mulxq 16(%rax), %rcx, %r8 + adcxq %rcx, %r9 + adoxq %r8, %r10 + # A[5] * B[3] + mulxq 24(%rax), %rcx, %r8 + adcxq %rcx, %r10 + adoxq %r8, %r11 + # A[5] * B[4] + mulxq 32(%rax), %rcx, %r8 + adcxq %rcx, %r11 + adoxq %r8, %r12 + # A[5] * B[5] + mulxq 40(%rax), %rcx, %r13 + adcxq %rcx, %r12 + adoxq %rbx, %r13 + adcxq %rbx, %r13 + movq %r14, 40(%rdi) + movq %r15, 48(%rdi) + movq %r9, 56(%rdi) + movq %r10, 64(%rdi) + movq %r11, 72(%rdi) + movq %r12, 80(%rdi) + movq %r13, 88(%rdi) + movq (%rsp), %r9 + movq 8(%rsp), %r10 + movq 16(%rsp), %r11 + movq 24(%rsp), %r12 + movq 32(%rsp), %r13 + movq %r9, (%rdi) + movq %r10, 8(%rdi) + movq %r11, 16(%rdi) + movq %r12, 24(%rdi) + movq %r13, 32(%rdi) + addq $40, %rsp + pop %rbx + pop %r15 + pop %r14 + pop %r13 + pop %r12 + repz retq +#ifndef __APPLE__ +.size sp_384_mul_avx2_6,.-sp_384_mul_avx2_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__ +.globl sp_384_cond_sub_avx2_6 +.type sp_384_cond_sub_avx2_6,@function +.align 16 +sp_384_cond_sub_avx2_6: +#else +.globl _sp_384_cond_sub_avx2_6 +.p2align 4 +_sp_384_cond_sub_avx2_6: +#endif /* __APPLE__ */ + movq $0, %rax + movq (%rsi), %r8 + movq (%rdx), %r10 + pextq %rcx, %r10, %r10 + subq %r10, %r8 + movq 8(%rsi), %r9 + movq 8(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, (%rdi) + sbbq %r10, %r9 + movq 16(%rsi), %r8 + movq 16(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 8(%rdi) + sbbq %r10, %r8 + movq 24(%rsi), %r9 + movq 24(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 16(%rdi) + sbbq %r10, %r9 + movq 32(%rsi), %r8 + movq 32(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r9, 24(%rdi) + sbbq %r10, %r8 + movq 40(%rsi), %r9 + movq 40(%rdx), %r10 + pextq %rcx, %r10, %r10 + movq %r8, 32(%rdi) + sbbq %r10, %r9 + movq %r9, 40(%rdi) + sbbq $0, %rax + repz retq +#ifndef __APPLE__ +.size sp_384_cond_sub_avx2_6,.-sp_384_cond_sub_avx2_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__ +.globl sp_384_mont_reduce_order_avx2_6 +.type sp_384_mont_reduce_order_avx2_6,@function +.align 16 +sp_384_mont_reduce_order_avx2_6: +#else +.globl _sp_384_mont_reduce_order_avx2_6 +.p2align 4 +_sp_384_mont_reduce_order_avx2_6: +#endif /* __APPLE__ */ + push %r12 + push %r13 + push %r14 + movq %rdx, %rax + xorq %r14, %r14 + # i = 6 + movq $6, %r9 + movq (%rdi), %r13 + xorq %r12, %r12 +L_mont_loop_order_avx2_6: + # mu = a[i] * mp + movq %r13, %rdx + mulxq %rax, %rdx, %r8 + movq %r13, %r10 + # a[i+0] += m[0] * mu + mulxq (%rsi), %rcx, %r8 + movq 8(%rdi), %r13 + adcxq %rcx, %r10 + adoxq %r8, %r13 + # a[i+1] += m[1] * mu + mulxq 8(%rsi), %rcx, %r8 + movq 16(%rdi), %r10 + adcxq %rcx, %r13 + adoxq %r8, %r10 + # a[i+2] += m[2] * mu + mulxq 16(%rsi), %rcx, %r8 + movq 24(%rdi), %r11 + adcxq %rcx, %r10 + adoxq %r8, %r11 + movq %r10, 16(%rdi) + # a[i+3] += m[3] * mu + mulxq 24(%rsi), %rcx, %r8 + movq 32(%rdi), %r10 + adcxq %rcx, %r11 + adoxq %r8, %r10 + movq %r11, 24(%rdi) + # a[i+4] += m[4] * mu + mulxq 32(%rsi), %rcx, %r8 + movq 40(%rdi), %r11 + adcxq %rcx, %r10 + adoxq %r8, %r11 + movq %r10, 32(%rdi) + # a[i+5] += m[5] * mu + mulxq 40(%rsi), %rcx, %r8 + movq 48(%rdi), %r10 + adcxq %rcx, %r11 + adoxq %r8, %r10 + movq %r11, 40(%rdi) + adcxq %r14, %r10 + movq %r12, %r14 + movq %r10, 48(%rdi) + adoxq %r12, %r14 + adcxq %r12, %r14 + # i -= 1 + addq $8, %rdi + decq %r9 + jnz L_mont_loop_order_avx2_6 + movq %r13, (%rdi) + negq %r14 + movq %r14, %rcx + movq %rsi, %rdx + movq %rdi, %rsi + subq $48, %rdi +#ifndef __APPLE__ + callq sp_384_cond_sub_avx2_6@plt +#else + callq _sp_384_cond_sub_avx2_6 +#endif /* __APPLE__ */ + pop %r14 + pop %r13 + pop %r12 + repz retq +#ifndef __APPLE__ +.size sp_384_mont_reduce_order_avx2_6,.-sp_384_mont_reduce_order_avx2_6 +#endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ +/* Square a and put result in r. (r = a * a) + * + * r Result of squaring. + * a Number to square in Montogmery form. + */ +#ifndef __APPLE__ +.globl sp_384_sqr_avx2_6 +.type sp_384_sqr_avx2_6,@function +.align 16 +sp_384_sqr_avx2_6: +#else +.globl _sp_384_sqr_avx2_6 +.p2align 4 +_sp_384_sqr_avx2_6: +#endif /* __APPLE__ */ + push %r12 + push %r13 + push %r14 + push %r15 + push %rbx + push %rbp + push %rdi + xorq %rdi, %rdi + movq (%rsi), %rdx + movq 8(%rsi), %r15 + movq 16(%rsi), %rbx + movq 24(%rsi), %rbp + # Diagonal 0 + # A[1] * A[0] + mulxq 8(%rsi), %r8, %r9 + # A[2] * A[0] + mulxq 16(%rsi), %rax, %r10 + adcxq %rax, %r9 + # A[3] * A[0] + mulxq 24(%rsi), %rax, %r11 + adcxq %rax, %r10 + # A[4] * A[0] + mulxq 32(%rsi), %rax, %r12 + adcxq %rax, %r11 + # A[5] * A[0] + mulxq 40(%rsi), %rax, %r13 + adcxq %rax, %r12 + adcxq %rdi, %r13 + # Diagonal 1 + movq %r15, %rdx + # A[2] * A[1] + mulxq 16(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r11 + # A[3] * A[1] + mulxq 24(%rsi), %rax, %rcx + adcxq %rax, %r11 + adoxq %rcx, %r12 + # A[4] * A[1] + mulxq 32(%rsi), %rax, %rcx + adcxq %rax, %r12 + adoxq %rcx, %r13 + # A[5] * A[1] + mulxq 40(%rsi), %rax, %r14 + adcxq %rax, %r13 + adoxq %rdi, %r14 + movq %rbx, %rdx + # A[5] * A[2] + mulxq 40(%rsi), %rax, %r15 + adcxq %rax, %r14 + adoxq %rdi, %r15 + adcxq %rdi, %r15 + adcxq %rdi, %rbx + # Diagonal 2 + # A[3] * A[2] + mulxq 24(%rsi), %rax, %rcx + adcxq %rax, %r12 + adoxq %rcx, %r13 + # A[4] * A[2] + mulxq 32(%rsi), %rax, %rcx + adcxq %rax, %r13 + adoxq %rcx, %r14 + movq %rbp, %rdx + # A[4] * A[3] + mulxq 32(%rsi), %rax, %rcx + adcxq %rax, %r14 + adoxq %rcx, %r15 + # A[5] * A[3] + mulxq 40(%rsi), %rax, %rbx + adcxq %rax, %r15 + adoxq %rdi, %rbx + movq 32(%rsi), %rdx + # A[5] * A[4] + mulxq 40(%rsi), %rax, %rbp + adcxq %rax, %rbx + adoxq %rdi, %rbp + adcxq %rdi, %rbp + adcxq %rdi, %rdi + # Doubling previous result as we add in square words results + # A[0] * A[0] + movq (%rsi), %rdx + mulxq %rdx, %rax, %rcx + pop %rdx + movq %rax, (%rdx) + adoxq %r8, %r8 + push %rdx + adcxq %rcx, %r8 + # A[1] * A[1] + movq 8(%rsi), %rdx + mulxq %rdx, %rax, %rcx + adoxq %r9, %r9 + adcxq %rax, %r9 + adoxq %r10, %r10 + adcxq %rcx, %r10 + # A[2] * A[2] + movq 16(%rsi), %rdx + mulxq %rdx, %rax, %rcx + adoxq %r11, %r11 + adcxq %rax, %r11 + adoxq %r12, %r12 + adcxq %rcx, %r12 + # A[3] * A[3] + movq 24(%rsi), %rdx + mulxq %rdx, %rax, %rcx + adoxq %r13, %r13 + adcxq %rax, %r13 + adoxq %r14, %r14 + adcxq %rcx, %r14 + # A[4] * A[4] + movq 32(%rsi), %rdx + mulxq %rdx, %rax, %rcx + adoxq %r15, %r15 + adcxq %rax, %r15 + adoxq %rbx, %rbx + adcxq %rcx, %rbx + # A[5] * A[5] + movq 40(%rsi), %rdx + mulxq %rdx, %rax, %rcx + adoxq %rbp, %rbp + adcxq %rax, %rbp + adcxq %rdi, %rcx + movq $0, %rax + adoxq %rax, %rcx + pop %rdi + movq %r8, 8(%rdi) + movq %r9, 16(%rdi) + movq %r10, 24(%rdi) + movq %r11, 32(%rdi) + movq %r12, 40(%rdi) + movq %r13, 48(%rdi) + movq %r14, 56(%rdi) + movq %r15, 64(%rdi) + movq %rbx, 72(%rdi) + movq %rbp, 80(%rdi) + movq %rcx, 88(%rdi) + pop %rbp + pop %rbx + pop %r15 + pop %r14 + pop %r13 + pop %r12 + repz retq +#ifndef __APPLE__ +.size sp_384_sqr_avx2_6,.-sp_384_sqr_avx2_6 +#endif /* __APPLE__ */ +/* Add 1 to a. (a = a + 1) + * + * a A single precision integer. + */ +#ifndef __APPLE__ +.globl sp_384_add_one_6 +.type sp_384_add_one_6,@function +.align 16 +sp_384_add_one_6: +#else +.globl _sp_384_add_one_6 +.p2align 4 +_sp_384_add_one_6: +#endif /* __APPLE__ */ + addq $1, (%rdi) + adcq $0, 8(%rdi) + adcq $0, 16(%rdi) + adcq $0, 24(%rdi) + adcq $0, 32(%rdi) + adcq $0, 40(%rdi) + repz retq +#ifndef __APPLE__ +.size sp_384_add_one_6,.-sp_384_add_one_6 +#endif /* __APPLE__ */ +/* 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. + */ +#ifndef __APPLE__ +.globl sp_384_from_bin +.type sp_384_from_bin,@function +.align 16 +sp_384_from_bin: +#else +.globl _sp_384_from_bin +.p2align 4 +_sp_384_from_bin: +#endif /* __APPLE__ */ + movq %rdx, %r9 + movq %rdi, %r10 + addq %rcx, %r9 + addq $48, %r10 + xorq %r11, %r11 + jmp L_384_from_bin_64_end +L_384_from_bin_64_start: + subq $64, %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 $64, %rdi + subq $64, %rcx +L_384_from_bin_64_end: + cmpq $63, %rcx + jg L_384_from_bin_64_start + jmp L_384_from_bin_8_end +L_384_from_bin_8_start: + subq $8, %r9 + movbeq (%r9), %rax + movq %rax, (%rdi) + addq $8, %rdi + subq $8, %rcx +L_384_from_bin_8_end: + cmpq $7, %rcx + jg L_384_from_bin_8_start + cmpq %r11, %rcx + je L_384_from_bin_hi_end + movq %r11, %r8 + movq %r11, %rax +L_384_from_bin_hi_start: + movb (%rdx), %al + shlq $8, %r8 + incq %rdx + addq %rax, %r8 + decq %rcx + jg L_384_from_bin_hi_start + movq %r8, (%rdi) + addq $8, %rdi +L_384_from_bin_hi_end: + cmpq %r10, %rdi + je L_384_from_bin_zero_end +L_384_from_bin_zero_start: + movq %r11, (%rdi) + addq $8, %rdi + cmpq %r10, %rdi + jl L_384_from_bin_zero_start +L_384_from_bin_zero_end: + repz retq +#ifndef __APPLE__ +.size sp_384_from_bin,.-sp_384_from_bin +#endif /* __APPLE__ */ +/* Write r as big endian to byte array. + * Fixed length number of bytes written: 48 + * + * r A single precision integer. + * a Byte array. + */ +#ifndef __APPLE__ +.globl sp_384_to_bin +.type sp_384_to_bin,@function +.align 16 +sp_384_to_bin: +#else +.globl _sp_384_to_bin +.p2align 4 +_sp_384_to_bin: +#endif /* __APPLE__ */ + movbeq 40(%rdi), %rdx + movbeq 32(%rdi), %rax + movq %rdx, (%rsi) + movq %rax, 8(%rsi) + movbeq 24(%rdi), %rdx + movbeq 16(%rdi), %rax + movq %rdx, 16(%rsi) + movq %rax, 24(%rsi) + movbeq 8(%rdi), %rdx + movbeq (%rdi), %rax + movq %rdx, 32(%rsi) + movq %rax, 40(%rsi) + repz retq +#ifndef __APPLE__ +.size sp_384_to_bin,.-sp_384_to_bin +#endif /* __APPLE__ */ +/* Sub b from a into a. (a -= b) + * + * a A single precision integer and result. + * b A single precision integer. + */ +#ifndef __APPLE__ +.globl sp_384_sub_in_place_6 +.type sp_384_sub_in_place_6,@function +.align 16 +sp_384_sub_in_place_6: +#else +.globl _sp_384_sub_in_place_6 +.p2align 4 +_sp_384_sub_in_place_6: +#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 %rcx, 40(%rdi) + sbbq $0, %rax + repz retq +#ifndef __APPLE__ +.size sp_384_sub_in_place_6,.-sp_384_sub_in_place_6 +#endif /* __APPLE__ */ +/* 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__ +.globl sp_384_mul_d_6 +.type sp_384_mul_d_6,@function +.align 16 +sp_384_mul_d_6: +#else +.globl _sp_384_mul_d_6 +.p2align 4 +_sp_384_mul_d_6: +#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 $0, %r8 + # A[2] * B + movq %rcx, %rax + xorq %r9, %r9 + mulq 16(%rsi) + addq %rax, %r10 + movq %r10, 16(%rdi) + adcq %rdx, %r8 + adcq $0, %r9 + # A[3] * B + movq %rcx, %rax + xorq %r10, %r10 + mulq 24(%rsi) + addq %rax, %r8 + movq %r8, 24(%rdi) + adcq %rdx, %r9 + adcq $0, %r10 + # A[4] * B + movq %rcx, %rax + xorq %r8, %r8 + mulq 32(%rsi) + addq %rax, %r9 + movq %r9, 32(%rdi) + adcq %rdx, %r10 + adcq $0, %r8 + # A[5] * B + movq %rcx, %rax + mulq 40(%rsi) + addq %rax, %r10 + adcq %rdx, %r8 + movq %r10, 40(%rdi) + movq %r8, 48(%rdi) + repz retq +#ifndef __APPLE__ +.size sp_384_mul_d_6,.-sp_384_mul_d_6 +#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__ +.globl sp_384_mul_d_avx2_6 +.type sp_384_mul_d_avx2_6,@function +.align 16 +sp_384_mul_d_avx2_6: +#else +.globl _sp_384_mul_d_avx2_6 +.p2align 4 +_sp_384_mul_d_avx2_6: +#endif /* __APPLE__ */ + # A[0] * B + xorq %r10, %r10 + mulxq (%rsi), %r8, %r9 + movq %r8, (%rdi) + # A[1] * B + mulxq 8(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 8(%rdi) + adoxq %rcx, %r8 + # A[2] * B + mulxq 16(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 16(%rdi) + adoxq %rcx, %r9 + # A[3] * B + mulxq 24(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + movq %r9, 24(%rdi) + adoxq %rcx, %r8 + # A[4] * B + mulxq 32(%rsi), %rax, %rcx + movq %r10, %r9 + adcxq %rax, %r8 + movq %r8, 32(%rdi) + adoxq %rcx, %r9 + # A[5] * B + mulxq 40(%rsi), %rax, %rcx + movq %r10, %r8 + adcxq %rax, %r9 + adoxq %rcx, %r8 + adcxq %r10, %r8 + movq %r9, 40(%rdi) + movq %r8, 48(%rdi) + repz retq +#ifndef __APPLE__ +.size sp_384_mul_d_avx2_6,.-sp_384_mul_d_avx2_6 +#endif /* __APPLE__ */ +#endif /* HAVE_INTEL_AVX2 */ +#endif /* WOLFSSL_SP_384 */ diff --git a/wolfssl/wolfcrypt/sp.h b/wolfssl/wolfcrypt/sp.h index a71ef9a49..e468a06fa 100644 --- a/wolfssl/wolfcrypt/sp.h +++ b/wolfssl/wolfcrypt/sp.h @@ -119,6 +119,28 @@ int sp_ecc_proj_dbl_point_256(mp_int* pX, mp_int* pY, mp_int* pZ, 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(mp_int* km, ecc_point* gm, ecc_point* rm, int map, + void* heap); +int sp_ecc_mulmod_base_384(mp_int* km, 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(mp_int* priv, ecc_point* pub, byte* out, + word32* outlen, void* heap); +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_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_is_point_384(mp_int* pX, mp_int* pY); +int sp_ecc_check_key_384(mp_int* pX, mp_int* pY, 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); + #endif /*ifdef WOLFSSL_HAVE_SP_ECC */ diff --git a/wolfssl/wolfcrypt/sp_int.h b/wolfssl/wolfcrypt/sp_int.h index fef9dd4ab..344e735e8 100644 --- a/wolfssl/wolfcrypt/sp_int.h +++ b/wolfssl/wolfcrypt/sp_int.h @@ -110,6 +110,8 @@ #if !defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_HAVE_SP_DH) #if !defined(NO_PWDBASED) && defined(WOLFSSL_SHA512) #define SP_INT_DIGITS ((512 + SP_WORD_SIZE) / SP_WORD_SIZE) + #elif defined(WOLFSSL_SP_384) + #define SP_INT_DIGITS ((384 + SP_WORD_SIZE) / SP_WORD_SIZE) #else #define SP_INT_DIGITS ((256 + SP_WORD_SIZE) / SP_WORD_SIZE) #endif From 59fb81c9500041ebdcaa4cb871f7c2bc664959db Mon Sep 17 00:00:00 2001 From: Eric Blankenhorn Date: Mon, 27 Jan 2020 21:10:47 -0600 Subject: [PATCH 057/649] Add fix --- src/ssl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 7bb58e1fd..e94bfc3ce 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -2947,7 +2947,7 @@ int wolfSSL_shutdown(WOLFSSL* ssl) /* call wolfSSL_shutdown again for bidirectional shutdown */ if (ssl->options.sentNotify && !ssl->options.closeNotify) { - ret = wolfSSL_read(ssl, &tmp, 0); + ret = wolfSSL_read(ssl, &tmp, 1); if (ret < 0) { WOLFSSL_ERROR(ssl->error); ret = WOLFSSL_FATAL_ERROR; @@ -2955,7 +2955,7 @@ int wolfSSL_shutdown(WOLFSSL* ssl) ssl->error = WOLFSSL_ERROR_SYSCALL; /* simulate OpenSSL behavior */ ret = WOLFSSL_SUCCESS; } else if ((ssl->error == WOLFSSL_ERROR_NONE) && - (ret < WOLFSSL_SUCCESS)) { + (ret > 0)) { ret = WOLFSSL_SHUTDOWN_NOT_DONE; } } From 41d3ba0efa4200b6f2302026245b9e99a4f2b607 Mon Sep 17 00:00:00 2001 From: Eric Blankenhorn Date: Mon, 17 Feb 2020 16:39:34 -0600 Subject: [PATCH 058/649] Tests and examples for bidirectional shutdown --- examples/client/client.c | 7 +++++-- examples/server/server.c | 8 ++++++-- tests/test.conf | 6 ++++++ 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/examples/client/client.c b/examples/client/client.c index de839b3e7..971306de6 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -3045,8 +3045,11 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) if (dtlsUDP == 0) { /* don't send alert after "break" command */ ret = wolfSSL_shutdown(ssl); - if (wc_shutdown && ret == WOLFSSL_SHUTDOWN_NOT_DONE) - wolfSSL_shutdown(ssl); /* bidirectional shutdown */ + while (wc_shutdown && ret == WOLFSSL_SHUTDOWN_NOT_DONE) { + ret = wolfSSL_shutdown(ssl); /* bidirectional shutdown */ + if (ret == WOLFSSL_SUCCESS) + printf("Bidirectional shutdown complete\n"); + } } #if defined(ATOMIC_USER) && !defined(WOLFSSL_AEAD_ONLY) if (atomicUser) diff --git a/examples/server/server.c b/examples/server/server.c index 7440d64df..140d21494 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -2378,9 +2378,13 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) if (dtlsUDP == 0) { ret = SSL_shutdown(ssl); - if (wc_shutdown && ret == WOLFSSL_SHUTDOWN_NOT_DONE) - SSL_shutdown(ssl); /* bidirectional shutdown */ + while (wc_shutdown && ret == WOLFSSL_SHUTDOWN_NOT_DONE) { + ret = SSL_shutdown(ssl); /* bidirectional shutdown */ + if (ret == WOLFSSL_SUCCESS) + printf("Bidirectional shutdown complete\n"); + } } + /* display collected statistics */ #ifdef WOLFSSL_STATIC_MEMORY if (wolfSSL_is_static_memory(ssl, &ssl_stats) != 1) diff --git a/tests/test.conf b/tests/test.conf index 2e67d461f..736bdf935 100644 --- a/tests/test.conf +++ b/tests/test.conf @@ -2188,3 +2188,9 @@ -v 3 -l ECDHE-RSA-AES128-SHA256 -U + +# server with bidirectional shutdown +-w + +# client with bidirectional shutdown +-w From 6f3623f220b038b19560e85c4d64df37f24d14d7 Mon Sep 17 00:00:00 2001 From: Stanislav Klima Date: Tue, 18 Feb 2020 09:59:59 +0100 Subject: [PATCH 059/649] Moved infinite loop check to the other bad func arg check. --- wolfcrypt/src/rsa.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index af1fdff73..1ed5fda78 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -1596,7 +1596,7 @@ static int RsaUnPad(const byte *pkcsBlock, unsigned int pkcsBlockLen, byte invalid = 0; #endif - if (output == NULL || pkcsBlockLen == 0) { + if (output == NULL || pkcsBlockLen == 0 || pkcsBlockLen > 0xFFFF) { return BAD_FUNC_ARG; } @@ -1624,9 +1624,6 @@ static int RsaUnPad(const byte *pkcsBlock, unsigned int pkcsBlockLen, word16 j; word16 pastSep = 0; - if (pkcsBlockLen > 0xFFFF) - return RSA_PAD_E; - /* Decrypted with private key - unpad must be constant time. */ for (i = 0, j = 2; j < pkcsBlockLen; j++) { /* Update i if not passed the separator and at separator. */ From b05cfaa601530cbea5f27db3b863ee6d89f607b9 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 18 Feb 2020 20:46:17 +0100 Subject: [PATCH 060/649] Add aes-gcm to wolfSSL_EVP_get_cipherbyname and wolfSSL_EVP_get_cipherbynid --- src/ssl.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/ssl.c b/src/ssl.c index 7bb58e1fd..797715ce3 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -3932,7 +3932,20 @@ const WOLFSSL_EVP_CIPHER *wolfSSL_EVP_get_cipherbyname(const char *name) #endif #ifdef WOLFSSL_AES_256 {"AES-256-ECB", "AES256-ECB"}, - {"AES-256-EBC", "aes256-ecb"}, + #endif + #ifdef HAVE_AESGCM + #ifdef WOLFSSL_AES_128 + {"AES-128-GCM", "aes-128-gcm"}, + {"AES-128-GCM", "id-aes128-GCM"}, + #endif + #ifdef WOLFSSL_AES_192 + {"AES-192-GCM", "aes-192-gcm"}, + {"AES-192-GCM", "id-aes192-GCM"}, + #endif + #ifdef WOLFSSL_AES_256 + {"AES-256-GCM", "aes-256-gcm"}, + {"AES-256-GCM", "id-aes256-GCM"}, + #endif #endif #endif #ifndef NO_RC4 @@ -4017,6 +4030,20 @@ const WOLFSSL_EVP_CIPHER *wolfSSL_EVP_get_cipherbynid(int id) return wolfSSL_EVP_aes_256_ecb(); #endif #endif /* HAVE_AES_ECB */ + #ifdef HAVE_AESGCM + #ifdef WOLFSSL_AES_128 + case NID_aes_128_gcm: + return wolfSSL_EVP_aes_128_gcm(); + #endif + #ifdef WOLFSSL_AES_192 + case NID_aes_192_gcm: + return wolfSSL_EVP_aes_192_gcm(); + #endif + #ifdef WOLFSSL_AES_256 + case NID_aes_256_gcm: + return wolfSSL_EVP_aes_256_gcm(); + #endif + #endif #endif #ifndef NO_DES3 From 41de1bb156ca800c5783687de309a8187fda4a72 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 14 Nov 2019 18:15:04 +0100 Subject: [PATCH 061/649] WIP --- configure.ac | 3 +- src/ssl.c | 90 ++++++++++++++++++++++++++++++++++++++ tests/api.c | 5 +++ wolfcrypt/src/dsa.c | 8 ---- wolfssl/openssl/bn.h | 2 + wolfssl/openssl/dsa.h | 20 +++++++++ wolfssl/openssl/evp.h | 3 ++ wolfssl/openssl/opensslv.h | 5 ++- wolfssl/openssl/ssl.h | 6 +++ wolfssl/ssl.h | 3 ++ wolfssl/wolfcrypt/asn.h | 4 +- wolfssl/wolfcrypt/dsa.h | 5 +++ 12 files changed, 142 insertions(+), 12 deletions(-) diff --git a/configure.ac b/configure.ac index 7ad86ed65..b606e3059 100644 --- a/configure.ac +++ b/configure.ac @@ -426,7 +426,7 @@ AC_ARG_ENABLE([mcast], # List of open source project defines using our openssl compatibility layer: -# openssh (--enable-openssh) +# openssh (--enable-openssh) WOLFSSL_OPENSSH # openvpn (--enable-openvpn) # nginix (--enable-nginx) WOLFSSL_NGINX # haproxy (--enable-haproxy) WOLFSSL_HAPROXY @@ -500,6 +500,7 @@ fi if test "$ENABLED_OPENSSH" = "yes" then ENABLED_FORTRESS="yes" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_OPENSSH" fi #Qt Support diff --git a/src/ssl.c b/src/ssl.c index 7bb58e1fd..a4cac156c 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -16553,6 +16553,15 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) return WOLFSSL_FAILURE; ret = wolfSSL_EVP_CIPHER_CTX_set_iv_length(ctx, arg); break; + case EVP_CTRL_AEAD_SET_IV_FIXED: + /* arg=-1 copies ctx->ivSz from ptr */ + if (arg == -1) { + ret = wolfSSL_EVP_CIPHER_CTX_set_iv(ctx, ptr, ctx->ivSz); + } + else { + ret = wolfSSL_EVP_CIPHER_CTX_set_iv(ctx, ptr, arg); + } + break; case EVP_CTRL_AEAD_SET_TAG: if(arg <= 0 || arg > 16 || (ptr == NULL)) return WOLFSSL_FAILURE; @@ -17125,6 +17134,26 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) return WOLFSSL_SUCCESS; } + + /* returns WOLFSSL_SUCCESS on success, otherwise returns WOLFSSL_FAILURE */ + int wolfSSL_EVP_CIPHER_CTX_set_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, byte* iv, + int ivLen) + { + WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_set_iv_length"); + if (!ctx || !iv +#ifndef NO_AES + || ivLen != AES_BLOCK_SIZE +#elif !defined(NO_DES3) + || ivLen != DES_BLOCK_SIZE +#endif + ) { + return WOLFSSL_FAILURE; + } + XMEMCPY(ctx->iv, iv, ivLen); + ctx->ivSz= ivLen; + + return WOLFSSL_SUCCESS; + } #endif /* WOLFSSL_SUCCESS on ok */ @@ -30557,6 +30586,30 @@ int wolfSSL_DSA_generate_parameters_ex(WOLFSSL_DSA* dsa, int bits, return ret; } +WOLFSSL_DSA_SIG* wolfSSL_DSA_SIG_new(void) +{ + WOLFSSL_DSA_SIG* sig; + WOLFSSL_ENTER("wolfSSL_DSA_SIG_new"); + sig = (WOLFSSL_DSA_SIG*)XMALLOC(sizeof(WOLFSSL_DSA_SIG), NULL, DYNAMIC_TYPE_OPENSSL); + if (sig) + XMEMSET(sig, 0, sizeof(WOLFSSL_DSA_SIG)); + return sig; +} + +void wolfSSL_DSA_SIG_free(WOLFSSL_DSA_SIG *sig) +{ + WOLFSSL_ENTER("wolfSSL_DSA_SIG_free"); + if (sig) { + if (sig->r) { + wolfSSL_BN_free(sig->r); + } + if (sig->s) { + wolfSSL_BN_free(sig->s); + } + XFREE(sig, NULL, DYNAMIC_TYPE_OPENSSL); + } +} + /* return WOLFSSL_SUCCESS on success, < 0 otherwise */ int wolfSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet, WOLFSSL_DSA* dsa) @@ -30621,6 +30674,43 @@ int wolfSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet, return ret; } +WOLFSSL_DSA_SIG* wolfSSL_DSA_do_sign_ex(const unsigned char* digest, + int outLen, WOLFSSL_DSA* dsa) +{ + WOLFSSL_DSA_SIG* sig = NULL; + byte sigBin[DSA_SIG_SIZE]; + + WOLFSSL_ENTER("wolfSSL_DSA_do_sign_ex"); + + if (digest == NULL || dsa == NULL || outLen != WC_SHA_DIGEST_SIZE) { + WOLFSSL_MSG("Bad function arguments"); + return NULL; + } + + if (wolfSSL_DSA_do_sign(digest, sigBin, dsa) != WOLFSSL_SUCCESS) { + return NULL; + } + + if (!(sig = wolfSSL_DSA_SIG_new())) { + goto error; + } + + if (!(sig->r = wolfSSL_BN_bin2bn(sigBin, DSA_HALF_SIZE, NULL))) { + goto error; + } + + if (!(sig->s = wolfSSL_BN_bin2bn(sigBin+DSA_HALF_SIZE, DSA_HALF_SIZE, NULL))) { + goto error; + } + + return sig; +error: + if (sig) { + wolfSSL_DSA_SIG_free(sig); + } + return NULL; +} + int wolfSSL_DSA_do_verify(const unsigned char* d, unsigned char* sig, WOLFSSL_DSA* dsa, int *dsacheck) diff --git a/tests/api.c b/tests/api.c index 3b67e66c8..b3b41bad5 100644 --- a/tests/api.c +++ b/tests/api.c @@ -20089,6 +20089,8 @@ static void test_wolfSSL_tmp_dh(void) BIO* bio; SSL* ssl; SSL_CTX* ctx; + unsigned char digest[WC_SHA_DIGEST_SIZE] = {202}; // initialize to anything + DSA_SIG* sig; printf(testingFmt, "wolfSSL_tmp_dh()"); @@ -20115,6 +20117,9 @@ static void test_wolfSSL_tmp_dh(void) dh = wolfSSL_DSA_dup_DH(dsa); AssertNotNull(dh); + AssertNotNull(sig = DSA_do_sign(digest, WC_SHA_DIGEST_SIZE, dsa)); + DSA_SIG_free(sig); + AssertIntEQ((int)SSL_CTX_set_tmp_dh(ctx, dh), WOLFSSL_SUCCESS); #ifndef NO_WOLFSSL_SERVER AssertIntEQ((int)SSL_set_tmp_dh(ssl, dh), WOLFSSL_SUCCESS); diff --git a/wolfcrypt/src/dsa.c b/wolfcrypt/src/dsa.c index b9183f8ca..4b83a571d 100644 --- a/wolfcrypt/src/dsa.c +++ b/wolfcrypt/src/dsa.c @@ -42,14 +42,6 @@ #include #endif - -enum { - DSA_HALF_SIZE = 20, /* r and s size */ - DSA_SIG_SIZE = 40 /* signature size */ -}; - - - int wc_InitDsaKey(DsaKey* key) { if (key == NULL) diff --git a/wolfssl/openssl/bn.h b/wolfssl/openssl/bn.h index 853106a7a..067d873d7 100644 --- a/wolfssl/openssl/bn.h +++ b/wolfssl/openssl/bn.h @@ -196,6 +196,8 @@ typedef WOLFSSL_BN_GENCB BN_GENCB; #define BN_mod_inverse wolfSSL_BN_mod_inverse +#define BN_set_flags(x1, x2) + #if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L #define BN_get_rfc2409_prime_768 wolfSSL_DH_768_prime #define BN_get_rfc2409_prime_1024 wolfSSL_DH_1024_prime diff --git a/wolfssl/openssl/dsa.h b/wolfssl/openssl/dsa.h index 561e0707e..9267cf479 100644 --- a/wolfssl/openssl/dsa.h +++ b/wolfssl/openssl/dsa.h @@ -31,6 +31,11 @@ extern "C" { #endif +typedef struct WOLFSSL_DSA_SIG { + WOLFSSL_BIGNUM *r; + WOLFSSL_BIGNUM *s; +} WOLFSSL_DSA_SIG; + #ifndef WOLFSSL_DSA_TYPE_DEFINED /* guard on redeclaration */ typedef struct WOLFSSL_DSA WOLFSSL_DSA; #define WOLFSSL_DSA_TYPE_DEFINED @@ -75,16 +80,31 @@ WOLFSSL_API int wolfSSL_DSA_do_verify(const unsigned char* d, unsigned char* sig, WOLFSSL_DSA* dsa, int *dsacheck); +WOLFSSL_API WOLFSSL_DSA_SIG* wolfSSL_DSA_SIG_new(void); +WOLFSSL_API void wolfSSL_DSA_SIG_free(WOLFSSL_DSA_SIG *sig); +WOLFSSL_API WOLFSSL_DSA_SIG* wolfSSL_DSA_do_sign_ex(const unsigned char* digest, + int outLen, WOLFSSL_DSA* dsa); +WOLFSSL_API int wolfSSL_DSA_do_verify_ex(const unsigned char* digest, int digest_len, + WOLFSSL_DSA_SIG* sig, WOLFSSL_DSA* dsa); + #define WOLFSSL_DSA_LOAD_PRIVATE 1 #define WOLFSSL_DSA_LOAD_PUBLIC 2 #define DSA_new wolfSSL_DSA_new #define DSA_free wolfSSL_DSA_free +#define DSA_LoadDer wolfSSL_DSA_LoadDer #define DSA_generate_key wolfSSL_DSA_generate_key #define DSA_generate_parameters wolfSSL_DSA_generate_parameters #define DSA_generate_parameters_ex wolfSSL_DSA_generate_parameters_ex +#define DSA_SIG_new wolfSSL_DSA_SIG_new +#define DSA_SIG_free wolfSSL_DSA_SIG_free +#define DSA_do_sign wolfSSL_DSA_do_sign_ex +#define DSA_do_verify wolfSSL_DSA_do_verify_ex + + +#define DSA_SIG WOLFSSL_DSA_SIG #ifdef __cplusplus } /* extern "C" */ diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index 5388d3deb..cfb9b154d 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -408,6 +408,8 @@ WOLFSSL_API int wolfSSL_EVP_CIPHER_CTX_set_key_length(WOLFSSL_EVP_CIPHER_CTX* c int keylen); WOLFSSL_API int wolfSSL_EVP_CIPHER_CTX_set_iv_length(WOLFSSL_EVP_CIPHER_CTX* ctx, int ivLen); +WOLFSSL_API int wolfSSL_EVP_CIPHER_CTX_set_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, byte* iv, + int ivLen); WOLFSSL_API int wolfSSL_EVP_Cipher(WOLFSSL_EVP_CIPHER_CTX* ctx, unsigned char* dst, unsigned char* src, unsigned int len); @@ -743,6 +745,7 @@ typedef WOLFSSL_EVP_CIPHER_CTX EVP_CIPHER_CTX; #define EVP_CTRL_GCM_SET_IVLEN EVP_CTRL_AEAD_SET_IVLEN #define EVP_CTRL_GCM_GET_TAG EVP_CTRL_AEAD_GET_TAG #define EVP_CTRL_GCM_SET_TAG EVP_CTRL_AEAD_SET_TAG +#define EVP_CTRL_GCM_SET_IV_FIXED EVP_CTRL_AEAD_SET_IV_FIXED #ifndef EVP_MAX_MD_SIZE #define EVP_MAX_MD_SIZE 64 /* sha512 */ diff --git a/wolfssl/openssl/opensslv.h b/wolfssl/openssl/opensslv.h index 884cad29d..1ec8db137 100644 --- a/wolfssl/openssl/opensslv.h +++ b/wolfssl/openssl/opensslv.h @@ -30,10 +30,11 @@ /* For Apache httpd, Use 1.1.0 compatibility */ #define OPENSSL_VERSION_NUMBER 0x10100000L #elif defined(OPENSSL_ALL) || defined(HAVE_STUNNEL) || defined(HAVE_LIGHTY) || \ - defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_QT) + defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \ + defined(WOLFSSL_OPENSSH) || defined(WOLFSSL_QT) /* version number can be increased for Lighty after compatibility for ECDH is added */ - #define OPENSSL_VERSION_NUMBER 0x10001000L + #define OPENSSL_VERSION_NUMBER 0x1000100fL #else #define OPENSSL_VERSION_NUMBER 0x0090810fL #endif diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 28a1fce22..36c7b33f2 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -1093,8 +1093,12 @@ enum { #define PEM_R_NO_START_LINE 108 #define PEM_R_PROBLEMS_GETTING_PASSWORD 109 +#define PEM_R_BAD_PASSWORD_READ 110 +#define PEM_R_BAD_DECRYPT 111 #define ERR_LIB_PEM 9 #define ERR_LIB_X509 10 +#define ERR_LIB_EVP 11 +#define ERR_LIB_ASN1 12 #if defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY) || \ defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(OPENSSL_ALL) || \ @@ -1201,6 +1205,8 @@ enum { #define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b) #define TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca9) +#define EC_METHOD_get_field_type(x) -1 + #define EVP_CIPHER_mode WOLFSSL_CIPHER_mode /* WOLFSSL_EVP_CIPHER is just the string name of the cipher */ #define EVP_CIPHER_name(x) x diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 9767e4d1f..e98c9543f 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1672,6 +1672,9 @@ enum { SSL_MAX_SSL_SESSION_ID_LENGTH = 32, EVP_R_BAD_DECRYPT = 2, + EVP_R_BN_DECODE_ERROR = 3, + EVP_R_DECODE_ERROR = 4, + EVP_R_PRIVATE_KEY_DECODE_ERROR = 5, SSL_ST_CONNECT = 0x1000, SSL_ST_ACCEPT = 0x2000, diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 017a3652c..b35a01dc4 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -220,7 +220,9 @@ enum NID_domainComponent = 0x19, /* matches ASN_DOMAIN_COMPONENT in asn.h */ NID_emailAddress = 0x30, /* emailAddress */ NID_id_on_dnsSRV = 82, /* 1.3.6.1.5.5.7.8.7 */ - NID_ms_upn = 265 /* 1.3.6.1.4.1.311.20.2.3 */ + NID_ms_upn = 265, /* 1.3.6.1.4.1.311.20.2.3 */ + + NID_X9_62_prime_field = 406 }; enum ECC_TYPES diff --git a/wolfssl/wolfcrypt/dsa.h b/wolfssl/wolfcrypt/dsa.h index bf0b104e2..acc133e5c 100644 --- a/wolfssl/wolfcrypt/dsa.h +++ b/wolfssl/wolfcrypt/dsa.h @@ -52,6 +52,11 @@ enum { DSA_PRIVATE = 1 }; +enum { + DSA_HALF_SIZE = 20, /* r and s size */ + DSA_SIG_SIZE = 40 /* signature size */ +}; + /* DSA */ typedef struct DsaKey { mp_int p, q, g, y, x; From b5c52d7c7035174bf799be74a2d5d11c80191bf7 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 19 Nov 2019 15:05:49 +0100 Subject: [PATCH 062/649] openssh WIP and some light refactoring --- configure.ac | 4 +- src/ssl.c | 381 +++++++++++++++++++++++++---------- tests/api.c | 59 +++++- tests/unit.h | 10 +- wolfssl/openssl/rsa.h | 14 ++ wolfssl/openssl/ssl.h | 1 + wolfssl/ssl.h | 8 +- wolfssl/wolfcrypt/settings.h | 3 + 8 files changed, 354 insertions(+), 126 deletions(-) diff --git a/configure.ac b/configure.ac index b606e3059..30280d922 100644 --- a/configure.ac +++ b/configure.ac @@ -500,7 +500,7 @@ fi if test "$ENABLED_OPENSSH" = "yes" then ENABLED_FORTRESS="yes" - AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_OPENSSH" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_OPENSSH -DHAVE_EX_DATA" fi #Qt Support @@ -1483,7 +1483,7 @@ then ENABLED_DSA="yes" fi -if test "$ENABLED_DSA" = "no" +if test "$ENABLED_DSA" = "no" && test "$ENABLED_OPENSSH" = "no" then AM_CFLAGS="$AM_CFLAGS -DNO_DSA" fi diff --git a/src/ssl.c b/src/ssl.c index a4cac156c..47af9db11 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -25374,8 +25374,8 @@ void* wolfSSL_X509_STORE_CTX_get_ex_data(WOLFSSL_X509_STORE_CTX* ctx, int idx) { WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_ex_data"); #if defined(HAVE_EX_DATA) || defined(FORTRESS) - if (ctx != NULL && idx < MAX_EX_DATA && idx >= 0) { - return ctx->ex_data[idx]; + if (ctx != NULL) { + return wolfSSL_CRYPTO_get_ex_data(ctx->ex_data, idx); } #else (void)ctx; @@ -25392,10 +25392,9 @@ int wolfSSL_X509_STORE_CTX_set_ex_data(WOLFSSL_X509_STORE_CTX* ctx, int idx, { WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_set_ex_data"); #if defined(HAVE_EX_DATA) || defined(FORTRESS) - if (ctx != NULL && idx < MAX_EX_DATA) + if (ctx != NULL) { - ctx->ex_data[idx] = data; - return WOLFSSL_SUCCESS; + return wolfSSL_CRYPTO_set_ex_data(ctx->ex_data, idx, data); } #else (void)ctx; @@ -30682,7 +30681,7 @@ WOLFSSL_DSA_SIG* wolfSSL_DSA_do_sign_ex(const unsigned char* digest, WOLFSSL_ENTER("wolfSSL_DSA_do_sign_ex"); - if (digest == NULL || dsa == NULL || outLen != WC_SHA_DIGEST_SIZE) { + if (!digest || !dsa || outLen != WC_SHA_DIGEST_SIZE) { WOLFSSL_MSG("Bad function arguments"); return NULL; } @@ -30699,7 +30698,7 @@ WOLFSSL_DSA_SIG* wolfSSL_DSA_do_sign_ex(const unsigned char* digest, goto error; } - if (!(sig->s = wolfSSL_BN_bin2bn(sigBin+DSA_HALF_SIZE, DSA_HALF_SIZE, NULL))) { + if (!(sig->s = wolfSSL_BN_bin2bn(sigBin + DSA_HALF_SIZE, DSA_HALF_SIZE, NULL))) { goto error; } @@ -30741,6 +30740,60 @@ int wolfSSL_DSA_do_verify(const unsigned char* d, unsigned char* sig, return WOLFSSL_SUCCESS; } + +int wolfSSL_DSA_do_verify_ex(const unsigned char* digest, int digest_len, + WOLFSSL_DSA_SIG* sig, WOLFSSL_DSA* dsa) +{ + int dsacheck, sz; + byte sigBin[DSA_SIG_SIZE]; + byte* sigBinPtr = sigBin; + + WOLFSSL_ENTER("wolfSSL_DSA_do_verify_ex"); + + if (!digest || !sig || !dsa || digest_len != WC_SHA_DIGEST_SIZE) { + WOLFSSL_MSG("Bad function arguments"); + return WOLFSSL_FAILURE; + } + + if (!sig->r || !sig->s) { + WOLFSSL_MSG("No signature found in DSA_SIG"); + return WOLFSSL_FAILURE; + } + + /* front pad with zeros */ + if (!(sz = wolfSSL_BN_num_bytes(sig->r))) { + return WOLFSSL_FAILURE; + } + while (sz++ < DSA_HALF_SIZE) { + *sigBinPtr++ = 0; + } + + if (wolfSSL_BN_bn2bin(sig->r, sigBinPtr) == WOLFSSL_FATAL_ERROR) { + return WOLFSSL_FAILURE; + } + + /* Move to s */ + sigBinPtr = sigBin + DSA_HALF_SIZE; + + /* front pad with zeros */ + if (!(sz = wolfSSL_BN_num_bytes(sig->s))) { + return WOLFSSL_FAILURE; + } + while (sz++ < DSA_HALF_SIZE) { + *sigBinPtr++ = 0; + } + + if (wolfSSL_BN_bn2bin(sig->s, sigBinPtr) == WOLFSSL_FATAL_ERROR) { + return WOLFSSL_FAILURE; + } + + if (wolfSSL_DSA_do_verify(digest, sigBin, dsa, &dsacheck) != WOLFSSL_SUCCESS || + dsacheck != 1) { + return WOLFSSL_FAILURE; + } + + return WOLFSSL_SUCCESS; +} #endif /* NO_DSA */ @@ -31953,6 +32006,51 @@ int wolfSSL_EVP_PKEY_assign(WOLFSSL_EVP_PKEY *pkey, int type, void *key) } #endif /* WOLFSSL_QT || OPENSSL_ALL */ +/* try and populate public pkey_sz and pkey.ptr */ +static void ECC_populate_EVP_PKEY(EVP_PKEY* pkey, ecc_key* ecc) +{ + int ret; + if (!pkey || !ecc) + return; + if ((ret = wc_EccPublicKeyDerSize(ecc, 1)) > 0) { + int derSz = ret; + char* derBuf = (char*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (derBuf) { + ret = wc_EccPublicKeyToDer(ecc, (byte*)derBuf, derSz, 1); + if (ret >= 0) { + if (pkey->pkey.ptr) { + XFREE(pkey->pkey.ptr, NULL, DYNAMIC_TYPE_OPENSSL); + } + pkey->pkey_sz = ret; + pkey->pkey.ptr = derBuf; + } + else { /* failure - okay to ignore */ + XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + derBuf = NULL; + } + } + } +} + +WOLFSSL_API int wolfSSL_EVP_PKEY_set1_EC_KEY(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_EC_KEY *key) +{ +#ifdef HAVE_ECC + if((pkey == NULL) || (key ==NULL))return WOLFSSL_FAILURE; + WOLFSSL_ENTER("wolfSSL_EVP_PKEY_set1_EC_KEY"); + if (pkey->rsa != NULL && pkey->ownRsa == 1) { + wolfSSL_RSA_free(pkey->rsa); + } + pkey->ecc = key; + pkey->ownEcc = 0; /* pkey does not own EC key */ + pkey->type = EVP_PKEY_EC; + ECC_populate_EVP_PKEY(pkey, (ecc_key*)key->internal); + return WOLFSSL_SUCCESS; +#else + (void)pkey; + (void)key; + return WOLFSSL_FAILURE; +#endif +} void* wolfSSL_EVP_X_STATE(const WOLFSSL_EVP_CIPHER_CTX* ctx) { @@ -32374,6 +32472,56 @@ static int EncryptDerKey(byte *der, int *derSz, const EVP_CIPHER* cipher, } #endif /* WOLFSSL_KEY_GEN || WOLFSSL_PEM_TO_DER */ +#ifndef NO_RSA +static int wolfSSL_RSA_To_Der(WOLFSSL_RSA* rsa, byte** outBuf, int publicKey) +{ + int derMax = 0; + int derSz = 0; + byte* derBuf; + + WOLFSSL_ENTER("wc_RsaKeyToDer"); + + if (!rsa || !outBuf || (publicKey != 0 && publicKey != 1)) { + WOLFSSL_LEAVE("wc_RsaKeyToDer", BAD_FUNC_ARG); + return BAD_FUNC_ARG; + } + /* 5 > size of n, d, p, q, d%(p-1), d(q-1), 1/q%p, e + ASN.1 additional + * informations + */ + derMax = 5 * wolfSSL_RSA_size(rsa) + AES_BLOCK_SIZE; + derBuf = (byte*)XMALLOC(derMax, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (derBuf == NULL) { + WOLFSSL_MSG("malloc failed"); + WOLFSSL_LEAVE("wc_RsaKeyToDer", MEMORY_ERROR); + return MEMORY_ERROR; + } + /* Key to DER */ + if (publicKey) { + derSz = wc_RsaKeyToPublicDer((RsaKey*)rsa->internal, derBuf, derMax); + if (derSz < 0) { + WOLFSSL_MSG("wc_RsaKeyToPublicDer failed"); + XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } + else { + *outBuf = derBuf; + } + } + else { + derSz = wc_RsaKeyToDer((RsaKey*)rsa->internal, derBuf, derMax); + if (derSz < 0) { + WOLFSSL_MSG("wc_RsaKeyToDer failed"); + XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } + else { + *outBuf = derBuf; + } + } + + WOLFSSL_LEAVE("wc_RsaKeyToDer", derSz); + return derSz; +} +#endif + #if defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_CERT_GEN) #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)) && !defined(NO_RSA) @@ -32414,19 +32562,11 @@ int wolfSSL_PEM_write_bio_RSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_RSA* key, #ifdef WOLFSSL_KEY_GEN /* similar to how wolfSSL_PEM_write_mem_RSAPrivateKey finds DER of key */ { - int derMax; int derSz; byte* derBuf; - /* 5 > size of n, d, p, q, d%(p-1), d(q-1), 1/q%p, e + ASN.1 additional - * information - */ - derMax = 5 * wolfSSL_RSA_size(key) + (2 * AES_BLOCK_SIZE); - - derBuf = (byte*)XMALLOC(derMax, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); - if (derBuf == NULL) { - WOLFSSL_MSG("malloc failed"); - wolfSSL_EVP_PKEY_free(pkey); + if ((derSz = wolfSSL_RSA_To_Der(key, &derBuf, 0)) < 0) { + WOLFSSL_MSG("wolfSSL_RSA_To_Der failed"); return WOLFSSL_FAILURE; } @@ -32436,7 +32576,7 @@ int wolfSSL_PEM_write_bio_RSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_RSA* key, WOLFSSL_MSG("wc_RsaKeyToDer failed"); XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); wolfSSL_EVP_PKEY_free(pkey); - return WOLFSSL_FAILURE; + return SSL_FAILURE; } pkey->pkey.ptr = (char*)XMALLOC(derSz, bio->heap, @@ -32467,7 +32607,7 @@ int wolfSSL_PEM_write_bio_RSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_RSA* key, */ int wolfSSL_PEM_write_bio_RSA_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_RSA* rsa) { - int ret = 0, derMax = 0, derSz = 0; + int ret = 0, derSz = 0; byte *derBuf = NULL; WOLFSSL_EVP_PKEY* pkey = NULL; @@ -32489,24 +32629,8 @@ int wolfSSL_PEM_write_bio_RSA_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_RSA* rsa) pkey->rsa = rsa; pkey->ownRsa = 0; - /* 5 > size of n, d, p, q, d%(p-1), d(q-1), 1/q%p, e + ASN.1 additional - * information - */ - derMax = 5 * wolfSSL_RSA_size(rsa) + AES_BLOCK_SIZE; - - derBuf = (byte*)XMALLOC(derMax, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); - if (derBuf == NULL) { - WOLFSSL_MSG("malloc failed"); - wolfSSL_EVP_PKEY_free(pkey); - return WOLFSSL_FAILURE; - } - - /* Key to DER */ - derSz = wc_RsaKeyToPublicDer((RsaKey*)rsa->internal, derBuf, derMax); - if (derSz < 0) { - WOLFSSL_MSG("wc_RsaKeyToPublicDer failed"); - XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); - wolfSSL_EVP_PKEY_free(pkey); + if ((derSz = wolfSSL_RSA_To_Der(rsa, &derBuf, 1)) < 0) { + WOLFSSL_MSG("wolfSSL_RSA_To_Der failed"); return WOLFSSL_FAILURE; } @@ -32704,7 +32828,7 @@ int wolfSSL_PEM_write_mem_RSAPrivateKey(RSA* rsa, const EVP_CIPHER* cipher, unsigned char **pem, int *plen) { byte *derBuf, *tmp, *cipherInfo = NULL; - int der_max_len = 0, derSz = 0; + int derSz = 0; const int type = PRIVATEKEY_TYPE; const char* header = NULL; const char* footer = NULL; @@ -32728,22 +32852,8 @@ int wolfSSL_PEM_write_mem_RSAPrivateKey(RSA* rsa, const EVP_CIPHER* cipher, } } - /* 5 > size of n, d, p, q, d%(p-1), d(q-1), 1/q%p, e + ASN.1 additional - * information - */ - der_max_len = 5 * wolfSSL_RSA_size(rsa) + AES_BLOCK_SIZE; - - derBuf = (byte*)XMALLOC(der_max_len, NULL, DYNAMIC_TYPE_DER); - if (derBuf == NULL) { - WOLFSSL_MSG("malloc failed"); - return WOLFSSL_FAILURE; - } - - /* Key to DER */ - derSz = wc_RsaKeyToDer((RsaKey*)rsa->internal, derBuf, der_max_len); - if (derSz < 0) { - WOLFSSL_MSG("wc_RsaKeyToDer failed"); - XFREE(derBuf, NULL, DYNAMIC_TYPE_DER); + if ((derSz = wolfSSL_RSA_To_Der(rsa, &derBuf, 0)) < 0) { + WOLFSSL_MSG("wolfSSL_RSA_To_Der failed"); return WOLFSSL_FAILURE; } @@ -35991,7 +36101,6 @@ int wolfSSL_i2d_RSAPrivateKey(WOLFSSL_RSA *rsa, unsigned char **pp) { #if defined(WOLFSSL_KEY_GEN) byte* der = NULL; - int derMax; int ret; int i; @@ -36010,25 +36119,11 @@ int wolfSSL_i2d_RSAPrivateKey(WOLFSSL_RSA *rsa, unsigned char **pp) } } - /* 5 > size of n, d, p, q, d%(p-1), d(q-1), 1/q%p, e + ASN.1 additional - * information - */ - derMax = 5 * wolfSSL_RSA_size(rsa) + AES_BLOCK_SIZE; - - der = (byte*)XMALLOC(derMax, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (der == NULL) { - WOLFSSL_MSG("Malloc failed"); + if ((ret = wolfSSL_RSA_To_Der(rsa, &der, 0)) < 0) { + WOLFSSL_MSG("wolfSSL_RSA_To_Der failed"); return WOLFSSL_FAILURE; } - /* RSA key to DER */ - if ((ret = wc_RsaKeyToDer((RsaKey *)rsa->internal, der, derMax)) < 0) { - WOLFSSL_MSG("wc_RsaKeyToDer() failed"); - XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); - der = NULL; - return ret; - } - if (pp != NULL) { if (*pp == NULL) { /* create buffer and return it */ @@ -36206,6 +36301,11 @@ const WOLFSSL_RSA_METHOD* wolfSSL_RSA_get_method(const WOLFSSL_RSA *rsa) return rsa->meth; } +const WOLFSSL_RSA_METHOD* wolfSSL_RSA_get_default_method(void) +{ + return wolfSSL_RSA_meth_new("wolfSSL RSA", 0); +} + int wolfSSL_RSA_flags(const WOLFSSL_RSA *r) { if (r && r->meth) { @@ -36222,6 +36322,68 @@ void wolfSSL_RSA_set_flags(WOLFSSL_RSA *r, int flags) } } +WOLFSSL_RSA* wolfSSL_RSAPublicKey_dup(WOLFSSL_RSA *rsa) +{ + int derSz = 0; + byte *derBuf = NULL; + WOLFSSL_RSA* local; + + WOLFSSL_ENTER("wolfSSL_RSAPublicKey_dup"); + + if (!rsa) { + return NULL; + } + + local = wolfSSL_RSA_new(); + if (local == NULL) { + WOLFSSL_MSG("Error creating a new WOLFSSL_RSA structure"); + return NULL; + } + + if ((derSz = wolfSSL_RSA_To_Der(rsa, &derBuf, 1)) < 0) { + WOLFSSL_MSG("wolfSSL_RSA_To_Der failed"); + return NULL; + } + + if (wolfSSL_RSA_LoadDer_ex(local, + derBuf, derSz, + WOLFSSL_RSA_LOAD_PUBLIC) != SSL_SUCCESS) { + wolfSSL_RSA_free(local); + local = NULL; + } + XFREE(derBuf, NULL, DYNAMIC_TYPE_ASN1); + return local; +} + +void* wolfSSL_RSA_get_ex_data(const WOLFSSL_RSA *rsa, int idx) +{ + WOLFSSL_ENTER("wolfSSL_RSA_get_ex_data"); + #ifdef HAVE_EX_DATA + if(rsa) { + return wolfSSL_CRYPTO_get_ex_data(rsa->ex_data, idx); + } + #else + (void)rsa; + (void)idx; + #endif + return NULL; +} + +int wolfSSL_RSA_set_ex_data(WOLFSSL_RSA *rsa, int idx, void *data) +{ + WOLFSSL_ENTER("wolfSSL_RSA_set_ex_data"); + #ifdef HAVE_EX_DATA + if(rsa) { + return wolfSSL_CRYPTO_set_ex_data(rsa->ex_data, idx, data); + } + #else + (void)rsa; + (void)idx; + (void)data; + #endif + return WOLFSSL_FAILURE; +} + int wolfSSL_RSA_set0_key(WOLFSSL_RSA *r, WOLFSSL_BIGNUM *n, WOLFSSL_BIGNUM *e, WOLFSSL_BIGNUM *d) { @@ -40361,8 +40523,8 @@ void* wolfSSL_CTX_get_ex_data(const WOLFSSL_CTX* ctx, int idx) { WOLFSSL_ENTER("wolfSSL_CTX_get_ex_data"); #ifdef HAVE_EX_DATA - if(ctx != NULL && idx < MAX_EX_DATA && idx >= 0) { - return ctx->ex_data[idx]; + if(ctx != NULL) { + return wolfSSL_CRYPTO_get_ex_data(ctx->ex_data, idx); } #else (void)ctx; @@ -40386,6 +40548,24 @@ int wolfSSL_CTX_get_ex_new_index(long idx, void* arg, void* a, void* b, return ctx_idx++; } +void* wolfSSL_CRYPTO_get_ex_data(void * const* ex_data, int idx) +{ + WOLFSSL_ENTER("wolfSSL_CTX_get_ex_data"); + if(ex_data && idx < MAX_EX_DATA && idx >= 0) { + return ex_data[idx]; + } + return NULL; +} + +int wolfSSL_CRYPTO_set_ex_data(void** ex_data, int idx, void *data) +{ + WOLFSSL_ENTER("wolfSSL_CRYPTO_set_ex_data"); + if (ex_data && idx < MAX_EX_DATA && idx >= 0) { + ex_data[idx] = data; + return WOLFSSL_SUCCESS; + } + return WOLFSSL_FAILURE; +} /* Return the index that can be used for the WOLFSSL structure to store * application data. @@ -40413,10 +40593,9 @@ int wolfSSL_CTX_set_ex_data(WOLFSSL_CTX* ctx, int idx, void* data) { WOLFSSL_ENTER("wolfSSL_CTX_set_ex_data"); #ifdef HAVE_EX_DATA - if (ctx != NULL && idx < MAX_EX_DATA) + if (ctx != NULL) { - ctx->ex_data[idx] = data; - return WOLFSSL_SUCCESS; + return wolfSSL_CRYPTO_set_ex_data(ctx->ex_data, idx, data); } #else (void)ctx; @@ -40458,10 +40637,9 @@ int wolfSSL_set_ex_data(WOLFSSL* ssl, int idx, void* data) { WOLFSSL_ENTER("wolfSSL_set_ex_data"); #if defined(HAVE_EX_DATA) || defined(FORTRESS) - if (ssl != NULL && idx < MAX_EX_DATA) + if (ssl != NULL) { - ssl->ex_data[idx] = data; - return WOLFSSL_SUCCESS; + return wolfSSL_CRYPTO_set_ex_data(ssl->ex_data, idx, data); } #else WOLFSSL_MSG("HAVE_EX_DATA macro is not defined"); @@ -40478,8 +40656,9 @@ void* wolfSSL_get_ex_data(const WOLFSSL* ssl, int idx) { WOLFSSL_ENTER("wolfSSL_get_ex_data"); #if defined(HAVE_EX_DATA) || defined(FORTRESS) - if (ssl != NULL && idx < MAX_EX_DATA && idx >= 0) - return ssl->ex_data[idx]; + if (ssl != NULL) { + return wolfSSL_CRYPTO_get_ex_data(ssl->ex_data, idx); + } #else WOLFSSL_MSG("HAVE_EX_DATA macro is not defined"); (void)ssl; @@ -41923,6 +42102,7 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey_EVP(WOLFSSL_EVP_PKEY** out, wolfSSL_EVP_PKEY_free(pkey); return NULL; } + pkey->rsa->pkey = pkey; if (wolfSSL_RSA_LoadDer_ex(pkey->rsa, (const unsigned char*)pkey->pkey.ptr, @@ -41994,9 +42174,8 @@ int wolfSSL_SESSION_set_ex_data(WOLFSSL_SESSION* session, int idx, void* data) { WOLFSSL_ENTER("wolfSSL_SESSION_set_ex_data"); #ifdef HAVE_EX_DATA - if(session != NULL && idx < MAX_EX_DATA) { - session->ex_data[idx] = data; - return WOLFSSL_SUCCESS; + if(session != NULL) { + return wolfSSL_CRYPTO_set_ex_data(session->ex_data, idx, data); } #else (void)session; @@ -42029,8 +42208,9 @@ void* wolfSSL_SESSION_get_ex_data(const WOLFSSL_SESSION* session, int idx) { WOLFSSL_ENTER("wolfSSL_SESSION_get_ex_data"); #ifdef HAVE_EX_DATA - if (session != NULL && idx < MAX_EX_DATA && idx >= 0) - return session->ex_data[idx]; + if (session != NULL) { + return wolfSSL_CRYPTO_get_ex_data(session->ex_data, idx); + } #else (void)session; (void)idx; @@ -43799,8 +43979,8 @@ void *wolfSSL_X509_get_ex_data(X509 *x509, int idx) { WOLFSSL_ENTER("wolfSSL_X509_get_ex_data"); #ifdef HAVE_EX_DATA - if (x509 != NULL && idx < MAX_EX_DATA && idx >= 0) { - return x509->ex_data[idx]; + if (x509 != NULL) { + return wolfSSL_CRYPTO_get_ex_data(x509->ex_data, idx); } #else (void)x509; @@ -43813,10 +43993,9 @@ int wolfSSL_X509_set_ex_data(X509 *x509, int idx, void *data) { WOLFSSL_ENTER("wolfSSL_X509_set_ex_data"); #ifdef HAVE_EX_DATA - if (x509 != NULL && idx < MAX_EX_DATA) + if (x509 != NULL) { - x509->ex_data[idx] = data; - return WOLFSSL_SUCCESS; + return wolfSSL_CRYPTO_set_ex_data(x509->ex_data, idx, data); } #else (void)x509; @@ -47450,25 +47629,7 @@ int wolfSSL_EVP_PKEY_assign_EC_KEY(EVP_PKEY* pkey, WOLFSSL_EC_KEY* key) pkey->ownEcc = 1; /* try and populate public pkey_sz and pkey.ptr */ - if (key->internal) { - ecc_key* ecc = (ecc_key*)key->internal; - int ret = wc_EccPublicKeyDerSize(ecc, 1); - if (ret > 0) { - int derSz = ret; - char* derBuf = (char*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (derBuf) { - ret = wc_EccPublicKeyToDer(ecc, (byte*)derBuf, derSz, 1); - if (ret >= 0) { - pkey->pkey_sz = ret; - pkey->pkey.ptr = derBuf; - } - else { /* failure - okay to ignore */ - XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER); - derBuf = NULL; - } - } - } - } + ECC_populate_EVP_PKEY(pkey, (ecc_key*)key->internal); return WOLFSSL_SUCCESS; } diff --git a/tests/api.c b/tests/api.c index b3b41bad5..ef2eac84f 100644 --- a/tests/api.c +++ b/tests/api.c @@ -19910,6 +19910,7 @@ static void test_wolfSSL_PEM_RSAPrivateKey(void) #if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \ !defined(NO_FILESYSTEM) && !defined(NO_RSA) RSA* rsa = NULL; + RSA* rsa_dup = NULL; BIO* bio = NULL; printf(testingFmt, "wolfSSL_PEM_RSAPrivateKey()"); @@ -19918,8 +19919,12 @@ static void test_wolfSSL_PEM_RSAPrivateKey(void) AssertNotNull((rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL))); AssertIntEQ(RSA_size(rsa), 256); + AssertNotNull(rsa_dup = RSAPublicKey_dup(rsa)); + AssertPtrNE(rsa_dup, rsa); + BIO_free(bio); RSA_free(rsa); + RSA_free(rsa_dup); #ifdef HAVE_ECC AssertNotNull(bio = BIO_new_file(eccKeyFile, "rb")); @@ -20075,6 +20080,54 @@ static void test_wolfSSL_PEM_PUBKEY(void) #endif } +static void test_DSA_do_sign_verify(void) +{ +#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && \ + !defined(NO_DSA) + unsigned char digest[WC_SHA_DIGEST_SIZE]; + DSA_SIG* sig; + DSA* dsa; + word32 bytes; + byte sigBin[DSA_SIG_SIZE]; + int dsacheck; + +#ifdef USE_CERT_BUFFERS_1024 + byte tmp[ONEK_BUF]; + XMEMSET(tmp, 0, sizeof(tmp)); + XMEMCPY(tmp, dsa_key_der_1024, sizeof_dsa_key_der_1024); + bytes = sizeof_dsa_key_der_1024; +#elif defined(USE_CERT_BUFFERS_2048) + byte tmp[TWOK_BUF]; + XMEMSET(tmp, 0, sizeof(tmp)); + XMEMCPY(tmp, dsa_key_der_2048, sizeof_dsa_key_der_2048); + bytes = sizeof_dsa_key_der_2048; +#else + byte tmp[TWOK_BUF]; + XMEMSET(tmp, 0, sizeof(tmp)); + XFILE fp = XFOPEN("./certs/dsa2048.der", "rb"); + if (fp == XBADFILE) { + return WOLFSSL_BAD_FILE; + } + bytes = (word32) XFREAD(tmp, 1, sizeof(tmp), fp); + XFCLOSE(fp); +#endif /* END USE_CERT_BUFFERS_1024 */ + + printf(testingFmt, "DSA_do_sign_verify()"); + XMEMSET(digest, 202, sizeof(digest)); + + AssertNotNull(dsa = DSA_new()); + AssertIntEQ(DSA_LoadDer(dsa, tmp, bytes), 1); + + AssertIntEQ(wolfSSL_DSA_do_sign(digest, sigBin, dsa), 1); + AssertIntEQ(wolfSSL_DSA_do_verify(digest, sigBin, dsa, &dsacheck), 1); + + AssertNotNull(sig = DSA_do_sign(digest, WC_SHA_DIGEST_SIZE, dsa)); + AssertIntEQ(DSA_do_verify(digest, WC_SHA_DIGEST_SIZE, sig, dsa), 1); + + DSA_SIG_free(sig); + DSA_free(dsa); +#endif +} static void test_wolfSSL_tmp_dh(void) { @@ -20089,8 +20142,6 @@ static void test_wolfSSL_tmp_dh(void) BIO* bio; SSL* ssl; SSL_CTX* ctx; - unsigned char digest[WC_SHA_DIGEST_SIZE] = {202}; // initialize to anything - DSA_SIG* sig; printf(testingFmt, "wolfSSL_tmp_dh()"); @@ -20117,9 +20168,6 @@ static void test_wolfSSL_tmp_dh(void) dh = wolfSSL_DSA_dup_DH(dsa); AssertNotNull(dh); - AssertNotNull(sig = DSA_do_sign(digest, WC_SHA_DIGEST_SIZE, dsa)); - DSA_SIG_free(sig); - AssertIntEQ((int)SSL_CTX_set_tmp_dh(ctx, dh), WOLFSSL_SUCCESS); #ifndef NO_WOLFSSL_SERVER AssertIntEQ((int)SSL_set_tmp_dh(ssl, dh), WOLFSSL_SUCCESS); @@ -30295,6 +30343,7 @@ void ApiTest(void) test_wolfSSL_PEM_bio_ECKey(); test_wolfSSL_PEM_RSAPrivateKey(); test_wolfSSL_PEM_PUBKEY(); + test_DSA_do_sign_verify(); test_wolfSSL_tmp_dh(); test_wolfSSL_ctrl(); test_wolfSSL_EVP_MD_size(); diff --git a/tests/unit.h b/tests/unit.h index e7e7687cc..67f49f5f9 100644 --- a/tests/unit.h +++ b/tests/unit.h @@ -96,11 +96,11 @@ } while(0) #define AssertPtrEq(x, y) AssertPtr(x, y, ==, !=) -#define AssertPtrNE(x, y) AssertInt(x, y, !=, ==) -#define AssertPtrGT(x, y) AssertInt(x, y, >, <=) -#define AssertPtrLT(x, y) AssertInt(x, y, <, >=) -#define AssertPtrGE(x, y) AssertInt(x, y, >=, <) -#define AssertPtrLE(x, y) AssertInt(x, y, <=, >) +#define AssertPtrNE(x, y) AssertPtr(x, y, !=, ==) +#define AssertPtrGT(x, y) AssertPtr(x, y, >, <=) +#define AssertPtrLT(x, y) AssertPtr(x, y, <, >=) +#define AssertPtrGE(x, y) AssertPtr(x, y, >=, <) +#define AssertPtrLE(x, y) AssertPtr(x, y, <=, >) void ApiTest(void); diff --git a/wolfssl/openssl/rsa.h b/wolfssl/openssl/rsa.h index 995c16f65..70c2efd5c 100644 --- a/wolfssl/openssl/rsa.h +++ b/wolfssl/openssl/rsa.h @@ -81,6 +81,9 @@ struct WOLFSSL_RSA { #if defined(OPENSSL_EXTRA) WOLFSSL_RSA_METHOD* meth; #endif +#if defined(HAVE_EX_DATA) + void* ex_data[MAX_EX_DATA]; /* external data */ +#endif }; WOLFSSL_API WOLFSSL_RSA* wolfSSL_RSA_new(void); @@ -118,6 +121,8 @@ WOLFSSL_API void wolfSSL_RSA_meth_free(WOLFSSL_RSA_METHOD *meth); WOLFSSL_API int wolfSSL_RSA_meth_set(WOLFSSL_RSA_METHOD *rsa, void* p); WOLFSSL_API int wolfSSL_RSA_set_method(WOLFSSL_RSA *rsa, WOLFSSL_RSA_METHOD *meth); WOLFSSL_API const WOLFSSL_RSA_METHOD* wolfSSL_RSA_get_method(const WOLFSSL_RSA *rsa); +WOLFSSL_API const WOLFSSL_RSA_METHOD* wolfSSL_RSA_get_default_method(void); + WOLFSSL_API void wolfSSL_RSA_get0_key(const WOLFSSL_RSA *r, const WOLFSSL_BIGNUM **n, const WOLFSSL_BIGNUM **e, const WOLFSSL_BIGNUM **d); WOLFSSL_API int wolfSSL_RSA_set0_key(WOLFSSL_RSA *r, WOLFSSL_BIGNUM *n, WOLFSSL_BIGNUM *e, @@ -125,6 +130,12 @@ WOLFSSL_API int wolfSSL_RSA_set0_key(WOLFSSL_RSA *r, WOLFSSL_BIGNUM *n, WOLFSSL_ WOLFSSL_API int wolfSSL_RSA_flags(const WOLFSSL_RSA *r); WOLFSSL_API void wolfSSL_RSA_set_flags(WOLFSSL_RSA *r, int flags); +WOLFSSL_API WOLFSSL_RSA* wolfSSL_RSAPublicKey_dup(WOLFSSL_RSA *rsa); + +WOLFSSL_API void* wolfSSL_RSA_get_ex_data(const WOLFSSL_RSA *rsa, int idx); +WOLFSSL_API int wolfSSL_RSA_set_ex_data(WOLFSSL_RSA *rsa, int idx, void *data); + + #define WOLFSSL_RSA_LOAD_PRIVATE 1 #define WOLFSSL_RSA_LOAD_PUBLIC 2 #define WOLFSSL_RSA_F4 0x10001L @@ -154,6 +165,7 @@ WOLFSSL_API void wolfSSL_RSA_set_flags(WOLFSSL_RSA *r, int flags); #define RSA_meth_set_init wolfSSL_RSA_meth_set #define RSA_meth_set_finish wolfSSL_RSA_meth_set #define RSA_meth_set0_app_data wolfSSL_RSA_meth_set +#define RSA_get_default_method wolfSSL_RSA_get_default_method #define RSA_get_method wolfSSL_RSA_get_method #define RSA_set_method wolfSSL_RSA_set_method #define RSA_get0_key wolfSSL_RSA_get0_key @@ -161,6 +173,8 @@ WOLFSSL_API void wolfSSL_RSA_set_flags(WOLFSSL_RSA *r, int flags); #define RSA_flags wolfSSL_RSA_flags #define RSA_set_flags wolfSSL_RSA_set_flags +#define RSAPublicKey_dup wolfSSL_RSAPublicKey_dup + #define RSA_get0_key wolfSSL_RSA_get0_key #define RSA_F4 WOLFSSL_RSA_F4 diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 36c7b33f2..099db31c4 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -626,6 +626,7 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define SSL_COMP_add_compression_method wolfSSL_COMP_add_compression_method #define SSL_get_ex_new_index wolfSSL_get_ex_new_index +#define RSA_get_ex_new_index wolfSSL_get_ex_new_index #define ASN1_BIT_STRING_new wolfSSL_ASN1_BIT_STRING_new #define ASN1_BIT_STRING_free wolfSSL_ASN1_BIT_STRING_free diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index e98c9543f..3f2f00b27 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -217,10 +217,6 @@ struct WOLFSSL_ASN1_STRING { #define WOLFSSL_MAX_SNAME 40 -#if defined(HAVE_EX_DATA) || defined(FORTRESS) - #define MAX_EX_DATA 5 /* allow for five items of ex_data */ -#endif - #define WOLFSSL_ASN1_DYNAMIC 0x1 #define WOLFSSL_ASN1_DYNAMIC_DATA 0x2 @@ -2024,6 +2020,9 @@ WOLFSSL_API WOLFSSL_ASN1_TIME *wolfSSL_ASN1_TIME_set(WOLFSSL_ASN1_TIME *s, time_ WOLFSSL_API int wolfSSL_sk_num(WOLFSSL_STACK* sk); WOLFSSL_API void* wolfSSL_sk_value(WOLFSSL_STACK* sk, int i); +WOLFSSL_API void* wolfSSL_CRYPTO_get_ex_data(void * const* ex_data, int idx); +WOLFSSL_API int wolfSSL_CRYPTO_set_ex_data(void** ex_data, int idx, void *data); + /* stunnel 4.28 needs */ WOLFSSL_API void* wolfSSL_CTX_get_ex_data(const WOLFSSL_CTX*, int); WOLFSSL_API int wolfSSL_CTX_set_ex_data(WOLFSSL_CTX*, int, void*); @@ -2042,6 +2041,7 @@ WOLFSSL_API long wolfSSL_SESSION_get_timeout(const WOLFSSL_SESSION*); WOLFSSL_API long wolfSSL_SESSION_get_time(const WOLFSSL_SESSION*); WOLFSSL_API int wolfSSL_CTX_get_ex_new_index(long, void*, void*, void*, void*); + /* extra ends */ diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 39472abdc..d7a612bff 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -2109,6 +2109,9 @@ extern void uITRON4_free(void *p) ; #define WOLFSSL_BASE64_DECODE #endif +#if defined(HAVE_EX_DATA) || defined(FORTRESS) + #define MAX_EX_DATA 5 /* allow for five items of ex_data */ +#endif #ifdef __cplusplus } /* extern "C" */ From 89e35e254787fa6ef9d647595a308b9bcf8697b2 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 21 Nov 2019 19:34:17 +0100 Subject: [PATCH 063/649] openssh 8.1 compiles --- src/ssl.c | 227 +++++++++++++++++++++++++++++++++++++++++- tests/api.c | 31 ++++++ wolfssl/openssl/ec.h | 22 ++++ wolfssl/openssl/err.h | 3 + wolfssl/openssl/evp.h | 1 + wolfssl/openssl/rsa.h | 6 ++ wolfssl/openssl/ssl.h | 1 + wolfssl/ssl.h | 1 + 8 files changed, 290 insertions(+), 2 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 47af9db11..766e0c203 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -85,6 +85,7 @@ #include #include #include + #include #include #include #include @@ -16459,6 +16460,14 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) return type; } + static WC_INLINE void IncCtr(byte* ctr, word32 ctrSz) + { + int i; + for (i = ctrSz-1; i >= 0; i--) { + if (++ctr[i]) + break; + } + } int wolfSSL_EVP_MD_CTX_cleanup(WOLFSSL_EVP_MD_CTX* ctx) { @@ -16530,6 +16539,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) int arg, void *ptr) { int ret = WOLFSSL_FAILURE; + WC_RNG rng; if (ctx == NULL) return WOLFSSL_FAILURE; @@ -16554,14 +16564,57 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ret = wolfSSL_EVP_CIPHER_CTX_set_iv_length(ctx, arg); break; case EVP_CTRL_AEAD_SET_IV_FIXED: - /* arg=-1 copies ctx->ivSz from ptr */ if (arg == -1) { + /* arg == -1 copies ctx->ivSz from ptr */ ret = wolfSSL_EVP_CIPHER_CTX_set_iv(ctx, ptr, ctx->ivSz); } else { - ret = wolfSSL_EVP_CIPHER_CTX_set_iv(ctx, ptr, arg); + /* + * Fixed field must be at least 4 bytes and invocation + * field at least 8. + */ + if ((arg < 4) || (ctx->ivSz - arg) < 8) { + WOLFSSL_MSG("Fixed field or invocation field too short"); + ret = WOLFSSL_FAILURE; + break; + } + if (wc_InitRng(&rng) != 0) { + WOLFSSL_MSG("wc_InitRng failed"); + ret = WOLFSSL_FAILURE; + break; + } + if (arg) { + XMEMCPY(ctx->iv, ptr, arg); + } + if (wc_RNG_GenerateBlock(&rng, ctx->iv + arg, + ctx->ivSz - arg) != 0) { + /* rng is freed immediately after if block so no need + * to do it here + */ + WOLFSSL_MSG("wc_RNG_GenerateBlock failed"); + ret = WOLFSSL_FAILURE; + } + + if (wc_FreeRng(&rng) != 0) { + WOLFSSL_MSG("wc_FreeRng failed"); + ret = WOLFSSL_FAILURE; + break; + } } break; + case EVP_CTRL_GCM_IV_GEN: + if (ctx->cipher.aes.keylen == 0 || ctx->ivSz == 0) { + ret = WOLFSSL_FAILURE; + WOLFSSL_MSG("Key or IV not set"); + break; + } + if ((ret = wc_AesGcmSetExtIV(&ctx->cipher.aes, ctx->iv, ctx->ivSz)) != 0) { + WOLFSSL_MSG("wc_AesGcmSetIV failed"); + ret = WOLFSSL_FAILURE; + } + /* OpenSSL increments the IV. Not sure why */ + IncCtr(ctx->iv, ctx->ivSz); + break; case EVP_CTRL_AEAD_SET_TAG: if(arg <= 0 || arg > 16 || (ptr == NULL)) return WOLFSSL_FAILURE; @@ -33692,6 +33745,78 @@ int wolfSSL_EC_KEY_set_public_key(WOLFSSL_EC_KEY *key, } /* End EC_KEY */ +int wolfSSL_ECDSA_size(const WOLFSSL_EC_KEY *key) +{ + const EC_GROUP *group; + int bits, bytes; + word32 headerSz = 4; /* 2*ASN_TAG + 2*LEN(ENUM) */ + + if (!key) { + return WOLFSSL_FAILURE; + } + + if (!(group = wolfSSL_EC_KEY_get0_group(key))) { + return WOLFSSL_FAILURE; + } + if ((bits = wolfSSL_EC_GROUP_order_bits(group)) == 0) { + return WOLFSSL_FAILURE; + } + bytes = (bits + 7) / 8; /* bytes needed to hold bits */ + return headerSz + + 2 + /* possible leading zeroes in r and s */ + bytes + bytes + /* r and s */ + 2; +} + +int wolfSSL_ECDSA_sign(int type, const unsigned char *digest, + int digestSz, unsigned char *sig, + unsigned int *sigSz, WOLFSSL_EC_KEY *key) +{ + int ret = WOLFSSL_SUCCESS; + WC_RNG* rng = NULL; +#ifdef WOLFSSL_SMALL_STACK + WC_RNG* tmpRNG = NULL; +#else + WC_RNG tmpRNG[1]; +#endif + int initTmpRng = 0; + +#ifdef WOLFSSL_SMALL_STACK + tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG); + if (tmpRNG == NULL) + return WOLFSSL_FAILURE; +#endif + WOLFSSL_ENTER("wolfSSL_ECDSA_sign"); + + if (!key) { + return WOLFSSL_FAILURE; + } + + if (wc_InitRng(tmpRNG) == 0) { + rng = tmpRNG; + initTmpRng = 1; + } + else { + WOLFSSL_MSG("Bad RNG Init, trying global"); + if (initGlobalRNG == 0) { + WOLFSSL_MSG("Global RNG no Init"); + } + else { + rng = &globalRNG; + } + } + if (!rng) { + return WOLFSSL_FAILURE; + } + if (wc_ecc_sign_hash(digest, digestSz, sig, sigSz, rng, (ecc_key*)key->internal) != MP_OKAY) { + ret = WOLFSSL_FAILURE; + } + if (initTmpRng) { + wc_FreeRng(tmpRNG); + } + (void)type; + return ret; +} #ifndef HAVE_SELFTEST /* ECC point compression types were not included in selftest ecc.h */ @@ -34149,6 +34274,68 @@ int wolfSSL_ECPoint_d2i(unsigned char *in, unsigned int len, return WOLFSSL_SUCCESS; } +size_t wolfSSL_EC_POINT_point2oct(const WOLFSSL_EC_GROUP *group, + const WOLFSSL_EC_POINT *p, + char form, + byte *buf, size_t len, WOLFSSL_BN_CTX *ctx) +{ + unsigned int min_len = 0; + + WOLFSSL_ENTER("EC_POINT_point2oct"); + + if (!group || !p) { + return WOLFSSL_FAILURE; + } + + if (wolfSSL_EC_POINT_is_at_infinity(group, p)) { + /* encodes to a single 0 octet */ + if (buf != NULL) { + if (len < 1) { + ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL); + return WOLFSSL_FAILURE; + } + buf[0] = 0; + } + return 1; + } + + if (form != POINT_CONVERSION_UNCOMPRESSED) { + WOLFSSL_MSG("Only POINT_CONVERSION_UNCOMPRESSED is supported"); + return WOLFSSL_FAILURE; + } + + if (wolfSSL_ECPoint_i2d(group, p, NULL, &min_len) != WOLFSSL_SUCCESS) { + return WOLFSSL_FAILURE; + } + + if (min_len > len) { + return WOLFSSL_FAILURE; + } + + if (wolfSSL_ECPoint_i2d(group, p, buf, &min_len) != WOLFSSL_SUCCESS) { + return WOLFSSL_FAILURE; + } + + (void)ctx; + + return min_len; +} + +int wolfSSL_EC_POINT_oct2point(const WOLFSSL_EC_GROUP *group, + WOLFSSL_EC_POINT *p, const unsigned char *buf, + size_t len, WOLFSSL_BN_CTX *ctx) +{ + WOLFSSL_ENTER("EC_POINT_point2oct"); + + if (!group || !p) { + return WOLFSSL_FAILURE; + } + + (void)ctx; + + return wolfSSL_ECPoint_d2i((unsigned char*)buf, len, group, p); +} + WOLFSSL_EC_POINT *wolfSSL_EC_POINT_new(const WOLFSSL_EC_GROUP *group) { WOLFSSL_EC_POINT *p; @@ -36568,6 +36755,22 @@ int wolfSSL_DH_LoadDer(WOLFSSL_DH* dh, const unsigned char* derBuf, int derSz) #if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) +/* increments ref count of WOLFSSL_RSA. Return 1 on success, 0 on error */ +int wolfSSL_RSA_up_ref(WOLFSSL_RSA* rsa) +{ + if (rsa) { + if (wc_LockMutex(&rsa->refMutex) != 0) { + WOLFSSL_MSG("Failed to lock x509 mutex"); + } + rsa->refCount++; + wc_UnLockMutex(&rsa->refMutex); + + return 1; + } + + return 0; +} + /* increments ref count of WOLFSSL_X509. Return 1 on success, 0 on error */ int wolfSSL_X509_up_ref(WOLFSSL_X509* x509) { @@ -47502,8 +47705,26 @@ static void InitwolfSSL_Rsa(WOLFSSL_RSA* rsa) void wolfSSL_RSA_free(WOLFSSL_RSA* rsa) { WOLFSSL_ENTER("wolfSSL_RSA_free"); + int doFree = 0; if (rsa) { + if (wc_LockMutex(&rsa->refMutex) != 0) { + WOLFSSL_MSG("Couldn't lock rsa mutex"); + } + + /* only free if all references to it are done */ + rsa->refCount--; + if (rsa->refCount == 0) { + doFree = 1; + } + wc_UnLockMutex(&rsa->refMutex); + + if (!doFree) { + return; + } + + wc_FreeMutex(&rsa->refMutex); + if (rsa->internal) { #if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && \ !defined(HAVE_FAST_RSA) && defined(WC_RSA_BLINDING) @@ -47614,6 +47835,8 @@ WOLFSSL_RSA* wolfSSL_RSA_new(void) external->internal = key; external->inSet = 0; + external->refCount = 1; + wc_InitMutex(&external->refMutex); return external; } #endif /* !NO_RSA && (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) */ diff --git a/tests/api.c b/tests/api.c index ef2eac84f..ac4cee6d9 100644 --- a/tests/api.c +++ b/tests/api.c @@ -1923,6 +1923,32 @@ static void test_wolfSSL_ECDSA_SIG(void) wolfSSL_ECDSA_SIG_free(sig); #endif /* HAVE_ECC */ } + +static void test_ECDSA_size_sign(void) +{ +#ifdef HAVE_ECC + EC_KEY *key; + int id; + byte hash[WC_SHA_DIGEST_SIZE]; + byte sig[ECC_BUFSIZE]; + unsigned int sigSz = sizeof(sig); + + + XMEMSET(hash, 123, sizeof(hash)); + +#if !defined(NO_ECC256) && !defined(NO_ECC_SECP) + id = wc_ecc_get_curve_id_from_name("SECP256R1"); + AssertIntEQ(id, ECC_SECP256R1); + + AssertNotNull(key = wolfSSL_EC_KEY_new_by_curve_name(id)); + AssertIntEQ(EC_KEY_generate_key(key), 1); + AssertIntEQ(ECDSA_sign(0, hash, sizeof(hash), sig, &sigSz, key), 1); + AssertIntGE(ECDSA_size(key), sigSz); + EC_KEY_free(key); +#endif + +#endif /* HAVE_ECC */ +} #endif /* OPENSSL_EXTRA */ #include @@ -19922,6 +19948,10 @@ static void test_wolfSSL_PEM_RSAPrivateKey(void) AssertNotNull(rsa_dup = RSAPublicKey_dup(rsa)); AssertPtrNE(rsa_dup, rsa); + /* test if valgrind complains about unreleased memory */ + RSA_up_ref(rsa); + RSA_free(rsa); + BIO_free(bio); RSA_free(rsa); RSA_free(rsa_dup); @@ -30687,6 +30717,7 @@ void ApiTest(void) test_wolfSSL_EVP_CIPHER_CTX(); test_wolfSSL_EC(); test_wolfSSL_ECDSA_SIG(); + test_ECDSA_size_sign(); #endif #if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) && \ !defined(HAVE_SELFTEST) && \ diff --git a/wolfssl/openssl/ec.h b/wolfssl/openssl/ec.h index 558364d3b..50175a6d1 100644 --- a/wolfssl/openssl/ec.h +++ b/wolfssl/openssl/ec.h @@ -132,6 +132,16 @@ WOLFSSL_API int wolfSSL_ECPoint_d2i(unsigned char *in, unsigned int len, const WOLFSSL_EC_GROUP *curve, WOLFSSL_EC_POINT *p); WOLFSSL_API +size_t wolfSSL_EC_POINT_point2oct(const WOLFSSL_EC_GROUP *group, + const WOLFSSL_EC_POINT *p, + char form, + byte *buf, size_t len, WOLFSSL_BN_CTX *ctx); +WOLFSSL_API +int wolfSSL_EC_POINT_oct2point(const WOLFSSL_EC_GROUP *group, + WOLFSSL_EC_POINT *p, const unsigned char *buf, + size_t len, WOLFSSL_BN_CTX *ctx); + +WOLFSSL_API int wolfSSL_EC_KEY_LoadDer(WOLFSSL_EC_KEY* key, const unsigned char* der, int derSz); WOLFSSL_API @@ -162,6 +172,10 @@ void wolfSSL_EC_KEY_set_asn1_flag(WOLFSSL_EC_KEY *key, int asn1_flag); WOLFSSL_API int wolfSSL_EC_KEY_set_public_key(WOLFSSL_EC_KEY *key, const WOLFSSL_EC_POINT *pub); +WOLFSSL_API int wolfSSL_ECDSA_size(const WOLFSSL_EC_KEY *key); +WOLFSSL_API int wolfSSL_ECDSA_sign(int type, const unsigned char *digest, + int digestSz, unsigned char *sig, + unsigned int *sigSz, WOLFSSL_EC_KEY *key); WOLFSSL_API void wolfSSL_EC_GROUP_set_asn1_flag(WOLFSSL_EC_GROUP *group, int flag); WOLFSSL_API @@ -229,6 +243,9 @@ char* wolfSSL_EC_POINT_point2hex(const WOLFSSL_EC_GROUP* group, #define EC_KEY_set_asn1_flag wolfSSL_EC_KEY_set_asn1_flag #define EC_KEY_set_public_key wolfSSL_EC_KEY_set_public_key +#define ECDSA_size wolfSSL_ECDSA_size +#define ECDSA_sign wolfSSL_ECDSA_sign + #define EC_GROUP_free wolfSSL_EC_GROUP_free #define EC_GROUP_set_asn1_flag wolfSSL_EC_GROUP_set_asn1_flag #define EC_GROUP_new_by_curve_name wolfSSL_EC_GROUP_new_by_curve_name @@ -249,6 +266,11 @@ char* wolfSSL_EC_POINT_point2hex(const WOLFSSL_EC_GROUP* group, #define EC_get_builtin_curves wolfSSL_EC_get_builtin_curves +#define ECPoint_i2d wolfSSL_ECPoint_i2d +#define ECPoint_d2i wolfSSL_ECPoint_d2i +#define EC_POINT_point2oct wolfSSL_EC_POINT_point2oct +#define EC_POINT_oct2point wolfSSL_EC_POINT_oct2point + #ifndef HAVE_SELFTEST #define EC_POINT_point2hex wolfSSL_EC_POINT_point2hex #endif diff --git a/wolfssl/openssl/err.h b/wolfssl/openssl/err.h index 5c856db99..ca59a0bb4 100644 --- a/wolfssl/openssl/err.h +++ b/wolfssl/openssl/err.h @@ -34,11 +34,13 @@ #define ERR_R_DISABLED NOT_COMPILED_IN #define ERR_R_PASSED_INVALID_ARGUMENT BAD_FUNC_ARG #define RSA_R_UNKNOWN_PADDING_TYPE RSA_PAD_E +#define EC_R_BUFFER_TOO_SMALL BUFFER_E /* SSL function codes */ #define RSA_F_RSA_OSSL_PRIVATE_ENCRYPT 1 #define SSL_F_SSL_CTX_USE_CERTIFICATE_FILE 2 #define SSL_F_SSL_USE_PRIVATEKEY 3 +#define EC_F_EC_GFP_SIMPLE_POINT2OCT 4 /* reasons */ #define ERR_R_SYS_LIB 1 @@ -46,6 +48,7 @@ #define RSAerr(f,r) ERR_put_error(0,(f),(r),__FILE__,__LINE__) #define SSLerr(f,r) ERR_put_error(0,(f),(r),__FILE__,__LINE__) +#define ECerr(f,r) ERR_put_error(0,(f),(r),__FILE__,__LINE__) #endif /* WOLFSSL_OPENSSL_ERR_ */ diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index cfb9b154d..1d564abd1 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -742,6 +742,7 @@ typedef WOLFSSL_EVP_CIPHER_CTX EVP_CIPHER_CTX; #define EVP_CTRL_AEAD_GET_TAG 0x10 #define EVP_CTRL_AEAD_SET_TAG 0x11 #define EVP_CTRL_AEAD_SET_IV_FIXED 0x12 +#define EVP_CTRL_GCM_IV_GEN 0x13 #define EVP_CTRL_GCM_SET_IVLEN EVP_CTRL_AEAD_SET_IVLEN #define EVP_CTRL_GCM_GET_TAG EVP_CTRL_AEAD_GET_TAG #define EVP_CTRL_GCM_SET_TAG EVP_CTRL_AEAD_SET_TAG diff --git a/wolfssl/openssl/rsa.h b/wolfssl/openssl/rsa.h index 70c2efd5c..ad8853fda 100644 --- a/wolfssl/openssl/rsa.h +++ b/wolfssl/openssl/rsa.h @@ -84,6 +84,10 @@ struct WOLFSSL_RSA { #if defined(HAVE_EX_DATA) void* ex_data[MAX_EX_DATA]; /* external data */ #endif +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) + wolfSSL_Mutex refMutex; /* ref count mutex */ + int refCount; /* reference count */ +#endif }; WOLFSSL_API WOLFSSL_RSA* wolfSSL_RSA_new(void); @@ -174,6 +178,8 @@ WOLFSSL_API int wolfSSL_RSA_set_ex_data(WOLFSSL_RSA *rsa, int idx, void *data); #define RSA_set_flags wolfSSL_RSA_set_flags #define RSAPublicKey_dup wolfSSL_RSAPublicKey_dup +#define RSA_get_ex_data wolfSSL_RSA_get_ex_data +#define RSA_set_ex_data wolfSSL_RSA_set_ex_data #define RSA_get0_key wolfSSL_RSA_get0_key diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 099db31c4..8df5e400b 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -698,6 +698,7 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define SSL_CTX_set_tmp_rsa_callback wolfSSL_CTX_set_tmp_rsa_callback #define RSA_print wolfSSL_RSA_print #define RSA_bits wolfSSL_RSA_size +#define RSA_up_ref wolfSSL_RSA_up_ref #define PEM_def_callback wolfSSL_PEM_def_callback diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 3f2f00b27..8d5045b6f 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1159,6 +1159,7 @@ WOLFSSL_API WOLFSSL_SESSION* wolfSSL_get1_session(WOLFSSL* ssl); WOLFSSL_API WOLFSSL_X509* wolfSSL_X509_new(void); #if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) +WOLFSSL_API int wolfSSL_RSA_up_ref(WOLFSSL_RSA* rsa); WOLFSSL_API int wolfSSL_X509_up_ref(WOLFSSL_X509* x509); WOLFSSL_API int wolfSSL_EVP_PKEY_up_ref(WOLFSSL_EVP_PKEY* pkey); #endif From aea95232d1cfa2fac2ee69a2ea1cd59f1535bfce Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 26 Nov 2019 15:29:12 +0100 Subject: [PATCH 064/649] WIP Add EC_POINT conversion to BIGNUM (EC_POINT_point2bn) Add setting affine coordinates for EC_POINT (EC_POINT_set_affine_coordinates_GFp) Add bit clearing for BIGNUM (BN_clear_bit) Add supporting unit tests in api.c --- src/ssl.c | 165 +++++++++++++++++++++++++++++++++++---- tests/api.c | 25 +++++- wolfssl/internal.h | 2 +- wolfssl/openssl/bn.h | 4 + wolfssl/openssl/crypto.h | 1 + wolfssl/openssl/ec.h | 14 ++++ wolfssl/openssl/err.h | 1 + wolfssl/wolfcrypt/ecc.h | 2 +- 8 files changed, 197 insertions(+), 17 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 766e0c203..16e7e9fd0 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -86,6 +86,7 @@ #include #include #include + #include #include #include #include @@ -15639,6 +15640,10 @@ size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out, return SSLEAY_VERSION_NUMBER; } + unsigned long OpenSSL_version_num(void) + { + return OPENSSL_VERSION_NUMBER; + } const char* wolfSSLeay_version(int type) { @@ -34308,11 +34313,9 @@ size_t wolfSSL_EC_POINT_point2oct(const WOLFSSL_EC_GROUP *group, return WOLFSSL_FAILURE; } - if (min_len > len) { - return WOLFSSL_FAILURE; - } - - if (wolfSSL_ECPoint_i2d(group, p, buf, &min_len) != WOLFSSL_SUCCESS) { + if (buf && + ((min_len > len) || + wolfSSL_ECPoint_i2d(group, p, buf, &min_len) != WOLFSSL_SUCCESS)) { return WOLFSSL_FAILURE; } @@ -34325,7 +34328,7 @@ int wolfSSL_EC_POINT_oct2point(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *p, const unsigned char *buf, size_t len, WOLFSSL_BN_CTX *ctx) { - WOLFSSL_ENTER("EC_POINT_point2oct"); + WOLFSSL_ENTER("wolfSSL_EC_POINT_oct2point"); if (!group || !p) { return WOLFSSL_FAILURE; @@ -34336,6 +34339,42 @@ int wolfSSL_EC_POINT_oct2point(const WOLFSSL_EC_GROUP *group, return wolfSSL_ECPoint_d2i((unsigned char*)buf, len, group, p); } +/* wolfSSL_EC_POINT_point2bn should return "in" if not null */ +WOLFSSL_BIGNUM *wolfSSL_EC_POINT_point2bn(const WOLFSSL_EC_GROUP *group, + const WOLFSSL_EC_POINT *p, + char form, + WOLFSSL_BIGNUM *in, WOLFSSL_BN_CTX *ctx) +{ + size_t len; + byte *buf; + WOLFSSL_BIGNUM *ret = NULL; + + WOLFSSL_ENTER("wolfSSL_EC_POINT_oct2point"); + + if (!group || !p) { + return NULL; + } + + if ((len = wolfSSL_EC_POINT_point2oct(group, p, form, + NULL, 0, ctx)) == WOLFSSL_FAILURE) { + return NULL; + } + + if (!(buf = (byte*)XMALLOC(len, NULL, DYNAMIC_TYPE_TMP_BUFFER))) { + WOLFSSL_MSG("malloc failed"); + return NULL; + } + + if (wolfSSL_EC_POINT_point2oct(group, p, form, + buf, len, ctx) == len) { + ret = wolfSSL_BN_bin2bn(buf, len, in); + } + + XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + + return ret; +} + WOLFSSL_EC_POINT *wolfSSL_EC_POINT_new(const WOLFSSL_EC_GROUP *group) { WOLFSSL_EC_POINT *p; @@ -34399,6 +34438,47 @@ int wolfSSL_EC_POINT_get_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group, return WOLFSSL_SUCCESS; } +int wolfSSL_EC_POINT_set_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group, + WOLFSSL_EC_POINT *point, + const WOLFSSL_BIGNUM *x, + const WOLFSSL_BIGNUM *y, + WOLFSSL_BN_CTX *ctx) +{ + (void)ctx; + WOLFSSL_ENTER("wolfSSL_EC_POINT_set_affine_coordinates_GFp"); + + if (group == NULL || point == NULL || point->internal == NULL || + x == NULL || y == NULL) { + WOLFSSL_MSG("wolfSSL_EC_POINT_set_affine_coordinates_GFp NULL error"); + return WOLFSSL_FAILURE; + } + + if (!point->X) { + point->X = wolfSSL_BN_new(); + } + if (!point->Y) { + point->Y = wolfSSL_BN_new(); + } + if (!point->Z) { + point->Z = wolfSSL_BN_new(); + } + if (!point->X || !point->Y || !point->Z) { + WOLFSSL_MSG("wolfSSL_BN_new failed"); + return WOLFSSL_FAILURE; + } + + BN_copy(point->X, x); + BN_copy(point->Y, y); + BN_copy(point->Z, wolfSSL_BN_value_one()); + + if (SetECPointInternal((WOLFSSL_EC_POINT *)point) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("SetECPointInternal failed"); + return WOLFSSL_FAILURE; + } + + return WOLFSSL_SUCCESS; +} + #ifndef WOLFSSL_ATECC508A /* return code compliant with OpenSSL : * 1 if success, 0 if error @@ -42358,7 +42438,7 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey_EVP(WOLFSSL_EVP_PKEY** out, /* stunnel compatibility functions*/ #if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && (defined(HAVE_STUNNEL) || \ defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY) || \ - defined(WOLFSSL_HAPROXY))) + defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_OPENSSH))) void wolfSSL_ERR_remove_thread_state(void* pid) { (void) pid; @@ -46485,11 +46565,6 @@ int wolfSSL_BN_is_bit_set(const WOLFSSL_BIGNUM* bn, int n) return WOLFSSL_FAILURE; } - if (n > DIGIT_BIT) { - WOLFSSL_MSG("input bit count too large"); - return WOLFSSL_FAILURE; - } - return mp_is_bit_set((mp_int*)bn->internal, (mp_digit)n); } @@ -46504,7 +46579,7 @@ int wolfSSL_BN_set_bit(WOLFSSL_BIGNUM* bn, int n) } if (mp_set_bit((mp_int*)bn->internal, n) != MP_OKAY) { - WOLFSSL_MSG("mp_set_int error"); + WOLFSSL_MSG("mp_set_bit error"); return WOLFSSL_FAILURE; } @@ -46512,6 +46587,60 @@ int wolfSSL_BN_set_bit(WOLFSSL_BIGNUM* bn, int n) } +int wolfSSL_BN_clear_bit(WOLFSSL_BIGNUM* bn, int n) +{ + int ret = WOLFSSL_FAILURE; +#ifndef WOLFSSL_SMALL_STACK + mp_int res[1]; + mp_int tmp[1]; +#else + mp_int* res = null; + mp_int* tmp = null; +#endif + + if (bn == NULL || bn->internal == NULL) { + WOLFSSL_MSG("bn NULL error"); + goto cleanup; + } + if (mp_is_bit_set((mp_int*)bn->internal, n)) { +#ifdef WOLFSSL_SMALL_STACK + res = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT); + if (res == NULL) { + goto cleanup; + } + tmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT); + if (tmp == NULL) { + goto cleanup; + } +#endif + if (mp_init(tmp) != MP_OKAY) { + goto cleanup; + } + if (mp_init(res) != MP_OKAY) { + goto cleanup; + } + if (mp_set_bit(tmp, n) != MP_OKAY) { + goto cleanup; + } + if (mp_sub((mp_int*)bn->internal, tmp, res) != MP_OKAY) { + goto cleanup; + } + if (mp_copy(res, (mp_int*)bn->internal) != MP_OKAY) { + goto cleanup; + } + } + ret = WOLFSSL_SUCCESS; +cleanup: +#ifdef WOLFSSL_SMALL_STACK + if (res): + XFREE(res, NULL, DYNAMIC_TYPE_BIGINT); + if (tmp): + XFREE(tmp, NULL, DYNAMIC_TYPE_BIGINT); +#endif + return ret; +} + + /* WOLFSSL_SUCCESS on ok */ /* Note on use: this function expects str to be an even length. It is * converting pairs of bytes into 8-bit values. As an example, the RSA @@ -47691,6 +47820,14 @@ void wolfSSL_BN_clear_free(WOLFSSL_BIGNUM* bn) wolfSSL_BN_free(bn); } } + +void wolfSSL_BN_clear(WOLFSSL_BIGNUM* bn) +{ + WOLFSSL_MSG("wolfSSL_BN_clear"); + if (bn && bn->internal) { + mp_forcezero((mp_int*)bn->internal); + } +} #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */ #if !defined(NO_RSA) && (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) @@ -47753,7 +47890,7 @@ void wolfSSL_RSA_free(WOLFSSL_RSA* rsa) wolfSSL_BN_free(rsa->n); #ifdef WC_RSA_BLINDING - if (wc_FreeRng(rsa->rng) != 0) { + if (rsa->rng && wc_FreeRng(rsa->rng) != 0) { WOLFSSL_MSG("Issue freeing rng"); } XFREE(rsa->rng, NULL, DYNAMIC_TYPE_RNG); diff --git a/tests/api.c b/tests/api.c index ac4cee6d9..c044f7a4f 100644 --- a/tests/api.c +++ b/tests/api.c @@ -1781,9 +1781,10 @@ static void test_wolfSSL_EC(void) #ifdef HAVE_ECC BN_CTX *ctx; EC_GROUP *group; - EC_POINT *Gxy, *new_point; + EC_POINT *Gxy, *new_point, *set_point; BIGNUM *k = NULL, *Gx = NULL, *Gy = NULL, *Gz = NULL; BIGNUM *X, *Y; + BIGNUM *set_point_bn; char* hexStr; int group_bits; @@ -1802,8 +1803,10 @@ static void test_wolfSSL_EC(void) AssertIntEQ((group_bits = EC_GROUP_order_bits(group)), 256); AssertNotNull(Gxy = EC_POINT_new(group)); AssertNotNull(new_point = EC_POINT_new(group)); + AssertNotNull(set_point = EC_POINT_new(group)); AssertNotNull(X = BN_new()); AssertNotNull(Y = BN_new()); + AssertNotNull(set_point_bn = BN_new()); /* load test values */ AssertIntEQ(BN_hex2bn(&k, kTest), WOLFSSL_SUCCESS); @@ -1828,6 +1831,15 @@ static void test_wolfSSL_EC(void) /* check if point X coordinate is zero */ AssertIntEQ(BN_is_zero(X), WOLFSSL_FAILURE); + /* set the same X and Y points in another object */ + AssertIntEQ(EC_POINT_set_affine_coordinates_GFp(group, set_point, X, Y, ctx), WOLFSSL_SUCCESS); + + /* compare points as they should be the same */ + AssertIntEQ(EC_POINT_cmp(group, new_point, set_point, ctx), 0); + + AssertPtrEq(EC_POINT_point2bn(group, set_point, POINT_CONVERSION_UNCOMPRESSED, + set_point_bn, ctx), set_point_bn); + /* check bn2hex */ hexStr = BN_bn2hex(k); AssertStrEQ(hexStr, kTest); @@ -1867,7 +1879,9 @@ static void test_wolfSSL_EC(void) BN_free(X); BN_free(Y); BN_free(k); + BN_free(set_point_bn); EC_POINT_free(new_point); + EC_POINT_free(set_point); EC_POINT_free(Gxy); EC_GROUP_free(group); BN_CTX_free(ctx); @@ -21519,6 +21533,15 @@ static void test_wolfSSL_BN(void) AssertIntLT(BN_cmp(a, c), 0); AssertIntGT(BN_cmp(c, b), 0); + AssertIntEQ(BN_set_word(a, 0), 1); + AssertIntEQ(BN_is_zero(a), 1); + AssertIntEQ(BN_set_bit(a, 0x45), 1); + AssertIntEQ(BN_is_zero(a), 0); + AssertIntEQ(BN_is_bit_set(a, 0x45), 1); + AssertIntEQ(BN_clear_bit(a, 0x45), 1); + AssertIntEQ(BN_is_bit_set(a, 0x45), 0); + AssertIntEQ(BN_is_zero(a), 1); + BN_free(a); BN_free(b); BN_free(c); diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 5f47ff767..028c0cf97 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2748,7 +2748,7 @@ struct WOLFSSL_CTX { #endif #if defined(OPENSSL_ALL) || (defined(OPENSSL_EXTRA) && (defined(HAVE_STUNNEL) || \ defined(WOLFSSL_NGINX) || defined(HAVE_LIGHTY) || \ - defined(WOLFSSL_HAPROXY))) + defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_OPENSSH) )) CallbackSniRecv sniRecvCb; void* sniRecvCbArg; #endif diff --git a/wolfssl/openssl/bn.h b/wolfssl/openssl/bn.h index 067d873d7..40f2ebe8b 100644 --- a/wolfssl/openssl/bn.h +++ b/wolfssl/openssl/bn.h @@ -64,6 +64,7 @@ WOLFSSL_API void wolfSSL_BN_init(WOLFSSL_BIGNUM *); #endif WOLFSSL_API void wolfSSL_BN_free(WOLFSSL_BIGNUM*); WOLFSSL_API void wolfSSL_BN_clear_free(WOLFSSL_BIGNUM*); +WOLFSSL_API void wolfSSL_BN_clear(WOLFSSL_BIGNUM*); WOLFSSL_API int wolfSSL_BN_sub(WOLFSSL_BIGNUM*, const WOLFSSL_BIGNUM*, @@ -110,6 +111,7 @@ WOLFSSL_API char* wolfSSL_BN_bn2dec(const WOLFSSL_BIGNUM*); WOLFSSL_API int wolfSSL_BN_lshift(WOLFSSL_BIGNUM*, const WOLFSSL_BIGNUM*, int); WOLFSSL_API int wolfSSL_BN_add_word(WOLFSSL_BIGNUM*, WOLFSSL_BN_ULONG); WOLFSSL_API int wolfSSL_BN_set_bit(WOLFSSL_BIGNUM*, int); +WOLFSSL_API int wolfSSL_BN_clear_bit(WOLFSSL_BIGNUM*, int); WOLFSSL_API int wolfSSL_BN_set_word(WOLFSSL_BIGNUM*, WOLFSSL_BN_ULONG); WOLFSSL_API unsigned long wolfSSL_BN_get_word(const WOLFSSL_BIGNUM*); @@ -141,6 +143,7 @@ typedef WOLFSSL_BN_GENCB BN_GENCB; #define BN_init wolfSSL_BN_init #define BN_free wolfSSL_BN_free #define BN_clear_free wolfSSL_BN_clear_free +#define BN_clear wolfSSL_BN_clear #define BN_num_bytes wolfSSL_BN_num_bytes #define BN_num_bits wolfSSL_BN_num_bits @@ -184,6 +187,7 @@ typedef WOLFSSL_BN_GENCB BN_GENCB; #define BN_add wolfSSL_BN_add #define BN_set_word wolfSSL_BN_set_word #define BN_set_bit wolfSSL_BN_set_bit +#define BN_clear_bit wolfSSL_BN_clear_bit #define BN_is_prime_ex wolfSSL_BN_is_prime_ex diff --git a/wolfssl/openssl/crypto.h b/wolfssl/openssl/crypto.h index 241108397..a3eeb7bd7 100644 --- a/wolfssl/openssl/crypto.h +++ b/wolfssl/openssl/crypto.h @@ -35,6 +35,7 @@ WOLFSSL_API const char* wolfSSLeay_version(int type); WOLFSSL_API unsigned long wolfSSLeay(void); +WOLFSSL_API unsigned long OpenSSL_version_num(void); #ifdef OPENSSL_EXTRA WOLFSSL_API void wolfSSL_OPENSSL_free(void*); diff --git a/wolfssl/openssl/ec.h b/wolfssl/openssl/ec.h index 50175a6d1..a8ef9d0c2 100644 --- a/wolfssl/openssl/ec.h +++ b/wolfssl/openssl/ec.h @@ -140,6 +140,11 @@ WOLFSSL_API int wolfSSL_EC_POINT_oct2point(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *p, const unsigned char *buf, size_t len, WOLFSSL_BN_CTX *ctx); +WOLFSSL_API +WOLFSSL_BIGNUM *wolfSSL_EC_POINT_point2bn(const WOLFSSL_EC_GROUP *group, + const WOLFSSL_EC_POINT *p, + char form, + WOLFSSL_BIGNUM *in, WOLFSSL_BN_CTX *ctx); WOLFSSL_API int wolfSSL_EC_KEY_LoadDer(WOLFSSL_EC_KEY* key, @@ -203,6 +208,12 @@ int wolfSSL_EC_POINT_get_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group, WOLFSSL_BIGNUM *y, WOLFSSL_BN_CTX *ctx); WOLFSSL_API +int wolfSSL_EC_POINT_set_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group, + WOLFSSL_EC_POINT *point, + const WOLFSSL_BIGNUM *x, + const WOLFSSL_BIGNUM *y, + WOLFSSL_BN_CTX *ctx); +WOLFSSL_API int wolfSSL_EC_POINT_mul(const WOLFSSL_EC_GROUP *group, WOLFSSL_EC_POINT *r, const WOLFSSL_BIGNUM *n, const WOLFSSL_EC_POINT *q, const WOLFSSL_BIGNUM *m, @@ -259,6 +270,8 @@ char* wolfSSL_EC_POINT_point2hex(const WOLFSSL_EC_GROUP* group, #define EC_POINT_free wolfSSL_EC_POINT_free #define EC_POINT_get_affine_coordinates_GFp \ wolfSSL_EC_POINT_get_affine_coordinates_GFp +#define EC_POINT_set_affine_coordinates_GFp \ + wolfSSL_EC_POINT_set_affine_coordinates_GFp #define EC_POINT_mul wolfSSL_EC_POINT_mul #define EC_POINT_clear_free wolfSSL_EC_POINT_clear_free #define EC_POINT_cmp wolfSSL_EC_POINT_cmp @@ -270,6 +283,7 @@ char* wolfSSL_EC_POINT_point2hex(const WOLFSSL_EC_GROUP* group, #define ECPoint_d2i wolfSSL_ECPoint_d2i #define EC_POINT_point2oct wolfSSL_EC_POINT_point2oct #define EC_POINT_oct2point wolfSSL_EC_POINT_oct2point +#define EC_POINT_point2bn wolfSSL_EC_POINT_point2bn #ifndef HAVE_SELFTEST #define EC_POINT_point2hex wolfSSL_EC_POINT_point2hex diff --git a/wolfssl/openssl/err.h b/wolfssl/openssl/err.h index ca59a0bb4..ae50458d5 100644 --- a/wolfssl/openssl/err.h +++ b/wolfssl/openssl/err.h @@ -26,6 +26,7 @@ /* err.h for openssl */ #define ERR_load_crypto_strings wolfSSL_ERR_load_crypto_strings +#define ERR_load_CRYPTO_strings wolfSSL_ERR_load_crypto_strings #define ERR_peek_last_error wolfSSL_ERR_peek_last_error /* fatal error */ diff --git a/wolfssl/wolfcrypt/ecc.h b/wolfssl/wolfcrypt/ecc.h index ad3f407e9..f15ba9746 100644 --- a/wolfssl/wolfcrypt/ecc.h +++ b/wolfssl/wolfcrypt/ecc.h @@ -327,7 +327,7 @@ typedef struct alt_fp_int { #endif -/* A point on an ECC curve, stored in Jacbobian format such that (x,y,z) => +/* A point on an ECC curve, stored in Jacobian format such that (x,y,z) => (x/z^2, y/z^3, 1) when interpreted as affine */ typedef struct { #ifndef ALT_ECC_SIZE From 84a2ca7a4ec14589a197adf6b5a595a72200dd6d Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 28 Nov 2019 13:05:36 +0100 Subject: [PATCH 065/649] Map the Jacobian point back to affine space in wolfSSL_EC_POINT_get_affine_coordinates_GFp --- src/ssl.c | 24 +++++++++++++++++++++++- tests/api.c | 5 +++++ wolfcrypt/src/ecc.c | 2 +- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 16e7e9fd0..f20ec0a8b 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -34413,12 +34413,14 @@ int wolfSSL_EC_POINT_get_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group, WOLFSSL_BIGNUM *y, WOLFSSL_BN_CTX *ctx) { + mp_digit mp; + mp_int modulus; (void)ctx; WOLFSSL_ENTER("wolfSSL_EC_POINT_get_affine_coordinates_GFp"); if (group == NULL || point == NULL || point->internal == NULL || - x == NULL || y == NULL) { + x == NULL || y == NULL || wolfSSL_EC_POINT_is_at_infinity(group, point)) { WOLFSSL_MSG("wolfSSL_EC_POINT_get_affine_coordinates_GFp NULL error"); return WOLFSSL_FAILURE; } @@ -34432,6 +34434,26 @@ int wolfSSL_EC_POINT_get_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group, } } + if (!wolfSSL_BN_is_one(point->Z)) { + /* Map the Jacobian point back to affine space */ + if (mp_read_radix(&modulus, ecc_sets[group->curve_idx].prime, MP_RADIX_HEX) != MP_OKAY) { + WOLFSSL_MSG("mp_read_radix failed"); + return WOLFSSL_FAILURE; + } + if (mp_montgomery_setup(&modulus, &mp) != MP_OKAY) { + WOLFSSL_MSG("mp_montgomery_setup failed"); + return WOLFSSL_FAILURE; + } + if (ecc_map((ecc_point*)point->internal, &modulus, mp) != MP_OKAY) { + WOLFSSL_MSG("ecc_map failed"); + return WOLFSSL_FAILURE; + } + if (SetECPointExternal((WOLFSSL_EC_POINT *)point) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("SetECPointExternal failed"); + return WOLFSSL_FAILURE; + } + } + BN_copy(x, point->X); BN_copy(y, point->Y); diff --git a/tests/api.c b/tests/api.c index c044f7a4f..107d8b802 100644 --- a/tests/api.c +++ b/tests/api.c @@ -1825,6 +1825,11 @@ static void test_wolfSSL_EC(void) /* check if point X coordinate is zero */ AssertIntEQ(BN_is_zero(new_point->X), WOLFSSL_FAILURE); + /* Force non-affine coordinates */ + AssertIntEQ(wolfSSL_BN_add(new_point->Z, (WOLFSSL_BIGNUM*)BN_value_one(), + (WOLFSSL_BIGNUM*)BN_value_one()), 1); + new_point->inSet = 0; + /* extract the coordinates from point */ AssertIntEQ(EC_POINT_get_affine_coordinates_GFp(group, new_point, X, Y, ctx), WOLFSSL_SUCCESS); diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index cedabc53b..31c4090fc 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -2281,7 +2281,7 @@ int ecc_projective_dbl_point(ecc_point *P, ecc_point *R, mp_int* a, /** - Map a projective jacbobian point back to affine space + Map a projective Jacobian point back to affine space P [in/out] The point to map modulus The modulus of the field the ECC curve is in mp The "b" value from montgomery_setup() From fbedabe6012c22b0d2c1151a630b0f3c9ba3e742 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 13 Dec 2019 19:34:14 +0100 Subject: [PATCH 066/649] OpenSSH changes - increase FP_MAX_BITS for OpenSSH - Add helpful loggin API (names are self-explanatory) -- wolfSSL_GetLoggingCb -- WOLFSSL_IS_DEBUG_ON - Define WOLFSSL_EC_METHOD as an alias of WOLFSSL_EC_GROUP - Add wolfSSL_EC_GROUP_method_of which really just returns the group itself - Add wolfSSL_EC_METHOD_get_field_type which gets the curve type of the WOLFSSL_EC_GROUP(remember that WOLFSSL_EC_METHOD is an alias of WOLFSSL_EC_GROUP for now) - Modify Base64_Decode so that it accepts arbitrary PEM line length - Modify PemToDer so that it accepts private keys with a custom -----BEGIN * PRIVATE KEY----- header --- src/ssl.c | 47 ++++++++++++++++++++++-- wolfcrypt/src/asn.c | 72 ++++++++++++++++++++++++++++++++++--- wolfcrypt/src/coding.c | 69 ++++++++++++++++++++++------------- wolfcrypt/src/logging.c | 11 ++++++ wolfcrypt/test/test.c | 2 +- wolfssl/openssl/ec.h | 11 ++++++ wolfssl/openssl/ssl.h | 2 -- wolfssl/ssl.h | 2 ++ wolfssl/wolfcrypt/logging.h | 3 ++ wolfssl/wolfcrypt/tfm.h | 5 +++ 10 files changed, 189 insertions(+), 35 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index f20ec0a8b..ed045b6b9 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -30002,7 +30002,12 @@ int wolfSSL_DH_generate_key(WOLFSSL_DH* dh) } if (rng) { - pubSz = privSz = wolfSSL_BN_num_bytes(dh->p); + pubSz = wolfSSL_BN_num_bytes(dh->p); + if (dh->length) { + privSz = dh->length/8; /* to bytes */ + } else { + privSz = pubSz; + } pub = (unsigned char*)XMALLOC(pubSz, NULL, DYNAMIC_TYPE_PUBLIC_KEY); priv = (unsigned char*)XMALLOC(privSz, NULL, DYNAMIC_TYPE_PRIVATE_KEY); if (pub == NULL || priv == NULL) { @@ -33219,6 +33224,12 @@ static int SetECKeyInternal(WOLFSSL_EC_KEY* eckey) return WOLFSSL_FATAL_ERROR; } + /* copy over the public point to key */ + if (wc_ecc_copy_point((ecc_point*)eckey->pub_key->internal, &key->pubkey) != MP_OKAY) { + WOLFSSL_MSG("wc_ecc_copy_point error"); + return WOLFSSL_FATAL_ERROR; + } + /* public key */ key->type = ECC_PUBLICKEY; } @@ -33306,6 +33317,11 @@ WOLFSSL_BIGNUM *wolfSSL_EC_KEY_get0_private_key(const WOLFSSL_EC_KEY *key) return NULL; } + if (wolfSSL_BN_is_zero(key->priv_key)) { + /* return NULL if not set */ + return NULL; + } + return key->priv_key; } @@ -33738,7 +33754,12 @@ int wolfSSL_EC_KEY_set_public_key(WOLFSSL_EC_KEY *key, return WOLFSSL_FAILURE; } - if (SetECKeyExternal(key) != WOLFSSL_SUCCESS) { + if (SetECPointExternal(key->pub_key) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("SetECKeyInternal failed"); + return WOLFSSL_FAILURE; + } + + if (SetECKeyInternal(key) != WOLFSSL_SUCCESS) { WOLFSSL_MSG("SetECKeyInternal failed"); return WOLFSSL_FAILURE; } @@ -33894,6 +33915,10 @@ void wolfSSL_EC_POINT_dump(const char *msg, const WOLFSSL_EC_POINT *p) WOLFSSL_ENTER("wolfSSL_EC_POINT_dump"); + if (!WOLFSSL_IS_DEBUG_ON() || wolfSSL_GetLoggingCb()) { + return; + } + if (p == NULL) { printf("%s = NULL", msg); return; @@ -33944,6 +33969,20 @@ int wolfSSL_EC_GROUP_cmp(const WOLFSSL_EC_GROUP *a, const WOLFSSL_EC_GROUP *b, #endif /* OPENSSL_EXTRA */ #if defined(HAVE_ECC) && (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) +const WOLFSSL_EC_METHOD* wolfSSL_EC_GROUP_method_of( + const WOLFSSL_EC_GROUP *group) +{ + return group; +} + +int wolfSSL_EC_METHOD_get_field_type(const WOLFSSL_EC_METHOD *meth) +{ + if (meth) { + return NID_X9_62_prime_field; + } + return WOLFSSL_FAILURE; +} + void wolfSSL_EC_GROUP_free(WOLFSSL_EC_GROUP *group) { WOLFSSL_ENTER("wolfSSL_EC_GROUP_free"); @@ -34661,7 +34700,7 @@ int wolfSSL_EC_POINT_is_at_infinity(const WOLFSSL_EC_GROUP *group, return WOLFSSL_FAILURE; } - return WOLFSSL_SUCCESS; + return ret; } /* End EC_POINT */ @@ -46407,6 +46446,8 @@ WOLFSSL_BIGNUM* wolfSSL_BN_bin2bn(const unsigned char* str, int len, wolfSSL_BN_free(ret); return NULL; } + } else { + return NULL; } return ret; diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 3f27159bf..ac5403e42 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -9759,6 +9759,11 @@ const char* const END_ENC_PRIV_KEY = "-----END ENCRYPTED PRIVATE KEY-----"; const char* const BEGIN_DSA_PRIV = "-----BEGIN DSA PRIVATE KEY-----"; const char* const END_DSA_PRIV = "-----END DSA PRIVATE KEY-----"; #endif +#ifdef OPENSSL_EXTRA + const char BEGIN_PRIV_KEY_PREFIX[] = "-----BEGIN"; + const char PRIV_KEY_SUFFIX[] = "PRIVATE KEY-----"; + const char END_PRIV_KEY_PREFIX[] = "-----END"; +#endif const char* const BEGIN_PUB_KEY = "-----BEGIN PUBLIC KEY-----"; const char* const END_PUB_KEY = "-----END PUBLIC KEY-----"; #ifdef HAVE_ED25519 @@ -10216,6 +10221,8 @@ int wc_DerToPemEx(const byte* der, word32 derSz, byte* output, word32 outSz, #ifdef WOLFSSL_PEM_TO_DER +#define STR_SIZEOF(x) (sizeof(x) - 1) /* -1 to not count the null char */ + /* Remove PEM header/footer, convert to ASN1, store any encrypted data info->consumed tracks of PEM bytes consumed in case multiple parts */ int PemToDer(const unsigned char* buff, long longSz, int type, @@ -10238,6 +10245,10 @@ int PemToDer(const unsigned char* buff, long longSz, int type, int padVal = 0; #endif #endif +#ifdef OPENSSL_EXTRA + char beginBuf[PEM_LINE_LEN]; + char endBuf[PEM_LINE_LEN]; +#endif WOLFSSL_ENTER("PemToDer"); @@ -10293,12 +10304,59 @@ int PemToDer(const unsigned char* buff, long longSz, int type, } if (!headerEnd) { +#ifdef OPENSSL_EXTRA + char* beginEnd; + int endLen; + /* see if there is a -----BEGIN * PRIVATE KEY----- header */ + headerEnd = XSTRNSTR((char*)buff, PRIV_KEY_SUFFIX, sz); + if (headerEnd) { + beginEnd = headerEnd + STR_SIZEOF(PRIV_KEY_SUFFIX); + /* back up to BEGIN_PRIV_KEY_PREFIX */ + headerEnd -= STR_SIZEOF(BEGIN_PRIV_KEY_PREFIX); + while (headerEnd > (char*)buff && + XSTRNCMP(headerEnd, BEGIN_PRIV_KEY_PREFIX, + STR_SIZEOF(BEGIN_PRIV_KEY_PREFIX)) != 0) { + headerEnd--; + } + if (XSTRNCMP(headerEnd, BEGIN_PRIV_KEY_PREFIX, + STR_SIZEOF(BEGIN_PRIV_KEY_PREFIX)) != 0 || + beginEnd - headerEnd > PEM_LINE_LEN) { + WOLFSSL_MSG("Couldn't find PEM header"); + return ASN_NO_PEM_HEADER; + } + /* headerEnd now points to beginning of header */ + XMEMCPY(beginBuf, headerEnd, beginEnd - headerEnd); + beginBuf[beginEnd - headerEnd] = '\0'; + /* look for matching footer */ + footer = XSTRNSTR(beginEnd, + beginBuf + STR_SIZEOF(BEGIN_PRIV_KEY_PREFIX), + (char*)buff + sz - beginEnd); + if (!footer) { + WOLFSSL_MSG("Couldn't find PEM footer"); + return ASN_NO_PEM_HEADER; + } + footer -= STR_SIZEOF(END_PRIV_KEY_PREFIX); + endLen = beginEnd - headerEnd - + (STR_SIZEOF(BEGIN_PRIV_KEY_PREFIX) - + STR_SIZEOF(END_PRIV_KEY_PREFIX)); + XMEMCPY(endBuf, footer, endLen); + endBuf[endLen] = '\0'; + + header = beginBuf; + footer = endBuf; + headerEnd = beginEnd; + } else { + WOLFSSL_MSG("Couldn't find PEM header"); + return ASN_NO_PEM_HEADER; + } +#else WOLFSSL_MSG("Couldn't find PEM header"); return ASN_NO_PEM_HEADER; +#endif + } else { + headerEnd += XSTRLEN(header); } - headerEnd += XSTRLEN(header); - /* eat end of line characters */ headerEnd = SkipEndOfLineChars(headerEnd, bufferEnd); @@ -10306,8 +10364,9 @@ int PemToDer(const unsigned char* buff, long longSz, int type, /* keyFormat is Key_Sum enum */ if (keyFormat) { #ifdef HAVE_ECC - if (header == BEGIN_EC_PRIV) - *keyFormat = ECDSAk; + *eccKey = (header == BEGIN_EC_PRIV || header == beginBuf) ? 1 : 0; + #else + *eccKey = 0; #endif #if !defined(NO_DSA) if (header == BEGIN_DSA_PRIV) @@ -10327,7 +10386,7 @@ int PemToDer(const unsigned char* buff, long longSz, int type, #endif /* WOLFSSL_ENCRYPTED_KEYS */ /* find footer */ - footerEnd = XSTRNSTR((char*)buff, footer, sz); + footerEnd = XSTRNSTR(headerEnd, footer, (char*)buff + sz - headerEnd); if (!footerEnd) { if (info) info->consumed = longSz; /* No more certs if no footer */ @@ -10363,6 +10422,9 @@ int PemToDer(const unsigned char* buff, long longSz, int type, return BUFFER_E; if ((header == BEGIN_PRIV_KEY +#ifdef OPENSSL_EXTRA + || header == beginBuf +#endif #ifdef HAVE_ECC || header == BEGIN_EC_PRIV #endif diff --git a/wolfcrypt/src/coding.c b/wolfcrypt/src/coding.c index 3aa59f0f3..c81588957 100644 --- a/wolfcrypt/src/coding.c +++ b/wolfcrypt/src/coding.c @@ -57,27 +57,66 @@ const byte base64Decode[] = { 62, BAD, BAD, BAD, 63, /* + starts at 0x2B */ 46, 47, 48, 49, 50, 51 }; +static WC_INLINE int Base64_SkipNewline(const byte* in, word32 *outLen, word32 *outJ) +{ + word32 inLen = *outLen; + word32 j = *outJ; + if (inLen && (in[j] == ' ' || in[j] == '\r' || in[j] == '\n')) { + byte endLine = in[j++]; + inLen--; + while (inLen && endLine == ' ') { /* allow trailing whitespace */ + endLine = in[j++]; + inLen--; + } + if (endLine == '\r') { + if (inLen) { + endLine = in[j++]; + inLen--; + } + } + if (endLine != '\n') { + WOLFSSL_MSG("Bad end of line in Base64 Decode"); + return ASN_INPUT_E; + } + } + *outLen = inLen; + *outJ = j; + return 0; +} int Base64_Decode(const byte* in, word32 inLen, byte* out, word32* outLen) { word32 i = 0; word32 j = 0; word32 plainSz = inLen - ((inLen + (PEM_LINE_SZ - 1)) / PEM_LINE_SZ ); + int ret; const byte maxIdx = (byte)sizeof(base64Decode) + BASE64_MIN - 1; plainSz = (plainSz * 3 + 3) / 4; if (plainSz > *outLen) return BAD_FUNC_ARG; while (inLen > 3) { - byte b1, b2, b3; - byte e1 = in[j++]; - byte e2 = in[j++]; - byte e3 = in[j++]; - byte e4 = in[j++]; - int pad3 = 0; int pad4 = 0; + byte b1, b2, b3; + if ((ret = Base64_SkipNewline(in, &inLen, &j)) != 0) { + return ret; + } + byte e1 = in[j++]; + if ((ret = Base64_SkipNewline(in, &inLen, &j)) != 0) { + return ret; + } + byte e2 = in[j++]; + if ((ret = Base64_SkipNewline(in, &inLen, &j)) != 0) { + return ret; + } + byte e3 = in[j++]; + if ((ret = Base64_SkipNewline(in, &inLen, &j)) != 0) { + return ret; + } + byte e4 = in[j++]; + if (e1 == 0) /* end file 0's */ break; if (e3 == PAD) @@ -118,24 +157,6 @@ int Base64_Decode(const byte* in, word32 inLen, byte* out, word32* outLen) break; inLen -= 4; - if (inLen && (in[j] == ' ' || in[j] == '\r' || in[j] == '\n')) { - byte endLine = in[j++]; - inLen--; - while (inLen && endLine == ' ') { /* allow trailing whitespace */ - endLine = in[j++]; - inLen--; - } - if (endLine == '\r') { - if (inLen) { - endLine = in[j++]; - inLen--; - } - } - if (endLine != '\n') { - WOLFSSL_MSG("Bad end of line in Base64 Decode"); - return ASN_INPUT_E; - } - } } /* If the output buffer has a room for an extra byte, add a null terminator */ if (out && *outLen > i) diff --git a/wolfcrypt/src/logging.c b/wolfcrypt/src/logging.c index 909062705..70d53121b 100644 --- a/wolfcrypt/src/logging.c +++ b/wolfcrypt/src/logging.c @@ -137,6 +137,12 @@ int wolfSSL_SetLoggingCb(wolfSSL_Logging_cb f) #endif } +/* allow this to be set to NULL, so logs can be redirected to default output */ +wolfSSL_Logging_cb wolfSSL_GetLoggingCb(void) +{ + return log_function; +} + int wolfSSL_Debugging_ON(void) { @@ -346,6 +352,11 @@ void WOLFSSL_LEAVE(const char* msg, int ret) wolfssl_log(LEAVE_LOG , buffer); } } + +WOLFSSL_API int WOLFSSL_IS_DEBUG_ON(void) +{ + return loggingEnabled; +} #endif /* !WOLFSSL_DEBUG_ERRORS_ONLY */ #endif /* DEBUG_WOLFSSL */ diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index e8217ba09..d0e28fbe5 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -1383,7 +1383,7 @@ int base64_test(void) #endif const byte badSmall[] = "AAA Gdj="; const byte badLarge[] = "AAA~Gdj="; - const byte badEOL[] = "A+Gd "; + const byte badEOL[] = "A+Gd AA"; int i; /* Good Base64 encodings. */ diff --git a/wolfssl/openssl/ec.h b/wolfssl/openssl/ec.h index a8ef9d0c2..25640af2b 100644 --- a/wolfssl/openssl/ec.h +++ b/wolfssl/openssl/ec.h @@ -76,11 +76,14 @@ typedef struct WOLFSSL_EC_KEY WOLFSSL_EC_KEY; typedef struct WOLFSSL_EC_POINT WOLFSSL_EC_POINT; typedef struct WOLFSSL_EC_GROUP WOLFSSL_EC_GROUP; typedef struct WOLFSSL_EC_BUILTIN_CURVE WOLFSSL_EC_BUILTIN_CURVE; +/* WOLFSSL_EC_METHOD is just an alias of WOLFSSL_EC_GROUP for now */ +typedef struct WOLFSSL_EC_GROUP WOLFSSL_EC_METHOD; #define WOLFSSL_EC_TYPE_DEFINED #endif typedef WOLFSSL_EC_KEY EC_KEY; typedef WOLFSSL_EC_GROUP EC_GROUP; +typedef WOLFSSL_EC_GROUP EC_METHOD; typedef WOLFSSL_EC_POINT EC_POINT; typedef WOLFSSL_EC_BUILTIN_CURVE EC_builtin_curve; @@ -200,6 +203,11 @@ int wolfSSL_EC_GROUP_order_bits(const WOLFSSL_EC_GROUP *group); WOLFSSL_API void wolfSSL_EC_GROUP_free(WOLFSSL_EC_GROUP *group); WOLFSSL_API +const WOLFSSL_EC_METHOD* wolfSSL_EC_GROUP_method_of( + const WOLFSSL_EC_GROUP *group); +WOLFSSL_API +int wolfSSL_EC_METHOD_get_field_type(const WOLFSSL_EC_METHOD *meth); +WOLFSSL_API WOLFSSL_EC_POINT *wolfSSL_EC_POINT_new(const WOLFSSL_EC_GROUP *group); WOLFSSL_API int wolfSSL_EC_POINT_get_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group, @@ -265,6 +273,9 @@ char* wolfSSL_EC_POINT_point2hex(const WOLFSSL_EC_GROUP* group, #define EC_GROUP_get_degree wolfSSL_EC_GROUP_get_degree #define EC_GROUP_get_order wolfSSL_EC_GROUP_get_order #define EC_GROUP_order_bits wolfSSL_EC_GROUP_order_bits +#define EC_GROUP_method_of wolfSSL_EC_GROUP_method_of + +#define EC_METHOD_get_field_type wolfSSL_EC_METHOD_get_field_type #define EC_POINT_new wolfSSL_EC_POINT_new #define EC_POINT_free wolfSSL_EC_POINT_free diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 8df5e400b..18dfc6779 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -1207,8 +1207,6 @@ enum { #define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b) #define TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca9) -#define EC_METHOD_get_field_type(x) -1 - #define EVP_CIPHER_mode WOLFSSL_CIPHER_mode /* WOLFSSL_EVP_CIPHER is just the string name of the cipher */ #define EVP_CIPHER_name(x) x diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 8d5045b6f..b2f3f52e8 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -151,6 +151,8 @@ typedef struct WOLFSSL_EC_KEY WOLFSSL_EC_KEY; typedef struct WOLFSSL_EC_POINT WOLFSSL_EC_POINT; typedef struct WOLFSSL_EC_GROUP WOLFSSL_EC_GROUP; typedef struct WOLFSSL_EC_BUILTIN_CURVE WOLFSSL_EC_BUILTIN_CURVE; +/* WOLFSSL_EC_METHOD is just an alias of WOLFSSL_EC_GROUP for now */ +typedef struct WOLFSSL_EC_GROUP WOLFSSL_EC_METHOD; #define WOLFSSL_EC_TYPE_DEFINED #endif diff --git a/wolfssl/wolfcrypt/logging.h b/wolfssl/wolfcrypt/logging.h index ea1d88087..51d9b23b9 100644 --- a/wolfssl/wolfcrypt/logging.h +++ b/wolfssl/wolfcrypt/logging.h @@ -93,6 +93,7 @@ typedef void (*wolfSSL_Logging_cb)(const int logLevel, const char *const logMessage); WOLFSSL_API int wolfSSL_SetLoggingCb(wolfSSL_Logging_cb log_function); +WOLFSSL_API wolfSSL_Logging_cb wolfSSL_GetLoggingCb(void); /* turn logging on, only if compiled in */ WOLFSSL_API int wolfSSL_Debugging_ON(void); @@ -148,6 +149,7 @@ WOLFSSL_API void wolfSSL_Debugging_OFF(void); WOLFSSL_API void WOLFSSL_LEAVE(const char* msg, int ret); #define WOLFSSL_STUB(m) \ WOLFSSL_MSG(WOLFSSL_LOG_CAT(wolfSSL Stub, m, not implemented)) + WOLFSSL_API int WOLFSSL_IS_DEBUG_ON(void); WOLFSSL_API void WOLFSSL_MSG(const char* msg); WOLFSSL_API void WOLFSSL_BUFFER(const byte* buffer, word32 length); @@ -157,6 +159,7 @@ WOLFSSL_API void wolfSSL_Debugging_OFF(void); #define WOLFSSL_ENTER(m) #define WOLFSSL_LEAVE(m, r) #define WOLFSSL_STUB(m) + #define WOLFSSL_IS_DEBUG_ON() 0 #define WOLFSSL_MSG(m) #define WOLFSSL_BUFFER(b, l) diff --git a/wolfssl/wolfcrypt/tfm.h b/wolfssl/wolfcrypt/tfm.h index 3ad33e11b..961472cff 100644 --- a/wolfssl/wolfcrypt/tfm.h +++ b/wolfssl/wolfcrypt/tfm.h @@ -258,6 +258,11 @@ #ifndef FP_MAX_BITS #define FP_MAX_BITS 4096 #endif +#ifdef WOLFSSL_OPENSSH + /* OpenSSH uses some BIG primes so we need to accommodate for that */ + #undef FP_MAX_BITS + #define FP_MAX_BITS 16384 +#endif #define FP_MAX_SIZE (FP_MAX_BITS+(8*DIGIT_BIT)) /* will this lib work? */ From ae948e2a07c5ffd03dd57f98d9b64ea1168cdc99 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 20 Dec 2019 16:23:41 +0100 Subject: [PATCH 067/649] Pass try-ciphers define EVP_CIPHER_CTX_set_iv as wolfSSL_EVP_CIPHER_CTX_set_iv add wolfSSL_GetLoggingCb functionality when compiling without enable-debug fix initialization vector handling of all cipher modes when using our EVP layer. The IV was incorrectly handled in initialization as well as not being updated after processing --- src/ssl.c | 89 ++++++++++++++++++++++++++++++++++------- wolfcrypt/src/logging.c | 4 ++ wolfssl/openssl/evp.h | 1 + 3 files changed, 80 insertions(+), 14 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index ed045b6b9..e566455f4 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -16720,6 +16720,10 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ctx->bufUsed = 0; ctx->lastUsed = 0; + if (!iv && ctx->ivSz) { + iv = ctx->iv; + } + #ifndef NO_AES #ifdef HAVE_AES_CBC #ifdef WOLFSSL_AES_128 @@ -16731,6 +16735,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ctx->flags |= WOLFSSL_EVP_CIPH_CBC_MODE; ctx->keyLen = 16; ctx->block_size = AES_BLOCK_SIZE; + ctx->ivSz = AES_BLOCK_SIZE; if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; if (key) { @@ -16755,6 +16760,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ctx->flags |= WOLFSSL_EVP_CIPH_CBC_MODE; ctx->keyLen = 24; ctx->block_size = AES_BLOCK_SIZE; + ctx->ivSz = AES_BLOCK_SIZE; if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; if (key) { @@ -16779,6 +16785,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ctx->flags |= WOLFSSL_EVP_CIPH_CBC_MODE; ctx->keyLen = 32; ctx->block_size = AES_BLOCK_SIZE; + ctx->ivSz = AES_BLOCK_SIZE; if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; if (key) { @@ -16810,7 +16817,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ctx->keyLen = 16; ctx->block_size = AES_BLOCK_SIZE; ctx->authTagSz = AES_BLOCK_SIZE; - ctx->ivSz = 12; /* set default IV length to 96 bits */ + ctx->ivSz = GCM_NONCE_MID_SZ; XMEMSET(ctx->authTag, 0, ctx->authTagSz); if (iv) @@ -16836,7 +16843,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ctx->keyLen = 24; ctx->block_size = AES_BLOCK_SIZE; ctx->authTagSz = AES_BLOCK_SIZE; - ctx->ivSz = 12; /* set default IV length to 96 bits */ + ctx->ivSz = GCM_NONCE_MID_SZ; XMEMSET(ctx->authTag, 0, ctx->authTagSz); if (iv) @@ -16862,7 +16869,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ctx->keyLen = 32; ctx->block_size = AES_BLOCK_SIZE; ctx->authTagSz = AES_BLOCK_SIZE; - ctx->ivSz = 12; /* set default IV length to 96 bits */ + ctx->ivSz = GCM_NONCE_MID_SZ; XMEMSET(ctx->authTag, 0, ctx->authTagSz); if (iv) @@ -16891,6 +16898,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ctx->flags |= WOLFSSL_EVP_CIPH_CTR_MODE; ctx->keyLen = 16; ctx->block_size = NO_PADDING_BLOCK_SIZE; + ctx->ivSz = AES_BLOCK_SIZE; #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) ctx->cipher.aes.left = 0; #endif @@ -16918,6 +16926,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ctx->flags |= WOLFSSL_EVP_CIPH_CTR_MODE; ctx->keyLen = 24; ctx->block_size = NO_PADDING_BLOCK_SIZE; + ctx->ivSz = AES_BLOCK_SIZE; #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) ctx->cipher.aes.left = 0; #endif @@ -16945,6 +16954,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ctx->flags |= WOLFSSL_EVP_CIPH_CTR_MODE; ctx->keyLen = 32; ctx->block_size = NO_PADDING_BLOCK_SIZE; + ctx->ivSz = AES_BLOCK_SIZE; #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) ctx->cipher.aes.left = 0; #endif @@ -17032,6 +17042,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ctx->flags |= WOLFSSL_EVP_CIPH_CBC_MODE; ctx->keyLen = 8; ctx->block_size = DES_BLOCK_SIZE; + ctx->ivSz = DES_BLOCK_SIZE; if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; if (key) { @@ -17073,6 +17084,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ctx->flags |= WOLFSSL_EVP_CIPH_CBC_MODE; ctx->keyLen = 24; ctx->block_size = DES_BLOCK_SIZE; + ctx->ivSz = DES_BLOCK_SIZE; if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; if (key) { @@ -17130,6 +17142,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ctx->flags |= WOLFSSL_EVP_CIPH_CBC_MODE; ctx->keyLen = IDEA_KEY_SIZE; ctx->block_size = 8; + ctx->ivSz = IDEA_BLOCK_SIZE; if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; if (key) { @@ -17151,6 +17164,12 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ctx->keyLen = 0; ctx->block_size = 16; } + ctx->ivSz = wolfSSL_EVP_CIPHER_CTX_iv_length(ctx); + if (iv && iv != ctx->iv) { + if (wolfSSL_StoreExternalIV(ctx) != WOLFSSL_SUCCESS) { + return WOLFSSL_FAILURE; + } + } (void)ret; /* remove warning. If execution reaches this point, ret=0 */ return WOLFSSL_SUCCESS; } @@ -17197,20 +17216,21 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) int wolfSSL_EVP_CIPHER_CTX_set_iv(WOLFSSL_EVP_CIPHER_CTX* ctx, byte* iv, int ivLen) { + int expectedIvLen; + WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_set_iv_length"); - if (!ctx || !iv -#ifndef NO_AES - || ivLen != AES_BLOCK_SIZE -#elif !defined(NO_DES3) - || ivLen != DES_BLOCK_SIZE -#endif - ) { + if (!ctx || !iv || !ivLen) { return WOLFSSL_FAILURE; } - XMEMCPY(ctx->iv, iv, ivLen); - ctx->ivSz= ivLen; - return WOLFSSL_SUCCESS; + expectedIvLen = wolfSSL_EVP_CIPHER_CTX_iv_length(ctx); + + if (expectedIvLen == 0 || expectedIvLen != ivLen) { + WOLFSSL_MSG("Wrong ivLen value"); + return WOLFSSL_FAILURE; + } + + return wolfSSL_EVP_CipherInit(ctx, NULL, NULL, iv, -1); } #endif @@ -17310,12 +17330,14 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) #ifndef NO_DES3 case DES_CBC_TYPE : + WOLFSSL_MSG("DES CBC"); if (ctx->enc) wc_Des_CbcEncrypt(&ctx->cipher.des, dst, src, len); else wc_Des_CbcDecrypt(&ctx->cipher.des, dst, src, len); break; case DES_EDE3_CBC_TYPE : + WOLFSSL_MSG("DES3 CBC"); if (ctx->enc) ret = wc_Des3_CbcEncrypt(&ctx->cipher.des3, dst, src, len); else @@ -17323,9 +17345,11 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) break; #ifdef WOLFSSL_DES_ECB case DES_ECB_TYPE : + WOLFSSL_MSG("DES ECB"); ret = wc_Des_EcbEncrypt(&ctx->cipher.des, dst, src, len); break; case DES_EDE3_ECB_TYPE : + WOLFSSL_MSG("DES3 ECB"); ret = wc_Des3_EcbEncrypt(&ctx->cipher.des3, dst, src, len); break; #endif @@ -17333,12 +17357,14 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) #ifndef NO_RC4 case ARC4_TYPE : + WOLFSSL_MSG("ARC4"); wc_Arc4Process(&ctx->cipher.arc4, dst, src, len); break; #endif #ifdef HAVE_IDEA case IDEA_CBC_TYPE : + WOLFSSL_MSG("IDEA CBC"); if (ctx->enc) wc_IdeaCbcEncrypt(&ctx->cipher.idea, dst, src, len); else @@ -17346,6 +17372,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) break; #endif case NULL_CIPHER_TYPE : + WOLFSSL_MSG("NULL CIPHER"); XMEMCPY(dst, src, len); break; @@ -17360,6 +17387,10 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) return 0; /* failure */ } + if (wolfSSL_StoreExternalIV(ctx) != WOLFSSL_SUCCESS) { + return WOLFSSL_FAILURE; + } + WOLFSSL_MSG("wolfSSL_EVP_Cipher success"); return WOLFSSL_SUCCESS; /* success */ } @@ -17397,6 +17428,13 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE); break; #endif /* HAVE_AESGCM */ +#ifdef HAVE_AES_ECB + case AES_128_ECB_TYPE : + case AES_192_ECB_TYPE : + case AES_256_ECB_TYPE : + WOLFSSL_MSG("AES ECB"); + break; +#endif #ifdef WOLFSSL_AES_COUNTER case AES_128_CTR_TYPE : case AES_192_CTR_TYPE : @@ -17419,6 +17457,14 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) XMEMCPY(ctx->iv, &ctx->cipher.des3.reg, DES_BLOCK_SIZE); break; #endif +#ifdef WOLFSSL_DES_ECB + case DES_ECB_TYPE : + WOLFSSL_MSG("DES ECB"); + break; + case DES_EDE3_ECB_TYPE : + WOLFSSL_MSG("DES3 ECB"); + break; +#endif #ifdef HAVE_IDEA case IDEA_CBC_TYPE : @@ -17473,6 +17519,13 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) XMEMCPY(&ctx->cipher.aes.reg, ctx->iv, AES_BLOCK_SIZE); break; #endif +#ifdef HAVE_AES_ECB + case AES_128_ECB_TYPE : + case AES_192_ECB_TYPE : + case AES_256_ECB_TYPE : + WOLFSSL_MSG("AES ECB"); + break; +#endif #ifdef WOLFSSL_AES_COUNTER case AES_128_CTR_TYPE : case AES_192_CTR_TYPE : @@ -17495,6 +17548,14 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) XMEMCPY(&ctx->cipher.des3.reg, ctx->iv, DES_BLOCK_SIZE); break; #endif +#ifdef WOLFSSL_DES_ECB + case DES_ECB_TYPE : + WOLFSSL_MSG("DES ECB"); + break; + case DES_EDE3_ECB_TYPE : + WOLFSSL_MSG("DES3 ECB"); + break; +#endif #ifdef HAVE_IDEA case IDEA_CBC_TYPE : @@ -34695,7 +34756,7 @@ int wolfSSL_EC_POINT_is_at_infinity(const WOLFSSL_EC_GROUP *group, } ret = wc_ecc_point_is_at_infinity((ecc_point*)point->internal); - if (ret <= 0) { + if (ret < 0) { WOLFSSL_MSG("ecc_point_is_at_infinity failure"); return WOLFSSL_FAILURE; } diff --git a/wolfcrypt/src/logging.c b/wolfcrypt/src/logging.c index 70d53121b..6b6ab7512 100644 --- a/wolfcrypt/src/logging.c +++ b/wolfcrypt/src/logging.c @@ -140,7 +140,11 @@ int wolfSSL_SetLoggingCb(wolfSSL_Logging_cb f) /* allow this to be set to NULL, so logs can be redirected to default output */ wolfSSL_Logging_cb wolfSSL_GetLoggingCb(void) { +#ifdef DEBUG_WOLFSSL return log_function; +#else + return NULL; +#endif } diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index 1d564abd1..e34a50809 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -708,6 +708,7 @@ typedef WOLFSSL_EVP_CIPHER_CTX EVP_CIPHER_CTX; #define EVP_CIPHER_CTX_clear_flags wolfSSL_EVP_CIPHER_CTX_clear_flags #define EVP_CIPHER_CTX_set_padding wolfSSL_EVP_CIPHER_CTX_set_padding #define EVP_CIPHER_CTX_flags wolfSSL_EVP_CIPHER_CTX_flags +#define EVP_CIPHER_CTX_set_iv wolfSSL_EVP_CIPHER_CTX_set_iv #define EVP_add_digest wolfSSL_EVP_add_digest #define EVP_add_cipher wolfSSL_EVP_add_cipher #define EVP_cleanup wolfSSL_EVP_cleanup From ab56d078a44207b42fc2e00e3ba643f327dc1a79 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 20 Dec 2019 17:24:06 +0100 Subject: [PATCH 068/649] keygen-moduli passed Handle trailing newlines in wolfSSL_BN_hex2bn --- configure.ac | 2 +- src/ssl.c | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 30280d922..a6268fc51 100644 --- a/configure.ac +++ b/configure.ac @@ -500,7 +500,7 @@ fi if test "$ENABLED_OPENSSH" = "yes" then ENABLED_FORTRESS="yes" - AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_OPENSSH -DHAVE_EX_DATA" + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_OPENSSH -DHAVE_EX_DATA -DWOLFSSL_BASE16" fi #Qt Support diff --git a/src/ssl.c b/src/ssl.c index e566455f4..ae55c77a6 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -46782,6 +46782,7 @@ int wolfSSL_BN_hex2bn(WOLFSSL_BIGNUM** bn, const char* str) byte decoded[1024]; #endif int weOwn = 0; + int strLen; WOLFSSL_MSG("wolfSSL_BN_hex2bn"); @@ -46791,9 +46792,16 @@ int wolfSSL_BN_hex2bn(WOLFSSL_BIGNUM** bn, const char* str) return ret; #endif - if (str == NULL || str[0] == '\0') + if (str == NULL || str[0] == '\0') { WOLFSSL_MSG("Bad function argument"); - else if (Base16_Decode((byte*)str, (int)XSTRLEN(str), decoded, &decSz) < 0) + return WOLFSSL_FAILURE; + } + + strLen = XSTRLEN(str); + /* ignore trailing new lines */ + while (str[strLen-1] == '\n' && strLen > 0) strLen--; + + if (Base16_Decode((byte*)str, strLen, decoded, &decSz) < 0) WOLFSSL_MSG("Bad Base16_Decode error"); else if (bn == NULL) ret = decSz; From 6e72a299d783c0d8602595372e69b31a7f1bc9b1 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 9 Jan 2020 18:55:45 +0100 Subject: [PATCH 069/649] Don't undef HAVE_GETADDRINFO as it disables defines in projects using wolfSSL Change test_wolfssl_EVP_aes_gcm so that changing the tag will fail the authentication check --- src/ssl.c | 11 +++++++++++ src/wolfio.c | 5 +++-- tests/api.c | 45 +++++++++++++++++++++------------------------ wolfcrypt/src/asn.c | 6 +++++- wolfssl/wolfio.h | 6 +----- 5 files changed, 41 insertions(+), 32 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index ae55c77a6..7f5a5a609 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -40956,19 +40956,30 @@ int wolfSSL_CTX_get_ex_new_index(long idx, void* arg, void* a, void* b, void* wolfSSL_CRYPTO_get_ex_data(void * const* ex_data, int idx) { WOLFSSL_ENTER("wolfSSL_CTX_get_ex_data"); +#ifdef MAX_EX_DATA if(ex_data && idx < MAX_EX_DATA && idx >= 0) { return ex_data[idx]; } +#else + (void)ex_data; + (void)idx; +#endif return NULL; } int wolfSSL_CRYPTO_set_ex_data(void** ex_data, int idx, void *data) { WOLFSSL_ENTER("wolfSSL_CRYPTO_set_ex_data"); +#ifdef MAX_EX_DATA if (ex_data && idx < MAX_EX_DATA && idx >= 0) { ex_data[idx] = data; return WOLFSSL_SUCCESS; } +#else + (void)ex_data; + (void)idx; + (void)data; +#endif return WOLFSSL_FAILURE; } diff --git a/src/wolfio.c b/src/wolfio.c index e64d82284..f72ada6c3 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -770,7 +770,7 @@ int wolfIO_TcpConnect(SOCKET_T* sockfd, const char* ip, word16 port, int to_sec) int ret = 0; SOCKADDR_S addr; int sockaddr_len = sizeof(SOCKADDR_IN); -#ifdef HAVE_GETADDRINFO +#ifndef WOLF_C99 ADDRINFO hints; ADDRINFO* answer = NULL; char strPort[6]; @@ -785,7 +785,8 @@ int wolfIO_TcpConnect(SOCKET_T* sockfd, const char* ip, word16 port, int to_sec) printf("TCP Connect: %s:%d\n", ip, port); #endif -#ifdef HAVE_GETADDRINFO + /* use gethostbyname for c99 */ +#ifndef WOLF_C99 XMEMSET(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; diff --git a/tests/api.c b/tests/api.c index 107d8b802..7c1119144 100644 --- a/tests/api.c +++ b/tests/api.c @@ -29315,34 +29315,31 @@ static void test_wolfssl_EVP_aes_gcm(void) if (i == 0) { /* Default uses 96-bits IV length */ #ifdef WOLFSSL_AES_128 - AssertIntEQ(1, EVP_EncryptInit_ex(&de[i], EVP_aes_128_gcm(), NULL, key, iv)); + AssertIntEQ(1, EVP_DecryptInit_ex(&de, EVP_aes_128_gcm(), NULL, NULL, NULL)); #elif defined(WOLFSSL_AES_192) - AssertIntEQ(1, EVP_EncryptInit_ex(&de[i], EVP_aes_192_gcm(), NULL, key, iv)); + AssertIntEQ(1, EVP_DecryptInit_ex(&de, EVP_aes_192_gcm(), NULL, NULL, NULL)); #elif defined(WOLFSSL_AES_256) - AssertIntEQ(1, EVP_EncryptInit_ex(&de[i], EVP_aes_256_gcm(), NULL, key, iv)); + AssertIntEQ(1, EVP_DecryptInit_ex(&de, EVP_aes_256_gcm(), NULL, NULL, NULL)); #endif - } - else { -#ifdef WOLFSSL_AES_128 - AssertIntEQ(1, EVP_EncryptInit_ex(&de[i], EVP_aes_128_gcm(), NULL, NULL, NULL)); -#elif defined(WOLFSSL_AES_192) - AssertIntEQ(1, EVP_EncryptInit_ex(&de[i], EVP_aes_192_gcm(), NULL, NULL, NULL)); -#elif defined(WOLFSSL_AES_256) - AssertIntEQ(1, EVP_EncryptInit_ex(&de[i], EVP_aes_256_gcm(), NULL, NULL, NULL)); -#endif - /* non-default must to set the IV length first */ - AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_IVLEN, ivSz, NULL)); - AssertIntEQ(1, EVP_EncryptInit_ex(&de[i], NULL, NULL, key, iv)); + AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&de, EVP_CTRL_GCM_SET_IVLEN, ivSz, NULL)); + AssertIntEQ(1, EVP_DecryptInit_ex(&de, NULL, NULL, key, iv)); + AssertIntEQ(1, EVP_DecryptUpdate(&de, NULL, &len, aad, aadSz)); + AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&de, EVP_CTRL_GCM_SET_TAG, AES_BLOCK_SIZE, tag)); + AssertIntEQ(1, EVP_DecryptUpdate(&de, decryptedtxt, &len, ciphertxt, ciphertxtSz)); + decryptedtxtSz = len; + AssertIntGT(EVP_DecryptFinal_ex(&de, decryptedtxt, &len), 0); + decryptedtxtSz += len; + AssertIntEQ(ciphertxtSz, decryptedtxtSz); + AssertIntEQ(0, XMEMCMP(plaintxt, decryptedtxt, decryptedtxtSz)); - } - AssertIntEQ(1, EVP_EncryptUpdate(&de[i], NULL, &len, aad, aadSz)); - AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_TAG, AES_BLOCK_SIZE, tag)); - AssertIntEQ(1, EVP_DecryptUpdate(&de[i], decryptedtxt, &len, ciphertxt, ciphertxtSz)); - decryptedtxtSz = len; - AssertIntGT(EVP_DecryptFinal_ex(&de[i], decryptedtxt, &len), 0); - decryptedtxtSz += len; - AssertIntEQ(ciphertxtSz, decryptedtxtSz); - AssertIntEQ(0, XMEMCMP(plaintxt, decryptedtxt, decryptedtxtSz)); + /* modify tag*/ + tag[AES_BLOCK_SIZE-1]+=0xBB; + AssertIntEQ(1, EVP_DecryptUpdate(&de, NULL, &len, aad, aadSz)); + AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&de, EVP_CTRL_GCM_SET_TAG, AES_BLOCK_SIZE, tag)); + /* fail due to wrong tag */ + AssertIntEQ(0, EVP_DecryptUpdate(&de, decryptedtxt, &len, ciphertxt, ciphertxtSz)); + AssertIntGT(EVP_DecryptFinal_ex(&de, decryptedtxt, &len), 0); + AssertIntEQ(0, len); /* modify tag*/ tag[AES_BLOCK_SIZE-1]+=0xBB; diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index ac5403e42..b6082933a 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -10364,7 +10364,11 @@ int PemToDer(const unsigned char* buff, long longSz, int type, /* keyFormat is Key_Sum enum */ if (keyFormat) { #ifdef HAVE_ECC - *eccKey = (header == BEGIN_EC_PRIV || header == beginBuf) ? 1 : 0; + *eccKey = (header == BEGIN_EC_PRIV +#ifdef OPENSSL_EXTRA + || header == beginBuf +#endif + ) ? 1 : 0; #else *eccKey = 0; #endif diff --git a/wolfssl/wolfio.h b/wolfssl/wolfio.h index f6ca47c25..a101c31e0 100644 --- a/wolfssl/wolfio.h +++ b/wolfssl/wolfio.h @@ -328,11 +328,7 @@ #endif /* HAVE_SOCKADDR */ /* use gethostbyname for c99 */ - #ifdef WOLF_C99 - #undef HAVE_GETADDRINFO - #endif - - #ifdef HAVE_GETADDRINFO + #ifndef WOLF_C99 typedef struct addrinfo ADDRINFO; #endif #endif /* WOLFSSL_NO_SOCK */ From d6a160c637e3c6c7d7cd6e355fcbe845f557cfb9 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 10 Jan 2020 18:37:57 +0100 Subject: [PATCH 070/649] Fix error codes for OpenSSL compatiblity --- src/ssl.c | 27 ++++++++++++++++++++++++--- wolfcrypt/src/asn.c | 14 ++++++++++++++ wolfssl/openssl/ssl.h | 20 +++++++++++++++----- wolfssl/ssl.h | 6 +----- 4 files changed, 54 insertions(+), 13 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 7f5a5a609..7174a1625 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -25617,6 +25617,23 @@ unsigned long wolfSSL_ERR_peek_error(void) return wolfSSL_ERR_peek_error_line_data(NULL, NULL, NULL, NULL); } +int wolfSSL_ERR_GET_LIB(unsigned long err) +{ + switch (err) { + case PEM_R_NO_START_LINE: + case PEM_R_PROBLEMS_GETTING_PASSWORD: + case PEM_R_BAD_PASSWORD_READ: + case PEM_R_BAD_DECRYPT: + return ERR_LIB_PEM; + case EVP_R_BAD_DECRYPT: + case EVP_R_BN_DECODE_ERROR: + case EVP_R_DECODE_ERROR: + case EVP_R_PRIVATE_KEY_DECODE_ERROR: + return ERR_LIB_EVP; + default: + return 0; + } +} /* This function is to find global error values that are the same through out * all library version. With wolfSSL having only one set of error codes the @@ -25641,7 +25658,7 @@ int wolfSSL_ERR_GET_REASON(unsigned long err) ret = 0 - ret; /* setting as negative value */ /* wolfCrypt range is less than MAX (-100) wolfSSL range is MIN (-300) and lower */ - if (ret < MAX_CODE_E) { + if (ret < MAX_CODE_E && ret > MIN_CODE_E) { return ret; } else { @@ -44218,7 +44235,8 @@ unsigned long wolfSSL_ERR_peek_error_line_data(const char **file, int *line, } #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \ - defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_MYSQL_COMPATIBLE) + defined(WOLFSSL_OPENSSH) || defined(WOLFSSL_HAPROXY) || \ + defined(WOLFSSL_MYSQL_COMPATIBLE) { int ret = 0; @@ -44227,7 +44245,10 @@ unsigned long wolfSSL_ERR_peek_error_line_data(const char **file, int *line, WOLFSSL_MSG("Issue peeking at error node in queue"); return 0; } - ret = -ret; + /* OpenSSL uses positive error codes */ + if (ret < 0) { + ret = -ret; + } if (ret == ASN_NO_PEM_HEADER) return (ERR_LIB_PEM << 24) | PEM_R_NO_START_LINE; diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index b6082933a..5d9e831d7 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -69,6 +69,10 @@ ASN Options: #include #include +#ifdef OPENSSL_EXTRA +#include +#endif + #include #include #ifdef NO_INLINE @@ -10510,8 +10514,18 @@ int PemToDer(const unsigned char* buff, long longSz, int type, #endif /* !NO_WOLFSSL_SKIP_TRAILING_PAD */ } +#ifdef OPENSSL_EXTRA + if (ret) { + PEMerr(0, PEM_R_BAD_DECRYPT); + } +#endif ForceZero(password, passwordSz); } +#ifdef OPENSSL_EXTRA + else { + PEMerr(0, PEM_R_BAD_PASSWORD_READ); + } +#endif #ifdef WOLFSSL_SMALL_STACK XFREE(password, heap, DYNAMIC_TYPE_STRING); diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 18dfc6779..ab58cc19e 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -47,6 +47,9 @@ #include #endif +/* need MIN_CODE_E to determine wolfSSL error range */ +#include + /* all NID_* values are in asn.h */ #include @@ -749,6 +752,7 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define SYS_F_IOCTLSOCKET WOLFSSL_SYS_IOCTLSOCKET #define SYS_F_LISTEN WOLFSSL_SYS_LISTEN +#define ERR_GET_LIB wolfSSL_ERR_GET_LIB #define ERR_GET_REASON wolfSSL_ERR_GET_REASON #define ERR_put_error wolfSSL_ERR_put_error @@ -1088,15 +1092,21 @@ enum { * PEM_read_bio_X509 is called and the return error is lost. * The error that needs to be detected is: SSL_NO_PEM_HEADER. */ -#define ERR_GET_LIB(l) (int)((((unsigned long)l) >> 24L) & 0xffL) #define ERR_GET_FUNC(l) (int)((((unsigned long)l) >> 12L) & 0xfffL) #define PEM_F_PEM_DEF_CALLBACK 100 -#define PEM_R_NO_START_LINE 108 -#define PEM_R_PROBLEMS_GETTING_PASSWORD 109 -#define PEM_R_BAD_PASSWORD_READ 110 -#define PEM_R_BAD_DECRYPT 111 +/* Avoid wolfSSL error code range */ +#define PEM_R_NO_START_LINE (-MIN_CODE_E + 1) +#define PEM_R_PROBLEMS_GETTING_PASSWORD (-MIN_CODE_E + 2) +#define PEM_R_BAD_PASSWORD_READ (-MIN_CODE_E + 3) +#define PEM_R_BAD_DECRYPT (-MIN_CODE_E + 4) + +#define EVP_R_BAD_DECRYPT (-MIN_CODE_E + 100 + 1) +#define EVP_R_BN_DECODE_ERROR (-MIN_CODE_E + 100 + 2) +#define EVP_R_DECODE_ERROR (-MIN_CODE_E + 100 + 3) +#define EVP_R_PRIVATE_KEY_DECODE_ERROR (-MIN_CODE_E + 100 + 4) + #define ERR_LIB_PEM 9 #define ERR_LIB_X509 10 #define ERR_LIB_EVP 11 diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index b2f3f52e8..84f0b175f 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1045,6 +1045,7 @@ WOLFSSL_API int wolfSSL_CTX_mcast_set_highwater_cb(WOLFSSL_CTX*, CallbackMcastHighwater); WOLFSSL_API int wolfSSL_mcast_set_highwater_ctx(WOLFSSL*, void*); +WOLFSSL_API int wolfSSL_ERR_GET_LIB(unsigned long err); WOLFSSL_API int wolfSSL_ERR_GET_REASON(unsigned long err); WOLFSSL_API char* wolfSSL_ERR_error_string(unsigned long,char*); WOLFSSL_API void wolfSSL_ERR_error_string_n(unsigned long e, char* buf, @@ -1670,11 +1671,6 @@ enum { ASN1_GENERALIZEDTIME = 4, SSL_MAX_SSL_SESSION_ID_LENGTH = 32, - EVP_R_BAD_DECRYPT = 2, - EVP_R_BN_DECODE_ERROR = 3, - EVP_R_DECODE_ERROR = 4, - EVP_R_PRIVATE_KEY_DECODE_ERROR = 5, - SSL_ST_CONNECT = 0x1000, SSL_ST_ACCEPT = 0x2000, SSL_ST_MASK = 0x0FFF, From 58c239a49f48fa2ae0f168ac437dfd3cfdaacf62 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 10 Jan 2020 20:47:29 +0100 Subject: [PATCH 071/649] Fix stuff after rebase --- tests/api.c | 53 ++++++++++++++++++++++++++--------------------------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/tests/api.c b/tests/api.c index 7c1119144..546628b70 100644 --- a/tests/api.c +++ b/tests/api.c @@ -29315,43 +29315,42 @@ static void test_wolfssl_EVP_aes_gcm(void) if (i == 0) { /* Default uses 96-bits IV length */ #ifdef WOLFSSL_AES_128 - AssertIntEQ(1, EVP_DecryptInit_ex(&de, EVP_aes_128_gcm(), NULL, NULL, NULL)); + AssertIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_128_gcm(), NULL, key, iv)); #elif defined(WOLFSSL_AES_192) - AssertIntEQ(1, EVP_DecryptInit_ex(&de, EVP_aes_192_gcm(), NULL, NULL, NULL)); + AssertIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_192_gcm(), NULL, key, iv)); #elif defined(WOLFSSL_AES_256) - AssertIntEQ(1, EVP_DecryptInit_ex(&de, EVP_aes_256_gcm(), NULL, NULL, NULL)); + AssertIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_256_gcm(), NULL, key, iv)); #endif - AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&de, EVP_CTRL_GCM_SET_IVLEN, ivSz, NULL)); - AssertIntEQ(1, EVP_DecryptInit_ex(&de, NULL, NULL, key, iv)); - AssertIntEQ(1, EVP_DecryptUpdate(&de, NULL, &len, aad, aadSz)); - AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&de, EVP_CTRL_GCM_SET_TAG, AES_BLOCK_SIZE, tag)); - AssertIntEQ(1, EVP_DecryptUpdate(&de, decryptedtxt, &len, ciphertxt, ciphertxtSz)); - decryptedtxtSz = len; - AssertIntGT(EVP_DecryptFinal_ex(&de, decryptedtxt, &len), 0); - decryptedtxtSz += len; - AssertIntEQ(ciphertxtSz, decryptedtxtSz); - AssertIntEQ(0, XMEMCMP(plaintxt, decryptedtxt, decryptedtxtSz)); + } + else { +#ifdef WOLFSSL_AES_128 + AssertIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_128_gcm(), NULL, NULL, NULL)); +#elif defined(WOLFSSL_AES_192) + AssertIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_192_gcm(), NULL, NULL, NULL)); +#elif defined(WOLFSSL_AES_256) + AssertIntEQ(1, EVP_DecryptInit_ex(&de[i], EVP_aes_256_gcm(), NULL, NULL, NULL)); +#endif + /* non-default must to set the IV length first */ + AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_IVLEN, ivSz, NULL)); + AssertIntEQ(1, EVP_DecryptInit_ex(&de[i], NULL, NULL, key, iv)); - /* modify tag*/ - tag[AES_BLOCK_SIZE-1]+=0xBB; - AssertIntEQ(1, EVP_DecryptUpdate(&de, NULL, &len, aad, aadSz)); - AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&de, EVP_CTRL_GCM_SET_TAG, AES_BLOCK_SIZE, tag)); - /* fail due to wrong tag */ - AssertIntEQ(0, EVP_DecryptUpdate(&de, decryptedtxt, &len, ciphertxt, ciphertxtSz)); - AssertIntGT(EVP_DecryptFinal_ex(&de, decryptedtxt, &len), 0); - AssertIntEQ(0, len); - - /* modify tag*/ - tag[AES_BLOCK_SIZE-1]+=0xBB; - AssertIntEQ(1, EVP_EncryptUpdate(&de[i], NULL, &len, aad, aadSz)); + } + AssertIntEQ(1, EVP_DecryptUpdate(&de[i], NULL, &len, aad, aadSz)); AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_TAG, AES_BLOCK_SIZE, tag)); AssertIntEQ(1, EVP_DecryptUpdate(&de[i], decryptedtxt, &len, ciphertxt, ciphertxtSz)); decryptedtxtSz = len; AssertIntGT(EVP_DecryptFinal_ex(&de[i], decryptedtxt, &len), 0); decryptedtxtSz += len; AssertIntEQ(ciphertxtSz, decryptedtxtSz); - /* decrypted text should not be equal to plain text*/ - AssertIntNE(0, XMEMCMP(plaintxt, decryptedtxt, decryptedtxtSz)); + AssertIntEQ(0, XMEMCMP(plaintxt, decryptedtxt, decryptedtxtSz)); + + /* modify tag*/ + tag[AES_BLOCK_SIZE-1]+=0xBB; + AssertIntEQ(1, EVP_DecryptUpdate(&de[i], NULL, &len, aad, aadSz)); + AssertIntEQ(1, EVP_CIPHER_CTX_ctrl(&de[i], EVP_CTRL_GCM_SET_TAG, AES_BLOCK_SIZE, tag)); + /* fail due to wrong tag */ + AssertIntEQ(0, EVP_DecryptUpdate(&de[i], decryptedtxt, &len, ciphertxt, ciphertxtSz)); + AssertIntEQ(0, len); } printf(resultFmt, passed); From 9a0d3ba36976dc56cd88da2eed9f89b92390fd33 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Mon, 13 Jan 2020 10:45:23 +0100 Subject: [PATCH 072/649] Check boundaries in B64 decode ERR_get_error will always return a positive error code --- src/ssl.c | 7 +++---- tests/api.c | 5 ----- wolfcrypt/src/asn.c | 8 ++++---- wolfcrypt/src/coding.c | 34 +++++++++++++++++++++++----------- 4 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 7174a1625..533701d36 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -34453,7 +34453,7 @@ int wolfSSL_EC_POINT_oct2point(const WOLFSSL_EC_GROUP *group, (void)ctx; - return wolfSSL_ECPoint_d2i((unsigned char*)buf, len, group, p); + return wolfSSL_ECPoint_d2i((unsigned char*)buf, (unsigned int)len, group, p); } /* wolfSSL_EC_POINT_point2bn should return "in" if not null */ @@ -34484,7 +34484,7 @@ WOLFSSL_BIGNUM *wolfSSL_EC_POINT_point2bn(const WOLFSSL_EC_GROUP *group, if (wolfSSL_EC_POINT_point2oct(group, p, form, buf, len, ctx) == len) { - ret = wolfSSL_BN_bin2bn(buf, len, in); + ret = wolfSSL_BN_bin2bn(buf, (int)len, in); } XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -42535,7 +42535,6 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey_EVP(WOLFSSL_EVP_PKEY** out, wolfSSL_EVP_PKEY_free(pkey); return NULL; } - pkey->rsa->pkey = pkey; if (wolfSSL_RSA_LoadDer_ex(pkey->rsa, (const unsigned char*)pkey->pkey.ptr, @@ -46829,7 +46828,7 @@ int wolfSSL_BN_hex2bn(WOLFSSL_BIGNUM** bn, const char* str) return WOLFSSL_FAILURE; } - strLen = XSTRLEN(str); + strLen = (int)XSTRLEN(str); /* ignore trailing new lines */ while (str[strLen-1] == '\n' && strLen > 0) strLen--; diff --git a/tests/api.c b/tests/api.c index 546628b70..bb9676187 100644 --- a/tests/api.c +++ b/tests/api.c @@ -23171,12 +23171,7 @@ static void test_wolfSSL_ERR_put_error(void) AssertIntEQ(ERR_get_error_line_data(&file, &line, NULL, NULL), 0); PEMerr(4,4); - #if defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || \ - defined(WOLFSSL_HAPROXY) - AssertIntEQ(ERR_get_error(), -4); - #else AssertIntEQ(ERR_get_error(), 4); - #endif /* Empty and free up all error nodes */ ERR_clear_error(); diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 5d9e831d7..6473fb431 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -10334,15 +10334,15 @@ int PemToDer(const unsigned char* buff, long longSz, int type, /* look for matching footer */ footer = XSTRNSTR(beginEnd, beginBuf + STR_SIZEOF(BEGIN_PRIV_KEY_PREFIX), - (char*)buff + sz - beginEnd); + (unsigned int)((char*)buff + sz - beginEnd)); if (!footer) { WOLFSSL_MSG("Couldn't find PEM footer"); return ASN_NO_PEM_HEADER; } footer -= STR_SIZEOF(END_PRIV_KEY_PREFIX); - endLen = beginEnd - headerEnd - + endLen = (unsigned int)(beginEnd - headerEnd - (STR_SIZEOF(BEGIN_PRIV_KEY_PREFIX) - - STR_SIZEOF(END_PRIV_KEY_PREFIX)); + STR_SIZEOF(END_PRIV_KEY_PREFIX))); XMEMCPY(endBuf, footer, endLen); endBuf[endLen] = '\0'; @@ -10394,7 +10394,7 @@ int PemToDer(const unsigned char* buff, long longSz, int type, #endif /* WOLFSSL_ENCRYPTED_KEYS */ /* find footer */ - footerEnd = XSTRNSTR(headerEnd, footer, (char*)buff + sz - headerEnd); + footerEnd = XSTRNSTR(headerEnd, footer, (unsigned int)((char*)buff + sz - headerEnd)); if (!footerEnd) { if (info) info->consumed = longSz; /* No more certs if no footer */ diff --git a/wolfcrypt/src/coding.c b/wolfcrypt/src/coding.c index c81588957..ba535abc0 100644 --- a/wolfcrypt/src/coding.c +++ b/wolfcrypt/src/coding.c @@ -57,21 +57,21 @@ const byte base64Decode[] = { 62, BAD, BAD, BAD, 63, /* + starts at 0x2B */ 46, 47, 48, 49, 50, 51 }; -static WC_INLINE int Base64_SkipNewline(const byte* in, word32 *outLen, word32 *outJ) +static WC_INLINE int Base64_SkipNewline(const byte* in, word32 *inLen, word32 *outJ) { - word32 inLen = *outLen; + word32 len = *inLen; word32 j = *outJ; - if (inLen && (in[j] == ' ' || in[j] == '\r' || in[j] == '\n')) { + if (len && (in[j] == ' ' || in[j] == '\r' || in[j] == '\n')) { byte endLine = in[j++]; - inLen--; - while (inLen && endLine == ' ') { /* allow trailing whitespace */ + len--; + while (len && endLine == ' ') { /* allow trailing whitespace */ endLine = in[j++]; - inLen--; + len--; } if (endLine == '\r') { - if (inLen) { + if (len) { endLine = in[j++]; - inLen--; + len--; } } if (endLine != '\n') { @@ -79,7 +79,10 @@ static WC_INLINE int Base64_SkipNewline(const byte* in, word32 *outLen, word32 * return ASN_INPUT_E; } } - *outLen = inLen; + if (!len) { + return BUFFER_E; + } + *inLen = len; *outJ = j; return 0; } @@ -101,21 +104,32 @@ int Base64_Decode(const byte* in, word32 inLen, byte* out, word32* outLen) byte b1, b2, b3; if ((ret = Base64_SkipNewline(in, &inLen, &j)) != 0) { + if (ret == BUFFER_E) { + /* Running out of buffer here is not an error */ + break; + } return ret; } byte e1 = in[j++]; + if (e1 == '\0') { + break; + } + inLen--; if ((ret = Base64_SkipNewline(in, &inLen, &j)) != 0) { return ret; } byte e2 = in[j++]; + inLen--; if ((ret = Base64_SkipNewline(in, &inLen, &j)) != 0) { return ret; } byte e3 = in[j++]; + inLen--; if ((ret = Base64_SkipNewline(in, &inLen, &j)) != 0) { return ret; } byte e4 = in[j++]; + inLen--; if (e1 == 0) /* end file 0's */ break; @@ -155,8 +169,6 @@ int Base64_Decode(const byte* in, word32 inLen, byte* out, word32* outLen) out[i++] = b3; else break; - - inLen -= 4; } /* If the output buffer has a room for an extra byte, add a null terminator */ if (out && *outLen > i) From e6547c75cde0991d5e2e67f0d24cde8053808503 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 14 Jan 2020 17:06:04 +0100 Subject: [PATCH 073/649] Reimplement external data as it was before: a fixed size vector. This makes external data implementation easier as it doesn't require allocation or cleanup. Only zeroing the entire structure that it is in (which happens in all structures anyway) and then calling the appropriate getter and setter functions to manipulate external data. --- src/internal.c | 5 +- src/ssl.c | 185 +++++++++++----------------------------- wolfcrypt/src/asn.c | 9 +- wolfssl/internal.h | 8 +- wolfssl/openssl/ecdsa.h | 1 + wolfssl/openssl/rsa.h | 29 ------- wolfssl/ssl.h | 59 ++++++++++--- wolfssl/wolfcrypt/asn.h | 3 +- wolfssl/wolfcrypt/dh.h | 2 +- 9 files changed, 110 insertions(+), 191 deletions(-) diff --git a/src/internal.c b/src/internal.c index df537aa14..0d6fa1630 100644 --- a/src/internal.c +++ b/src/internal.c @@ -9553,7 +9553,10 @@ int DoVerifyCallback(WOLFSSL_CERT_MANAGER* cm, WOLFSSL* ssl, int ret, store->certs = args->certs; store->totalCerts = args->totalCerts; #if defined(HAVE_EX_DATA) || defined(FORTRESS) - store->ex_data[0] = ssl; + if (wolfSSL_CRYPTO_set_ex_data(&store->ex_data, 0, ssl) + != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("Failed to store ssl context in WOLFSSL_X509_STORE_CTX"); + } #endif if (ssl != NULL) { diff --git a/src/ssl.c b/src/ssl.c index 533701d36..cb782945f 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -23129,8 +23129,7 @@ int wolfSSL_BIO_set_ex_data(WOLFSSL_BIO *bio, int idx, void *data) WOLFSSL_ENTER("wolfSSL_BIO_set_ex_data"); #ifdef HAVE_EX_DATA if (bio != NULL && idx < MAX_EX_DATA) { - bio->ex_data[idx] = data; - return WOLFSSL_SUCCESS; + return wolfSSL_CRYPTO_set_ex_data(&bio->ex_data, idx, data); } #else (void)bio; @@ -23152,7 +23151,7 @@ void *wolfSSL_BIO_get_ex_data(WOLFSSL_BIO *bio, int idx) WOLFSSL_ENTER("wolfSSL_BIO_get_ex_data"); #ifdef HAVE_EX_DATA if (bio != NULL && idx < MAX_EX_DATA && idx >= 0) { - return bio->ex_data[idx]; + return wolfSSL_CRYPTO_get_ex_data(&bio->ex_data, idx); } #else (void)bio; @@ -24223,15 +24222,6 @@ WOLFSSL_X509_STORE* wolfSSL_X509_STORE_new(void) goto err_exit; #endif -#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) - sk = wolfSSL_sk_new_null(); - if (sk == NULL) { - WOLFSSL_MSG("WOLFSSL_STACK memory error"); - goto err_exit; - } - store->ex_data.data = sk; -#endif - #ifdef OPENSSL_EXTRA if ((store->param = (WOLFSSL_X509_VERIFY_PARAM*)XMALLOC( sizeof(WOLFSSL_X509_VERIFY_PARAM), @@ -24264,10 +24254,6 @@ void wolfSSL_X509_STORE_free(WOLFSSL_X509_STORE* store) #ifdef OPENSSL_EXTRA if (store->param != NULL) XFREE(store->param, NULL, DYNAMIC_TYPE_OPENSSL); -#endif -#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) - if (store->ex_data.data != NULL) - wolfSSL_sk_GENERIC_free(store->ex_data.data); #endif XFREE(store, NULL, DYNAMIC_TYPE_X509_STORE); } @@ -24366,7 +24352,7 @@ int wolfSSL_X509_STORE_CTX_init(WOLFSSL_X509_STORE_CTX* ctx, ctx->sesChain = NULL; ctx->domain = NULL; #if defined(HAVE_EX_DATA) || defined(FORTRESS) - XMEMSET(ctx->ex_data, 0, MAX_EX_DATA * sizeof(void*)); + XMEMSET(&ctx->ex_data, 0, sizeof(ctx->ex_data)); #endif ctx->userCtx = NULL; ctx->error = 0; @@ -25494,7 +25480,7 @@ void* wolfSSL_X509_STORE_CTX_get_ex_data(WOLFSSL_X509_STORE_CTX* ctx, int idx) WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_ex_data"); #if defined(HAVE_EX_DATA) || defined(FORTRESS) if (ctx != NULL) { - return wolfSSL_CRYPTO_get_ex_data(ctx->ex_data, idx); + return wolfSSL_CRYPTO_get_ex_data(&ctx->ex_data, idx); } #else (void)ctx; @@ -25513,7 +25499,7 @@ int wolfSSL_X509_STORE_CTX_set_ex_data(WOLFSSL_X509_STORE_CTX* ctx, int idx, #if defined(HAVE_EX_DATA) || defined(FORTRESS) if (ctx != NULL) { - return wolfSSL_CRYPTO_set_ex_data(ctx->ex_data, idx, data); + return wolfSSL_CRYPTO_set_ex_data(&ctx->ex_data, idx, data); } #else (void)ctx; @@ -29594,7 +29580,7 @@ static int SetDhInternal(WOLFSSL_DH* dh) return ret; } -#if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL)) +#if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH)) /* Set the members of DhKey into WOLFSSL_DH * DhKey was populated from wc_DhKeyDecode */ @@ -32711,15 +32697,6 @@ int wolfSSL_PEM_write_bio_RSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_RSA* key, return WOLFSSL_FAILURE; } - /* Key to DER */ - derSz = wc_RsaKeyToDer((RsaKey*)key->internal, derBuf, derMax); - if (derSz < 0) { - WOLFSSL_MSG("wc_RsaKeyToDer failed"); - XFREE(derBuf, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); - wolfSSL_EVP_PKEY_free(pkey); - return SSL_FAILURE; - } - pkey->pkey.ptr = (char*)XMALLOC(derSz, bio->heap, DYNAMIC_TYPE_TMP_BUFFER); if (pkey->pkey.ptr == NULL) { @@ -36765,8 +36742,8 @@ void* wolfSSL_RSA_get_ex_data(const WOLFSSL_RSA *rsa, int idx) { WOLFSSL_ENTER("wolfSSL_RSA_get_ex_data"); #ifdef HAVE_EX_DATA - if(rsa) { - return wolfSSL_CRYPTO_get_ex_data(rsa->ex_data, idx); + if (rsa) { + return wolfSSL_CRYPTO_get_ex_data(&rsa->ex_data, idx); } #else (void)rsa; @@ -36779,8 +36756,8 @@ int wolfSSL_RSA_set_ex_data(WOLFSSL_RSA *rsa, int idx, void *data) { WOLFSSL_ENTER("wolfSSL_RSA_set_ex_data"); #ifdef HAVE_EX_DATA - if(rsa) { - return wolfSSL_CRYPTO_set_ex_data(rsa->ex_data, idx, data); + if (rsa) { + return wolfSSL_CRYPTO_set_ex_data(&rsa->ex_data, idx, data); } #else (void)rsa; @@ -36942,7 +36919,7 @@ int wolfSSL_EC_KEY_LoadDer_ex(WOLFSSL_EC_KEY* key, const unsigned char* derBuf, } #endif /* HAVE_ECC */ -#if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL)) +#if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH)) /* return WOLFSSL_SUCCESS if success, WOLFSSL_FATAL_ERROR if error */ int wolfSSL_DH_LoadDer(WOLFSSL_DH* dh, const unsigned char* derBuf, int derSz) { @@ -40941,12 +40918,13 @@ int wolfSSL_CTX_use_PrivateKey(WOLFSSL_CTX *ctx, WOLFSSL_EVP_PKEY *pkey) #endif /* !NO_CERTS */ +#if defined(HAVE_EX_DATA) || defined(FORTRESS) void* wolfSSL_CTX_get_ex_data(const WOLFSSL_CTX* ctx, int idx) { WOLFSSL_ENTER("wolfSSL_CTX_get_ex_data"); #ifdef HAVE_EX_DATA if(ctx != NULL) { - return wolfSSL_CRYPTO_get_ex_data(ctx->ex_data, idx); + return wolfSSL_CRYPTO_get_ex_data(&ctx->ex_data, idx); } #else (void)ctx; @@ -40970,36 +40948,6 @@ int wolfSSL_CTX_get_ex_new_index(long idx, void* arg, void* a, void* b, return ctx_idx++; } -void* wolfSSL_CRYPTO_get_ex_data(void * const* ex_data, int idx) -{ - WOLFSSL_ENTER("wolfSSL_CTX_get_ex_data"); -#ifdef MAX_EX_DATA - if(ex_data && idx < MAX_EX_DATA && idx >= 0) { - return ex_data[idx]; - } -#else - (void)ex_data; - (void)idx; -#endif - return NULL; -} - -int wolfSSL_CRYPTO_set_ex_data(void** ex_data, int idx, void *data) -{ - WOLFSSL_ENTER("wolfSSL_CRYPTO_set_ex_data"); -#ifdef MAX_EX_DATA - if (ex_data && idx < MAX_EX_DATA && idx >= 0) { - ex_data[idx] = data; - return WOLFSSL_SUCCESS; - } -#else - (void)ex_data; - (void)idx; - (void)data; -#endif - return WOLFSSL_FAILURE; -} - /* Return the index that can be used for the WOLFSSL structure to store * application data. * @@ -41028,7 +40976,7 @@ int wolfSSL_CTX_set_ex_data(WOLFSSL_CTX* ctx, int idx, void* data) #ifdef HAVE_EX_DATA if (ctx != NULL) { - return wolfSSL_CRYPTO_set_ex_data(ctx->ex_data, idx, data); + return wolfSSL_CRYPTO_set_ex_data(&ctx->ex_data, idx, data); } #else (void)ctx; @@ -41037,6 +40985,7 @@ int wolfSSL_CTX_set_ex_data(WOLFSSL_CTX* ctx, int idx, void* data) #endif return WOLFSSL_FAILURE; } +#endif /* Returns char* to app data stored in ex[0]. @@ -41072,7 +41021,7 @@ int wolfSSL_set_ex_data(WOLFSSL* ssl, int idx, void* data) #if defined(HAVE_EX_DATA) || defined(FORTRESS) if (ssl != NULL) { - return wolfSSL_CRYPTO_set_ex_data(ssl->ex_data, idx, data); + return wolfSSL_CRYPTO_set_ex_data(&ssl->ex_data, idx, data); } #else WOLFSSL_MSG("HAVE_EX_DATA macro is not defined"); @@ -41090,7 +41039,7 @@ void* wolfSSL_get_ex_data(const WOLFSSL* ssl, int idx) WOLFSSL_ENTER("wolfSSL_get_ex_data"); #if defined(HAVE_EX_DATA) || defined(FORTRESS) if (ssl != NULL) { - return wolfSSL_CRYPTO_get_ex_data(ssl->ex_data, idx); + return wolfSSL_CRYPTO_get_ex_data(&ssl->ex_data, idx); } #else WOLFSSL_MSG("HAVE_EX_DATA macro is not defined"); @@ -41464,7 +41413,7 @@ end: } #ifndef NO_FILESYSTEM -#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) +#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH) /* Convert DH key parameters to DER format, write to output (outSz) * If output is NULL then max expected size is set to outSz and LENGTH_ONLY_E is * returned. @@ -42607,7 +42556,7 @@ int wolfSSL_SESSION_set_ex_data(WOLFSSL_SESSION* session, int idx, void* data) WOLFSSL_ENTER("wolfSSL_SESSION_set_ex_data"); #ifdef HAVE_EX_DATA if(session != NULL) { - return wolfSSL_CRYPTO_set_ex_data(session->ex_data, idx, data); + return wolfSSL_CRYPTO_set_ex_data(&session->ex_data, idx, data); } #else (void)session; @@ -42641,7 +42590,7 @@ void* wolfSSL_SESSION_get_ex_data(const WOLFSSL_SESSION* session, int idx) WOLFSSL_ENTER("wolfSSL_SESSION_get_ex_data"); #ifdef HAVE_EX_DATA if (session != NULL) { - return wolfSSL_CRYPTO_get_ex_data(session->ex_data, idx); + return wolfSSL_CRYPTO_get_ex_data(&session->ex_data, idx); } #else (void)session; @@ -44343,80 +44292,44 @@ int wolfSSL_X509_get_ex_new_index(int idx, void *arg, void *a, void *b, void *c) return x509_idx++; } -#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) -int wolfSSL_CRYPTO_set_ex_data(WOLFSSL_CRYPTO_EX_DATA* r, int idx, void* arg) +#if defined(HAVE_EX_DATA) || defined(FORTRESS) +void* wolfSSL_CRYPTO_get_ex_data(const WOLFSSL_CRYPTO_EX_DATA* ex_data, int idx) +{ + WOLFSSL_ENTER("wolfSSL_CTX_get_ex_data"); +#ifdef MAX_EX_DATA + if(ex_data && idx < MAX_EX_DATA && idx >= 0) { + return ex_data->ex_data[idx]; + } +#else + (void)ex_data; + (void)idx; +#endif + return NULL; +} + +int wolfSSL_CRYPTO_set_ex_data(WOLFSSL_CRYPTO_EX_DATA* ex_data, int idx, void *data) { - WOLFSSL_STACK* sk; WOLFSSL_ENTER("wolfSSL_CRYPTO_set_ex_data"); - - if (r == NULL || arg == NULL) { - WOLFSSL_MSG("Invalid Input: WOLFSSL_CRYPTO_EX_DATA"); - return WOLFSSL_FAILURE; +#ifdef MAX_EX_DATA + if (ex_data && idx < MAX_EX_DATA && idx >= 0) { + ex_data->ex_data[idx] = data; + return WOLFSSL_SUCCESS; } - - sk = r->data; - if (sk == NULL || sk->num < (unsigned long)idx) { - WOLFSSL_MSG("Invalid Input: Stack"); - return WOLFSSL_FAILURE; - } - - /* Go to node at idx */ - for (; sk != NULL && idx > 0; idx--) - sk = sk->next; - /* if node is tail of stack */ - if (sk == NULL) { - WOLFSSL_MSG("idx exceeds stack size."); - return WOLFSSL_FAILURE; - } - /* Free any data */ - if (sk->data.generic != NULL) - XFREE(sk->data.generic, NULL, DYNAMIC_TYPE_OPENSSL); - - sk->data.generic = arg; - - return WOLFSSL_SUCCESS; +#else + (void)ex_data; + (void)idx; + (void)data; +#endif + return WOLFSSL_FAILURE; } - -void* wolfSSL_CRYPTO_get_ex_data(const WOLFSSL_CRYPTO_EX_DATA* r, int idx) -{ - void* ex_data; - WOLFSSL_STACK* sk; - WOLFSSL_ENTER("wolfSSL_CRYPTO_get_ex_data"); - - if (r == NULL) { - WOLFSSL_MSG("Invalid Input: WOLFSSL_CRYPTO_EX_DATA"); - return NULL; - } - - sk = r->data; - if (sk == NULL || sk->num < (unsigned long)idx) { - WOLFSSL_MSG("Invalid Input: Stack"); - return NULL; - } - - /* Go to node at idx */ - for (; sk != NULL && idx > 0; idx--) - sk = sk->next; - /* if node is tail of stack */ - if (sk == NULL) { - WOLFSSL_MSG("idx exceeds stack size."); - return NULL; - } - ex_data = sk->data.generic; - if (ex_data == NULL) { - WOLFSSL_MSG("Error getting ex_data"); - } - - return ex_data; -} -#endif /* WOLFSSL_QT || OPENSSL_ALL */ +#endif /* defined(HAVE_EX_DATA) || defined(FORTRESS) */ void *wolfSSL_X509_get_ex_data(X509 *x509, int idx) { WOLFSSL_ENTER("wolfSSL_X509_get_ex_data"); #ifdef HAVE_EX_DATA if (x509 != NULL) { - return wolfSSL_CRYPTO_get_ex_data(x509->ex_data, idx); + return wolfSSL_CRYPTO_get_ex_data(&x509->ex_data, idx); } #else (void)x509; @@ -44431,7 +44344,7 @@ int wolfSSL_X509_set_ex_data(X509 *x509, int idx, void *data) #ifdef HAVE_EX_DATA if (x509 != NULL) { - return wolfSSL_CRYPTO_set_ex_data(x509->ex_data, idx, data); + return wolfSSL_CRYPTO_set_ex_data(&x509->ex_data, idx, data); } #else (void)x509; diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 6473fb431..2c938c3a9 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -10368,13 +10368,8 @@ int PemToDer(const unsigned char* buff, long longSz, int type, /* keyFormat is Key_Sum enum */ if (keyFormat) { #ifdef HAVE_ECC - *eccKey = (header == BEGIN_EC_PRIV -#ifdef OPENSSL_EXTRA - || header == beginBuf -#endif - ) ? 1 : 0; - #else - *eccKey = 0; + if (header == BEGIN_EC_PRIV) + *keyFormat = ECDSAk; #endif #if !defined(NO_DSA) if (header == BEGIN_DSA_PRIV) diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 028c0cf97..f3d9d2e6b 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2740,7 +2740,7 @@ struct WOLFSSL_CTX { void* userPRFArg; /* passed to prf callback */ #endif #ifdef HAVE_EX_DATA - void* ex_data[MAX_EX_DATA]; + WOLFSSL_CRYPTO_EX_DATA ex_data; #endif #if defined(HAVE_ALPN) && (defined(OPENSSL_ALL) || defined(WOLFSSL_NGINX) || defined(WOLFSSL_HAPROXY)) CallbackALPNSelect alpnSelect; @@ -3121,7 +3121,7 @@ struct WOLFSSL_SESSION { byte isAlloced; #endif #ifdef HAVE_EX_DATA - void* ex_data[MAX_EX_DATA]; + WOLFSSL_CRYPTO_EX_DATA ex_data; #endif }; @@ -3597,7 +3597,7 @@ struct WOLFSSL_X509 { #endif #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) #ifdef HAVE_EX_DATA - void* ex_data[MAX_EX_DATA]; + WOLFSSL_CRYPTO_EX_DATA ex_data; #endif byte* authKeyId; byte* subjKeyId; @@ -4007,7 +4007,7 @@ struct WOLFSSL { #endif byte keepCert; /* keep certificate after handshake */ #if defined(HAVE_EX_DATA) || defined(FORTRESS) - void* ex_data[MAX_EX_DATA]; /* external data, for Fortress */ + WOLFSSL_CRYPTO_EX_DATA ex_data; /* external data, for Fortress */ #endif int devId; /* async device id to use */ #ifdef HAVE_ONE_TIME_AUTH diff --git a/wolfssl/openssl/ecdsa.h b/wolfssl/openssl/ecdsa.h index db3faf8b3..77c1a18b0 100644 --- a/wolfssl/openssl/ecdsa.h +++ b/wolfssl/openssl/ecdsa.h @@ -25,6 +25,7 @@ #define WOLFSSL_ECDSA_H_ #include +#include #ifdef __cplusplus diff --git a/wolfssl/openssl/rsa.h b/wolfssl/openssl/rsa.h index ad8853fda..f573b10fb 100644 --- a/wolfssl/openssl/rsa.h +++ b/wolfssl/openssl/rsa.h @@ -61,35 +61,6 @@ typedef struct WOLFSSL_RSA_METHOD { typedef WOLFSSL_RSA_METHOD RSA_METHOD; -struct WOLFSSL_RSA { -#ifdef WC_RSA_BLINDING - WC_RNG* rng; /* for PrivateDecrypt blinding */ -#endif - WOLFSSL_BIGNUM* n; - WOLFSSL_BIGNUM* e; - WOLFSSL_BIGNUM* d; - WOLFSSL_BIGNUM* p; - WOLFSSL_BIGNUM* q; - WOLFSSL_BIGNUM* dmp1; /* dP */ - WOLFSSL_BIGNUM* dmq1; /* dQ */ - WOLFSSL_BIGNUM* iqmp; /* u */ - void* heap; - void* internal; /* our RSA */ - char inSet; /* internal set from external ? */ - char exSet; /* external set from internal ? */ - char ownRng; /* flag for if the rng should be free'd */ -#if defined(OPENSSL_EXTRA) - WOLFSSL_RSA_METHOD* meth; -#endif -#if defined(HAVE_EX_DATA) - void* ex_data[MAX_EX_DATA]; /* external data */ -#endif -#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) - wolfSSL_Mutex refMutex; /* ref count mutex */ - int refCount; /* reference count */ -#endif -}; - WOLFSSL_API WOLFSSL_RSA* wolfSSL_RSA_new(void); WOLFSSL_API void wolfSSL_RSA_free(WOLFSSL_RSA*); diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 84f0b175f..dfae99d2c 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -69,7 +69,6 @@ #include #include #include - #include #endif /* make sure old names are disabled */ @@ -81,7 +80,6 @@ #endif #elif (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) - #include #include /* We need the old SSL names */ @@ -92,6 +90,8 @@ #undef NO_OLD_WC_NAMES #endif #endif +/* Needed for WOLFSSL_RSA struct */ +#include #ifdef __cplusplus extern "C" { @@ -455,6 +455,12 @@ struct WOLFSSL_BIO_METHOD { typedef long (*wolf_bio_info_cb)(WOLFSSL_BIO *bio, int event, const char *parg, int iarg, long larg, long return_value); +#if defined(HAVE_EX_DATA) || defined(FORTRESS) +typedef struct WOLFSSL_CRYPTO_EX_DATA { + void* ex_data[MAX_EX_DATA]; +} WOLFSSL_CRYPTO_EX_DATA; +#endif + struct WOLFSSL_BIO { WOLFSSL_BUF_MEM* mem_buf; WOLFSSL_BIO_METHOD* method; @@ -477,13 +483,38 @@ struct WOLFSSL_BIO { byte init:1; /* bio has been initialized */ byte shutdown:1; /* close flag */ #ifdef HAVE_EX_DATA - void* ex_data[MAX_EX_DATA]; + WOLFSSL_CRYPTO_EX_DATA ex_data; #endif }; -typedef struct WOLFSSL_CRYPTO_EX_DATA { - WOLFSSL_STACK* data; -} WOLFSSL_CRYPTO_EX_DATA; +struct WOLFSSL_RSA { +#ifdef WC_RSA_BLINDING + WC_RNG* rng; /* for PrivateDecrypt blinding */ +#endif + WOLFSSL_BIGNUM* n; + WOLFSSL_BIGNUM* e; + WOLFSSL_BIGNUM* d; + WOLFSSL_BIGNUM* p; + WOLFSSL_BIGNUM* q; + WOLFSSL_BIGNUM* dmp1; /* dP */ + WOLFSSL_BIGNUM* dmq1; /* dQ */ + WOLFSSL_BIGNUM* iqmp; /* u */ + void* heap; + void* internal; /* our RSA */ + char inSet; /* internal set from external ? */ + char exSet; /* external set from internal ? */ + char ownRng; /* flag for if the rng should be free'd */ +#if defined(OPENSSL_EXTRA) + WOLFSSL_RSA_METHOD* meth; +#endif +#if defined(HAVE_EX_DATA) + WOLFSSL_CRYPTO_EX_DATA ex_data; /* external data */ +#endif +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) + wolfSSL_Mutex refMutex; /* ref count mutex */ + int refCount; /* reference count */ +#endif +}; typedef struct WOLFSSL_COMP_METHOD { int type; /* stunnel dereference */ @@ -513,6 +544,8 @@ struct WOLFSSL_X509_STORE { #endif #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) WOLFSSL_X509_STORE_CTX_verify_cb verify_cb; +#endif +#ifdef HAVE_EX_DATA WOLFSSL_CRYPTO_EX_DATA ex_data; #endif #if defined(OPENSSL_EXTRA) && defined(HAVE_CRL) @@ -578,7 +611,7 @@ struct WOLFSSL_X509_STORE_CTX { #endif char* domain; /* subject CN domain name */ #if defined(HAVE_EX_DATA) || defined(FORTRESS) - void* ex_data[MAX_EX_DATA]; /* external data */ + WOLFSSL_CRYPTO_EX_DATA ex_data; /* external data */ #endif #if defined(WOLFSSL_APACHE_HTTPD) || defined(OPENSSL_EXTRA) int depth; /* used in X509_STORE_CTX_*_depth */ @@ -930,9 +963,9 @@ WOLFSSL_API #endif /* SESSION_INDEX && SESSION_CERTS */ typedef int (*VerifyCallback)(int, WOLFSSL_X509_STORE_CTX*); -#ifdef OPENSSL_EXTRA typedef void (CallbackInfoState)(const WOLFSSL*, int, int); +#if defined(HAVE_EX_DATA) || defined(FORTRESS) typedef int (WOLFSSL_CRYPTO_EX_new)(void* p, void* ptr, WOLFSSL_CRYPTO_EX_DATA* a, int idx, long argValue, void* arg); typedef int (WOLFSSL_CRYPTO_EX_dup)(WOLFSSL_CRYPTO_EX_DATA* out, @@ -943,8 +976,6 @@ typedef void (WOLFSSL_CRYPTO_EX_free)(void* p, void* ptr, WOLFSSL_API int wolfSSL_get_ex_new_index(long argValue, void* arg, WOLFSSL_CRYPTO_EX_new* a, WOLFSSL_CRYPTO_EX_dup* b, WOLFSSL_CRYPTO_EX_free* c); -WOLFSSL_API int wolfSSL_CRYPTO_set_ex_data(WOLFSSL_CRYPTO_EX_DATA* r, int idx, void* arg); -WOLFSSL_API void* wolfSSL_CRYPTO_get_ex_data(const WOLFSSL_CRYPTO_EX_DATA* r, int idx); #endif WOLFSSL_API void wolfSSL_CTX_set_verify(WOLFSSL_CTX*, int, @@ -2019,8 +2050,12 @@ WOLFSSL_API WOLFSSL_ASN1_TIME *wolfSSL_ASN1_TIME_set(WOLFSSL_ASN1_TIME *s, time_ WOLFSSL_API int wolfSSL_sk_num(WOLFSSL_STACK* sk); WOLFSSL_API void* wolfSSL_sk_value(WOLFSSL_STACK* sk, int i); -WOLFSSL_API void* wolfSSL_CRYPTO_get_ex_data(void * const* ex_data, int idx); -WOLFSSL_API int wolfSSL_CRYPTO_set_ex_data(void** ex_data, int idx, void *data); +#if defined(HAVE_EX_DATA) || defined(FORTRESS) +WOLFSSL_API void* wolfSSL_CRYPTO_get_ex_data(const WOLFSSL_CRYPTO_EX_DATA* ex_data, + int idx); +WOLFSSL_API int wolfSSL_CRYPTO_set_ex_data(WOLFSSL_CRYPTO_EX_DATA* ex_data, int idx, + void *data); +#endif /* stunnel 4.28 needs */ WOLFSSL_API void* wolfSSL_CTX_get_ex_data(const WOLFSSL_CTX*, int); diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index b35a01dc4..12f835b6e 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -1144,7 +1144,8 @@ WOLFSSL_LOCAL int GetASNTag(const byte* input, word32* idx, byte* tag, WOLFSSL_LOCAL word32 SetLength(word32 length, byte* output); WOLFSSL_LOCAL word32 SetSequence(word32 len, byte* output); WOLFSSL_LOCAL word32 SetOctetString(word32 len, byte* output); -#if (defined(WOLFSSL_QT) || defined(OPENSSL_ALL)) && !defined(NO_DH) +#if (defined(WOLFSSL_QT) || defined(OPENSSL_ALL)) && !defined(NO_DH) \ + || defined(WOLFSSL_OPENSSH) WOLFSSL_LOCAL int wc_DhParamsToDer(DhKey* key, byte* out, word32* outSz); WOLFSSL_LOCAL int wc_DhPubKeyToDer(DhKey* key, byte* out, word32* outSz); WOLFSSL_LOCAL int wc_DhPrivKeyToDer(DhKey* key, byte* out, word32* outSz); diff --git a/wolfssl/wolfcrypt/dh.h b/wolfssl/wolfcrypt/dh.h index 27cf03c67..a69232cc0 100644 --- a/wolfssl/wolfcrypt/dh.h +++ b/wolfssl/wolfcrypt/dh.h @@ -59,7 +59,7 @@ typedef struct DhParams { /* Diffie-Hellman Key */ struct DhKey { mp_int p, g, q; /* group parameters */ -#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) +#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) || defined(WOLFSSL_OPENSSH) mp_int pub; mp_int priv; #endif From 50f8fb1475a83a405c9e3945b0b045573414f6ee Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 14 Jan 2020 19:37:29 +0100 Subject: [PATCH 074/649] Enable wc_RsaKeyToDer even when key generation is turned off --- src/ssl.c | 4 ++++ wolfssl/wolfcrypt/rsa.h | 5 ++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index cb782945f..ae3248f77 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -69,6 +69,10 @@ #include +#ifndef NO_RSA + #include +#endif + #ifdef OPENSSL_EXTRA /* openssl headers begin */ #include diff --git a/wolfssl/wolfcrypt/rsa.h b/wolfssl/wolfcrypt/rsa.h index f51484f53..b8e41608a 100644 --- a/wolfssl/wolfcrypt/rsa.h +++ b/wolfssl/wolfcrypt/rsa.h @@ -278,9 +278,8 @@ WOLFSSL_API int wc_RsaPublicKeyDecode(const byte* input, word32* inOutIdx, RsaKey*, word32); WOLFSSL_API int wc_RsaPublicKeyDecodeRaw(const byte* n, word32 nSz, const byte* e, word32 eSz, RsaKey* key); -#ifdef WOLFSSL_KEY_GEN - WOLFSSL_API int wc_RsaKeyToDer(RsaKey*, byte* output, word32 inLen); -#endif +WOLFSSL_API int wc_RsaKeyToDer(RsaKey*, byte* output, word32 inLen); + #ifdef WC_RSA_BLINDING WOLFSSL_API int wc_RsaSetRNG(RsaKey* key, WC_RNG* rng); From 59b001c484dbfc023fe46a2123ec7660e85e066d Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 14 Jan 2020 21:13:52 +0100 Subject: [PATCH 075/649] Fix header definitions when running CAVP self test --- wolfcrypt/src/asn.c | 129 +++++++++++++++++--------------------- wolfssl/internal.h | 2 + wolfssl/wolfcrypt/aes.h | 4 +- wolfssl/wolfcrypt/pkcs7.h | 2 +- wolfssl/wolfcrypt/sha3.h | 2 +- 5 files changed, 64 insertions(+), 75 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 2c938c3a9..9100e9423 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -82,9 +82,6 @@ ASN Options: #include #endif -#ifndef NO_PWDBASED - #include -#endif #ifndef NO_RC4 #include #endif @@ -132,7 +129,9 @@ extern int wc_InitRsaHw(RsaKey* key); #define ERROR_OUT(err, eLabel) { ret = (err); goto eLabel; } #ifdef HAVE_SELFTEST +#include #ifndef WOLFSSL_AES_KEY_SIZE_ENUM + #define WOLFSSL_AES_KEY_SIZE_ENUM enum Asn_Misc { AES_IV_SIZE = 16, AES_128_KEY_SIZE = 16, @@ -8788,20 +8787,6 @@ int ParseCert(DecodedCert* cert, int type, int verify, void* cm) return ret; } - -/* from SSL proper, for locking can't do find here anymore */ -#ifdef __cplusplus - extern "C" { -#endif - Signer* GetCA(void* signers, byte* hash); - #ifndef NO_SKID - Signer* GetCAByName(void* signers, byte* hash); - #endif -#ifdef __cplusplus - } -#endif - - #if defined(WOLFCRYPT_ONLY) || defined(NO_CERTS) /* dummy functions, not using wolfSSL so don't need actual ones */ @@ -12976,36 +12961,36 @@ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey, /* write DER encoded cert to buffer, size already checked */ -static int WriteCertBody(DerCert* der, byte* buffer) +static int WriteCertBody(DerCert* der, byte* buf) { int idx; /* signed part header */ - idx = SetSequence(der->total, buffer); + idx = SetSequence(der->total, buf); /* version */ - XMEMCPY(buffer + idx, der->version, der->versionSz); + XMEMCPY(buf + idx, der->version, der->versionSz); idx += der->versionSz; /* serial */ - XMEMCPY(buffer + idx, der->serial, der->serialSz); + XMEMCPY(buf + idx, der->serial, der->serialSz); idx += der->serialSz; /* sig algo */ - XMEMCPY(buffer + idx, der->sigAlgo, der->sigAlgoSz); + XMEMCPY(buf + idx, der->sigAlgo, der->sigAlgoSz); idx += der->sigAlgoSz; /* issuer */ - XMEMCPY(buffer + idx, der->issuer, der->issuerSz); + XMEMCPY(buf + idx, der->issuer, der->issuerSz); idx += der->issuerSz; /* validity */ - XMEMCPY(buffer + idx, der->validity, der->validitySz); + XMEMCPY(buf + idx, der->validity, der->validitySz); idx += der->validitySz; /* subject */ - XMEMCPY(buffer + idx, der->subject, der->subjectSz); + XMEMCPY(buf + idx, der->subject, der->subjectSz); idx += der->subjectSz; /* public key */ - XMEMCPY(buffer + idx, der->publicKey, der->publicKeySz); + XMEMCPY(buf + idx, der->publicKey, der->publicKeySz); idx += der->publicKeySz; if (der->extensionsSz) { /* extensions */ - XMEMCPY(buffer + idx, der->extensions, min(der->extensionsSz, + XMEMCPY(buf + idx, der->extensions, min(der->extensionsSz, (int)sizeof(der->extensions))); idx += der->extensionsSz; } @@ -13015,7 +13000,7 @@ static int WriteCertBody(DerCert* der, byte* buffer) /* Make RSA signature from buffer (sz), write to sig (sigSz) */ -static int MakeSignature(CertSignCtx* certSignCtx, const byte* buffer, int sz, +static int MakeSignature(CertSignCtx* certSignCtx, const byte* buf, int sz, byte* sig, int sigSz, RsaKey* rsaKey, ecc_key* eccKey, ed25519_key* ed25519Key, WC_RNG* rng, int sigAlgoType, void* heap) { @@ -13023,7 +13008,7 @@ static int MakeSignature(CertSignCtx* certSignCtx, const byte* buffer, int sz, (void)digestSz; (void)typeH; - (void)buffer; + (void)buf; (void)sz; (void)sig; (void)sigSz; @@ -13044,7 +13029,7 @@ static int MakeSignature(CertSignCtx* certSignCtx, const byte* buffer, int sz, ret = MEMORY_E; goto exit_ms; } - ret = HashForSignature(buffer, sz, sigAlgoType, certSignCtx->digest, + ret = HashForSignature(buf, sz, sigAlgoType, certSignCtx->digest, &typeH, &digestSz, 0); /* set next state, since WC_PENDING_E rentry for these are not "call again" */ certSignCtx->state = CERTSIGN_STATE_ENCODE; @@ -13096,7 +13081,7 @@ static int MakeSignature(CertSignCtx* certSignCtx, const byte* buffer, int sz, if (!rsaKey && !eccKey && ed25519Key) { word32 outSz = sigSz; - ret = wc_ed25519_sign_msg(buffer, sz, sig, &outSz, ed25519Key); + ret = wc_ed25519_sign_msg(buf, sz, sig, &outSz, ed25519Key); if (ret == 0) ret = outSz; } @@ -13130,26 +13115,26 @@ exit_ms: /* add signature to end of buffer, size of buffer assumed checked, return new length */ -static int AddSignature(byte* buffer, int bodySz, const byte* sig, int sigSz, +static int AddSignature(byte* buf, int bodySz, const byte* sig, int sigSz, int sigAlgoType) { byte seq[MAX_SEQ_SZ]; int idx = bodySz, seqSz; /* algo */ - idx += SetAlgoID(sigAlgoType, buffer ? buffer + idx : NULL, oidSigType, 0); + idx += SetAlgoID(sigAlgoType, buf ? buf + idx : NULL, oidSigType, 0); /* bit string */ - idx += SetBitString(sigSz, 0, buffer ? buffer + idx : NULL); + idx += SetBitString(sigSz, 0, buf ? buf + idx : NULL); /* signature */ - if (buffer) - XMEMCPY(buffer + idx, sig, sigSz); + if (buf) + XMEMCPY(buf + idx, sig, sigSz); idx += sigSz; /* make room for overall header */ seqSz = SetSequence(idx, seq); - if (buffer) { - XMEMMOVE(buffer + seqSz, buffer, idx); - XMEMCPY(buffer, seq, seqSz); + if (buf) { + XMEMMOVE(buf + seqSz, buf, idx); + XMEMCPY(buf, seq, seqSz); } return idx + seqSz; @@ -13495,32 +13480,32 @@ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey, /* write DER encoded cert req to buffer, size already checked */ -static int WriteCertReqBody(DerCert* der, byte* buffer) +static int WriteCertReqBody(DerCert* der, byte* buf) { int idx; /* signed part header */ - idx = SetSequence(der->total, buffer); + idx = SetSequence(der->total, buf); /* version */ - if (buffer) - XMEMCPY(buffer + idx, der->version, der->versionSz); + if (buf) + XMEMCPY(buf + idx, der->version, der->versionSz); idx += der->versionSz; /* subject */ - if (buffer) - XMEMCPY(buffer + idx, der->subject, der->subjectSz); + if (buf) + XMEMCPY(buf + idx, der->subject, der->subjectSz); idx += der->subjectSz; /* public key */ - if (buffer) - XMEMCPY(buffer + idx, der->publicKey, der->publicKeySz); + if (buf) + XMEMCPY(buf + idx, der->publicKey, der->publicKeySz); idx += der->publicKeySz; /* attributes */ - if (buffer) - XMEMCPY(buffer + idx, der->attrib, der->attribSz); + if (buf) + XMEMCPY(buf + idx, der->attrib, der->attribSz); idx += der->attribSz; /* extensions */ if (der->extensionsSz) { - if (buffer) - XMEMCPY(buffer + idx, der->extensions, min(der->extensionsSz, + if (buf) + XMEMCPY(buf + idx, der->extensions, min(der->extensionsSz, (int)sizeof(der->extensions))); idx += der->extensionsSz; } @@ -13589,7 +13574,7 @@ int wc_MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz, #endif /* WOLFSSL_CERT_REQ */ -static int SignCert(int requestSz, int sType, byte* buffer, word32 buffSz, +static int SignCert(int requestSz, int sType, byte* buf, word32 buffSz, RsaKey* rsaKey, ecc_key* eccKey, ed25519_key* ed25519Key, WC_RNG* rng) { @@ -13643,7 +13628,7 @@ static int SignCert(int requestSz, int sType, byte* buffer, word32 buffSz, return MEMORY_E; } - sigSz = MakeSignature(certSignCtx, buffer, requestSz, certSignCtx->sig, + sigSz = MakeSignature(certSignCtx, buf, requestSz, certSignCtx->sig, MAX_ENCODED_SIG_SZ, rsaKey, eccKey, ed25519Key, rng, sType, heap); #ifdef WOLFSSL_ASYNC_CRYPT if (sigSz == WC_PENDING_E) { @@ -13657,7 +13642,7 @@ static int SignCert(int requestSz, int sType, byte* buffer, word32 buffSz, if (requestSz + MAX_SEQ_SZ * 2 + sigSz > (int)buffSz) sigSz = BUFFER_E; else - sigSz = AddSignature(buffer, requestSz, certSignCtx->sig, sigSz, + sigSz = AddSignature(buf, requestSz, certSignCtx->sig, sigSz, sType); } @@ -13667,7 +13652,7 @@ static int SignCert(int requestSz, int sType, byte* buffer, word32 buffSz, return sigSz; } -int wc_SignCert_ex(int requestSz, int sType, byte* buffer, word32 buffSz, +int wc_SignCert_ex(int requestSz, int sType, byte* buf, word32 buffSz, int keyType, void* key, WC_RNG* rng) { RsaKey* rsaKey = NULL; @@ -13681,28 +13666,28 @@ int wc_SignCert_ex(int requestSz, int sType, byte* buffer, word32 buffSz, else if (keyType == ED25519_TYPE) ed25519Key = (ed25519_key*)key; - return SignCert(requestSz, sType, buffer, buffSz, rsaKey, eccKey, + return SignCert(requestSz, sType, buf, buffSz, rsaKey, eccKey, ed25519Key, rng); } -int wc_SignCert(int requestSz, int sType, byte* buffer, word32 buffSz, +int wc_SignCert(int requestSz, int sType, byte* buf, word32 buffSz, RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng) { - return SignCert(requestSz, sType, buffer, buffSz, rsaKey, eccKey, NULL, + return SignCert(requestSz, sType, buf, buffSz, rsaKey, eccKey, NULL, rng); } -int wc_MakeSelfCert(Cert* cert, byte* buffer, word32 buffSz, +int wc_MakeSelfCert(Cert* cert, byte* buf, word32 buffSz, RsaKey* key, WC_RNG* rng) { int ret; - ret = wc_MakeCert(cert, buffer, buffSz, key, NULL, rng); + ret = wc_MakeCert(cert, buf, buffSz, key, NULL, rng); if (ret < 0) return ret; return wc_SignCert(cert->bodySz, cert->sigType, - buffer, buffSz, key, NULL, rng); + buf, buffSz, key, NULL, rng); } @@ -13725,7 +13710,7 @@ static int SetKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey, byte *ntruKey, word16 ntruKeySz, ed25519_key* ed25519Key, int kid_type) { - byte *buffer; + byte *buf; int bufferSz, ret; if (cert == NULL || @@ -13734,9 +13719,9 @@ static int SetKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey, (kid_type != SKID_TYPE && kid_type != AKID_TYPE)) return BAD_FUNC_ARG; - buffer = (byte *)XMALLOC(MAX_PUBLIC_KEY_SZ, cert->heap, + buf = (byte *)XMALLOC(MAX_PUBLIC_KEY_SZ, cert->heap, DYNAMIC_TYPE_TMP_BUFFER); - if (buffer == NULL) + if (buf == NULL) return MEMORY_E; /* Public Key */ @@ -13744,19 +13729,19 @@ static int SetKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey, #ifndef NO_RSA /* RSA public key */ if (rsakey != NULL) - bufferSz = SetRsaPublicKey(buffer, rsakey, MAX_PUBLIC_KEY_SZ, 0); + bufferSz = SetRsaPublicKey(buf, rsakey, MAX_PUBLIC_KEY_SZ, 0); #endif #ifdef HAVE_ECC /* ECC public key */ if (eckey != NULL) - bufferSz = SetEccPublicKey(buffer, eckey, 0); + bufferSz = SetEccPublicKey(buf, eckey, 0); #endif #ifdef HAVE_NTRU /* NTRU public key */ if (ntruKey != NULL) { bufferSz = MAX_PUBLIC_KEY_SZ; ret = ntru_crypto_ntru_encrypt_publicKey2SubjectPublicKeyInfo( - ntruKeySz, ntruKey, (word16 *)(&bufferSz), buffer); + ntruKeySz, ntruKey, (word16 *)(&bufferSz), buf); if (ret != NTRU_OK) bufferSz = -1; } @@ -13766,27 +13751,27 @@ static int SetKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey, #ifdef HAVE_ED25519 /* ED25519 public key */ if (ed25519Key != NULL) - bufferSz = SetEd25519PublicKey(buffer, ed25519Key, 0); + bufferSz = SetEd25519PublicKey(buf, ed25519Key, 0); #endif if (bufferSz <= 0) { - XFREE(buffer, cert->heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(buf, cert->heap, DYNAMIC_TYPE_TMP_BUFFER); return PUBLIC_KEY_E; } /* Compute SKID by hashing public key */ if (kid_type == SKID_TYPE) { - ret = CalcHashId(buffer, bufferSz, cert->skid); + ret = CalcHashId(buf, bufferSz, cert->skid); cert->skidSz = KEYID_SIZE; } else if (kid_type == AKID_TYPE) { - ret = CalcHashId(buffer, bufferSz, cert->akid); + ret = CalcHashId(buf, bufferSz, cert->akid); cert->akidSz = KEYID_SIZE; } else ret = BAD_FUNC_ARG; - XFREE(buffer, cert->heap, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(buf, cert->heap, DYNAMIC_TYPE_TMP_BUFFER); return ret; } diff --git a/wolfssl/internal.h b/wolfssl/internal.h index f3d9d2e6b..cdcd2694a 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -1329,11 +1329,13 @@ enum Misc { #endif #ifdef HAVE_SELFTEST + #ifndef WOLFSSL_AES_KEY_SIZE_ENUM #define WOLFSSL_AES_KEY_SIZE_ENUM AES_IV_SIZE = 16, AES_128_KEY_SIZE = 16, AES_192_KEY_SIZE = 24, AES_256_KEY_SIZE = 32, + #endif #endif MAX_IV_SZ = AES_BLOCK_SIZE, diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index b0f8f92a1..5b5478bff 100644 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -94,6 +94,8 @@ extern "C" { #endif +#ifndef WOLFSSL_AES_KEY_SIZE_ENUM +#define WOLFSSL_AES_KEY_SIZE_ENUM /* these are required for FIPS and non-FIPS */ enum { AES_128_KEY_SIZE = 16, /* for 128 bit */ @@ -102,7 +104,7 @@ enum { AES_IV_SIZE = 16, /* always block size */ }; - +#endif /* avoid redefinition of structs */ #if !defined(HAVE_FIPS) || \ diff --git a/wolfssl/wolfcrypt/pkcs7.h b/wolfssl/wolfcrypt/pkcs7.h index 840d94281..b0b0de2fb 100644 --- a/wolfssl/wolfcrypt/pkcs7.h +++ b/wolfssl/wolfcrypt/pkcs7.h @@ -154,7 +154,7 @@ enum Pkcs7_Misc { MAX_SEQ_SZ + ASN_NAME_MAX + MAX_SN_SZ + MAX_SEQ_SZ + MAX_ALGO_SZ + 1 + MAX_ENCRYPTED_KEY_SZ, #if (defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && \ - (HAVE_FIPS_VERSION >= 2)) || defined(HAVE_SELFTEST) + (HAVE_FIPS_VERSION >= 2)) /* In the event of fips cert 3389 or CAVP selftest build, these enums are * not in aes.h for use with pkcs7 so enumerate it here outside the fips * boundary */ diff --git a/wolfssl/wolfcrypt/sha3.h b/wolfssl/wolfcrypt/sha3.h index 1663fbc6f..ed0e65b97 100644 --- a/wolfssl/wolfcrypt/sha3.h +++ b/wolfssl/wolfcrypt/sha3.h @@ -58,7 +58,7 @@ enum { WC_SHA3_512_DIGEST_SIZE = 64, WC_SHA3_512_COUNT = 9, -#ifndef HAVE_SELFTEST +#ifdef HAVE_SELFTEST /* These values are used for HMAC, not SHA-3 directly. * They come from from FIPS PUB 202. */ WC_SHA3_224_BLOCK_SIZE = 144, From 480227704dae81acb3c5c0c1b53d345b908f8520 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 15 Jan 2020 12:35:16 +0100 Subject: [PATCH 076/649] Fix missing stuff in headers --- wolfcrypt/src/asn.c | 2 +- wolfssl/wolfcrypt/sha3.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 9100e9423..cbcf99eb9 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -128,7 +128,7 @@ extern int wc_InitRsaHw(RsaKey* key); #define ERROR_OUT(err, eLabel) { ret = (err); goto eLabel; } -#ifdef HAVE_SELFTEST +#if defined(HAVE_SELFTEST) || !defined(NO_SKID) #include #ifndef WOLFSSL_AES_KEY_SIZE_ENUM #define WOLFSSL_AES_KEY_SIZE_ENUM diff --git a/wolfssl/wolfcrypt/sha3.h b/wolfssl/wolfcrypt/sha3.h index ed0e65b97..c4e9a7096 100644 --- a/wolfssl/wolfcrypt/sha3.h +++ b/wolfssl/wolfcrypt/sha3.h @@ -58,14 +58,12 @@ enum { WC_SHA3_512_DIGEST_SIZE = 64, WC_SHA3_512_COUNT = 9, -#ifdef HAVE_SELFTEST /* These values are used for HMAC, not SHA-3 directly. * They come from from FIPS PUB 202. */ WC_SHA3_224_BLOCK_SIZE = 144, WC_SHA3_256_BLOCK_SIZE = 136, WC_SHA3_384_BLOCK_SIZE = 104, WC_SHA3_512_BLOCK_SIZE = 72, -#endif }; #ifndef NO_OLD_WC_NAMES From b58f26945da1d8a53f2cbb55e5a80babb4775dea Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 15 Jan 2020 20:42:19 +0100 Subject: [PATCH 077/649] Different configuration fixes --- src/ssl.c | 79 ++++++++++++++++++++++++++------------- tests/api.c | 7 ++++ wolfssl/openssl/rsa.h | 41 ++++++++++++++++---- wolfssl/ssl.h | 36 +----------------- wolfssl/wolfcrypt/types.h | 10 +++++ 5 files changed, 106 insertions(+), 67 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index ae3248f77..182c2ffae 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -24201,9 +24201,6 @@ int wolfSSL_X509_STORE_add_cert(WOLFSSL_X509_STORE* store, WOLFSSL_X509* x509) WOLFSSL_X509_STORE* wolfSSL_X509_STORE_new(void) { -#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) - WOLFSSL_STACK* sk; -#endif WOLFSSL_X509_STORE* store = NULL; WOLFSSL_ENTER("SSL_X509_STORE_new"); @@ -32137,6 +32134,7 @@ int wolfSSL_EVP_PKEY_assign(WOLFSSL_EVP_PKEY *pkey, int type, void *key) } #endif /* WOLFSSL_QT || OPENSSL_ALL */ +#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) /* try and populate public pkey_sz and pkey.ptr */ static void ECC_populate_EVP_PKEY(EVP_PKEY* pkey, ecc_key* ecc) { @@ -32171,8 +32169,12 @@ WOLFSSL_API int wolfSSL_EVP_PKEY_set1_EC_KEY(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_EC_ if (pkey->rsa != NULL && pkey->ownRsa == 1) { wolfSSL_RSA_free(pkey->rsa); } + if (pkey->ecc != NULL && pkey->ownEcc == 1) { + wolfSSL_EC_KEY_free(pkey->ecc); + } pkey->ecc = key; pkey->ownEcc = 0; /* pkey does not own EC key */ + pkey->ownRsa = 0; pkey->type = EVP_PKEY_EC; ECC_populate_EVP_PKEY(pkey, (ecc_key*)key->internal); return WOLFSSL_SUCCESS; @@ -32201,7 +32203,21 @@ void* wolfSSL_EVP_X_STATE(const WOLFSSL_EVP_CIPHER_CTX* ctx) return NULL; } +int wolfSSL_EVP_PKEY_assign_EC_KEY(EVP_PKEY* pkey, WOLFSSL_EC_KEY* key) +{ + if (pkey == NULL || key == NULL) + return WOLFSSL_FAILURE; + pkey->type = EVP_PKEY_EC; + pkey->ecc = key; + pkey->ownEcc = 1; + + /* try and populate public pkey_sz and pkey.ptr */ + ECC_populate_EVP_PKEY(pkey, (ecc_key*)key->internal); + + return WOLFSSL_SUCCESS; +} +#endif /* OPENSSL_EXTRA || HAVE_ECC */ int wolfSSL_EVP_X_STATE_LEN(const WOLFSSL_EVP_CIPHER_CTX* ctx) { @@ -32603,17 +32619,17 @@ static int EncryptDerKey(byte *der, int *derSz, const EVP_CIPHER* cipher, } #endif /* WOLFSSL_KEY_GEN || WOLFSSL_PEM_TO_DER */ -#ifndef NO_RSA +#if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA) static int wolfSSL_RSA_To_Der(WOLFSSL_RSA* rsa, byte** outBuf, int publicKey) { int derMax = 0; int derSz = 0; byte* derBuf; - WOLFSSL_ENTER("wc_RsaKeyToDer"); + WOLFSSL_ENTER("wolfSSL_RSA_To_Der"); if (!rsa || !outBuf || (publicKey != 0 && publicKey != 1)) { - WOLFSSL_LEAVE("wc_RsaKeyToDer", BAD_FUNC_ARG); + WOLFSSL_LEAVE("wolfSSL_RSA_To_Der", BAD_FUNC_ARG); return BAD_FUNC_ARG; } /* 5 > size of n, d, p, q, d%(p-1), d(q-1), 1/q%p, e + ASN.1 additional @@ -32623,7 +32639,7 @@ static int wolfSSL_RSA_To_Der(WOLFSSL_RSA* rsa, byte** outBuf, int publicKey) derBuf = (byte*)XMALLOC(derMax, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (derBuf == NULL) { WOLFSSL_MSG("malloc failed"); - WOLFSSL_LEAVE("wc_RsaKeyToDer", MEMORY_ERROR); + WOLFSSL_LEAVE("wolfSSL_RSA_To_Der", MEMORY_ERROR); return MEMORY_ERROR; } /* Key to DER */ @@ -32648,7 +32664,7 @@ static int wolfSSL_RSA_To_Der(WOLFSSL_RSA* rsa, byte** outBuf, int publicKey) } } - WOLFSSL_LEAVE("wc_RsaKeyToDer", derSz); + WOLFSSL_LEAVE("wolfSSL_RSA_To_Der", derSz); return derSz; } #endif @@ -33475,6 +33491,34 @@ int wolfSSL_EVP_PKEY_set1_EC_KEY(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_EC_KEY *key) } #endif /* WOLFSSL_QT || OPENSSL_ALL */ +typedef struct { + const char *name; + int nid; +} WOLF_EC_NIST_NAME; +static const WOLF_EC_NIST_NAME kNistCurves[] = { + {"P-192", NID_X9_62_prime192v1}, + {"P-256", NID_X9_62_prime256v1}, + {"P-112", NID_secp112r1}, + {"P-112-2", NID_secp112r2}, + {"P-128", NID_secp128r1}, + {"P-128-2", NID_secp128r2}, + {"P-160", NID_secp160r1}, + {"P-160-2", NID_secp160r2}, + {"P-224", NID_secp224r1}, + {"P-384", NID_secp384r1}, + {"P-521", NID_secp521r1}, + {"K-160", NID_secp160k1}, + {"K-192", NID_secp192k1}, + {"K-224", NID_secp224k1}, + {"K-256", NID_secp256k1}, + {"B-160", NID_brainpoolP160r1}, + {"B-192", NID_brainpoolP192r1}, + {"B-224", NID_brainpoolP224r1}, + {"B-256", NID_brainpoolP256r1}, + {"B-320", NID_brainpoolP320r1}, + {"B-384", NID_brainpoolP384r1}, + {"B-512", NID_brainpoolP512r1}, +}; const char* wolfSSL_EC_curve_nid2nist(int nid) { const WOLF_EC_NIST_NAME* nist_name; @@ -36709,6 +36753,7 @@ void wolfSSL_RSA_set_flags(WOLFSSL_RSA *r, int flags) } } +#if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA) WOLFSSL_RSA* wolfSSL_RSAPublicKey_dup(WOLFSSL_RSA *rsa) { int derSz = 0; @@ -36741,6 +36786,7 @@ WOLFSSL_RSA* wolfSSL_RSAPublicKey_dup(WOLFSSL_RSA *rsa) XFREE(derBuf, NULL, DYNAMIC_TYPE_ASN1); return local; } +#endif void* wolfSSL_RSA_get_ex_data(const WOLFSSL_RSA *rsa, int idx) { @@ -48058,23 +48104,6 @@ WOLFSSL_RSA* wolfSSL_RSA_new(void) } #endif /* !NO_RSA && (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) */ -#if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) -int wolfSSL_EVP_PKEY_assign_EC_KEY(EVP_PKEY* pkey, WOLFSSL_EC_KEY* key) -{ - if (pkey == NULL || key == NULL) - return WOLFSSL_FAILURE; - - pkey->type = EVP_PKEY_EC; - pkey->ecc = key; - pkey->ownEcc = 1; - - /* try and populate public pkey_sz and pkey.ptr */ - ECC_populate_EVP_PKEY(pkey, (ecc_key*)key->internal); - - return WOLFSSL_SUCCESS; -} -#endif - #if defined(OPENSSL_EXTRA) && !defined(NO_DSA) int wolfSSL_EVP_PKEY_assign_DSA(EVP_PKEY* pkey, WOLFSSL_DSA* key) { diff --git a/tests/api.c b/tests/api.c index bb9676187..0a6c48c1b 100644 --- a/tests/api.c +++ b/tests/api.c @@ -5034,9 +5034,14 @@ static void test_wolfSSL_PKCS8(void) /* Test using a PKCS8 ECC PEM */ AssertIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, buffer, bytes, WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS); +#else +#ifdef OPENSSL_EXTRA + AssertIntGT((bytes = wc_KeyPemToDer(buffer, bytes, der, + (word32)sizeof(der), NULL)), 0); #else AssertIntEQ((bytes = wc_KeyPemToDer(buffer, bytes, der, (word32)sizeof(der), NULL)), ASN_NO_PEM_HEADER); +#endif #endif /* HAVE_ECC */ wolfSSL_CTX_free(ctx); @@ -19964,8 +19969,10 @@ static void test_wolfSSL_PEM_RSAPrivateKey(void) AssertNotNull((rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL))); AssertIntEQ(RSA_size(rsa), 256); +#if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA) AssertNotNull(rsa_dup = RSAPublicKey_dup(rsa)); AssertPtrNE(rsa_dup, rsa); +#endif /* test if valgrind complains about unreleased memory */ RSA_up_ref(rsa); diff --git a/wolfssl/openssl/rsa.h b/wolfssl/openssl/rsa.h index f573b10fb..658dc7b46 100644 --- a/wolfssl/openssl/rsa.h +++ b/wolfssl/openssl/rsa.h @@ -26,6 +26,7 @@ #define WOLFSSL_RSA_H_ #include +#include #ifdef __cplusplus extern "C" { @@ -47,18 +48,44 @@ #define RSA_FLAG_NO_BLINDING (1 << 7) #define RSA_FLAG_NO_CONSTTIME (1 << 8) -#ifndef WOLFSSL_RSA_TYPE_DEFINED /* guard on redeclaration */ -typedef struct WOLFSSL_RSA WOLFSSL_RSA; -#define WOLFSSL_RSA_TYPE_DEFINED -#endif - -typedef WOLFSSL_RSA RSA; - typedef struct WOLFSSL_RSA_METHOD { int flags; char *name; } WOLFSSL_RSA_METHOD; +#ifndef WOLFSSL_RSA_TYPE_DEFINED /* guard on redeclaration */ +#define WOLFSSL_RSA_TYPE_DEFINED +typedef struct WOLFSSL_RSA { +#ifdef WC_RSA_BLINDING + WC_RNG* rng; /* for PrivateDecrypt blinding */ +#endif + WOLFSSL_BIGNUM* n; + WOLFSSL_BIGNUM* e; + WOLFSSL_BIGNUM* d; + WOLFSSL_BIGNUM* p; + WOLFSSL_BIGNUM* q; + WOLFSSL_BIGNUM* dmp1; /* dP */ + WOLFSSL_BIGNUM* dmq1; /* dQ */ + WOLFSSL_BIGNUM* iqmp; /* u */ + void* heap; + void* internal; /* our RSA */ + char inSet; /* internal set from external ? */ + char exSet; /* external set from internal ? */ + char ownRng; /* flag for if the rng should be free'd */ +#if defined(OPENSSL_EXTRA) + WOLFSSL_RSA_METHOD* meth; +#endif +#if defined(HAVE_EX_DATA) + WOLFSSL_CRYPTO_EX_DATA ex_data; /* external data */ +#endif +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) + wolfSSL_Mutex refMutex; /* ref count mutex */ + int refCount; /* reference count */ +#endif +} WOLFSSL_RSA; +#endif + +typedef WOLFSSL_RSA RSA; typedef WOLFSSL_RSA_METHOD RSA_METHOD; WOLFSSL_API WOLFSSL_RSA* wolfSSL_RSA_new(void); diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index dfae99d2c..a83b51246 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -34,6 +34,7 @@ #include #include #include +#include #ifdef HAVE_WOLF_EVENT #include @@ -455,12 +456,6 @@ struct WOLFSSL_BIO_METHOD { typedef long (*wolf_bio_info_cb)(WOLFSSL_BIO *bio, int event, const char *parg, int iarg, long larg, long return_value); -#if defined(HAVE_EX_DATA) || defined(FORTRESS) -typedef struct WOLFSSL_CRYPTO_EX_DATA { - void* ex_data[MAX_EX_DATA]; -} WOLFSSL_CRYPTO_EX_DATA; -#endif - struct WOLFSSL_BIO { WOLFSSL_BUF_MEM* mem_buf; WOLFSSL_BIO_METHOD* method; @@ -487,35 +482,6 @@ struct WOLFSSL_BIO { #endif }; -struct WOLFSSL_RSA { -#ifdef WC_RSA_BLINDING - WC_RNG* rng; /* for PrivateDecrypt blinding */ -#endif - WOLFSSL_BIGNUM* n; - WOLFSSL_BIGNUM* e; - WOLFSSL_BIGNUM* d; - WOLFSSL_BIGNUM* p; - WOLFSSL_BIGNUM* q; - WOLFSSL_BIGNUM* dmp1; /* dP */ - WOLFSSL_BIGNUM* dmq1; /* dQ */ - WOLFSSL_BIGNUM* iqmp; /* u */ - void* heap; - void* internal; /* our RSA */ - char inSet; /* internal set from external ? */ - char exSet; /* external set from internal ? */ - char ownRng; /* flag for if the rng should be free'd */ -#if defined(OPENSSL_EXTRA) - WOLFSSL_RSA_METHOD* meth; -#endif -#if defined(HAVE_EX_DATA) - WOLFSSL_CRYPTO_EX_DATA ex_data; /* external data */ -#endif -#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) - wolfSSL_Mutex refMutex; /* ref count mutex */ - int refCount; /* reference count */ -#endif -}; - typedef struct WOLFSSL_COMP_METHOD { int type; /* stunnel dereference */ } WOLFSSL_COMP_METHOD; diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index 0da95c271..98ab3b1cd 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -37,6 +37,16 @@ #define WOLFSSL_ABI /* Tag for all the APIs that are a part of the fixed ABI. */ + /* + * This struct is used multiple time by other structs and + * needs to be defined somwhere that all structs can import + * (with minimal depencencies). + */ + #if defined(HAVE_EX_DATA) || defined(FORTRESS) + typedef struct WOLFSSL_CRYPTO_EX_DATA { + void* ex_data[MAX_EX_DATA]; + } WOLFSSL_CRYPTO_EX_DATA; + #endif #if defined(WORDS_BIGENDIAN) #define BIG_ENDIAN_ORDER From b592b241c7fe4b8775889f665af5fa7efa58da3e Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 15 Jan 2020 21:41:43 +0100 Subject: [PATCH 078/649] Fix Segfault in wolfSSL_EC_KEY_dup Fix more header stuff --- src/ssl.c | 28 ++++++++++++++++++++-------- wolfssl/openssl/evp.h | 3 ++- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 182c2ffae..3853ba4db 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -16548,7 +16548,9 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) int arg, void *ptr) { int ret = WOLFSSL_FAILURE; +#ifdef HAVE_AESGCM WC_RNG rng; +#endif if (ctx == NULL) return WOLFSSL_FAILURE; @@ -20003,10 +20005,12 @@ WOLFSSL_EC_KEY *wolfSSL_EC_KEY_dup(const WOLFSSL_EC_KEY *src) } /* copy domain parameters */ - ret = wc_ecc_set_curve(key, 0, srcKey->dp->id); - if (ret != 0) { - WOLFSSL_MSG("wc_ecc_set_curve error"); - return NULL; + if (srcKey->dp) { + ret = wc_ecc_set_curve(key, 0, srcKey->dp->id); + if (ret != 0) { + WOLFSSL_MSG("wc_ecc_set_curve error"); + return NULL; + } } key->type = srcKey->type; @@ -20043,19 +20047,22 @@ WOLFSSL_EC_KEY *wolfSSL_EC_KEY_dup(const WOLFSSL_EC_KEY *src) /* Copy X, Y, Z */ dup->pub_key->X = wolfSSL_BN_dup(src->pub_key->X); - if (dup->pub_key->X == NULL) { + if (!dup->pub_key->X && src->pub_key->X) { WOLFSSL_MSG("Error copying EC_POINT"); wolfSSL_EC_KEY_free(dup); + return NULL; } dup->pub_key->Y = wolfSSL_BN_dup(src->pub_key->Y); - if (dup->pub_key->Y == NULL) { + if (!dup->pub_key->Y && src->pub_key->Y) { WOLFSSL_MSG("Error copying EC_POINT"); wolfSSL_EC_KEY_free(dup); + return NULL; } dup->pub_key->Z = wolfSSL_BN_dup(src->pub_key->Z); - if (dup->pub_key->Z == NULL) { + if (!dup->pub_key->Z && src->pub_key->Z) { WOLFSSL_MSG("Error copying EC_POINT"); wolfSSL_EC_KEY_free(dup); + return NULL; } dup->pub_key->inSet = src->pub_key->inSet; @@ -31963,6 +31970,9 @@ WOLFSSL_EC_KEY* wolfSSL_EVP_PKEY_get1_EC_KEY(WOLFSSL_EVP_PKEY* key) wolfSSL_EC_KEY_free(local); local = NULL; } + if (!local && key->ecc) { + local = wolfSSL_EC_KEY_dup(key->ecc); + } return local; } #endif /* HAVE_ECC */ @@ -32166,15 +32176,17 @@ WOLFSSL_API int wolfSSL_EVP_PKEY_set1_EC_KEY(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_EC_ #ifdef HAVE_ECC if((pkey == NULL) || (key ==NULL))return WOLFSSL_FAILURE; WOLFSSL_ENTER("wolfSSL_EVP_PKEY_set1_EC_KEY"); +#ifndef NO_RSA if (pkey->rsa != NULL && pkey->ownRsa == 1) { wolfSSL_RSA_free(pkey->rsa); } + pkey->ownRsa = 0; +#endif if (pkey->ecc != NULL && pkey->ownEcc == 1) { wolfSSL_EC_KEY_free(pkey->ecc); } pkey->ecc = key; pkey->ownEcc = 0; /* pkey does not own EC key */ - pkey->ownRsa = 0; pkey->type = EVP_PKEY_EC; ECC_populate_EVP_PKEY(pkey, (ecc_key*)key->internal); return WOLFSSL_SUCCESS; diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index e34a50809..b80b127e9 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -262,7 +262,8 @@ struct WOLFSSL_EVP_CIPHER_CTX { int bufUsed; ALIGN16 byte lastBlock[WOLFSSL_EVP_BUF_SIZE]; int lastUsed; -#if defined(HAVE_AESGCM) +#if defined(HAVE_AESGCM) || defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_COUNTER) \ + || !defined(NO_DES3) || defined(HAVE_IDEA) int ivSz; ALIGN16 unsigned char authTag[AES_BLOCK_SIZE]; int authTagSz; From 48b39a34c79cb5f3dfd40be2c2db8ed2c4d4c31d Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 16 Jan 2020 00:40:41 +0100 Subject: [PATCH 079/649] Properly Init mp_int number --- src/ssl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ssl.c b/src/ssl.c index 3853ba4db..86effec32 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -34589,6 +34589,10 @@ int wolfSSL_EC_POINT_get_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group, } if (!wolfSSL_BN_is_one(point->Z)) { + if (mp_init(&modulus) != MP_OKAY) { + WOLFSSL_MSG("mp_init failed"); + return WOLFSSL_FAILURE; + } /* Map the Jacobian point back to affine space */ if (mp_read_radix(&modulus, ecc_sets[group->curve_idx].prime, MP_RADIX_HEX) != MP_OKAY) { WOLFSSL_MSG("mp_read_radix failed"); From f765b711bf6997269fe33979c3dd032f7169c5e8 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 16 Jan 2020 20:06:30 +0100 Subject: [PATCH 080/649] More macro preproc stuff --- src/ssl.c | 22 ++++++++++++++++------ tests/api.c | 8 +++----- wolfcrypt/src/asn.c | 2 +- wolfssl/openssl/evp.h | 7 +++++-- wolfssl/openssl/ssl.h | 7 ++++++- 5 files changed, 31 insertions(+), 15 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 86effec32..6d077e43b 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -16726,9 +16726,11 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ctx->bufUsed = 0; ctx->lastUsed = 0; +#ifdef HAVE_WOLFSSL_EVP_CIPHER_CTX_IV if (!iv && ctx->ivSz) { iv = ctx->iv; } +#endif #ifndef NO_AES #ifdef HAVE_AES_CBC @@ -17170,12 +17172,14 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ctx->keyLen = 0; ctx->block_size = 16; } +#ifdef HAVE_WOLFSSL_EVP_CIPHER_CTX_IV ctx->ivSz = wolfSSL_EVP_CIPHER_CTX_iv_length(ctx); if (iv && iv != ctx->iv) { if (wolfSSL_StoreExternalIV(ctx) != WOLFSSL_SUCCESS) { return WOLFSSL_FAILURE; } } +#endif (void)ret; /* remove warning. If execution reaches this point, ret=0 */ return WOLFSSL_SUCCESS; } @@ -31970,9 +31974,11 @@ WOLFSSL_EC_KEY* wolfSSL_EVP_PKEY_get1_EC_KEY(WOLFSSL_EVP_PKEY* key) wolfSSL_EC_KEY_free(local); local = NULL; } +#ifdef OPENSSL_ALL if (!local && key->ecc) { local = wolfSSL_EC_KEY_dup(key->ecc); } +#endif return local; } #endif /* HAVE_ECC */ @@ -32718,7 +32724,7 @@ int wolfSSL_PEM_write_bio_RSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_RSA* key, pkey->type = EVP_PKEY_RSA; pkey->rsa = key; pkey->ownRsa = 0; -#ifdef WOLFSSL_KEY_GEN +#if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA) /* similar to how wolfSSL_PEM_write_mem_RSAPrivateKey finds DER of key */ { int derSz; @@ -46728,8 +46734,8 @@ int wolfSSL_BN_clear_bit(WOLFSSL_BIGNUM* bn, int n) mp_int res[1]; mp_int tmp[1]; #else - mp_int* res = null; - mp_int* tmp = null; + mp_int* res = NULL; + mp_int* tmp = NULL; #endif if (bn == NULL || bn->internal == NULL) { @@ -46766,9 +46772,9 @@ int wolfSSL_BN_clear_bit(WOLFSSL_BIGNUM* bn, int n) ret = WOLFSSL_SUCCESS; cleanup: #ifdef WOLFSSL_SMALL_STACK - if (res): + if (res) XFREE(res, NULL, DYNAMIC_TYPE_BIGINT); - if (tmp): + if (tmp) XFREE(tmp, NULL, DYNAMIC_TYPE_BIGINT); #endif return ret; @@ -47984,9 +47990,10 @@ static void InitwolfSSL_Rsa(WOLFSSL_RSA* rsa) void wolfSSL_RSA_free(WOLFSSL_RSA* rsa) { WOLFSSL_ENTER("wolfSSL_RSA_free"); - int doFree = 0; if (rsa) { +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) + int doFree = 0; if (wc_LockMutex(&rsa->refMutex) != 0) { WOLFSSL_MSG("Couldn't lock rsa mutex"); } @@ -48003,6 +48010,7 @@ void wolfSSL_RSA_free(WOLFSSL_RSA* rsa) } wc_FreeMutex(&rsa->refMutex); +#endif if (rsa->internal) { #if !defined(HAVE_FIPS) && !defined(HAVE_USER_RSA) && \ @@ -48114,8 +48122,10 @@ WOLFSSL_RSA* wolfSSL_RSA_new(void) external->internal = key; external->inSet = 0; +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) external->refCount = 1; wc_InitMutex(&external->refMutex); +#endif return external; } #endif /* !NO_RSA && (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) */ diff --git a/tests/api.c b/tests/api.c index 0a6c48c1b..a5cde9759 100644 --- a/tests/api.c +++ b/tests/api.c @@ -1945,17 +1945,16 @@ static void test_wolfSSL_ECDSA_SIG(void) static void test_ECDSA_size_sign(void) { -#ifdef HAVE_ECC +#if defined(HAVE_ECC) && !defined(NO_ECC256) && !defined(NO_ECC_SECP) EC_KEY *key; int id; - byte hash[WC_SHA_DIGEST_SIZE]; + byte hash[WC_MAX_DIGEST_SIZE]; byte sig[ECC_BUFSIZE]; unsigned int sigSz = sizeof(sig); XMEMSET(hash, 123, sizeof(hash)); -#if !defined(NO_ECC256) && !defined(NO_ECC_SECP) id = wc_ecc_get_curve_id_from_name("SECP256R1"); AssertIntEQ(id, ECC_SECP256R1); @@ -1964,9 +1963,8 @@ static void test_ECDSA_size_sign(void) AssertIntEQ(ECDSA_sign(0, hash, sizeof(hash), sig, &sigSz, key), 1); AssertIntGE(ECDSA_size(key), sigSz); EC_KEY_free(key); -#endif -#endif /* HAVE_ECC */ +#endif /* HAVE_ECC && !NO_ECC256 && !NO_ECC_SECP */ } #endif /* OPENSSL_EXTRA */ diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index cbcf99eb9..67d37965d 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -128,8 +128,8 @@ extern int wc_InitRsaHw(RsaKey* key); #define ERROR_OUT(err, eLabel) { ret = (err); goto eLabel; } -#if defined(HAVE_SELFTEST) || !defined(NO_SKID) #include +#if defined(HAVE_SELFTEST) || !defined(NO_SKID) #ifndef WOLFSSL_AES_KEY_SIZE_ENUM #define WOLFSSL_AES_KEY_SIZE_ENUM enum Asn_Misc { diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index b80b127e9..bdb765c04 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -256,14 +256,17 @@ struct WOLFSSL_EVP_CIPHER_CTX { #elif !defined(NO_DES3) /* working iv pointer into cipher */ ALIGN16 unsigned char iv[DES_BLOCK_SIZE]; +#elif defined(HAVE_IDEA) + /* working iv pointer into cipher */ + ALIGN16 unsigned char iv[IDEA_BLOCK_SIZE]; #endif WOLFSSL_Cipher cipher; ALIGN16 byte buf[WOLFSSL_EVP_BUF_SIZE]; int bufUsed; ALIGN16 byte lastBlock[WOLFSSL_EVP_BUF_SIZE]; int lastUsed; -#if defined(HAVE_AESGCM) || defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_COUNTER) \ - || !defined(NO_DES3) || defined(HAVE_IDEA) +#if !defined(NO_AES) || !defined(NO_DES3) || defined(HAVE_IDEA) +#define HAVE_WOLFSSL_EVP_CIPHER_CTX_IV int ivSz; ALIGN16 unsigned char authTag[AES_BLOCK_SIZE]; int authTagSz; diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index ab58cc19e..9feb76ea9 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -775,8 +775,13 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define ERR_reason_error_string wolfSSL_ERR_reason_error_string #define ERR_load_BIO_strings wolfSSL_ERR_load_BIO_strings -#define PEMerr(func, reason) wolfSSL_ERR_put_error(ERR_LIB_PEM,\ +#ifndef WOLFCRYPT_ONLY +#define PEMerr(func, reason) wolfSSL_ERR_put_error(ERR_LIB_PEM, \ (func), (reason), __FILE__, __LINE__) +#else +#define PEMerr(func, reason) WOLFSSL_ERROR_LINE((reason), \ + NULL, __LINE__, __FILE__, NULL) +#endif #define SSLv23_server_method wolfSSLv23_server_method #define SSL_CTX_set_options wolfSSL_CTX_set_options From 7ce7017521250ec4b469cf048c85d1fc346b930c Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 17 Jan 2020 14:52:33 +0100 Subject: [PATCH 081/649] Fix memory leaks when compiling with SMALL_STACK --- src/ssl.c | 92 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 51 insertions(+), 41 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 6d077e43b..a7432f402 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -16537,6 +16537,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) { WOLFSSL_ENTER("EVP_CIPHER_CTX_init"); if (ctx) { + XMEMSET(ctx, 0, sizeof(WOLFSSL_EVP_CIPHER_CTX)); ctx->cipherType = WOLFSSL_EVP_CIPH_TYPE_INIT; /* not yet initialized */ ctx->keyLen = 0; ctx->enc = 1; /* start in encrypt mode */ @@ -16577,7 +16578,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) case EVP_CTRL_AEAD_SET_IV_FIXED: if (arg == -1) { /* arg == -1 copies ctx->ivSz from ptr */ - ret = wolfSSL_EVP_CIPHER_CTX_set_iv(ctx, ptr, ctx->ivSz); + ret = wolfSSL_EVP_CIPHER_CTX_set_iv(ctx, (byte*)ptr, ctx->ivSz); } else { /* @@ -32757,7 +32758,7 @@ int wolfSSL_PEM_write_bio_RSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_RSA* key, return ret; } - +#if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA) /* Takes an RSA public key and writes it out to a WOLFSSL_BIO * Returns WOLFSSL_SUCCESS or WOLFSSL_FAILURE */ @@ -32806,6 +32807,7 @@ int wolfSSL_PEM_write_bio_RSA_PUBKEY(WOLFSSL_BIO* bio, WOLFSSL_RSA* rsa) return ret; } +#endif /* Reads an RSA public key from a WOLFSSL_BIO into a WOLFSSL_RSA @@ -32973,7 +32975,7 @@ int wolfSSL_PEM_write_bio_PrivateKey(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key, } #endif /* defined(WOLFSSL_KEY_GEN) || defined(WOLFSSL_CERT_GEN) */ -#if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA) && \ +#if (defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA)) && \ (defined(WOLFSSL_PEM_TO_DER) || defined(WOLFSSL_DER_TO_PEM)) /* return code compliant with OpenSSL : @@ -33928,17 +33930,18 @@ int wolfSSL_ECDSA_sign(int type, const unsigned char *digest, #endif int initTmpRng = 0; -#ifdef WOLFSSL_SMALL_STACK - tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG); - if (tmpRNG == NULL) - return WOLFSSL_FAILURE; -#endif WOLFSSL_ENTER("wolfSSL_ECDSA_sign"); if (!key) { return WOLFSSL_FAILURE; } +#ifdef WOLFSSL_SMALL_STACK + tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG); + if (tmpRNG == NULL) + return WOLFSSL_FAILURE; +#endif + if (wc_InitRng(tmpRNG) == 0) { rng = tmpRNG; initTmpRng = 1; @@ -33952,15 +33955,22 @@ int wolfSSL_ECDSA_sign(int type, const unsigned char *digest, rng = &globalRNG; } } - if (!rng) { - return WOLFSSL_FAILURE; - } - if (wc_ecc_sign_hash(digest, digestSz, sig, sigSz, rng, (ecc_key*)key->internal) != MP_OKAY) { + if (rng) { + if (wc_ecc_sign_hash(digest, digestSz, sig, sigSz, rng, (ecc_key*)key->internal) != MP_OKAY) { + ret = WOLFSSL_FAILURE; + } + if (initTmpRng) { + wc_FreeRng(tmpRNG); + } + } else { ret = WOLFSSL_FAILURE; } - if (initTmpRng) { - wc_FreeRng(tmpRNG); - } + +#ifdef WOLFSSL_SMALL_STACK + if (tmpRNG) + XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG); +#endif + (void)type; return ret; } @@ -36552,7 +36562,7 @@ WOLFSSL_RSA *wolfSSL_d2i_RSAPrivateKey(WOLFSSL_RSA **r, */ int wolfSSL_i2d_RSAPrivateKey(WOLFSSL_RSA *rsa, unsigned char **pp) { -#if defined(WOLFSSL_KEY_GEN) +#if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA) byte* der = NULL; int ret; int i; @@ -36599,7 +36609,7 @@ int wolfSSL_i2d_RSAPrivateKey(WOLFSSL_RSA *rsa, unsigned char **pp) #else (void)rsa; (void)pp; - WOLFSSL_MSG("Error, WOLFSSL_KEY_GEN not defined"); + WOLFSSL_MSG("Error, wolfSSL_i2d_RSAPrivateKey missing defines"); return WOLFSSL_FAILURE; #endif /* WOLFSSL_KEY_GEN */ } @@ -46810,35 +46820,35 @@ int wolfSSL_BN_hex2bn(WOLFSSL_BIGNUM** bn, const char* str) if (str == NULL || str[0] == '\0') { WOLFSSL_MSG("Bad function argument"); - return WOLFSSL_FAILURE; - } + ret = WOLFSSL_FAILURE; + } else { + strLen = (int)XSTRLEN(str); + /* ignore trailing new lines */ + while (str[strLen-1] == '\n' && strLen > 0) strLen--; - strLen = (int)XSTRLEN(str); - /* ignore trailing new lines */ - while (str[strLen-1] == '\n' && strLen > 0) strLen--; - - if (Base16_Decode((byte*)str, strLen, decoded, &decSz) < 0) - WOLFSSL_MSG("Bad Base16_Decode error"); - else if (bn == NULL) - ret = decSz; - else { - if (*bn == NULL) { - *bn = wolfSSL_BN_new(); - if (*bn != NULL) { - weOwn = 1; + if (Base16_Decode((byte*)str, strLen, decoded, &decSz) < 0) + WOLFSSL_MSG("Bad Base16_Decode error"); + else if (bn == NULL) + ret = decSz; + else { + if (*bn == NULL) { + *bn = wolfSSL_BN_new(); + if (*bn != NULL) { + weOwn = 1; + } } - } - if (*bn == NULL) - WOLFSSL_MSG("BN new failed"); - else if (wolfSSL_BN_bin2bn(decoded, decSz, *bn) == NULL) { - WOLFSSL_MSG("Bad bin2bn error"); - if (weOwn == 1) { - wolfSSL_BN_free(*bn); /* Free new BN */ + if (*bn == NULL) + WOLFSSL_MSG("BN new failed"); + else if (wolfSSL_BN_bin2bn(decoded, decSz, *bn) == NULL) { + WOLFSSL_MSG("Bad bin2bn error"); + if (weOwn == 1) { + wolfSSL_BN_free(*bn); /* Free new BN */ + } } + else + ret = WOLFSSL_SUCCESS; } - else - ret = WOLFSSL_SUCCESS; } #ifdef WOLFSSL_SMALL_STACK From 1df9963b80eccba1497be2b6658bc073a70d1151 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 17 Jan 2020 15:02:16 +0100 Subject: [PATCH 082/649] sha3.h --- wolfssl/wolfcrypt/sha3.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/wolfssl/wolfcrypt/sha3.h b/wolfssl/wolfcrypt/sha3.h index c4e9a7096..1663fbc6f 100644 --- a/wolfssl/wolfcrypt/sha3.h +++ b/wolfssl/wolfcrypt/sha3.h @@ -58,12 +58,14 @@ enum { WC_SHA3_512_DIGEST_SIZE = 64, WC_SHA3_512_COUNT = 9, +#ifndef HAVE_SELFTEST /* These values are used for HMAC, not SHA-3 directly. * They come from from FIPS PUB 202. */ WC_SHA3_224_BLOCK_SIZE = 144, WC_SHA3_256_BLOCK_SIZE = 136, WC_SHA3_384_BLOCK_SIZE = 104, WC_SHA3_512_BLOCK_SIZE = 72, +#endif }; #ifndef NO_OLD_WC_NAMES From 97a4889bb3d362b1fa1ba5ef08c96118ea35f58c Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 17 Jan 2020 16:04:34 +0100 Subject: [PATCH 083/649] Undo some stuff --- tests/api.c | 4 ++-- wolfssl/wolfcrypt/pkcs7.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/api.c b/tests/api.c index a5cde9759..62be70388 100644 --- a/tests/api.c +++ b/tests/api.c @@ -19905,8 +19905,8 @@ static void test_wolfSSL_PEM_PrivateKey(void) static void test_wolfSSL_PEM_bio_RSAKey(void) { #if (defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL)) && \ - defined(WOLFSSL_KEY_GEN) && \ - !defined(NO_FILESYSTEM) && !defined(NO_RSA) && !defined(NO_CERTS) + defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && \ + !defined(HAVE_USER_RSA) && !defined(NO_FILESYSTEM) && !defined(NO_CERTS) RSA* rsa = NULL; BIO* bio = NULL; diff --git a/wolfssl/wolfcrypt/pkcs7.h b/wolfssl/wolfcrypt/pkcs7.h index b0b0de2fb..840d94281 100644 --- a/wolfssl/wolfcrypt/pkcs7.h +++ b/wolfssl/wolfcrypt/pkcs7.h @@ -154,7 +154,7 @@ enum Pkcs7_Misc { MAX_SEQ_SZ + ASN_NAME_MAX + MAX_SN_SZ + MAX_SEQ_SZ + MAX_ALGO_SZ + 1 + MAX_ENCRYPTED_KEY_SZ, #if (defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && \ - (HAVE_FIPS_VERSION >= 2)) + (HAVE_FIPS_VERSION >= 2)) || defined(HAVE_SELFTEST) /* In the event of fips cert 3389 or CAVP selftest build, these enums are * not in aes.h for use with pkcs7 so enumerate it here outside the fips * boundary */ From eedbce7c0ad6d89d8f88545be3d487f68e6c6524 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 22 Jan 2020 11:23:40 -0800 Subject: [PATCH 084/649] Null-check keyFormat Zero all of WOLFSSL_DH struct Fix macros for self-test --- src/ssl.c | 44 +++++++++++++++++++++++--------------------- tests/api.c | 5 ++++- 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index a7432f402..17afbb5ce 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -115,6 +115,9 @@ && !defined(WC_NO_RNG) #include #endif + #if defined(HAVE_FIPS) || defined(HAVE_SELFTEST) + #include + #endif #if defined(OPENSSL_ALL) && defined(HAVE_PKCS7) #include #endif /* OPENSSL_ALL && HAVE_PKCS7 */ @@ -16469,15 +16472,6 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) return type; } - static WC_INLINE void IncCtr(byte* ctr, word32 ctrSz) - { - int i; - for (i = ctrSz-1; i >= 0; i--) { - if (++ctr[i]) - break; - } - } - int wolfSSL_EVP_MD_CTX_cleanup(WOLFSSL_EVP_MD_CTX* ctx) { WOLFSSL_ENTER("EVP_MD_CTX_cleanup"); @@ -16543,13 +16537,25 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ctx->enc = 1; /* start in encrypt mode */ } } + +#if defined(HAVE_AESGCM) && !defined(HAVE_SELFTEST) + static WC_INLINE void IncCtr(byte* ctr, word32 ctrSz) + { + int i; + for (i = ctrSz-1; i >= 0; i--) { + if (++ctr[i]) + break; + } + } +#endif + /* This function allows cipher specific parameters to be determined and set. */ int wolfSSL_EVP_CIPHER_CTX_ctrl(WOLFSSL_EVP_CIPHER_CTX *ctx, int type, \ int arg, void *ptr) { int ret = WOLFSSL_FAILURE; -#ifdef HAVE_AESGCM +#if defined(HAVE_AESGCM) && !defined(HAVE_SELFTEST) WC_RNG rng; #endif if (ctx == NULL) @@ -16569,7 +16575,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) case EVP_CTRL_SET_KEY_LENGTH: ret = wolfSSL_EVP_CIPHER_CTX_set_key_length(ctx, arg); break; -#ifdef HAVE_AESGCM +#if defined(HAVE_AESGCM) && !defined(HAVE_SELFTEST) case EVP_CTRL_GCM_SET_IVLEN: if(arg <= 0 || arg > 16) return WOLFSSL_FAILURE; @@ -16643,7 +16649,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) XMEMCPY(ptr, ctx->authTag, arg); ret = WOLFSSL_SUCCESS; break; -#endif /* HAVE_AESGCM */ +#endif /* HAVE_AESGCM && !HAVE_SELFTEST */ default: WOLFSSL_MSG("EVP_CIPHER_CTX_ctrl operation not yet handled"); ret = WOLFSSL_FAILURE; @@ -29425,14 +29431,7 @@ WOLFSSL_ASN1_INTEGER* wolfSSL_BN_to_ASN1_INTEGER(const WOLFSSL_BIGNUM *bn, WOLFS static void InitwolfSSL_DH(WOLFSSL_DH* dh) { if (dh) { - dh->p = NULL; - dh->g = NULL; - dh->q = NULL; - dh->pub_key = NULL; - dh->priv_key = NULL; - dh->internal = NULL; - dh->inSet = 0; - dh->exSet = 0; + XMEMSET(dh, 0, sizeof(WOLFSSL_DH)); } } @@ -30813,6 +30812,7 @@ int wolfSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet, return ret; } +#if !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS) WOLFSSL_DSA_SIG* wolfSSL_DSA_do_sign_ex(const unsigned char* digest, int outLen, WOLFSSL_DSA* dsa) { @@ -30849,7 +30849,7 @@ error: } return NULL; } - +#endif /* !HAVE_SELFTEST && !HAVE_FIPS */ int wolfSSL_DSA_do_verify(const unsigned char* d, unsigned char* sig, WOLFSSL_DSA* dsa, int *dsacheck) @@ -30881,6 +30881,7 @@ int wolfSSL_DSA_do_verify(const unsigned char* d, unsigned char* sig, return WOLFSSL_SUCCESS; } +#if !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS) int wolfSSL_DSA_do_verify_ex(const unsigned char* digest, int digest_len, WOLFSSL_DSA_SIG* sig, WOLFSSL_DSA* dsa) { @@ -30934,6 +30935,7 @@ int wolfSSL_DSA_do_verify_ex(const unsigned char* digest, int digest_len, return WOLFSSL_SUCCESS; } +#endif /* !HAVE_SELFTEST && !HAVE_FIPS */ #endif /* NO_DSA */ diff --git a/tests/api.c b/tests/api.c index 62be70388..e0ba89598 100644 --- a/tests/api.c +++ b/tests/api.c @@ -20136,6 +20136,7 @@ static void test_wolfSSL_PEM_PUBKEY(void) static void test_DSA_do_sign_verify(void) { +#if !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS) #if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && \ !defined(NO_DSA) unsigned char digest[WC_SHA_DIGEST_SIZE]; @@ -20181,6 +20182,7 @@ static void test_DSA_do_sign_verify(void) DSA_SIG_free(sig); DSA_free(dsa); #endif +#endif /* !HAVE_SELFTEST && !HAVE_FIPS */ } static void test_wolfSSL_tmp_dh(void) @@ -29252,7 +29254,8 @@ static void test_wolfSSL_PEM_read(void) static void test_wolfssl_EVP_aes_gcm(void) { -#if defined(OPENSSL_EXTRA) && !defined(NO_AES) && defined(HAVE_AESGCM) +#if defined(OPENSSL_EXTRA) && !defined(NO_AES) && defined(HAVE_AESGCM) && \ + !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS) /* A 256 bit key, AES_128 will use the first 128 bit*/ byte *key = (byte*)"01234567890123456789012345678901"; From 43ce272cb3e10d40ab6e7295b502f629a0396135 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 22 Jan 2020 11:38:13 -0800 Subject: [PATCH 085/649] Variable declaration at start of scope --- wolfcrypt/src/coding.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/wolfcrypt/src/coding.c b/wolfcrypt/src/coding.c index ba535abc0..f6c814e01 100644 --- a/wolfcrypt/src/coding.c +++ b/wolfcrypt/src/coding.c @@ -103,6 +103,7 @@ int Base64_Decode(const byte* in, word32 inLen, byte* out, word32* outLen) int pad4 = 0; byte b1, b2, b3; + byte e1, e2, e3, e4; if ((ret = Base64_SkipNewline(in, &inLen, &j)) != 0) { if (ret == BUFFER_E) { /* Running out of buffer here is not an error */ @@ -110,7 +111,7 @@ int Base64_Decode(const byte* in, word32 inLen, byte* out, word32* outLen) } return ret; } - byte e1 = in[j++]; + e1 = in[j++]; if (e1 == '\0') { break; } @@ -118,17 +119,17 @@ int Base64_Decode(const byte* in, word32 inLen, byte* out, word32* outLen) if ((ret = Base64_SkipNewline(in, &inLen, &j)) != 0) { return ret; } - byte e2 = in[j++]; + e2 = in[j++]; inLen--; if ((ret = Base64_SkipNewline(in, &inLen, &j)) != 0) { return ret; } - byte e3 = in[j++]; + e3 = in[j++]; inLen--; if ((ret = Base64_SkipNewline(in, &inLen, &j)) != 0) { return ret; } - byte e4 = in[j++]; + e4 = in[j++]; inLen--; if (e1 == 0) /* end file 0's */ From 7aaa89aedcfbfefe5efc1d7175293c88708a70a1 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 22 Jan 2020 15:18:23 -0800 Subject: [PATCH 086/649] Cleanup bn_one in wolfSSL_Cleanup --- src/ssl.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 17afbb5ce..9e3748eaa 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -345,6 +345,10 @@ int wolfSSL_send_session(WOLFSSL* ssl) #endif /* WOLFSSL_DTLS */ #endif /* WOLFSSL_SESSION_EXPORT */ +#ifdef OPENSSL_EXTRA +/* Global pointer to constant BN on */ +static WOLFSSL_BIGNUM* bn_one = NULL; +#endif /* prevent multiple mutex initializations */ static volatile WOLFSSL_GLOBAL int initRefCount = 0; @@ -12463,6 +12467,13 @@ int wolfSSL_Cleanup(void) if (!release) return ret; +#ifdef OPENSSL_EXTRA + if (bn_one) { + wolfSSL_BN_free(bn_one); + bn_one = NULL; + } +#endif + #ifndef NO_SESSION_CACHE if (wc_FreeMutex(&session_mutex) != 0) ret = BAD_MUTEX_E; @@ -46357,10 +46368,9 @@ int wolfSSL_BN_mod_mul(WOLFSSL_BIGNUM *r, const WOLFSSL_BIGNUM *a, return SSL_FAILURE; } +#ifdef OPENSSL_EXTRA const WOLFSSL_BIGNUM* wolfSSL_BN_value_one(void) { - static WOLFSSL_BIGNUM* bn_one = NULL; - WOLFSSL_MSG("wolfSSL_BN_value_one"); if (bn_one == NULL) { @@ -46376,6 +46386,7 @@ const WOLFSSL_BIGNUM* wolfSSL_BN_value_one(void) return bn_one; } +#endif /* return compliant with OpenSSL * size of BIGNUM in bytes, 0 if error */ From dac23dfe15f744d549e204eb1787fbb83145b89e Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 23 Jan 2020 09:01:50 -0800 Subject: [PATCH 087/649] Add DSA and DH free to wolfSSL_EVP_PKEY_set1_EC_KEY --- src/ssl.c | 25 +++++++++++++++++++------ wolfssl/openssl/crypto.h | 4 +++- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 9e3748eaa..167a381f3 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -141,6 +141,12 @@ #include #endif #endif /* !WOLFCRYPT_ONLY || OPENSSL_EXTRA */ + +#ifdef OPENSSL_EXTRA +/* Global pointer to constant BN on */ +static WOLFSSL_BIGNUM* bn_one = NULL; +#endif + #ifndef WOLFCRYPT_ONLY #if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) @@ -345,11 +351,6 @@ int wolfSSL_send_session(WOLFSSL* ssl) #endif /* WOLFSSL_DTLS */ #endif /* WOLFSSL_SESSION_EXPORT */ -#ifdef OPENSSL_EXTRA -/* Global pointer to constant BN on */ -static WOLFSSL_BIGNUM* bn_one = NULL; -#endif - /* prevent multiple mutex initializations */ static volatile WOLFSSL_GLOBAL int initRefCount = 0; static WOLFSSL_GLOBAL wolfSSL_Mutex count_mutex; /* init ref count mutex */ @@ -15658,7 +15659,7 @@ size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out, return SSLEAY_VERSION_NUMBER; } - unsigned long OpenSSL_version_num(void) + unsigned long wolfSSL_OpenSSL_version_num(void) { return OPENSSL_VERSION_NUMBER; } @@ -32201,6 +32202,18 @@ WOLFSSL_API int wolfSSL_EVP_PKEY_set1_EC_KEY(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_EC_ wolfSSL_RSA_free(pkey->rsa); } pkey->ownRsa = 0; +#endif +#ifndef NO_DSA + if (pkey->dsa != NULL && pkey->ownDsa == 1) { + wolfSSL_DSA_free(pkey->dsa); + } + pkey->ownDsa = 0; +#endif +#ifndef NO_DH + if (pkey->dh != NULL && pkey->ownDh == 1) { + wolfSSL_DH_free(pkey->dh); + } + pkey->ownDh = 0; #endif if (pkey->ecc != NULL && pkey->ownEcc == 1) { wolfSSL_EC_KEY_free(pkey->ecc); diff --git a/wolfssl/openssl/crypto.h b/wolfssl/openssl/crypto.h index a3eeb7bd7..25d0c31b2 100644 --- a/wolfssl/openssl/crypto.h +++ b/wolfssl/openssl/crypto.h @@ -35,7 +35,7 @@ WOLFSSL_API const char* wolfSSLeay_version(int type); WOLFSSL_API unsigned long wolfSSLeay(void); -WOLFSSL_API unsigned long OpenSSL_version_num(void); +WOLFSSL_API unsigned long wolfSSL_OpenSSL_version_num(void); #ifdef OPENSSL_EXTRA WOLFSSL_API void wolfSSL_OPENSSL_free(void*); @@ -85,6 +85,8 @@ typedef void (CRYPTO_free_func)(void*parent, void*ptr, CRYPTO_EX_DATA *ad, int i #define CRYPTO_THREAD_r_lock wc_LockMutex #define CRYPTO_THREAD_unlock wc_UnLockMutex +#define OpenSSL_version_num wolfSSL_OpenSSL_version_num + #endif /* OPENSSL_ALL || HAVE_STUNNEL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */ #endif /* header */ From 5ed1c233b72d5f9b363f8c0c90fb249ee3e51372 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 23 Jan 2020 10:12:42 -0800 Subject: [PATCH 088/649] Sean comments --- src/ssl.c | 6 +++--- wolfssl/wolfcrypt/asn.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 167a381f3..72984c93e 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -36849,14 +36849,14 @@ WOLFSSL_RSA* wolfSSL_RSAPublicKey_dup(WOLFSSL_RSA *rsa) void* wolfSSL_RSA_get_ex_data(const WOLFSSL_RSA *rsa, int idx) { WOLFSSL_ENTER("wolfSSL_RSA_get_ex_data"); - #ifdef HAVE_EX_DATA +#ifdef HAVE_EX_DATA if (rsa) { return wolfSSL_CRYPTO_get_ex_data(&rsa->ex_data, idx); } - #else +#else (void)rsa; (void)idx; - #endif +#endif return NULL; } diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 12f835b6e..29cd9d703 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -220,9 +220,9 @@ enum NID_domainComponent = 0x19, /* matches ASN_DOMAIN_COMPONENT in asn.h */ NID_emailAddress = 0x30, /* emailAddress */ NID_id_on_dnsSRV = 82, /* 1.3.6.1.5.5.7.8.7 */ - NID_ms_upn = 265, /* 1.3.6.1.4.1.311.20.2.3 */ + NID_ms_upn = 265, /* 1.3.6.1.4.1.311.20.2.3 */ - NID_X9_62_prime_field = 406 + NID_X9_62_prime_field = 406 /* 1.2.840.10045.1.1 */ }; enum ECC_TYPES From 3fcec191a48f06942e69adc10446788c6ea2d5a6 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 23 Jan 2020 13:17:14 -0800 Subject: [PATCH 089/649] Refactor wolfSSL_RSA_To_Der --- src/ssl.c | 150 +++++++++++++------------------- tests/api.c | 10 +-- wolfcrypt/src/asn.c | 28 +++--- wolfcrypt/src/evp.c | 3 +- wolfcrypt/user-crypto/src/rsa.c | 26 +++--- wolfssl/openssl/crypto.h | 3 +- 6 files changed, 98 insertions(+), 122 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 72984c93e..61c76a514 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -32667,45 +32667,67 @@ static int EncryptDerKey(byte *der, int *derSz, const EVP_CIPHER* cipher, #if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA) static int wolfSSL_RSA_To_Der(WOLFSSL_RSA* rsa, byte** outBuf, int publicKey) { - int derMax = 0; int derSz = 0; + int ret; byte* derBuf; WOLFSSL_ENTER("wolfSSL_RSA_To_Der"); - if (!rsa || !outBuf || (publicKey != 0 && publicKey != 1)) { + if (!rsa || (publicKey != 0 && publicKey != 1)) { WOLFSSL_LEAVE("wolfSSL_RSA_To_Der", BAD_FUNC_ARG); return BAD_FUNC_ARG; } - /* 5 > size of n, d, p, q, d%(p-1), d(q-1), 1/q%p, e + ASN.1 additional - * informations - */ - derMax = 5 * wolfSSL_RSA_size(rsa) + AES_BLOCK_SIZE; - derBuf = (byte*)XMALLOC(derMax, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (derBuf == NULL) { - WOLFSSL_MSG("malloc failed"); - WOLFSSL_LEAVE("wolfSSL_RSA_To_Der", MEMORY_ERROR); - return MEMORY_ERROR; + + if (rsa->inSet == 0) { + if ((ret = SetRsaInternal(rsa)) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("SetRsaInternal() Failed"); + WOLFSSL_LEAVE("wolfSSL_RSA_To_Der", ret); + return ret; + } } - /* Key to DER */ + if (publicKey) { - derSz = wc_RsaKeyToPublicDer((RsaKey*)rsa->internal, derBuf, derMax); + if ((derSz = wc_RsaPublicKeyDerSize((RsaKey *)rsa->internal, 1)) < 0) { + WOLFSSL_MSG("wc_RsaPublicKeyDerSize failed"); + WOLFSSL_LEAVE("wolfSSL_RSA_To_Der", derSz); + return derSz; + } + } + else { + if ((derSz = wc_RsaKeyToDer((RsaKey*)rsa->internal, NULL, 0)) < 0) { + WOLFSSL_MSG("wc_RsaKeyToDer failed"); + WOLFSSL_LEAVE("wolfSSL_RSA_To_Der", derSz); + return derSz; + } + } + + if (outBuf) { + if (!(derBuf = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER))) { + WOLFSSL_MSG("malloc failed"); + WOLFSSL_LEAVE("wolfSSL_RSA_To_Der", MEMORY_ERROR); + return MEMORY_ERROR; + } + + /* Key to DER */ + if (publicKey) { + derSz = wc_RsaKeyToPublicDer((RsaKey*)rsa->internal, derBuf, derSz); + } + else { + derSz = wc_RsaKeyToDer((RsaKey*)rsa->internal, derBuf, derSz); + } + if (derSz < 0) { WOLFSSL_MSG("wc_RsaKeyToPublicDer failed"); XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER); } else { - *outBuf = derBuf; - } - } - else { - derSz = wc_RsaKeyToDer((RsaKey*)rsa->internal, derBuf, derMax); - if (derSz < 0) { - WOLFSSL_MSG("wc_RsaKeyToDer failed"); - XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER); - } - else { - *outBuf = derBuf; + if (*outBuf) { + XMEMCPY(*outBuf, derBuf, derSz); + XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } + else { + *outBuf = derBuf; + } } } @@ -32755,7 +32777,7 @@ int wolfSSL_PEM_write_bio_RSAPrivateKey(WOLFSSL_BIO* bio, WOLFSSL_RSA* key, /* similar to how wolfSSL_PEM_write_mem_RSAPrivateKey finds DER of key */ { int derSz; - byte* derBuf; + byte* derBuf = NULL; if ((derSz = wolfSSL_RSA_To_Der(key, &derBuf, 0)) < 0) { WOLFSSL_MSG("wolfSSL_RSA_To_Der failed"); @@ -33011,7 +33033,7 @@ int wolfSSL_PEM_write_mem_RSAPrivateKey(RSA* rsa, const EVP_CIPHER* cipher, unsigned char* passwd, int passwdSz, unsigned char **pem, int *plen) { - byte *derBuf, *tmp, *cipherInfo = NULL; + byte *derBuf = NULL, *tmp, *cipherInfo = NULL; int derSz = 0; const int type = PRIVATEKEY_TYPE; const char* header = NULL; @@ -36579,7 +36601,8 @@ WOLFSSL_RSA *wolfSSL_d2i_RSAPrivateKey(WOLFSSL_RSA **r, return rsa; } -#if !defined(HAVE_FAST_RSA) +#if !defined(HAVE_FAST_RSA) && defined(WOLFSSL_KEY_GEN) && \ + !defined(NO_RSA) && !defined(HAVE_USER_RSA) /* Converts an internal RSA structure to DER format. * If "pp" is null then buffer size only is returned. * If "*pp" is null then a created buffer is set in *pp and the caller is @@ -36588,10 +36611,7 @@ WOLFSSL_RSA *wolfSSL_d2i_RSAPrivateKey(WOLFSSL_RSA **r, */ int wolfSSL_i2d_RSAPrivateKey(WOLFSSL_RSA *rsa, unsigned char **pp) { -#if defined(WOLFSSL_KEY_GEN) && !defined(NO_RSA) && !defined(HAVE_USER_RSA) - byte* der = NULL; int ret; - int i; WOLFSSL_ENTER("wolfSSL_i2d_RSAPrivateKey"); @@ -36601,82 +36621,34 @@ int wolfSSL_i2d_RSAPrivateKey(WOLFSSL_RSA *rsa, unsigned char **pp) return BAD_FUNC_ARG; } - if (rsa->inSet == 0) { - if ((ret = SetRsaInternal(rsa)) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("SetRsaInternal() Failed"); - return ret; - } - } - - if ((ret = wolfSSL_RSA_To_Der(rsa, &der, 0)) < 0) { + if ((ret = wolfSSL_RSA_To_Der(rsa, pp, 0)) < 0) { WOLFSSL_MSG("wolfSSL_RSA_To_Der failed"); return WOLFSSL_FAILURE; } - if (pp != NULL) { - if (*pp == NULL) { - /* create buffer and return it */ - *pp = (unsigned char*)XMALLOC(ret, NULL, DYNAMIC_TYPE_OPENSSL); - if (*pp == NULL) { - return WOLFSSL_FATAL_ERROR; - } - XMEMCPY(*pp, der, ret); - } - else { - /* ret is the size of the DER buffer */ - for (i = 0; i < ret; i++) { - *(*pp + i) = *(der + i); - } - *pp += ret; - } - } - XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); return ret; /* returns size of DER if successful */ -#else - (void)rsa; - (void)pp; - WOLFSSL_MSG("Error, wolfSSL_i2d_RSAPrivateKey missing defines"); - return WOLFSSL_FAILURE; -#endif /* WOLFSSL_KEY_GEN */ } int wolfSSL_i2d_RSAPublicKey(WOLFSSL_RSA *rsa, const unsigned char **pp) { - byte *der; - int derLen; int ret; - WOLFSSL_ENTER("i2d_RSAPublicKey"); - if (rsa == NULL) - return WOLFSSL_FATAL_ERROR; + /* check for bad functions arguments */ + if (rsa == NULL) { + WOLFSSL_MSG("Bad Function Arguments"); + return BAD_FUNC_ARG; + } - if (rsa->inSet == 0) { - if ((ret = SetRsaInternal(rsa)) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("SetRsaInternal Failed"); - return ret; - } + if ((ret = wolfSSL_RSA_To_Der(rsa, (byte**)pp, 1)) < 0) { + WOLFSSL_MSG("wolfSSL_RSA_To_Der failed"); + return WOLFSSL_FAILURE; } - if ((derLen = wc_RsaPublicKeyDerSize((RsaKey *)rsa->internal, 1)) < 0) - return WOLFSSL_FATAL_ERROR; - der = (byte*)XMALLOC(derLen, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (der == NULL) { - return WOLFSSL_FATAL_ERROR; - } - if ((ret = wc_RsaKeyToPublicDer((RsaKey *)rsa->internal, der, derLen)) < 0){ - WOLFSSL_MSG("RsaKeyToPublicDer failed"); - if(der != NULL) - XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); - return ret; - } - if ((pp != NULL) && (ret >= 0)) - *pp = der; - else - XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); return ret; } -#endif /* #if !defined(HAVE_FAST_RSA) */ +#endif /* !defined(HAVE_FAST_RSA) && defined(WOLFSSL_KEY_GEN) && \ + * !defined(NO_RSA) && !defined(HAVE_USER_RSA) */ #endif /* !NO_RSA */ #endif /* OPENSSL_EXTRA */ diff --git a/tests/api.c b/tests/api.c index e0ba89598..aa98c0eed 100644 --- a/tests/api.c +++ b/tests/api.c @@ -12291,7 +12291,7 @@ static int test_wc_RsaKeyToDer (void) if (ret == BAD_FUNC_ARG) { ret = wc_RsaKeyToDer(&genKey, NULL, FOURK_BUF); } - if (ret == BAD_FUNC_ARG) { + if (ret > 0) { /* Try Public Key. */ genKey.type = 0; ret = wc_RsaKeyToDer(&genKey, der, FOURK_BUF); @@ -24202,8 +24202,7 @@ static void test_wolfSSL_d2i_PrivateKeys_bio(void) #if defined(WOLFSSL_KEY_GEN) unsigned char buff[4096]; - unsigned char* bufPtr; - bufPtr = buff; + unsigned char* bufPtr = buff; #endif printf(testingFmt, "wolfSSL_d2i_PrivateKeys_bio()"); @@ -24432,11 +24431,12 @@ static void test_wolfSSL_RSA(void) static void test_wolfSSL_RSA_DER(void) { -#if defined(OPENSSL_EXTRA) && !defined(NO_RSA) && !defined(HAVE_FAST_RSA) +#if !defined(HAVE_FAST_RSA) && defined(WOLFSSL_KEY_GEN) && \ + !defined(NO_RSA) && !defined(HAVE_USER_RSA) && defined(OPENSSL_EXTRA) RSA *rsa; int i; - const unsigned char *buff; + const unsigned char *buff = NULL; struct tbl_s { diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 67d37965d..5624258a9 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -11089,7 +11089,7 @@ int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen) byte ver[MAX_VERSION_SZ]; byte* tmps[RSA_INTS]; - if (!key || !output) + if (!key) return BAD_FUNC_ARG; if (key->type != RSA_PRIVATE) @@ -11128,20 +11128,22 @@ int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen) seqSz = SetSequence(verSz + intTotalLen, seq); outLen = seqSz + verSz + intTotalLen; - if (outLen > (int)inLen) { - FreeTmpRsas(tmps, key->heap); - return BAD_FUNC_ARG; - } + if (output) { + if (outLen > (int)inLen) { + FreeTmpRsas(tmps, key->heap); + return BAD_FUNC_ARG; + } - /* write to output */ - XMEMCPY(output, seq, seqSz); - j = seqSz; - XMEMCPY(output + j, ver, verSz); - j += verSz; + /* write to output */ + XMEMCPY(output, seq, seqSz); + j = seqSz; + XMEMCPY(output + j, ver, verSz); + j += verSz; - for (i = 0; i < RSA_INTS; i++) { - XMEMCPY(output + j, tmps[i], sizes[i]); - j += sizes[i]; + for (i = 0; i < RSA_INTS; i++) { + XMEMCPY(output + j, tmps[i], sizes[i]); + j += sizes[i]; + } } FreeTmpRsas(tmps, key->heap); diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 6a2f61651..b4ec5efab 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -1247,7 +1247,8 @@ int wolfSSL_EVP_PKEY_keygen(WOLFSSL_EVP_PKEY_CTX *ctx, } switch (pkey->type) { -#if !defined(NO_RSA) && !defined(HAVE_USER_RSA) +#if !defined(HAVE_FAST_RSA) && defined(WOLFSSL_KEY_GEN) && \ + !defined(NO_RSA) && !defined(HAVE_USER_RSA) case EVP_PKEY_RSA: pkey->rsa = wolfSSL_RSA_generate_key(ctx->nbits, WC_RSA_EXPONENT, NULL, NULL); diff --git a/wolfcrypt/user-crypto/src/rsa.c b/wolfcrypt/user-crypto/src/rsa.c index b88510167..a9f5afd8b 100644 --- a/wolfcrypt/user-crypto/src/rsa.c +++ b/wolfcrypt/user-crypto/src/rsa.c @@ -2663,7 +2663,7 @@ int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen) USER_DEBUG(("Entering RsaKeyToDer\n")); - if (!key || !output) + if (!key) return USER_CRYPTO_ERROR; if (key->type != RSA_PRIVATE) @@ -2739,19 +2739,21 @@ int wc_RsaKeyToDer(RsaKey* key, byte* output, word32 inLen) seqSz = SetSequence(verSz + intTotalLen, seq); outLen = seqSz + verSz + intTotalLen; - if (outLen > (int)inLen) { - return USER_CRYPTO_ERROR; - } + if (output) { + if (outLen > (int)inLen) { + return USER_CRYPTO_ERROR; + } - /* write to output */ - XMEMCPY(output, seq, seqSz); - j = seqSz; - XMEMCPY(output + j, ver, verSz); - j += verSz; + /* write to output */ + XMEMCPY(output, seq, seqSz); + j = seqSz; + XMEMCPY(output + j, ver, verSz); + j += verSz; - for (i = 0; i < RSA_INTS; i++) { - XMEMCPY(output + j, tmps[i], sizes[i]); - j += sizes[i]; + for (i = 0; i < RSA_INTS; i++) { + XMEMCPY(output + j, tmps[i], sizes[i]); + j += sizes[i]; + } } FreeTmpRsas(tmps, key->heap); diff --git a/wolfssl/openssl/crypto.h b/wolfssl/openssl/crypto.h index 25d0c31b2..fe2bb7d94 100644 --- a/wolfssl/openssl/crypto.h +++ b/wolfssl/openssl/crypto.h @@ -46,6 +46,7 @@ WOLFSSL_API void *wolfSSL_OPENSSL_malloc(size_t a); #define SSLeay_version wolfSSLeay_version #define SSLeay wolfSSLeay +#define OpenSSL_version_num wolfSSL_OpenSSL_version_num #ifdef WOLFSSL_QT #define SSLEAY_VERSION 0x10001000L @@ -85,8 +86,6 @@ typedef void (CRYPTO_free_func)(void*parent, void*ptr, CRYPTO_EX_DATA *ad, int i #define CRYPTO_THREAD_r_lock wc_LockMutex #define CRYPTO_THREAD_unlock wc_UnLockMutex -#define OpenSSL_version_num wolfSSL_OpenSSL_version_num - #endif /* OPENSSL_ALL || HAVE_STUNNEL || WOLFSSL_NGINX || WOLFSSL_HAPROXY */ #endif /* header */ From f55cfd7ba736f3ff9e806ba1b6fd59340dcc13f2 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Sun, 26 Jan 2020 17:56:20 +0100 Subject: [PATCH 090/649] Fix missing wolfSSL_i2d_RSAPrivateKey references --- src/ssl.c | 6 ++++-- tests/api.c | 49 ++++++++++++++++++++++++++----------------------- 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 61c76a514..f0aef5e57 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -42297,7 +42297,8 @@ int wolfSSL_BIO_new_bio_pair(WOLFSSL_BIO **bio1_p, size_t writebuf1, } -#if !defined(NO_RSA) +#if !defined(HAVE_FAST_RSA) && defined(WOLFSSL_KEY_GEN) && \ + !defined(NO_RSA) && !defined(HAVE_USER_RSA) /* Converts an rsa key from a bio buffer into an internal rsa structure. Returns a pointer to the new WOLFSSL_RSA structure. */ WOLFSSL_RSA* wolfSSL_d2i_RSAPrivateKey_bio(WOLFSSL_BIO *bio, WOLFSSL_RSA **out) @@ -42402,7 +42403,8 @@ int wolfSSL_CTX_use_certificate_ASN1(WOLFSSL_CTX *ctx, int derSz, } -#if !defined(NO_RSA) && !defined(HAVE_FAST_RSA) +#if !defined(HAVE_FAST_RSA) && defined(WOLFSSL_KEY_GEN) && \ + !defined(NO_RSA) && !defined(HAVE_USER_RSA) /* Adds the rsa private key to the user ctx. Returns WOLFSSL_SUCCESS if no error, returns WOLFSSL_FAILURE otherwise.*/ int wolfSSL_CTX_use_RSAPrivateKey(WOLFSSL_CTX* ctx, WOLFSSL_RSA* rsa) diff --git a/tests/api.c b/tests/api.c index aa98c0eed..ae97fcbbb 100644 --- a/tests/api.c +++ b/tests/api.c @@ -24196,7 +24196,6 @@ static void test_wolfSSL_d2i_PrivateKeys_bio(void) BIO* bio = NULL; EVP_PKEY* pkey = NULL; #ifndef NO_RSA - RSA* rsa = NULL; #endif WOLFSSL_CTX* ctx; @@ -24273,34 +24272,38 @@ static void test_wolfSSL_d2i_PrivateKeys_bio(void) AssertNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method())); #endif -#ifndef NO_RSA - /* Tests bad parameters */ - AssertNull(d2i_RSAPrivateKey_bio(NULL, NULL)); +#if !defined(HAVE_FAST_RSA) && defined(WOLFSSL_KEY_GEN) && \ + !defined(NO_RSA) && !defined(HAVE_USER_RSA) + { + RSA* rsa = NULL; + /* Tests bad parameters */ + AssertNull(d2i_RSAPrivateKey_bio(NULL, NULL)); - /* RSA not set yet, expecting to fail*/ - AssertIntEQ(SSL_CTX_use_RSAPrivateKey(ctx, rsa), BAD_FUNC_ARG); + /* RSA not set yet, expecting to fail*/ + AssertIntEQ(SSL_CTX_use_RSAPrivateKey(ctx, rsa), BAD_FUNC_ARG); #if defined(USE_CERT_BUFFERS_2048) && defined(WOLFSSL_KEY_GEN) - /* set RSA using bio*/ - AssertIntGT(BIO_write(bio, client_key_der_2048, - sizeof_client_key_der_2048), 0); - AssertNotNull(rsa = d2i_RSAPrivateKey_bio(bio, NULL)); + /* set RSA using bio*/ + AssertIntGT(BIO_write(bio, client_key_der_2048, + sizeof_client_key_der_2048), 0); + AssertNotNull(rsa = d2i_RSAPrivateKey_bio(bio, NULL)); - AssertIntEQ(SSL_CTX_use_RSAPrivateKey(ctx, rsa), WOLFSSL_SUCCESS); + AssertIntEQ(SSL_CTX_use_RSAPrivateKey(ctx, rsa), WOLFSSL_SUCCESS); - /*i2d RSAprivate key tests */ - AssertIntEQ(wolfSSL_i2d_RSAPrivateKey(NULL, NULL), BAD_FUNC_ARG); - AssertIntEQ(wolfSSL_i2d_RSAPrivateKey(rsa, NULL), 1192); - AssertIntEQ(wolfSSL_i2d_RSAPrivateKey(rsa, &bufPtr), - sizeof_client_key_der_2048); - bufPtr = NULL; - AssertIntEQ(wolfSSL_i2d_RSAPrivateKey(rsa, &bufPtr), - sizeof_client_key_der_2048); - AssertNotNull(bufPtr); - XFREE(bufPtr, NULL, DYNAMIC_TYPE_OPENSSL); + /*i2d RSAprivate key tests */ + AssertIntEQ(wolfSSL_i2d_RSAPrivateKey(NULL, NULL), BAD_FUNC_ARG); + AssertIntEQ(wolfSSL_i2d_RSAPrivateKey(rsa, NULL), 1192); + AssertIntEQ(wolfSSL_i2d_RSAPrivateKey(rsa, &bufPtr), + sizeof_client_key_der_2048); + bufPtr = NULL; + AssertIntEQ(wolfSSL_i2d_RSAPrivateKey(rsa, &bufPtr), + sizeof_client_key_der_2048); + AssertNotNull(bufPtr); + XFREE(bufPtr, NULL, DYNAMIC_TYPE_OPENSSL); #endif /* USE_CERT_BUFFERS_2048 WOLFSSL_KEY_GEN */ - RSA_free(rsa); -#endif /* NO_RSA */ + RSA_free(rsa); + } +#endif /* !HAVE_FAST_RSA && WOLFSSL_KEY_GEN && !NO_RSA && !HAVE_USER_RSA*/ SSL_CTX_free(ctx); ctx = NULL; BIO_free(bio); From 5c4d3df4f3f6baa6f665283d80025dbf7a799212 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 28 Jan 2020 12:06:57 +0100 Subject: [PATCH 091/649] Fix broken Windows FIPS build --- IDE/WIN/user_settings.h | 2 ++ src/ssl.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/IDE/WIN/user_settings.h b/IDE/WIN/user_settings.h index 406003ed1..d5fc044d4 100644 --- a/IDE/WIN/user_settings.h +++ b/IDE/WIN/user_settings.h @@ -22,6 +22,8 @@ #define NO_RABBIT #define NO_DSA #define NO_MD4 + + #define GCM_NONCE_MID_SZ 12 #else /* Enables blinding mode, to prevent timing attacks */ #define WC_RSA_BLINDING diff --git a/src/ssl.c b/src/ssl.c index f0aef5e57..5d356efdd 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -16632,6 +16632,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) } } break; +#if !defined(_WIN32) && !defined(HAVE_FIPS) case EVP_CTRL_GCM_IV_GEN: if (ctx->cipher.aes.keylen == 0 || ctx->ivSz == 0) { ret = WOLFSSL_FAILURE; @@ -16645,6 +16646,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) /* OpenSSL increments the IV. Not sure why */ IncCtr(ctx->iv, ctx->ivSz); break; +#endif case EVP_CTRL_AEAD_SET_TAG: if(arg <= 0 || arg > 16 || (ptr == NULL)) return WOLFSSL_FAILURE; From 1512485926ec02d6ebad67b0db4137910d5d2ef2 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Tue, 28 Jan 2020 14:24:39 +0100 Subject: [PATCH 092/649] Fix user-rsa tests --- tests/api.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/api.c b/tests/api.c index ae97fcbbb..79ceab8ea 100644 --- a/tests/api.c +++ b/tests/api.c @@ -12285,11 +12285,12 @@ static int test_wc_RsaKeyToDer (void) } } #ifndef HAVE_USER_RSA - /* Pass bad args. */ + /* Pass good/bad args. */ if (ret == 0) { ret = wc_RsaKeyToDer(NULL, der, FOURK_BUF); if (ret == BAD_FUNC_ARG) { - ret = wc_RsaKeyToDer(&genKey, NULL, FOURK_BUF); + /* Get just the output length */ + ret = wc_RsaKeyToDer(&genKey, NULL, 0); } if (ret > 0) { /* Try Public Key. */ @@ -12303,13 +12304,14 @@ static int test_wc_RsaKeyToDer (void) } } #else - /* Pass bad args. */ + /* Pass good/bad args. */ if (ret == 0) { ret = wc_RsaKeyToDer(NULL, der, FOURK_BUF); if (ret == USER_CRYPTO_ERROR) { - ret = wc_RsaKeyToDer(&genKey, NULL, FOURK_BUF); + /* Get just the output length */ + ret = wc_RsaKeyToDer(&genKey, NULL, 0); } - if (ret == USER_CRYPTO_ERROR) { + if (ret > 0) { /* Try Public Key. */ genKey.type = 0; ret = wc_RsaKeyToDer(&genKey, der, FOURK_BUF); From 5a766bd5bbacaf71966a91d745ec241022f11f67 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 30 Jan 2020 14:44:57 +0100 Subject: [PATCH 093/649] Change STR_SIZEOF declaration file --- wolfcrypt/src/asn.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 5624258a9..4494893af 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -10210,8 +10210,6 @@ int wc_DerToPemEx(const byte* der, word32 derSz, byte* output, word32 outSz, #ifdef WOLFSSL_PEM_TO_DER -#define STR_SIZEOF(x) (sizeof(x) - 1) /* -1 to not count the null char */ - /* Remove PEM header/footer, convert to ASN1, store any encrypted data info->consumed tracks of PEM bytes consumed in case multiple parts */ int PemToDer(const unsigned char* buff, long longSz, int type, From d6686f1320ba26864ea3d39bb140b0f210803771 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Mon, 3 Feb 2020 20:28:10 +0100 Subject: [PATCH 094/649] Remove usage of res in wolfSSL_BN_clear_bit --- src/ssl.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 5d356efdd..a0c3695c0 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -46743,10 +46743,8 @@ int wolfSSL_BN_clear_bit(WOLFSSL_BIGNUM* bn, int n) { int ret = WOLFSSL_FAILURE; #ifndef WOLFSSL_SMALL_STACK - mp_int res[1]; mp_int tmp[1]; #else - mp_int* res = NULL; mp_int* tmp = NULL; #endif @@ -46756,10 +46754,6 @@ int wolfSSL_BN_clear_bit(WOLFSSL_BIGNUM* bn, int n) } if (mp_is_bit_set((mp_int*)bn->internal, n)) { #ifdef WOLFSSL_SMALL_STACK - res = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT); - if (res == NULL) { - goto cleanup; - } tmp = (mp_int*)XMALLOC(sizeof(mp_int), NULL, DYNAMIC_TYPE_BIGINT); if (tmp == NULL) { goto cleanup; @@ -46768,24 +46762,16 @@ int wolfSSL_BN_clear_bit(WOLFSSL_BIGNUM* bn, int n) if (mp_init(tmp) != MP_OKAY) { goto cleanup; } - if (mp_init(res) != MP_OKAY) { - goto cleanup; - } if (mp_set_bit(tmp, n) != MP_OKAY) { goto cleanup; } - if (mp_sub((mp_int*)bn->internal, tmp, res) != MP_OKAY) { - goto cleanup; - } - if (mp_copy(res, (mp_int*)bn->internal) != MP_OKAY) { + if (mp_sub((mp_int*)bn->internal, tmp, (mp_int*)bn->internal) != MP_OKAY) { goto cleanup; } } ret = WOLFSSL_SUCCESS; cleanup: #ifdef WOLFSSL_SMALL_STACK - if (res) - XFREE(res, NULL, DYNAMIC_TYPE_BIGINT); if (tmp) XFREE(tmp, NULL, DYNAMIC_TYPE_BIGINT); #endif From 2218f7b95d8a193360bdd96c2152f483eab78164 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Mon, 3 Feb 2020 20:43:23 +0100 Subject: [PATCH 095/649] Fix merge issues --- src/ssl.c | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index a0c3695c0..347fb6215 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -33561,34 +33561,6 @@ int wolfSSL_EVP_PKEY_set1_EC_KEY(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_EC_KEY *key) } #endif /* WOLFSSL_QT || OPENSSL_ALL */ -typedef struct { - const char *name; - int nid; -} WOLF_EC_NIST_NAME; -static const WOLF_EC_NIST_NAME kNistCurves[] = { - {"P-192", NID_X9_62_prime192v1}, - {"P-256", NID_X9_62_prime256v1}, - {"P-112", NID_secp112r1}, - {"P-112-2", NID_secp112r2}, - {"P-128", NID_secp128r1}, - {"P-128-2", NID_secp128r2}, - {"P-160", NID_secp160r1}, - {"P-160-2", NID_secp160r2}, - {"P-224", NID_secp224r1}, - {"P-384", NID_secp384r1}, - {"P-521", NID_secp521r1}, - {"K-160", NID_secp160k1}, - {"K-192", NID_secp192k1}, - {"K-224", NID_secp224k1}, - {"K-256", NID_secp256k1}, - {"B-160", NID_brainpoolP160r1}, - {"B-192", NID_brainpoolP192r1}, - {"B-224", NID_brainpoolP224r1}, - {"B-256", NID_brainpoolP256r1}, - {"B-320", NID_brainpoolP320r1}, - {"B-384", NID_brainpoolP384r1}, - {"B-512", NID_brainpoolP512r1}, -}; const char* wolfSSL_EC_curve_nid2nist(int nid) { const WOLF_EC_NIST_NAME* nist_name; From b736a65fa8d7f799dee819765eb2931457674a1b Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Mon, 3 Feb 2020 20:57:50 +0100 Subject: [PATCH 096/649] Fix redefinition issue --- src/ssl.c | 58 ------------------------------------------------------- 1 file changed, 58 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 347fb6215..7179bf9a8 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -33503,64 +33503,6 @@ WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new_by_curve_name(int nid) return key; } -#if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) -int wolfSSL_EVP_PKEY_set1_EC_KEY(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_EC_KEY *key) -{ - int derMax = 0; - int derSz = 0; - byte* derBuf = NULL; - - WOLFSSL_ENTER("wolfSSL_EVP_PKEY_set1_EC_KEY"); - if (pkey == NULL || key == NULL) - return WOLFSSL_FAILURE; - - if (pkey->ecc != NULL && pkey->ownEcc == 1) - wolfSSL_EC_KEY_free(pkey->ecc); - - pkey->ecc = key; - pkey->ownEcc = 0; /* pkey does not own ECC */ - pkey->type = EVP_PKEY_EC; - - if(key->group != NULL) - pkey->pkey_curve = key->group->curve_oid; - - if (key->inSet == 0) { - WOLFSSL_MSG("No ECC internal set, do it"); - - if (SetECKeyInternal(key) != WOLFSSL_SUCCESS) { - WOLFSSL_MSG("SetECKeyInternal failed"); - return WOLFSSL_FAILURE; - } - } - /* 4 > size of pub, priv + ASN.1 additional informations */ - derMax = 4 * wc_ecc_size((ecc_key*)key->internal) + AES_BLOCK_SIZE; - - derBuf = (byte*)XMALLOC(derMax, pkey->heap, DYNAMIC_TYPE_TMP_BUFFER); - if (derBuf == NULL) { - WOLFSSL_MSG("malloc failed"); - return WOLFSSL_FAILURE; - } - /* Key to DER */ - derSz = wc_EccKeyToDer((ecc_key*)key->internal, derBuf, derMax); - if (derSz < 0) { - WOLFSSL_MSG("wc_EccKeyToDer failed"); - XFREE(derBuf, pkey->heap, DYNAMIC_TYPE_TMP_BUFFER); - return WOLFSSL_FAILURE; - } - - pkey->pkey.ptr = (char*)XMALLOC(derSz, pkey->heap, DYNAMIC_TYPE_DER); - if (pkey->pkey.ptr == NULL) { - WOLFSSL_MSG("key malloc failed"); - XFREE(derBuf, pkey->heap, DYNAMIC_TYPE_TMP_BUFFER); - return WOLFSSL_FAILURE; - } - pkey->pkey_sz = derSz; - XMEMCPY(pkey->pkey.ptr, derBuf, derSz); - XFREE(derBuf, pkey->heap, DYNAMIC_TYPE_TMP_BUFFER); - return WOLFSSL_SUCCESS; -} -#endif /* WOLFSSL_QT || OPENSSL_ALL */ - const char* wolfSSL_EC_curve_nid2nist(int nid) { const WOLF_EC_NIST_NAME* nist_name; From 26e2d6eacf39855519d291eebe3377b55fe28547 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Mon, 17 Feb 2020 17:51:22 +0100 Subject: [PATCH 097/649] Adressing Todd's comments Check for HAVE_GETADDRINFO beside WOLF_C99 Move STR_SIZEOF to wolfssl/wolfcrypt/types.h and rename to XSTR_SIZEOF to prevent collision in client projects Remove wolfssl/openssl/ssl.h and wolfssl/internal.h from crypto layer --- src/ssl.c | 44 +++++++++++++++++++-------------------- src/wolfio.c | 5 +++-- wolfcrypt/src/asn.c | 33 +++++++++++++++++------------ wolfssl/internal.h | 2 -- wolfssl/wolfcrypt/types.h | 1 + wolfssl/wolfio.h | 2 +- 6 files changed, 47 insertions(+), 40 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 7179bf9a8..3e8463cef 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -151,28 +151,28 @@ static WOLFSSL_BIGNUM* bn_one = NULL; #if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) const WOLF_EC_NIST_NAME kNistCurves[] = { - {STR_SIZEOF("P-192"), "P-192", NID_X9_62_prime192v1}, - {STR_SIZEOF("P-256"), "P-256", NID_X9_62_prime256v1}, - {STR_SIZEOF("P-112"), "P-112", NID_secp112r1}, - {STR_SIZEOF("P-112-2"), "P-112-2", NID_secp112r2}, - {STR_SIZEOF("P-128"), "P-128", NID_secp128r1}, - {STR_SIZEOF("P-128-2"), "P-128-2", NID_secp128r2}, - {STR_SIZEOF("P-160"), "P-160", NID_secp160r1}, - {STR_SIZEOF("P-160-2"), "P-160-2", NID_secp160r2}, - {STR_SIZEOF("P-224"), "P-224", NID_secp224r1}, - {STR_SIZEOF("P-384"), "P-384", NID_secp384r1}, - {STR_SIZEOF("P-521"), "P-521", NID_secp521r1}, - {STR_SIZEOF("K-160"), "K-160", NID_secp160k1}, - {STR_SIZEOF("K-192"), "K-192", NID_secp192k1}, - {STR_SIZEOF("K-224"), "K-224", NID_secp224k1}, - {STR_SIZEOF("K-256"), "K-256", NID_secp256k1}, - {STR_SIZEOF("B-160"), "B-160", NID_brainpoolP160r1}, - {STR_SIZEOF("B-192"), "B-192", NID_brainpoolP192r1}, - {STR_SIZEOF("B-224"), "B-224", NID_brainpoolP224r1}, - {STR_SIZEOF("B-256"), "B-256", NID_brainpoolP256r1}, - {STR_SIZEOF("B-320"), "B-320", NID_brainpoolP320r1}, - {STR_SIZEOF("B-384"), "B-384", NID_brainpoolP384r1}, - {STR_SIZEOF("B-512"), "B-512", NID_brainpoolP512r1}, + {XSTR_SIZEOF("P-192"), "P-192", NID_X9_62_prime192v1}, + {XSTR_SIZEOF("P-256"), "P-256", NID_X9_62_prime256v1}, + {XSTR_SIZEOF("P-112"), "P-112", NID_secp112r1}, + {XSTR_SIZEOF("P-112-2"), "P-112-2", NID_secp112r2}, + {XSTR_SIZEOF("P-128"), "P-128", NID_secp128r1}, + {XSTR_SIZEOF("P-128-2"), "P-128-2", NID_secp128r2}, + {XSTR_SIZEOF("P-160"), "P-160", NID_secp160r1}, + {XSTR_SIZEOF("P-160-2"), "P-160-2", NID_secp160r2}, + {XSTR_SIZEOF("P-224"), "P-224", NID_secp224r1}, + {XSTR_SIZEOF("P-384"), "P-384", NID_secp384r1}, + {XSTR_SIZEOF("P-521"), "P-521", NID_secp521r1}, + {XSTR_SIZEOF("K-160"), "K-160", NID_secp160k1}, + {XSTR_SIZEOF("K-192"), "K-192", NID_secp192k1}, + {XSTR_SIZEOF("K-224"), "K-224", NID_secp224k1}, + {XSTR_SIZEOF("K-256"), "K-256", NID_secp256k1}, + {XSTR_SIZEOF("B-160"), "B-160", NID_brainpoolP160r1}, + {XSTR_SIZEOF("B-192"), "B-192", NID_brainpoolP192r1}, + {XSTR_SIZEOF("B-224"), "B-224", NID_brainpoolP224r1}, + {XSTR_SIZEOF("B-256"), "B-256", NID_brainpoolP256r1}, + {XSTR_SIZEOF("B-320"), "B-320", NID_brainpoolP320r1}, + {XSTR_SIZEOF("B-384"), "B-384", NID_brainpoolP384r1}, + {XSTR_SIZEOF("B-512"), "B-512", NID_brainpoolP512r1}, {0, NULL, 0}, }; #endif diff --git a/src/wolfio.c b/src/wolfio.c index f72ada6c3..7f0293652 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -770,7 +770,8 @@ int wolfIO_TcpConnect(SOCKET_T* sockfd, const char* ip, word16 port, int to_sec) int ret = 0; SOCKADDR_S addr; int sockaddr_len = sizeof(SOCKADDR_IN); -#ifndef WOLF_C99 + /* use gethostbyname for c99 */ +#if defined(HAVE_GETADDRINFO) && !defined(WOLF_C99) ADDRINFO hints; ADDRINFO* answer = NULL; char strPort[6]; @@ -786,7 +787,7 @@ int wolfIO_TcpConnect(SOCKET_T* sockfd, const char* ip, word16 port, int to_sec) #endif /* use gethostbyname for c99 */ -#ifndef WOLF_C99 +#if defined(HAVE_GETADDRINFO) && !defined(WOLF_C99) XMEMSET(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 4494893af..245470fc8 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -69,10 +69,6 @@ ASN Options: #include #include -#ifdef OPENSSL_EXTRA -#include -#endif - #include #include #ifdef NO_INLINE @@ -128,7 +124,6 @@ extern int wc_InitRsaHw(RsaKey* key); #define ERROR_OUT(err, eLabel) { ret = (err); goto eLabel; } -#include #if defined(HAVE_SELFTEST) || !defined(NO_SKID) #ifndef WOLFSSL_AES_KEY_SIZE_ENUM #define WOLFSSL_AES_KEY_SIZE_ENUM @@ -8787,6 +8782,18 @@ int ParseCert(DecodedCert* cert, int type, int verify, void* cm) return ret; } +/* from SSL proper, for locking can't do find here anymore */ +#ifdef __cplusplus + extern "C" { +#endif + Signer* GetCA(void* signers, byte* hash); + #ifndef NO_SKID + Signer* GetCAByName(void* signers, byte* hash); + #endif +#ifdef __cplusplus + } +#endif + #if defined(WOLFCRYPT_ONLY) || defined(NO_CERTS) /* dummy functions, not using wolfSSL so don't need actual ones */ @@ -10297,16 +10304,16 @@ int PemToDer(const unsigned char* buff, long longSz, int type, /* see if there is a -----BEGIN * PRIVATE KEY----- header */ headerEnd = XSTRNSTR((char*)buff, PRIV_KEY_SUFFIX, sz); if (headerEnd) { - beginEnd = headerEnd + STR_SIZEOF(PRIV_KEY_SUFFIX); + beginEnd = headerEnd + XSTR_SIZEOF(PRIV_KEY_SUFFIX); /* back up to BEGIN_PRIV_KEY_PREFIX */ - headerEnd -= STR_SIZEOF(BEGIN_PRIV_KEY_PREFIX); + headerEnd -= XSTR_SIZEOF(BEGIN_PRIV_KEY_PREFIX); while (headerEnd > (char*)buff && XSTRNCMP(headerEnd, BEGIN_PRIV_KEY_PREFIX, - STR_SIZEOF(BEGIN_PRIV_KEY_PREFIX)) != 0) { + XSTR_SIZEOF(BEGIN_PRIV_KEY_PREFIX)) != 0) { headerEnd--; } if (XSTRNCMP(headerEnd, BEGIN_PRIV_KEY_PREFIX, - STR_SIZEOF(BEGIN_PRIV_KEY_PREFIX)) != 0 || + XSTR_SIZEOF(BEGIN_PRIV_KEY_PREFIX)) != 0 || beginEnd - headerEnd > PEM_LINE_LEN) { WOLFSSL_MSG("Couldn't find PEM header"); return ASN_NO_PEM_HEADER; @@ -10316,16 +10323,16 @@ int PemToDer(const unsigned char* buff, long longSz, int type, beginBuf[beginEnd - headerEnd] = '\0'; /* look for matching footer */ footer = XSTRNSTR(beginEnd, - beginBuf + STR_SIZEOF(BEGIN_PRIV_KEY_PREFIX), + beginBuf + XSTR_SIZEOF(BEGIN_PRIV_KEY_PREFIX), (unsigned int)((char*)buff + sz - beginEnd)); if (!footer) { WOLFSSL_MSG("Couldn't find PEM footer"); return ASN_NO_PEM_HEADER; } - footer -= STR_SIZEOF(END_PRIV_KEY_PREFIX); + footer -= XSTR_SIZEOF(END_PRIV_KEY_PREFIX); endLen = (unsigned int)(beginEnd - headerEnd - - (STR_SIZEOF(BEGIN_PRIV_KEY_PREFIX) - - STR_SIZEOF(END_PRIV_KEY_PREFIX))); + (XSTR_SIZEOF(BEGIN_PRIV_KEY_PREFIX) - + XSTR_SIZEOF(END_PRIV_KEY_PREFIX))); XMEMCPY(endBuf, footer, endLen); endBuf[endLen] = '\0'; diff --git a/wolfssl/internal.h b/wolfssl/internal.h index cdcd2694a..17d9fc496 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -4241,8 +4241,6 @@ static const byte server[SIZEOF_SENDER] = { 0x53, 0x52, 0x56, 0x52 }; static const byte tls_client[FINISHED_LABEL_SZ + 1] = "client finished"; static const byte tls_server[FINISHED_LABEL_SZ + 1] = "server finished"; -#define STR_SIZEOF(x) (sizeof(x) - 1) /* -1 to not count the null char */ - #ifdef OPENSSL_EXTRA typedef struct { int name_len; diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index 98ab3b1cd..a248e26c1 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -248,6 +248,7 @@ #define USE_WINDOWS_API #endif + #define XSTR_SIZEOF(x) (sizeof(x) - 1) /* -1 to not count the null char */ /* idea to add global alloc override by Moises Guimaraes */ /* default to libc stuff */ diff --git a/wolfssl/wolfio.h b/wolfssl/wolfio.h index a101c31e0..7e97accce 100644 --- a/wolfssl/wolfio.h +++ b/wolfssl/wolfio.h @@ -328,7 +328,7 @@ #endif /* HAVE_SOCKADDR */ /* use gethostbyname for c99 */ - #ifndef WOLF_C99 + #if defined(HAVE_GETADDRINFO) && !defined(WOLF_C99) typedef struct addrinfo ADDRINFO; #endif #endif /* WOLFSSL_NO_SOCK */ From 9953f2d01de823546adf6f992cb6f0faef184d0c Mon Sep 17 00:00:00 2001 From: John Safranek Date: Tue, 18 Feb 2020 16:16:59 -0800 Subject: [PATCH 098/649] 1. Remove duplicate AM_CONDITIONAL statments from configure.ac. 2. Update copyright year in configure.ac. --- configure.ac | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 7ad86ed65..7dafe8874 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ # configure.ac # -# Copyright (C) 2006-2017 wolfSSL Inc. +# Copyright (C) 2006-2020 wolfSSL Inc. # # This file is part of wolfSSL. (formerly known as CyaSSL) # @@ -1891,7 +1891,6 @@ then then ENABLED_OCSP="yes" AM_CFLAGS="$AM_CFLAGS -DHAVE_OCSP" - AM_CONDITIONAL([BUILD_OCSP], [test "x$ENABLED_OCSP" = "xyes"]) fi # Requires PSK make sure on @@ -3452,8 +3451,6 @@ else fi fi -AM_CONDITIONAL([BUILD_RC4], [test "x$ENABLED_ARC4" = "xyes"]) - # Asio Support AC_ARG_ENABLE([asio], [AS_HELP_STRING([--enable-asio],[Enable asio (default: disabled)])], From cc597add48a0baec22b9da131e61f3708e0b15c7 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 19 Feb 2020 11:17:31 +0100 Subject: [PATCH 099/649] Don't always include wolfssl/openssl/bn.h --- wolfssl/ssl.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index a83b51246..2937e5608 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -70,6 +70,7 @@ #include #include #include + #include #endif /* make sure old names are disabled */ @@ -81,6 +82,7 @@ #endif #elif (defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)) + #include #include /* We need the old SSL names */ @@ -91,8 +93,6 @@ #undef NO_OLD_WC_NAMES #endif #endif -/* Needed for WOLFSSL_RSA struct */ -#include #ifdef __cplusplus extern "C" { From baace2c0e3846d8e99cc4cc286ea923bd3d566bc Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 20 Jan 2020 21:35:32 -0800 Subject: [PATCH 100/649] Fix to enable inclusion of all .c files when using the `--enable-usersettings` option. --- configure.ac | 118 +++++++++++++++++++++++++-------------------------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/configure.ac b/configure.ac index a6268fc51..9f34a359a 100644 --- a/configure.ac +++ b/configure.ac @@ -5058,111 +5058,111 @@ esac # test scripts for make check. AM_CONDITIONAL([BUILD_DISTRO],[test "x$ENABLED_DISTRO" = "xyes"]) AM_CONDITIONAL([BUILD_ALL],[test "x$ENABLED_ALL" = "xyes"]) -AM_CONDITIONAL([BUILD_TLS13],[test "x$ENABLED_TLS13" = "xyes"]) -AM_CONDITIONAL([BUILD_RNG],[test "x$ENABLED_RNG" = "xyes"]) -AM_CONDITIONAL([BUILD_SCTP],[test "x$ENABLED_SCTP" = "xyes"]) +AM_CONDITIONAL([BUILD_TLS13],[test "x$ENABLED_TLS13" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_RNG],[test "x$ENABLED_RNG" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_SCTP],[test "x$ENABLED_SCTP" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_MCAST],[test "x$ENABLED_MCAST" = "xyes"]) AM_CONDITIONAL([BUILD_IPV6],[test "x$ENABLED_IPV6" = "xyes"]) AM_CONDITIONAL([BUILD_LEANPSK],[test "x$ENABLED_LEANPSK" = "xyes"]) AM_CONDITIONAL([BUILD_LEANTLS],[test "x$ENABLED_LEANTLS" = "xyes"]) AM_CONDITIONAL([BUILD_LOWMEM],[test "x$ENABLED_LOWRESOURCE" = "xyes"]) -AM_CONDITIONAL([BUILD_PKCALLBACKS], [ test "x$ENABLED_PKCALLBACKS" = "xyes" ]) +AM_CONDITIONAL([BUILD_PKCALLBACKS], [ test "x$ENABLED_PKCALLBACKS" = "xyes"]) AM_CONDITIONAL([BUILD_CRYPTOAUTHLIB],[test "x$ENABLED_CRYPTOAUTHLIB" = "xyes"]) -AM_CONDITIONAL([BUILD_SNIFFER], [ test "x$ENABLED_SNIFFER" = "xyes" ]) -AM_CONDITIONAL([BUILD_SNIFFTEST],[ test "x$ENABLED_SNIFFTEST" = "xyes" ]) -AM_CONDITIONAL([BUILD_AESGCM],[test "x$ENABLED_AESGCM" = "xyes"]) -AM_CONDITIONAL([BUILD_AESCCM],[test "x$ENABLED_AESCCM" = "xyes"]) +AM_CONDITIONAL([BUILD_SNIFFER], [ test "x$ENABLED_SNIFFER" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_SNIFFTEST],[ test "x$ENABLED_SNIFFTEST" = "xyes"]) +AM_CONDITIONAL([BUILD_AESGCM],[test "x$ENABLED_AESGCM" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_AESCCM],[test "x$ENABLED_AESCCM" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_ARMASM],[test "x$ENABLED_ARMASM" = "xyes"]) AM_CONDITIONAL([BUILD_XILINX],[test "x$ENABLED_XILINX" = "xyes"]) AM_CONDITIONAL([BUILD_AESNI],[test "x$ENABLED_AESNI" = "xyes"]) AM_CONDITIONAL([BUILD_INTELASM],[test "x$ENABLED_INTELASM" = "xyes"]) AM_CONDITIONAL([BUILD_AFALG],[test "x$ENABLED_AFALG" = "xyes"]) AM_CONDITIONAL([BUILD_DEVCRYPTO],[test "x$ENABLED_DEVCRYPTO" = "xyes"]) -AM_CONDITIONAL([BUILD_CAMELLIA],[test "x$ENABLED_CAMELLIA" = "xyes"]) -AM_CONDITIONAL([BUILD_MD2],[test "x$ENABLED_MD2" = "xyes"]) -AM_CONDITIONAL([BUILD_RIPEMD],[test "x$ENABLED_RIPEMD" = "xyes"]) -AM_CONDITIONAL([BUILD_BLAKE2],[test "x$ENABLED_BLAKE2" = "xyes"]) -AM_CONDITIONAL([BUILD_BLAKE2S],[test "x$ENABLED_BLAKE2S" = "xyes"]) -AM_CONDITIONAL([BUILD_SHA512],[test "x$ENABLED_SHA512" = "xyes" || test "x$ENABLED_SHA384" = "xyes"]) -AM_CONDITIONAL([BUILD_DSA],[test "x$ENABLED_DSA" = "xyes"]) -AM_CONDITIONAL([BUILD_ECC],[test "x$ENABLED_ECC" = "xyes"]) -AM_CONDITIONAL([BUILD_ED25519],[test "x$ENABLED_ED25519" = "xyes"]) +AM_CONDITIONAL([BUILD_CAMELLIA],[test "x$ENABLED_CAMELLIA" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_MD2],[test "x$ENABLED_MD2" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_RIPEMD],[test "x$ENABLED_RIPEMD" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_BLAKE2],[test "x$ENABLED_BLAKE2" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_BLAKE2S],[test "x$ENABLED_BLAKE2S" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_SHA512],[test "x$ENABLED_SHA512" = "xyes" || test "x$ENABLED_SHA384" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_DSA],[test "x$ENABLED_DSA" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_ECC],[test "x$ENABLED_ECC" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_ED25519],[test "x$ENABLED_ED25519" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_ED25519_SMALL],[test "x$ENABLED_ED25519_SMALL" = "xyes"]) -AM_CONDITIONAL([BUILD_FEMATH], [test "x$ENABLED_FEMATH" = "xyes"]) -AM_CONDITIONAL([BUILD_GEMATH], [test "x$ENABLED_GEMATH" = "xyes"]) -AM_CONDITIONAL([BUILD_CURVE25519],[test "x$ENABLED_CURVE25519" = "xyes"]) -AM_CONDITIONAL([BUILD_CURVE25519_SMALL],[test "x$ENABLED_CURVE25519_SMALL" = "xyes"]) -AM_CONDITIONAL([BUILD_MEMORY],[test "x$ENABLED_MEMORY" = "xyes"]) -AM_CONDITIONAL([BUILD_RSA],[test "x$ENABLED_RSA" = "xyes"]) -AM_CONDITIONAL([BUILD_DH],[test "x$ENABLED_DH" = "xyes"]) -AM_CONDITIONAL([BUILD_ASN],[test "x$ENABLED_ASN" != "xno"]) -AM_CONDITIONAL([BUILD_AES],[test "x$ENABLED_AES" = "xyes"]) -AM_CONDITIONAL([BUILD_CODING],[test "x$ENABLED_CODING" = "xyes"]) -AM_CONDITIONAL([BUILD_IDEA],[test "x$ENABLED_IDEA" = "xyes"]) -AM_CONDITIONAL([BUILD_RC4],[test "x$ENABLED_ARC4" = "xyes"]) -AM_CONDITIONAL([BUILD_MD5],[test "x$ENABLED_MD5" = "xyes"]) -AM_CONDITIONAL([BUILD_SHA],[test "x$ENABLED_SHA" = "xyes"]) -AM_CONDITIONAL([BUILD_HC128],[test "x$ENABLED_HC128" = "xyes"]) -AM_CONDITIONAL([BUILD_RABBIT],[test "x$ENABLED_RABBIT" = "xyes"]) +AM_CONDITIONAL([BUILD_FEMATH], [test "x$ENABLED_FEMATH" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_GEMATH], [test "x$ENABLED_GEMATH" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_CURVE25519],[test "x$ENABLED_CURVE25519" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_CURVE25519_SMALL],[test "x$ENABLED_CURVE25519_SMALL" = "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"]) +AM_CONDITIONAL([BUILD_ASN],[test "x$ENABLED_ASN" != "xno" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_AES],[test "x$ENABLED_AES" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_CODING],[test "x$ENABLED_CODING" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_IDEA],[test "x$ENABLED_IDEA" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_RC4],[test "x$ENABLED_ARC4" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_MD5],[test "x$ENABLED_MD5" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_SHA],[test "x$ENABLED_SHA" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_HC128],[test "x$ENABLED_HC128" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_RABBIT],[test "x$ENABLED_RABBIT" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_FIPS],[test "x$ENABLED_FIPS" = "xyes"]) AM_CONDITIONAL([BUILD_FIPS_V1],[test "x$FIPS_VERSION" = "xv1"]) AM_CONDITIONAL([BUILD_FIPS_V2],[test "x$FIPS_VERSION" = "xv2"]) AM_CONDITIONAL([BUILD_FIPS_RAND],[test "x$FIPS_VERSION" = "xrand"]) -AM_CONDITIONAL([BUILD_CMAC],[test "x$ENABLED_CMAC" = "xyes"]) +AM_CONDITIONAL([BUILD_CMAC],[test "x$ENABLED_CMAC" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_SELFTEST],[test "x$ENABLED_SELFTEST" = "xyes"]) -AM_CONDITIONAL([BUILD_SHA224],[test "x$ENABLED_SHA224" = "xyes"]) -AM_CONDITIONAL([BUILD_SHA3],[test "x$ENABLED_SHA3" = "xyes"]) -AM_CONDITIONAL([BUILD_POLY1305],[test "x$ENABLED_POLY1305" = "xyes"]) -AM_CONDITIONAL([BUILD_CHACHA],[test "x$ENABLED_CHACHA" = "xyes"]) +AM_CONDITIONAL([BUILD_SHA224],[test "x$ENABLED_SHA224" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_SHA3],[test "x$ENABLED_SHA3" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_POLY1305],[test "x$ENABLED_POLY1305" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_CHACHA],[test "x$ENABLED_CHACHA" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_INLINE],[test "x$ENABLED_INLINE" = "xyes"]) -AM_CONDITIONAL([BUILD_OCSP],[test "x$ENABLED_OCSP" = "xyes"]) +AM_CONDITIONAL([BUILD_OCSP],[test "x$ENABLED_OCSP" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_OCSP_STAPLING],[test "x$ENABLED_CERTIFICATE_STATUS_REQUEST" = "xyes"]) AM_CONDITIONAL([BUILD_OCSP_STAPLING_V2],[test "x$ENABLED_CERTIFICATE_STATUS_REQUEST_V2" = "xyes"]) -AM_CONDITIONAL([BUILD_CRL],[test "x$ENABLED_CRL" = "xyes"]) +AM_CONDITIONAL([BUILD_CRL],[test "x$ENABLED_CRL" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_CRL_MONITOR],[test "x$ENABLED_CRL_MONITOR" = "xyes"]) AM_CONDITIONAL([BUILD_USER_RSA],[test "x$ENABLED_USER_RSA" = "xyes"] ) AM_CONDITIONAL([BUILD_USER_CRYPTO],[test "x$ENABLED_USER_CRYPTO" = "xyes"]) AM_CONDITIONAL([BUILD_NTRU],[test "x$ENABLED_NTRU" = "xyes"]) AM_CONDITIONAL([BUILD_WNR],[test "x$ENABLED_WNR" = "xyes"]) -AM_CONDITIONAL([BUILD_SRP],[test "x$ENABLED_SRP" = "xyes"]) +AM_CONDITIONAL([BUILD_SRP],[test "x$ENABLED_SRP" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([USE_VALGRIND],[test "x$ENABLED_VALGRIND" = "xyes"]) -AM_CONDITIONAL([BUILD_MD4],[test "x$ENABLED_MD4" = "xyes"]) -AM_CONDITIONAL([BUILD_PWDBASED],[test "x$ENABLED_PWDBASED" = "xyes"]) -AM_CONDITIONAL([BUILD_SCRYPT],[test "x$ENABLED_SCRYPT" = "xyes"]) +AM_CONDITIONAL([BUILD_MD4],[test "x$ENABLED_MD4" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_PWDBASED],[test "x$ENABLED_PWDBASED" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_SCRYPT],[test "x$ENABLED_SCRYPT" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_CRYPTONLY],[test "x$ENABLED_CRYPTONLY" = "xyes" && test "x$ENABLED_OPENSSLEXTRA" = "xno"]) -AM_CONDITIONAL([BUILD_FASTMATH],[test "x$ENABLED_FASTMATH" = "xyes"]) -AM_CONDITIONAL([BUILD_SLOWMATH],[test "x$ENABLED_SLOWMATH" = "xyes"]) +AM_CONDITIONAL([BUILD_FASTMATH],[test "x$ENABLED_FASTMATH" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_SLOWMATH],[test "x$ENABLED_SLOWMATH" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_EXAMPLE_SERVERS],[test "x$ENABLED_EXAMPLES" = "xyes" && test "x$ENABLED_LEANTLS" = "xno"]) AM_CONDITIONAL([BUILD_EXAMPLE_CLIENTS],[test "x$ENABLED_EXAMPLES" = "xyes"]) AM_CONDITIONAL([BUILD_TESTS],[test "x$ENABLED_EXAMPLES" = "xyes" && test "x$ENABLED_LEANTLS" = "xno"]) AM_CONDITIONAL([BUILD_THREADED_EXAMPLES],[test "x$ENABLED_SINGLETHREADED" = "xno" && test "x$ENABLED_EXAMPLES" = "xyes" && test "x$ENABLED_LEANTLS" = "xno"]) AM_CONDITIONAL([BUILD_WOLFCRYPT_TESTS],[test "x$ENABLED_CRYPT_TESTS" = "xyes"]) AM_CONDITIONAL([BUILD_LIBZ],[test "x$ENABLED_LIBZ" = "xyes"]) -AM_CONDITIONAL([BUILD_PKCS11],[test "x$ENABLED_PKCS11" = "xyes"]) -AM_CONDITIONAL([BUILD_PKCS12],[test "x$ENABLED_PKCS12" = "xyes"]) +AM_CONDITIONAL([BUILD_PKCS11],[test "x$ENABLED_PKCS11" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_PKCS12],[test "x$ENABLED_PKCS12" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_CAVIUM],[test "x$ENABLED_CAVIUM" = "xyes"]) AM_CONDITIONAL([BUILD_CAVIUM_V],[test "x$ENABLED_CAVIUM_V" = "xyes"]) AM_CONDITIONAL([BUILD_OCTEON_SYNC],[test "x$ENABLED_OCTEON_SYNC" = "xyes"]) AM_CONDITIONAL([BUILD_INTEL_QA],[test "x$ENABLED_INTEL_QA" = "xyes"]) AM_CONDITIONAL([BUILD_INTEL_QA_SYNC],[test "x$ENABLED_INTEL_QA_SYNC" = "xyes"]) -AM_CONDITIONAL([BUILD_SP],[test "x$ENABLED_SP" = "xyes"]) -AM_CONDITIONAL([BUILD_SP_C],[test "x$ENABLED_SP" = "xyes" && test "x$ENABLED_SP_ASM" = "xno" ]) -AM_CONDITIONAL([BUILD_SP_ARM64],[test "x$ENABLED_SP_ARM64_ASM" = "xyes" ]) -AM_CONDITIONAL([BUILD_SP_ARM32],[test "x$ENABLED_SP_ARM32_ASM" = "xyes" ]) -AM_CONDITIONAL([BUILD_SP_ARM_THUMB],[test "x$ENABLED_SP_ARM_THUMB_ASM" = "xyes" ]) -AM_CONDITIONAL([BUILD_SP_ARM_CORTEX],[test "x$ENABLED_SP_ARM_CORTEX_ASM" = "xyes" ]) -AM_CONDITIONAL([BUILD_SP_X86_64],[test "x$ENABLED_SP_X86_64_ASM" = "xyes" ]) -AM_CONDITIONAL([BUILD_SP_INT],[test "x$ENABLED_SP_MATH" = "xyes" ]) +AM_CONDITIONAL([BUILD_SP],[test "x$ENABLED_SP" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_SP_C],[(test "x$ENABLED_SP" = "xyes" && test "x$ENABLED_SP_ASM" = "xno") || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_SP_ARM64],[test "x$ENABLED_SP_ARM64_ASM" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_SP_ARM32],[test "x$ENABLED_SP_ARM32_ASM" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_SP_ARM_THUMB],[test "x$ENABLED_SP_ARM_THUMB_ASM" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_SP_ARM_CORTEX],[test "x$ENABLED_SP_ARM_CORTEX_ASM" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_SP_X86_64],[test "x$ENABLED_SP_X86_64_ASM" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_SP_INT],[test "x$ENABLED_SP_MATH" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_FAST_RSA],[test "x$ENABLED_FAST_RSA" = "xyes"]) AM_CONDITIONAL([BUILD_MCAPI],[test "x$ENABLED_MCAPI" = "xyes"]) AM_CONDITIONAL([BUILD_ASYNCCRYPT],[test "x$ENABLED_ASYNCCRYPT" = "xyes"]) AM_CONDITIONAL([BUILD_WOLFEVENT],[test "x$ENABLED_ASYNCCRYPT" = "xyes"]) -AM_CONDITIONAL([BUILD_CRYPTOCB],[test "x$ENABLED_CRYPTOCB" = "xyes"]) +AM_CONDITIONAL([BUILD_CRYPTOCB],[test "x$ENABLED_CRYPTOCB" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_PSK],[test "x$ENABLED_PSK" = "xyes"]) AM_CONDITIONAL([BUILD_TRUST_PEER_CERT],[test "x$ENABLED_TRUSTED_PEER_CERT" = "xyes"]) AM_CONDITIONAL([BUILD_PKI],[test "x$ENABLED_PKI" = "xyes"]) -AM_CONDITIONAL([BUILD_DES3],[test "x$ENABLED_DES3" = "xyes"]) -AM_CONDITIONAL([BUILD_PKCS7],[test "x$ENABLED_PKCS7" = "xyes"]) +AM_CONDITIONAL([BUILD_DES3],[test "x$ENABLED_DES3" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) +AM_CONDITIONAL([BUILD_PKCS7],[test "x$ENABLED_PKCS7" = "xyes" || test "x$ENABLED_USERSETTINGS" = "xyes"]) AM_CONDITIONAL([BUILD_HASHFLAGS],[test "x$ENABLED_HASHFLAGS" = "xyes"]) From 75183262adf8ccb3d01f947b1a7b775518b05a26 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 22 Jan 2020 23:00:48 -0800 Subject: [PATCH 101/649] Minor typos and fixes to the MDK5 examples. --- IDE/MDK5-ARM/Conf/user_settings.h | 13 ++++++------- .../CryptBenchmark/RTE/wolfSSL/user_settings.h | 11 +++++------ .../Projects/CryptTest/RTE/wolfSSL/user_settings.h | 13 ++++++------- .../Projects/EchoClient/RTE/wolfSSL/user_settings.h | 13 ++++++------- .../Projects/EchoServer/RTE/wolfSSL/user_settings.h | 13 ++++++------- .../SimpleClient/RTE/wolfSSL/user_settings.h | 13 ++++++------- .../SimpleServer/RTE/wolfSSL/user_settings.h | 13 ++++++------- .../wolfSSL-Lib/RTE/wolfSSL/user_settings.h | 13 ++++++------- wolfcrypt/src/integer.c | 6 ------ wolfssl/wolfcrypt/settings.h | 4 ++++ 10 files changed, 51 insertions(+), 61 deletions(-) diff --git a/IDE/MDK5-ARM/Conf/user_settings.h b/IDE/MDK5-ARM/Conf/user_settings.h index b65ee7bf7..5251f1470 100644 --- a/IDE/MDK5-ARM/Conf/user_settings.h +++ b/IDE/MDK5-ARM/Conf/user_settings.h @@ -55,11 +55,11 @@ #define STM32F7xx #endif -// Thread/RTOS<0=>Single Threaded <1=>FreeRTOS <2=>SafeRTOS<3=>Windows -// <4=>PThread <5=>ThreadX<6=> ThreadX/NetX -// <7=>Micrium <8=>EBSnet<9=>MQX -// <10=>T-RTOS <11=>uITRON4<12=>uTKERNEL2 -// <13=>Frosted <14=>CMSIS RTOS<15=>CMSIS RTOSv2<16=>Others +// Thread/RTOS<0=>Single Threaded <1=>FreeRTOS <3=>SafeRTOS <4=>Windows +// <5=>PThread <6=>ThreadX +// <7=>Micrium <8=>EBSnet <9=>MQX +// <10=>T-RTOS <11=>uITRON4 <12=>uTKERNEL2 +// <13=>Frosted <14=>CMSIS RTOS <15=>CMSIS RTOSv2 <16=>Others #define MDK_CONF_THREAD 15 #if MDK_CONF_THREAD== 0 #define SINGLE_THREADED @@ -247,7 +247,7 @@ // HC128 #define MDK_CONF_HC128 1 -#if MDK_CONF_AESGCM == 0 +#if MDK_CONF_HC128 == 0 #define NO_HC128 #endif // @@ -516,4 +516,3 @@ // // - 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 5a09b717c..9ce8e4d0b 100644 --- a/IDE/MDK5-ARM/Projects/CryptBenchmark/RTE/wolfSSL/user_settings.h +++ b/IDE/MDK5-ARM/Projects/CryptBenchmark/RTE/wolfSSL/user_settings.h @@ -55,10 +55,10 @@ #define STM32F7xx #endif -// Thread/RTOS<0=>Single Threaded <1=>FreeRTOS <2=>SafeRTOS<3=>Windows -// <4=>PThread <5=>ThreadX<6=> ThreadX/NetX -// <7=>Micrium <8=>EBSnet<9=>MQX -// <10=>T-RTOS <11=>uITRON4<12=>uTKERNEL2 +// Thread/RTOS<0=>Single Threaded <1=>FreeRTOS <3=>SafeRTOS<4=>Windows +// <5=>PThread <6=>ThreadX +// <7=>Micrium <8=>EBSnet<9=>MQX +// <10=>T-RTOS <11=>uITRON4<12=>uTKERNEL2 // <13=>Frosted <14=>CMSIS RTOS<15=>CMSIS RTOSv2<16=>Others #define MDK_CONF_THREAD 15 #if MDK_CONF_THREAD== 0 @@ -247,7 +247,7 @@ // HC128 #define MDK_CONF_HC128 1 -#if MDK_CONF_AESGCM == 0 +#if MDK_CONF_HC128 == 0 #define NO_HC128 #endif // @@ -516,4 +516,3 @@ // // - 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 a7cc2f761..1645d956c 100644 --- a/IDE/MDK5-ARM/Projects/CryptTest/RTE/wolfSSL/user_settings.h +++ b/IDE/MDK5-ARM/Projects/CryptTest/RTE/wolfSSL/user_settings.h @@ -55,11 +55,11 @@ #define STM32F7xx #endif -// Thread/RTOS<0=>Single Threaded <1=>FreeRTOS <2=>SafeRTOS<3=>Windows -// <4=>PThread <5=>ThreadX<6=> ThreadX/NetX -// <7=>Micrium <8=>EBSnet<9=>MQX -// <10=>T-RTOS <11=>uITRON4<12=>uTKERNEL2 -// <13=>Frosted <14=>CMSIS RTOS<15=>CMSIS RTOSv2<16=>Others +// Thread/RTOS<0=>Single Threaded <1=>FreeRTOS <3=>SafeRTOS <4=>Windows +// <5=>PThread <6=>ThreadX +// <7=>Micrium <8=>EBSnet <9=>MQX +// <10=>T-RTOS <11=>uITRON4 <12=>uTKERNEL2 +// <13=>Frosted <14=>CMSIS RTOS <15=>CMSIS RTOSv2 <16=>Others #define MDK_CONF_THREAD 15 #if MDK_CONF_THREAD== 0 #define SINGLE_THREADED @@ -247,7 +247,7 @@ // HC128 #define MDK_CONF_HC128 1 -#if MDK_CONF_AESGCM == 0 +#if MDK_CONF_HC128 == 0 #define NO_HC128 #endif // @@ -516,4 +516,3 @@ // // - 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 251693a0d..a62071372 100644 --- a/IDE/MDK5-ARM/Projects/EchoClient/RTE/wolfSSL/user_settings.h +++ b/IDE/MDK5-ARM/Projects/EchoClient/RTE/wolfSSL/user_settings.h @@ -55,11 +55,11 @@ #define STM32F7xx #endif -// Thread/RTOS<0=>Single Threaded <1=>FreeRTOS <2=>SafeRTOS<3=>Windows -// <4=>PThread <5=>ThreadX<6=> ThreadX/NetX -// <7=>Micrium <8=>EBSnet<9=>MQX -// <10=>T-RTOS <11=>uITRON4<12=>uTKERNEL2 -// <13=>Frosted <14=>CMSIS RTOS<15=>Others +// Thread/RTOS<0=>Single Threaded <1=>FreeRTOS <3=>SafeRTOS <4=>Windows +// <5=>PThread <6=>ThreadX +// <7=>Micrium <8=>EBSnet <9=>MQX +// <10=>T-RTOS <11=>uITRON4 <12=>uTKERNEL2 +// <13=>Frosted <14=>CMSIS RTOS <15=>CMSIS RTOSv2 <16=>Others #define MDK_CONF_THREAD 14 #if MDK_CONF_THREAD== 0 #define SINGLE_THREADED @@ -245,7 +245,7 @@ // HC128 #define MDK_CONF_HC128 1 -#if MDK_CONF_AESGCM == 0 +#if MDK_CONF_HC128 == 0 #define NO_HC128 #endif // @@ -514,4 +514,3 @@ // // - 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 d0c28a96c..4caaed5d0 100644 --- a/IDE/MDK5-ARM/Projects/EchoServer/RTE/wolfSSL/user_settings.h +++ b/IDE/MDK5-ARM/Projects/EchoServer/RTE/wolfSSL/user_settings.h @@ -55,11 +55,11 @@ #define STM32F7xx #endif -// Thread/RTOS<0=>Single Threaded <1=>FreeRTOS <2=>SafeRTOS<3=>Windows -// <4=>PThread <5=>ThreadX<6=> ThreadX/NetX -// <7=>Micrium <8=>EBSnet<9=>MQX -// <10=>T-RTOS <11=>uITRON4<12=>uTKERNEL2 -// <13=>Frosted <14=>CMSIS RTOS<15=>CMSIS RTOSv2<16=>Others +// Thread/RTOS<0=>Single Threaded <1=>FreeRTOS <3=>SafeRTOS <4=>Windows +// <5=>PThread <6=>ThreadX +// <7=>Micrium <8=>EBSnet <9=>MQX +// <10=>T-RTOS <11=>uITRON4 <12=>uTKERNEL2 +// <13=>Frosted <14=>CMSIS RTOS <15=>CMSIS RTOSv2 <16=>Others #define MDK_CONF_THREAD 14 #if MDK_CONF_THREAD== 0 #define SINGLE_THREADED @@ -247,7 +247,7 @@ // HC128 #define MDK_CONF_HC128 1 -#if MDK_CONF_AESGCM == 0 +#if MDK_CONF_HC128 == 0 #define NO_HC128 #endif // @@ -516,4 +516,3 @@ // // - 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 045f9d03e..74630fa88 100644 --- a/IDE/MDK5-ARM/Projects/SimpleClient/RTE/wolfSSL/user_settings.h +++ b/IDE/MDK5-ARM/Projects/SimpleClient/RTE/wolfSSL/user_settings.h @@ -55,11 +55,11 @@ #define STM32F7xx #endif -// Thread/RTOS<0=>Single Threaded <1=>FreeRTOS <2=>SafeRTOS<3=>Windows -// <4=>PThread <5=>ThreadX<6=> ThreadX/NetX -// <7=>Micrium <8=>EBSnet<9=>MQX -// <10=>T-RTOS <11=>uITRON4<12=>uTKERNEL2 -// <13=>Frosted <14=>CMSIS RTOS<15=>CMSIS RTOSv2<16=>Others +// Thread/RTOS<0=>Single Threaded <1=>FreeRTOS <3=>SafeRTOS <4=>Windows +// <5=>PThread <6=>ThreadX +// <7=>Micrium <8=>EBSnet <9=>MQX +// <10=>T-RTOS <11=>uITRON4 <12=>uTKERNEL2 +// <13=>Frosted <14=>CMSIS RTOS <15=>CMSIS RTOSv2 <16=>Others #define MDK_CONF_THREAD 15 #if MDK_CONF_THREAD== 0 #define SINGLE_THREADED @@ -247,7 +247,7 @@ // HC128 #define MDK_CONF_HC128 1 -#if MDK_CONF_AESGCM == 0 +#if MDK_CONF_HC128 == 0 #define NO_HC128 #endif // @@ -516,4 +516,3 @@ // // - 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 045f9d03e..74630fa88 100644 --- a/IDE/MDK5-ARM/Projects/SimpleServer/RTE/wolfSSL/user_settings.h +++ b/IDE/MDK5-ARM/Projects/SimpleServer/RTE/wolfSSL/user_settings.h @@ -55,11 +55,11 @@ #define STM32F7xx #endif -// Thread/RTOS<0=>Single Threaded <1=>FreeRTOS <2=>SafeRTOS<3=>Windows -// <4=>PThread <5=>ThreadX<6=> ThreadX/NetX -// <7=>Micrium <8=>EBSnet<9=>MQX -// <10=>T-RTOS <11=>uITRON4<12=>uTKERNEL2 -// <13=>Frosted <14=>CMSIS RTOS<15=>CMSIS RTOSv2<16=>Others +// Thread/RTOS<0=>Single Threaded <1=>FreeRTOS <3=>SafeRTOS <4=>Windows +// <5=>PThread <6=>ThreadX +// <7=>Micrium <8=>EBSnet <9=>MQX +// <10=>T-RTOS <11=>uITRON4 <12=>uTKERNEL2 +// <13=>Frosted <14=>CMSIS RTOS <15=>CMSIS RTOSv2 <16=>Others #define MDK_CONF_THREAD 15 #if MDK_CONF_THREAD== 0 #define SINGLE_THREADED @@ -247,7 +247,7 @@ // HC128 #define MDK_CONF_HC128 1 -#if MDK_CONF_AESGCM == 0 +#if MDK_CONF_HC128 == 0 #define NO_HC128 #endif // @@ -516,4 +516,3 @@ // // - 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 045f9d03e..74630fa88 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 @@ -55,11 +55,11 @@ #define STM32F7xx #endif -// Thread/RTOS<0=>Single Threaded <1=>FreeRTOS <2=>SafeRTOS<3=>Windows -// <4=>PThread <5=>ThreadX<6=> ThreadX/NetX -// <7=>Micrium <8=>EBSnet<9=>MQX -// <10=>T-RTOS <11=>uITRON4<12=>uTKERNEL2 -// <13=>Frosted <14=>CMSIS RTOS<15=>CMSIS RTOSv2<16=>Others +// Thread/RTOS<0=>Single Threaded <1=>FreeRTOS <3=>SafeRTOS <4=>Windows +// <5=>PThread <6=>ThreadX +// <7=>Micrium <8=>EBSnet <9=>MQX +// <10=>T-RTOS <11=>uITRON4 <12=>uTKERNEL2 +// <13=>Frosted <14=>CMSIS RTOS <15=>CMSIS RTOSv2 <16=>Others #define MDK_CONF_THREAD 15 #if MDK_CONF_THREAD== 0 #define SINGLE_THREADED @@ -247,7 +247,7 @@ // HC128 #define MDK_CONF_HC128 1 -#if MDK_CONF_AESGCM == 0 +#if MDK_CONF_HC128 == 0 #define NO_HC128 #endif // @@ -516,4 +516,3 @@ // // - diff --git a/wolfcrypt/src/integer.c b/wolfcrypt/src/integer.c index 21a87c3aa..6827e2030 100644 --- a/wolfcrypt/src/integer.c +++ b/wolfcrypt/src/integer.c @@ -56,12 +56,6 @@ #include #endif -#ifndef NO_WOLFSSL_SMALL_STACK - #ifndef WOLFSSL_SMALL_STACK - #define WOLFSSL_SMALL_STACK - #endif -#endif - #ifdef SHOW_GEN #ifndef NO_STDIO_FILESYSTEM #include diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 3c80ead26..c5cd45d58 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -2114,6 +2114,10 @@ extern void uITRON4_free(void *p) ; #define MAX_EX_DATA 5 /* allow for five items of ex_data */ #endif +#ifdef NO_WOLFSSL_SMALL_STACK + #undef WOLFSSL_SMALL_STACK +#endif + #ifdef __cplusplus } /* extern "C" */ #endif From 6036f604a691edb9eab81ad3aa5a44ecae8249e2 Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 17 Jan 2020 05:30:14 -0800 Subject: [PATCH 102/649] Added missing argument checks for public API's in wolfio.c. --- src/wolfio.c | 78 +++++++++++++++++++++++++++++----------------------- 1 file changed, 43 insertions(+), 35 deletions(-) diff --git a/src/wolfio.c b/src/wolfio.c index 7f0293652..6040f9f61 100644 --- a/src/wolfio.c +++ b/src/wolfio.c @@ -1521,65 +1521,67 @@ int EmbedCrlLookup(WOLFSSL_CRL* crl, const char* url, int urlSz) -WOLFSSL_API void wolfSSL_CTX_SetIORecv(WOLFSSL_CTX *ctx, CallbackIORecv CBIORecv) +void wolfSSL_CTX_SetIORecv(WOLFSSL_CTX *ctx, CallbackIORecv CBIORecv) { - if (ctx != NULL) { + if (ctx) { ctx->CBIORecv = CBIORecv; - #ifdef OPENSSL_EXTRA + #ifdef OPENSSL_EXTRA ctx->cbioFlag |= WOLFSSL_CBIO_RECV; - #endif + #endif } } -WOLFSSL_API void wolfSSL_CTX_SetIOSend(WOLFSSL_CTX *ctx, CallbackIOSend CBIOSend) +void wolfSSL_CTX_SetIOSend(WOLFSSL_CTX *ctx, CallbackIOSend CBIOSend) { - if (ctx != NULL) { + if (ctx) { ctx->CBIOSend = CBIOSend; - #ifdef OPENSSL_EXTRA + #ifdef OPENSSL_EXTRA ctx->cbioFlag |= WOLFSSL_CBIO_SEND; - #endif + #endif } } /* sets the IO callback to use for receives at WOLFSSL level */ -WOLFSSL_API void wolfSSL_SSLSetIORecv(WOLFSSL *ssl, CallbackIORecv CBIORecv) +void wolfSSL_SSLSetIORecv(WOLFSSL *ssl, CallbackIORecv CBIORecv) { - if (ssl != NULL) { + if (ssl) { ssl->CBIORecv = CBIORecv; - #ifdef OPENSSL_EXTRA + #ifdef OPENSSL_EXTRA ssl->cbioFlag |= WOLFSSL_CBIO_RECV; - #endif + #endif } } /* sets the IO callback to use for sends at WOLFSSL level */ -WOLFSSL_API void wolfSSL_SSLSetIOSend(WOLFSSL *ssl, CallbackIOSend CBIOSend) +void wolfSSL_SSLSetIOSend(WOLFSSL *ssl, CallbackIOSend CBIOSend) { - if (ssl != NULL) { + if (ssl) { ssl->CBIOSend = CBIOSend; - #ifdef OPENSSL_EXTRA + #ifdef OPENSSL_EXTRA ssl->cbioFlag |= WOLFSSL_CBIO_SEND; - #endif + #endif } } -WOLFSSL_API void wolfSSL_SetIOReadCtx(WOLFSSL* ssl, void *rctx) +void wolfSSL_SetIOReadCtx(WOLFSSL* ssl, void *rctx) { - ssl->IOCB_ReadCtx = rctx; + if (ssl) + ssl->IOCB_ReadCtx = rctx; } -WOLFSSL_API void wolfSSL_SetIOWriteCtx(WOLFSSL* ssl, void *wctx) +void wolfSSL_SetIOWriteCtx(WOLFSSL* ssl, void *wctx) { - ssl->IOCB_WriteCtx = wctx; + if (ssl) + ssl->IOCB_WriteCtx = wctx; } -WOLFSSL_API void* wolfSSL_GetIOReadCtx(WOLFSSL* ssl) +void* wolfSSL_GetIOReadCtx(WOLFSSL* ssl) { if (ssl) return ssl->IOCB_ReadCtx; @@ -1588,7 +1590,7 @@ WOLFSSL_API void* wolfSSL_GetIOReadCtx(WOLFSSL* ssl) } -WOLFSSL_API void* wolfSSL_GetIOWriteCtx(WOLFSSL* ssl) +void* wolfSSL_GetIOWriteCtx(WOLFSSL* ssl) { if (ssl) return ssl->IOCB_WriteCtx; @@ -1597,33 +1599,37 @@ WOLFSSL_API void* wolfSSL_GetIOWriteCtx(WOLFSSL* ssl) } -WOLFSSL_API void wolfSSL_SetIOReadFlags(WOLFSSL* ssl, int flags) +void wolfSSL_SetIOReadFlags(WOLFSSL* ssl, int flags) { - ssl->rflags = flags; + if (ssl) + ssl->rflags = flags; } -WOLFSSL_API void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags) +void wolfSSL_SetIOWriteFlags(WOLFSSL* ssl, int flags) { - ssl->wflags = flags; + if (ssl) + ssl->wflags = flags; } #ifdef WOLFSSL_DTLS -WOLFSSL_API void wolfSSL_CTX_SetGenCookie(WOLFSSL_CTX* ctx, CallbackGenCookie cb) +void wolfSSL_CTX_SetGenCookie(WOLFSSL_CTX* ctx, CallbackGenCookie cb) { - ctx->CBIOCookie = cb; + if (ctx) + ctx->CBIOCookie = cb; } -WOLFSSL_API void wolfSSL_SetCookieCtx(WOLFSSL* ssl, void *ctx) +void wolfSSL_SetCookieCtx(WOLFSSL* ssl, void *ctx) { - ssl->IOCB_CookieCtx = ctx; + if (ssl) + ssl->IOCB_CookieCtx = ctx; } -WOLFSSL_API void* wolfSSL_GetCookieCtx(WOLFSSL* ssl) +void* wolfSSL_GetCookieCtx(WOLFSSL* ssl) { if (ssl) return ssl->IOCB_CookieCtx; @@ -1633,15 +1639,17 @@ WOLFSSL_API void* wolfSSL_GetCookieCtx(WOLFSSL* ssl) #ifdef WOLFSSL_SESSION_EXPORT -WOLFSSL_API void wolfSSL_CTX_SetIOGetPeer(WOLFSSL_CTX* ctx, CallbackGetPeer cb) +void wolfSSL_CTX_SetIOGetPeer(WOLFSSL_CTX* ctx, CallbackGetPeer cb) { - ctx->CBGetPeer = cb; + if (ctx) + ctx->CBGetPeer = cb; } -WOLFSSL_API void wolfSSL_CTX_SetIOSetPeer(WOLFSSL_CTX* ctx, CallbackSetPeer cb) +void wolfSSL_CTX_SetIOSetPeer(WOLFSSL_CTX* ctx, CallbackSetPeer cb) { - ctx->CBSetPeer = cb; + if (ctx) + ctx->CBSetPeer = cb; } #endif /* WOLFSSL_SESSION_EXPORT */ From 418c508eba59de0adf55943b1b3d8f7152fcafbd Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 19 Feb 2020 12:28:49 -0800 Subject: [PATCH 103/649] Fixes for SCTP example to check build options. --- examples/sctp/sctp-client-dtls.c | 17 +++++++++++------ examples/sctp/sctp-client.c | 10 +++++++++- examples/sctp/sctp-server-dtls.c | 16 ++++++++++------ examples/sctp/sctp-server.c | 9 ++++++++- 4 files changed, 38 insertions(+), 14 deletions(-) diff --git a/examples/sctp/sctp-client-dtls.c b/examples/sctp/sctp-client-dtls.c index 11e7ee841..c0a222463 100644 --- a/examples/sctp/sctp-client-dtls.c +++ b/examples/sctp/sctp-client-dtls.c @@ -20,6 +20,14 @@ */ +/* wolfssl */ +#ifndef WOLFSSL_USER_SETTINGS + #include +#endif +#include +#include + +#if defined(WOLFSSL_SCTP) && defined(WOLFSSL_DTLS) /* sctp */ #include #include @@ -32,12 +40,6 @@ #include #include -/* wolfssl */ -#include -#include - - - #define cacert "./certs/ca-cert.pem" static int err_sys(const char* msg) @@ -45,9 +47,11 @@ static int err_sys(const char* msg) perror(msg); exit(EXIT_FAILURE); } +#endif /* WOLFSSL_SCTP && WOLFSSL_DTLS */ int main() { +#if defined(WOLFSSL_SCTP) && defined(WOLFSSL_DTLS) int sd = socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP); if (sd < 0) @@ -120,6 +124,7 @@ int main() wolfSSL_CTX_free(ctx); close(sd); +#endif /* WOLFSSL_SCTP && WOLFSSL_DTLS */ return 0; } diff --git a/examples/sctp/sctp-client.c b/examples/sctp/sctp-client.c index 21d12714b..cb01354d8 100644 --- a/examples/sctp/sctp-client.c +++ b/examples/sctp/sctp-client.c @@ -19,6 +19,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ +#ifndef WOLFSSL_USER_SETTINGS + #include +#endif +#include + +#ifdef WOLFSSL_SCTP /* sctp */ #include @@ -30,9 +36,11 @@ #include #include #include +#endif /* WOLFSSL_SCTP */ int main() { +#ifdef WOLFSSL_SCTP int sd = socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP); if (sd < 0) @@ -59,6 +67,6 @@ int main() } close(sd); - +#endif /* WOLFSSL_SCTP */ return 0; } diff --git a/examples/sctp/sctp-server-dtls.c b/examples/sctp/sctp-server-dtls.c index 1a486a9a3..50a20f241 100644 --- a/examples/sctp/sctp-server-dtls.c +++ b/examples/sctp/sctp-server-dtls.c @@ -19,7 +19,14 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ +/* wolfssl */ +#ifndef WOLFSSL_USER_SETTINGS + #include +#endif +#include +#include +#if defined(WOLFSSL_SCTP) && defined(WOLFSSL_DTLS) /* sctp */ #include #include @@ -31,11 +38,6 @@ #include #include -/* wolfssl */ -#include -#include - - #define key "./certs/server-key.pem" #define cert "./certs/server-cert.pem" @@ -45,9 +47,11 @@ static int err_sys(const char* msg) perror(msg); exit(EXIT_FAILURE); } +#endif /* WOLFSSL_SCTP && WOLFSSL_DTLS */ int main() { +#if defined(WOLFSSL_SCTP) && defined(WOLFSSL_DTLS) int sd = socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP); if (sd < 0) @@ -119,6 +123,6 @@ int main() wolfSSL_CTX_free(ctx); close(sd); - +#endif /* WOLFSSL_SCTP && WOLFSSL_DTLS */ return 0; } diff --git a/examples/sctp/sctp-server.c b/examples/sctp/sctp-server.c index ac372f1d7..34b02c9ce 100644 --- a/examples/sctp/sctp-server.c +++ b/examples/sctp/sctp-server.c @@ -19,7 +19,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA */ +#ifndef WOLFSSL_USER_SETTINGS + #include +#endif +#include +#ifdef WOLFSSL_SCTP /* sctp */ #include #include @@ -29,9 +34,11 @@ #include #include #include +#endif /* WOLFSSL_SCTP */ int main() { +#ifdef WOLFSSL_SCTP int sd = socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP); if (sd < 0) @@ -65,6 +72,6 @@ int main() close(sd); - +#endif /* WOLFSSL_SCTP */ return 0; } From c62f31cd271797bdebc9e86ca5230c8591438c6f Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Wed, 19 Feb 2020 09:33:17 +1000 Subject: [PATCH 104/649] Fix cache resist compile to work with SP C code --- wolfcrypt/src/sp_arm32.c | 30 ++++++---- wolfcrypt/src/sp_arm64.c | 30 ++++++---- wolfcrypt/src/sp_armthumb.c | 30 ++++++---- wolfcrypt/src/sp_c32.c | 116 +++++++++++++++++++++++------------- wolfcrypt/src/sp_c64.c | 116 +++++++++++++++++++++++------------- wolfcrypt/src/sp_cortexm.c | 30 ++++++---- 6 files changed, 228 insertions(+), 124 deletions(-) diff --git a/wolfcrypt/src/sp_arm32.c b/wolfcrypt/src/sp_arm32.c index 8fd412d3b..ef47c8f7b 100644 --- a/wolfcrypt/src/sp_arm32.c +++ b/wolfcrypt/src/sp_arm32.c @@ -180,12 +180,14 @@ static void sp_2048_to_bin(sp_digit* r, byte* a) for (i=0; i<64 && j>=0; i++) { b = 0; /* lint allow cast of mismatch sp_digit and int */ - a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ + a[j--] |= (byte)(r[i] << s); /*lint !e9033*/ + b += 8 - s; if (j < 0) { break; } while (b < 32) { - a[j--] = r[i] >> b; b += 8; + a[j--] = (byte)(r[i] >> b); + b += 8; if (j < 0) { break; } @@ -8487,12 +8489,14 @@ static void sp_3072_to_bin(sp_digit* r, byte* a) for (i=0; i<96 && j>=0; i++) { b = 0; /* lint allow cast of mismatch sp_digit and int */ - a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ + a[j--] |= (byte)(r[i] << s); /*lint !e9033*/ + b += 8 - s; if (j < 0) { break; } while (b < 32) { - a[j--] = r[i] >> b; b += 8; + a[j--] = (byte)(r[i] >> b); + b += 8; if (j < 0) { break; } @@ -19960,12 +19964,14 @@ static void sp_4096_to_bin(sp_digit* r, byte* a) for (i=0; i<128 && j>=0; i++) { b = 0; /* lint allow cast of mismatch sp_digit and int */ - a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ + a[j--] |= (byte)(r[i] << s); /*lint !e9033*/ + b += 8 - s; if (j < 0) { break; } while (b < 32) { - a[j--] = r[i] >> b; b += 8; + a[j--] = (byte)(r[i] >> b); + b += 8; if (j < 0) { break; } @@ -77807,12 +77813,14 @@ static void sp_256_to_bin(sp_digit* r, byte* a) for (i=0; i<8 && j>=0; i++) { b = 0; /* lint allow cast of mismatch sp_digit and int */ - a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ + a[j--] |= (byte)(r[i] << s); /*lint !e9033*/ + b += 8 - s; if (j < 0) { break; } while (b < 32) { - a[j--] = r[i] >> b; b += 8; + a[j--] = (byte)(r[i] >> b); + b += 8; if (j < 0) { break; } @@ -86472,12 +86480,14 @@ static void sp_384_to_bin(sp_digit* r, byte* a) for (i=0; i<12 && j>=0; i++) { b = 0; /* lint allow cast of mismatch sp_digit and int */ - a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ + a[j--] |= (byte)(r[i] << s); /*lint !e9033*/ + b += 8 - s; if (j < 0) { break; } while (b < 32) { - a[j--] = r[i] >> b; b += 8; + a[j--] = (byte)(r[i] >> b); + b += 8; if (j < 0) { break; } diff --git a/wolfcrypt/src/sp_arm64.c b/wolfcrypt/src/sp_arm64.c index 5f9704332..30e7d0ff5 100644 --- a/wolfcrypt/src/sp_arm64.c +++ b/wolfcrypt/src/sp_arm64.c @@ -180,12 +180,14 @@ static void sp_2048_to_bin(sp_digit* r, byte* a) for (i=0; i<32 && j>=0; i++) { b = 0; /* lint allow cast of mismatch sp_digit and int */ - a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ + a[j--] |= (byte)(r[i] << s); /*lint !e9033*/ + b += 8 - s; if (j < 0) { break; } while (b < 64) { - a[j--] = r[i] >> b; b += 8; + a[j--] = (byte)(r[i] >> b); + b += 8; if (j < 0) { break; } @@ -5650,12 +5652,14 @@ static void sp_3072_to_bin(sp_digit* r, byte* a) for (i=0; i<48 && j>=0; i++) { b = 0; /* lint allow cast of mismatch sp_digit and int */ - a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ + a[j--] |= (byte)(r[i] << s); /*lint !e9033*/ + b += 8 - s; if (j < 0) { break; } while (b < 64) { - a[j--] = r[i] >> b; b += 8; + a[j--] = (byte)(r[i] >> b); + b += 8; if (j < 0) { break; } @@ -13190,12 +13194,14 @@ static void sp_4096_to_bin(sp_digit* r, byte* a) for (i=0; i<64 && j>=0; i++) { b = 0; /* lint allow cast of mismatch sp_digit and int */ - a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ + a[j--] |= (byte)(r[i] << s); /*lint !e9033*/ + b += 8 - s; if (j < 0) { break; } while (b < 64) { - a[j--] = r[i] >> b; b += 8; + a[j--] = (byte)(r[i] >> b); + b += 8; if (j < 0) { break; } @@ -46598,12 +46604,14 @@ static void sp_256_to_bin(sp_digit* r, byte* a) for (i=0; i<4 && j>=0; i++) { b = 0; /* lint allow cast of mismatch sp_digit and int */ - a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ + a[j--] |= (byte)(r[i] << s); /*lint !e9033*/ + b += 8 - s; if (j < 0) { break; } while (b < 64) { - a[j--] = r[i] >> b; b += 8; + a[j--] = (byte)(r[i] >> b); + b += 8; if (j < 0) { break; } @@ -52648,12 +52656,14 @@ static void sp_384_to_bin(sp_digit* r, byte* a) for (i=0; i<6 && j>=0; i++) { b = 0; /* lint allow cast of mismatch sp_digit and int */ - a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ + a[j--] |= (byte)(r[i] << s); /*lint !e9033*/ + b += 8 - s; if (j < 0) { break; } while (b < 64) { - a[j--] = r[i] >> b; b += 8; + a[j--] = (byte)(r[i] >> b); + b += 8; if (j < 0) { break; } diff --git a/wolfcrypt/src/sp_armthumb.c b/wolfcrypt/src/sp_armthumb.c index a1d239f8a..5c6b01ab0 100644 --- a/wolfcrypt/src/sp_armthumb.c +++ b/wolfcrypt/src/sp_armthumb.c @@ -180,12 +180,14 @@ static void sp_2048_to_bin(sp_digit* r, byte* a) for (i=0; i<64 && j>=0; i++) { b = 0; /* lint allow cast of mismatch sp_digit and int */ - a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ + a[j--] |= (byte)(r[i] << s); /*lint !e9033*/ + b += 8 - s; if (j < 0) { break; } while (b < 32) { - a[j--] = r[i] >> b; b += 8; + a[j--] = (byte)(r[i] >> b); + b += 8; if (j < 0) { break; } @@ -5366,12 +5368,14 @@ static void sp_3072_to_bin(sp_digit* r, byte* a) for (i=0; i<96 && j>=0; i++) { b = 0; /* lint allow cast of mismatch sp_digit and int */ - a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ + a[j--] |= (byte)(r[i] << s); /*lint !e9033*/ + b += 8 - s; if (j < 0) { break; } while (b < 32) { - a[j--] = r[i] >> b; b += 8; + a[j--] = (byte)(r[i] >> b); + b += 8; if (j < 0) { break; } @@ -11265,12 +11269,14 @@ static void sp_4096_to_bin(sp_digit* r, byte* a) for (i=0; i<128 && j>=0; i++) { b = 0; /* lint allow cast of mismatch sp_digit and int */ - a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ + a[j--] |= (byte)(r[i] << s); /*lint !e9033*/ + b += 8 - s; if (j < 0) { break; } while (b < 32) { - a[j--] = r[i] >> b; b += 8; + a[j--] = (byte)(r[i] >> b); + b += 8; if (j < 0) { break; } @@ -20220,12 +20226,14 @@ static void sp_256_to_bin(sp_digit* r, byte* a) for (i=0; i<8 && j>=0; i++) { b = 0; /* lint allow cast of mismatch sp_digit and int */ - a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ + a[j--] |= (byte)(r[i] << s); /*lint !e9033*/ + b += 8 - s; if (j < 0) { break; } while (b < 32) { - a[j--] = r[i] >> b; b += 8; + a[j--] = (byte)(r[i] >> b); + b += 8; if (j < 0) { break; } @@ -26028,12 +26036,14 @@ static void sp_384_to_bin(sp_digit* r, byte* a) for (i=0; i<12 && j>=0; i++) { b = 0; /* lint allow cast of mismatch sp_digit and int */ - a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ + a[j--] |= (byte)(r[i] << s); /*lint !e9033*/ + b += 8 - s; if (j < 0) { break; } while (b < 32) { - a[j--] = r[i] >> b; b += 8; + a[j--] = (byte)(r[i] >> b); + b += 8; if (j < 0) { break; } diff --git a/wolfcrypt/src/sp_c32.c b/wolfcrypt/src/sp_c32.c index d86d5a0b1..a308dcf0c 100644 --- a/wolfcrypt/src/sp_c32.c +++ b/wolfcrypt/src/sp_c32.c @@ -194,12 +194,14 @@ static void sp_2048_to_bin(sp_digit* r, byte* a) for (i=0; i<90 && j>=0; i++) { b = 0; /* lint allow cast of mismatch sp_digit and int */ - a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ + a[j--] |= (byte)(r[i] << s); /*lint !e9033*/ + b += 8 - s; if (j < 0) { break; } while (b < 23) { - a[j--] = r[i] >> b; b += 8; + a[j--] = (byte)(r[i] >> b); + b += 8; if (j < 0) { break; } @@ -4629,12 +4631,14 @@ static void sp_3072_to_bin(sp_digit* r, byte* a) for (i=0; i<134 && j>=0; i++) { b = 0; /* lint allow cast of mismatch sp_digit and int */ - a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ + a[j--] |= (byte)(r[i] << s); /*lint !e9033*/ + b += 8 - s; if (j < 0) { break; } while (b < 23) { - a[j--] = r[i] >> b; b += 8; + a[j--] = (byte)(r[i] >> b); + b += 8; if (j < 0) { break; } @@ -8588,12 +8592,14 @@ static void sp_4096_to_bin(sp_digit* r, byte* a) for (i=0; i<196 && j>=0; i++) { b = 0; /* lint allow cast of mismatch sp_digit and int */ - a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ + a[j--] |= (byte)(r[i] << s); /*lint !e9033*/ + b += 8 - s; if (j < 0) { break; } while (b < 21) { - a[j--] = r[i] >> b; b += 8; + a[j--] = (byte)(r[i] >> b); + b += 8; if (j < 0) { break; } @@ -13179,7 +13185,7 @@ SP_NOINLINE static void sp_256_mul_add_10(sp_digit* r, const sp_digit* a, t[ 7] = tb * a[ 7]; t[ 8] = tb * a[ 8]; t[ 9] = tb * a[ 9]; - r[ 0] += (sp_digit)(t[ 0] & 0x3ffffff); + r[ 0] += (sp_digit) (t[ 0] & 0x3ffffff); r[ 1] += (sp_digit)((t[ 0] >> 26) + (t[ 1] & 0x3ffffff)); r[ 2] += (sp_digit)((t[ 1] >> 26) + (t[ 2] & 0x3ffffff)); r[ 3] += (sp_digit)((t[ 2] >> 26) + (t[ 3] & 0x3ffffff)); @@ -13189,7 +13195,7 @@ SP_NOINLINE static void sp_256_mul_add_10(sp_digit* r, const sp_digit* a, r[ 7] += (sp_digit)((t[ 6] >> 26) + (t[ 7] & 0x3ffffff)); r[ 8] += (sp_digit)((t[ 7] >> 26) + (t[ 8] & 0x3ffffff)); r[ 9] += (sp_digit)((t[ 8] >> 26) + (t[ 9] & 0x3ffffff)); - r[10] += t[ 9] >> 26; + r[10] += (sp_digit) (t[ 9] >> 26); #endif /* WOLFSSL_SP_SMALL */ } @@ -14121,11 +14127,12 @@ static int sp_256_ecc_mulmod_10(sp_point_256* r, const sp_point_256* g, const sp int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point_256 td[3]; - sp_digit tmpd[2 * 10 * 5]; -#endif + sp_point_256 t[3]; + sp_digit tmp[2 * 10 * 5]; +#else sp_point_256* t; sp_digit* tmp; +#endif sp_digit n; int i; int c, y; @@ -14134,28 +14141,21 @@ static int sp_256_ecc_mulmod_10(sp_point_256* r, const sp_point_256* g, const sp (void)heap; #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - sp_point_256 td[3]; - t = (sp_point_256*)XMALLOC(sizeof(*td) * 3, heap, DYNAMIC_TYPE_ECC); + t = (sp_point*)XMALLOC(sizeof(*t) * 3, heap, DYNAMIC_TYPE_ECC); if (t == NULL) err = MEMORY_E; tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 10 * 5, heap, DYNAMIC_TYPE_ECC); if (tmp == NULL) err = MEMORY_E; -#else - t = td; - tmp = tmpd; #endif if (err == MP_OKAY) { - t[0] = &td[0]; - t[1] = &td[1]; - t[2] = &td[2]; - /* 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 */ + t[1].infinity = 0; err = sp_256_mod_mul_norm_10(t[1].x, g->x, p256_mod); } if (err == MP_OKAY) @@ -14206,8 +14206,8 @@ static int sp_256_ecc_mulmod_10(sp_point_256* r, const sp_point_256* g, const sp XFREE(t, heap, DYNAMIC_TYPE_ECC); } #else - ForceZero(tmpd, sizeof(tmpd)); - ForceZero(td, sizeof(td)); + ForceZero(tmp, sizeof(tmp)); + ForceZero(t, sizeof(t)); #endif return err; @@ -14899,6 +14899,23 @@ static int sp_256_ecc_mulmod_base_10(sp_point_256* r, const sp_digit* k, return sp_256_ecc_mulmod_10(r, &p256_base, k, map, heap); } +#elif defined(WOLFSSL_SP_CACHE_RESISTANT) +/* Multiply the base point of P256 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_256_ecc_mulmod_base_10(sp_point_256* r, const sp_digit* k, + int map, void* heap) +{ + /* No pre-computed values. */ + return sp_256_ecc_mulmod_10(r, &p256_base, k, map, heap); +} + #else static const sp_table_entry_256 p256_table[256] = { /* 0 */ @@ -16439,12 +16456,14 @@ static void sp_256_to_bin(sp_digit* r, byte* a) for (i=0; i<10 && j>=0; i++) { b = 0; /* lint allow cast of mismatch sp_digit and int */ - a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ + a[j--] |= (byte)(r[i] << s); /*lint !e9033*/ + b += 8 - s; if (j < 0) { break; } while (b < 26) { - a[j--] = r[i] >> b; b += 8; + a[j--] = (byte)(r[i] >> b); + b += 8; if (j < 0) { break; } @@ -18689,7 +18708,7 @@ SP_NOINLINE static void sp_384_mul_add_15(sp_digit* r, const sp_digit* a, t[12] = tb * a[12]; t[13] = tb * a[13]; t[14] = tb * a[14]; - r[ 0] += (sp_digit)(t[ 0] & 0x3ffffff); + r[ 0] += (sp_digit) (t[ 0] & 0x3ffffff); r[ 1] += (sp_digit)((t[ 0] >> 26) + (t[ 1] & 0x3ffffff)); r[ 2] += (sp_digit)((t[ 1] >> 26) + (t[ 2] & 0x3ffffff)); r[ 3] += (sp_digit)((t[ 2] >> 26) + (t[ 3] & 0x3ffffff)); @@ -18704,7 +18723,7 @@ SP_NOINLINE static void sp_384_mul_add_15(sp_digit* r, const sp_digit* a, r[12] += (sp_digit)((t[11] >> 26) + (t[12] & 0x3ffffff)); r[13] += (sp_digit)((t[12] >> 26) + (t[13] & 0x3ffffff)); r[14] += (sp_digit)((t[13] >> 26) + (t[14] & 0x3ffffff)); - r[15] += t[14] >> 26; + r[15] += (sp_digit) (t[14] >> 26); #endif /* WOLFSSL_SP_SMALL */ } @@ -19734,11 +19753,12 @@ static int sp_384_ecc_mulmod_15(sp_point_384* r, const sp_point_384* g, const sp int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point_384 td[3]; - sp_digit tmpd[2 * 15 * 6]; -#endif + sp_point_384 t[3]; + sp_digit tmp[2 * 15 * 6]; +#else sp_point_384* t; sp_digit* tmp; +#endif sp_digit n; int i; int c, y; @@ -19747,28 +19767,21 @@ static int sp_384_ecc_mulmod_15(sp_point_384* r, const sp_point_384* g, const sp (void)heap; #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - sp_point_384 td[3]; - t = (sp_point_384*)XMALLOC(sizeof(*td) * 3, heap, DYNAMIC_TYPE_ECC); + t = (sp_point*)XMALLOC(sizeof(*t) * 3, heap, DYNAMIC_TYPE_ECC); if (t == NULL) err = MEMORY_E; tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 15 * 6, heap, DYNAMIC_TYPE_ECC); if (tmp == NULL) err = MEMORY_E; -#else - t = td; - tmp = tmpd; #endif if (err == MP_OKAY) { - t[0] = &td[0]; - t[1] = &td[1]; - t[2] = &td[2]; - /* 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 */ + t[1].infinity = 0; err = sp_384_mod_mul_norm_15(t[1].x, g->x, p384_mod); } if (err == MP_OKAY) @@ -19819,8 +19832,8 @@ static int sp_384_ecc_mulmod_15(sp_point_384* r, const sp_point_384* g, const sp XFREE(t, heap, DYNAMIC_TYPE_ECC); } #else - ForceZero(tmpd, sizeof(tmpd)); - ForceZero(td, sizeof(td)); + ForceZero(tmp, sizeof(tmp)); + ForceZero(t, sizeof(t)); #endif return err; @@ -20512,6 +20525,23 @@ static int sp_384_ecc_mulmod_base_15(sp_point_384* r, const sp_digit* k, return sp_384_ecc_mulmod_15(r, &p384_base, k, map, heap); } +#elif defined(WOLFSSL_SP_CACHE_RESISTANT) +/* 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. + * 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_15(sp_point_384* r, const sp_digit* k, + int map, void* heap) +{ + /* No pre-computed values. */ + return sp_384_ecc_mulmod_15(r, &p384_base, k, map, heap); +} + #else static const sp_table_entry_384 p384_table[256] = { /* 0 */ @@ -22562,12 +22592,14 @@ static void sp_384_to_bin(sp_digit* r, byte* a) for (i=0; i<15 && j>=0; i++) { b = 0; /* lint allow cast of mismatch sp_digit and int */ - a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ + a[j--] |= (byte)(r[i] << s); /*lint !e9033*/ + b += 8 - s; if (j < 0) { break; } while (b < 26) { - a[j--] = r[i] >> b; b += 8; + a[j--] = (byte)(r[i] >> b); + b += 8; if (j < 0) { break; } diff --git a/wolfcrypt/src/sp_c64.c b/wolfcrypt/src/sp_c64.c index 38ca21d62..814d06d46 100644 --- a/wolfcrypt/src/sp_c64.c +++ b/wolfcrypt/src/sp_c64.c @@ -194,12 +194,14 @@ static void sp_2048_to_bin(sp_digit* r, byte* a) for (i=0; i<36 && j>=0; i++) { b = 0; /* lint allow cast of mismatch sp_digit and int */ - a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ + a[j--] |= (byte)(r[i] << s); /*lint !e9033*/ + b += 8 - s; if (j < 0) { break; } while (b < 57) { - a[j--] = r[i] >> b; b += 8; + a[j--] = (byte)(r[i] >> b); + b += 8; if (j < 0) { break; } @@ -4159,12 +4161,14 @@ static void sp_3072_to_bin(sp_digit* r, byte* a) for (i=0; i<54 && j>=0; i++) { b = 0; /* lint allow cast of mismatch sp_digit and int */ - a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ + a[j--] |= (byte)(r[i] << s); /*lint !e9033*/ + b += 8 - s; if (j < 0) { break; } while (b < 57) { - a[j--] = r[i] >> b; b += 8; + a[j--] = (byte)(r[i] >> b); + b += 8; if (j < 0) { break; } @@ -8340,12 +8344,14 @@ static void sp_4096_to_bin(sp_digit* r, byte* a) for (i=0; i<78 && j>=0; i++) { b = 0; /* lint allow cast of mismatch sp_digit and int */ - a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ + a[j--] |= (byte)(r[i] << s); /*lint !e9033*/ + b += 8 - s; if (j < 0) { break; } while (b < 53) { - a[j--] = r[i] >> b; b += 8; + a[j--] = (byte)(r[i] >> b); + b += 8; if (j < 0) { break; } @@ -13098,12 +13104,12 @@ SP_NOINLINE static void sp_256_mul_add_5(sp_digit* r, const sp_digit* a, t[ 2] = tb * a[ 2]; t[ 3] = tb * a[ 3]; t[ 4] = tb * a[ 4]; - r[ 0] += (sp_digit)(t[ 0] & 0xfffffffffffffL); + r[ 0] += (sp_digit) (t[ 0] & 0xfffffffffffffL); r[ 1] += (sp_digit)((t[ 0] >> 52) + (t[ 1] & 0xfffffffffffffL)); r[ 2] += (sp_digit)((t[ 1] >> 52) + (t[ 2] & 0xfffffffffffffL)); r[ 3] += (sp_digit)((t[ 2] >> 52) + (t[ 3] & 0xfffffffffffffL)); r[ 4] += (sp_digit)((t[ 3] >> 52) + (t[ 4] & 0xfffffffffffffL)); - r[ 5] += t[ 4] >> 52; + r[ 5] += (sp_digit) (t[ 4] >> 52); #endif /* WOLFSSL_SP_SMALL */ } @@ -13943,11 +13949,12 @@ static int sp_256_ecc_mulmod_5(sp_point_256* r, const sp_point_256* g, const sp_ int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point_256 td[3]; - sp_digit tmpd[2 * 5 * 5]; -#endif + sp_point_256 t[3]; + sp_digit tmp[2 * 5 * 5]; +#else sp_point_256* t; sp_digit* tmp; +#endif sp_digit n; int i; int c, y; @@ -13956,28 +13963,21 @@ static int sp_256_ecc_mulmod_5(sp_point_256* r, const sp_point_256* g, const sp_ (void)heap; #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - sp_point_256 td[3]; - t = (sp_point_256*)XMALLOC(sizeof(*td) * 3, heap, DYNAMIC_TYPE_ECC); + t = (sp_point*)XMALLOC(sizeof(*t) * 3, heap, DYNAMIC_TYPE_ECC); if (t == NULL) err = MEMORY_E; tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 5 * 5, heap, DYNAMIC_TYPE_ECC); if (tmp == NULL) err = MEMORY_E; -#else - t = td; - tmp = tmpd; #endif if (err == MP_OKAY) { - t[0] = &td[0]; - t[1] = &td[1]; - t[2] = &td[2]; - /* 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 */ + t[1].infinity = 0; err = sp_256_mod_mul_norm_5(t[1].x, g->x, p256_mod); } if (err == MP_OKAY) @@ -14028,8 +14028,8 @@ static int sp_256_ecc_mulmod_5(sp_point_256* r, const sp_point_256* g, const sp_ XFREE(t, heap, DYNAMIC_TYPE_ECC); } #else - ForceZero(tmpd, sizeof(tmpd)); - ForceZero(td, sizeof(td)); + ForceZero(tmp, sizeof(tmp)); + ForceZero(t, sizeof(t)); #endif return err; @@ -14721,6 +14721,23 @@ static int sp_256_ecc_mulmod_base_5(sp_point_256* r, const sp_digit* k, return sp_256_ecc_mulmod_5(r, &p256_base, k, map, heap); } +#elif defined(WOLFSSL_SP_CACHE_RESISTANT) +/* Multiply the base point of P256 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_256_ecc_mulmod_base_5(sp_point_256* r, const sp_digit* k, + int map, void* heap) +{ + /* No pre-computed values. */ + return sp_256_ecc_mulmod_5(r, &p256_base, k, map, heap); +} + #else static const sp_table_entry_256 p256_table[256] = { /* 0 */ @@ -16260,12 +16277,14 @@ static void sp_256_to_bin(sp_digit* r, byte* a) for (i=0; i<5 && j>=0; i++) { b = 0; /* lint allow cast of mismatch sp_digit and int */ - a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ + a[j--] |= (byte)(r[i] << s); /*lint !e9033*/ + b += 8 - s; if (j < 0) { break; } while (b < 52) { - a[j--] = r[i] >> b; b += 8; + a[j--] = (byte)(r[i] >> b); + b += 8; if (j < 0) { break; } @@ -18235,14 +18254,14 @@ SP_NOINLINE static void sp_384_mul_add_7(sp_digit* r, const sp_digit* a, t[ 4] = tb * a[ 4]; t[ 5] = tb * a[ 5]; t[ 6] = tb * a[ 6]; - r[ 0] += (sp_digit)(t[ 0] & 0x7fffffffffffffL); + r[ 0] += (sp_digit) (t[ 0] & 0x7fffffffffffffL); r[ 1] += (sp_digit)((t[ 0] >> 55) + (t[ 1] & 0x7fffffffffffffL)); r[ 2] += (sp_digit)((t[ 1] >> 55) + (t[ 2] & 0x7fffffffffffffL)); r[ 3] += (sp_digit)((t[ 2] >> 55) + (t[ 3] & 0x7fffffffffffffL)); r[ 4] += (sp_digit)((t[ 3] >> 55) + (t[ 4] & 0x7fffffffffffffL)); r[ 5] += (sp_digit)((t[ 4] >> 55) + (t[ 5] & 0x7fffffffffffffL)); r[ 6] += (sp_digit)((t[ 5] >> 55) + (t[ 6] & 0x7fffffffffffffL)); - r[ 7] += t[ 6] >> 55; + r[ 7] += (sp_digit) (t[ 6] >> 55); #endif /* WOLFSSL_SP_SMALL */ } @@ -19116,11 +19135,12 @@ static int sp_384_ecc_mulmod_7(sp_point_384* r, const sp_point_384* g, const sp_ int map, void* heap) { #if !defined(WOLFSSL_SP_SMALL) && !defined(WOLFSSL_SMALL_STACK) - sp_point_384 td[3]; - sp_digit tmpd[2 * 7 * 6]; -#endif + sp_point_384 t[3]; + sp_digit tmp[2 * 7 * 6]; +#else sp_point_384* t; sp_digit* tmp; +#endif sp_digit n; int i; int c, y; @@ -19129,28 +19149,21 @@ static int sp_384_ecc_mulmod_7(sp_point_384* r, const sp_point_384* g, const sp_ (void)heap; #if defined(WOLFSSL_SP_SMALL) || defined(WOLFSSL_SMALL_STACK) - sp_point_384 td[3]; - t = (sp_point_384*)XMALLOC(sizeof(*td) * 3, heap, DYNAMIC_TYPE_ECC); + t = (sp_point*)XMALLOC(sizeof(*t) * 3, heap, DYNAMIC_TYPE_ECC); if (t == NULL) err = MEMORY_E; tmp = (sp_digit*)XMALLOC(sizeof(sp_digit) * 2 * 7 * 6, heap, DYNAMIC_TYPE_ECC); if (tmp == NULL) err = MEMORY_E; -#else - t = td; - tmp = tmpd; #endif if (err == MP_OKAY) { - t[0] = &td[0]; - t[1] = &td[1]; - t[2] = &td[2]; - /* 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 */ + t[1].infinity = 0; err = sp_384_mod_mul_norm_7(t[1].x, g->x, p384_mod); } if (err == MP_OKAY) @@ -19201,8 +19214,8 @@ static int sp_384_ecc_mulmod_7(sp_point_384* r, const sp_point_384* g, const sp_ XFREE(t, heap, DYNAMIC_TYPE_ECC); } #else - ForceZero(tmpd, sizeof(tmpd)); - ForceZero(td, sizeof(td)); + ForceZero(tmp, sizeof(tmp)); + ForceZero(t, sizeof(t)); #endif return err; @@ -19894,6 +19907,23 @@ static int sp_384_ecc_mulmod_base_7(sp_point_384* r, const sp_digit* k, return sp_384_ecc_mulmod_7(r, &p384_base, k, map, heap); } +#elif defined(WOLFSSL_SP_CACHE_RESISTANT) +/* 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. + * 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_7(sp_point_384* r, const sp_digit* k, + int map, void* heap) +{ + /* No pre-computed values. */ + return sp_384_ecc_mulmod_7(r, &p384_base, k, map, heap); +} + #else static const sp_table_entry_384 p384_table[256] = { /* 0 */ @@ -21943,12 +21973,14 @@ static void sp_384_to_bin(sp_digit* r, byte* a) for (i=0; i<7 && j>=0; i++) { b = 0; /* lint allow cast of mismatch sp_digit and int */ - a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ + a[j--] |= (byte)(r[i] << s); /*lint !e9033*/ + b += 8 - s; if (j < 0) { break; } while (b < 55) { - a[j--] = r[i] >> b; b += 8; + a[j--] = (byte)(r[i] >> b); + b += 8; if (j < 0) { break; } diff --git a/wolfcrypt/src/sp_cortexm.c b/wolfcrypt/src/sp_cortexm.c index 94decf725..39a27d630 100644 --- a/wolfcrypt/src/sp_cortexm.c +++ b/wolfcrypt/src/sp_cortexm.c @@ -189,12 +189,14 @@ static void sp_2048_to_bin(sp_digit* r, byte* a) for (i=0; i<64 && j>=0; i++) { b = 0; /* lint allow cast of mismatch sp_digit and int */ - a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ + a[j--] |= (byte)(r[i] << s); /*lint !e9033*/ + b += 8 - s; if (j < 0) { break; } while (b < 32) { - a[j--] = r[i] >> b; b += 8; + a[j--] = (byte)(r[i] >> b); + b += 8; if (j < 0) { break; } @@ -5120,12 +5122,14 @@ static void sp_3072_to_bin(sp_digit* r, byte* a) for (i=0; i<96 && j>=0; i++) { b = 0; /* lint allow cast of mismatch sp_digit and int */ - a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ + a[j--] |= (byte)(r[i] << s); /*lint !e9033*/ + b += 8 - s; if (j < 0) { break; } while (b < 32) { - a[j--] = r[i] >> b; b += 8; + a[j--] = (byte)(r[i] >> b); + b += 8; if (j < 0) { break; } @@ -9868,12 +9872,14 @@ static void sp_4096_to_bin(sp_digit* r, byte* a) for (i=0; i<128 && j>=0; i++) { b = 0; /* lint allow cast of mismatch sp_digit and int */ - a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ + a[j--] |= (byte)(r[i] << s); /*lint !e9033*/ + b += 8 - s; if (j < 0) { break; } while (b < 32) { - a[j--] = r[i] >> b; b += 8; + a[j--] = (byte)(r[i] >> b); + b += 8; if (j < 0) { break; } @@ -18469,12 +18475,14 @@ static void sp_256_to_bin(sp_digit* r, byte* a) for (i=0; i<8 && j>=0; i++) { b = 0; /* lint allow cast of mismatch sp_digit and int */ - a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ + a[j--] |= (byte)(r[i] << s); /*lint !e9033*/ + b += 8 - s; if (j < 0) { break; } while (b < 32) { - a[j--] = r[i] >> b; b += 8; + a[j--] = (byte)(r[i] >> b); + b += 8; if (j < 0) { break; } @@ -23995,12 +24003,14 @@ static void sp_384_to_bin(sp_digit* r, byte* a) for (i=0; i<12 && j>=0; i++) { b = 0; /* lint allow cast of mismatch sp_digit and int */ - a[j--] |= (byte)(r[i] << s); b += 8 - s; /*lint !e9033*/ + a[j--] |= (byte)(r[i] << s); /*lint !e9033*/ + b += 8 - s; if (j < 0) { break; } while (b < 32) { - a[j--] = r[i] >> b; b += 8; + a[j--] = (byte)(r[i] >> b); + b += 8; if (j < 0) { break; } From f7018c4765405e6fa045ea7d13f6c4d196351efa Mon Sep 17 00:00:00 2001 From: Hideki Miyazaki Date: Thu, 20 Feb 2020 18:22:25 +0900 Subject: [PATCH 105/649] fixed build failure and warnings fixed unit test app failure --- .../wolfssl_server/main/wifi_connect.c | 10 ++++- IDE/Espressif/ESP-IDF/test/test_wolfssl.c | 38 +++++++++---------- wolfssl/wolfcrypt/settings.h | 10 ++++- 3 files changed, 36 insertions(+), 22 deletions(-) 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 e2a2efbc0..a699eb336 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 @@ -98,8 +98,13 @@ static esp_err_t wifi_event_handler(void *ctx, system_event_t *event) esp_wifi_connect(); break; case SYSTEM_EVENT_STA_GOT_IP: +#if ESP_IDF_VERSION_MAJOR >= 4 && ESP_IDF_VERSION_MINOR >= 1 + ESP_LOGI(TAG, "got ip:" IPSTR "\n", + IP2STR(&event->event_info.got_ip.ip_info.ip)); +#else ESP_LOGI(TAG, "got ip:%s", ip4addr_ntoa(&event->event_info.got_ip.ip_info.ip)); +#endif /* http://esp32.info/docs/esp_idf/html/dd/d08/group__xEventGroupSetBits.html */ xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); break; @@ -120,8 +125,11 @@ void app_main(void) ESP_LOGI(TAG, "Initialize wifi"); /* TCP/IP adapter initialization */ +#if ESP_IDF_VERSION_MAJOR >= 4 && ESP_IDF_VERSION_MINOR >= 1 + esp_netif_init(); +#else tcpip_adapter_init(); - +#endif /* */ #if ESP_IDF_VERSION_MAJOR >= 4 && ESP_IDF_VERSION_MINOR >= 1 (void) wifi_event_handler; diff --git a/IDE/Espressif/ESP-IDF/test/test_wolfssl.c b/IDE/Espressif/ESP-IDF/test/test_wolfssl.c index b2ad2083e..cdf377de9 100644 --- a/IDE/Espressif/ESP-IDF/test/test_wolfssl.c +++ b/IDE/Espressif/ESP-IDF/test/test_wolfssl.c @@ -539,20 +539,20 @@ int mp_unitest_exptmod(const char* strZ, const char* strX, const char* strY, TEST_CASE("wolfssl mp exptmod test" , "[wolfssl]") { ESP_LOGI(TAG, "mp test"); - int verbose = 0; + int verbose = 1; - TEST_ASSERT_EQUAL(0, mp_unitest_exptmod("2", "5", "1", "3", verbose)); - TEST_ASSERT_EQUAL(0, mp_unitest_exptmod("1", "-5", "1", "3", verbose)); + TEST_ASSERT_EQUAL(0, mp_unitest_exptmod("02", "5", "1", "3", verbose)); + TEST_ASSERT_EQUAL(0, mp_unitest_exptmod("01", "-5", "1", "3", verbose)); TEST_ASSERT_EQUAL(0, mp_unitest_exptmod("CE331E6D30A77A57", "1234", "A", "FFFFFFFFFFFFFFFF", verbose)); - TEST_ASSERT_EQUAL(0, mp_unitest_exptmod("1000000", "1000", "2", "FFFFFFF", verbose)); - TEST_ASSERT_EQUAL(0, mp_unitest_exptmod("1000000", "2", "128", + TEST_ASSERT_EQUAL(0, mp_unitest_exptmod("01000000", "1000", "2", "FFFFFFF", verbose)); + TEST_ASSERT_EQUAL(0, mp_unitest_exptmod("01000000", "2", "128", "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", verbose)); - TEST_ASSERT_EQUAL(0, mp_unitest_exptmod("14B5A90", "1234", "2", "FFFFFFF", verbose)); - TEST_ASSERT_EQUAL(0, mp_unitest_exptmod("1234321", "1111", "2", "FFFFFFFF", verbose)); - TEST_ASSERT_EQUAL(0, mp_unitest_exptmod("2", "5", "1", "3", verbose)); + TEST_ASSERT_EQUAL(0, mp_unitest_exptmod("014B5A90", "1234", "2", "FFFFFFF", verbose)); + TEST_ASSERT_EQUAL(0, mp_unitest_exptmod("01234321", "1111", "2", "FFFFFFFF", verbose)); + TEST_ASSERT_EQUAL(0, mp_unitest_exptmod("02", "5", "1", "3", verbose)); TEST_ASSERT_EQUAL(0, mp_unitest_exptmod("22", "55", "1", "33", verbose)); - TEST_ASSERT_EQUAL(0, mp_unitest_exptmod("222", "555", "1", "333", verbose)); + TEST_ASSERT_EQUAL(0, mp_unitest_exptmod("0222", "555", "1", "333", verbose)); TEST_ASSERT_EQUAL(0, mp_unitest_exptmod("2222", "5555", "1", "3333", verbose)); TEST_ASSERT_EQUAL(0, mp_unitest_exptmod("11", "5555", "1", "33", verbose)); TEST_ASSERT_EQUAL(0, mp_unitest_exptmod("55", "1111", "1", "77", verbose)); @@ -564,14 +564,14 @@ TEST_CASE("wolfssl mp mulmod test" , "[wolfssl]") ESP_LOGI(TAG, "mp test"); int verbose = 0; /* Z X Y M */ - TEST_ASSERT_EQUAL(0, mp_unitest_mulmod("2", "5", "1", "3", verbose)); - TEST_ASSERT_EQUAL(0, mp_unitest_mulmod("1", "-5", "1", "3", verbose)); - TEST_ASSERT_EQUAL(0, mp_unitest_mulmod("2", "-64", "A", "3", verbose)); + TEST_ASSERT_EQUAL(0, mp_unitest_mulmod("02", "5", "1", "3", verbose)); + TEST_ASSERT_EQUAL(0, mp_unitest_mulmod("01", "-5", "1", "3", verbose)); + TEST_ASSERT_EQUAL(0, mp_unitest_mulmod("02", "-64", "A", "3", verbose)); TEST_ASSERT_EQUAL(0, mp_unitest_mulmod("74C3AC", "123456", "55555", "AAAAA1", verbose)); TEST_ASSERT_EQUAL(0, mp_unitest_mulmod("73A068", "123456", "55555", "AAAAA3", verbose)); mp_unitest_mulmod( - "10C530243ADE5EA7C557E9A2FF5B4573195665A89CB921F573267B15CD2BCB6467E925235AA752CC2D08B07D31497B497744CA3685A46E76247439826628589DD814AC9EEE9EF8B4B44BEE2DB6065BE3C51B788E4ECFF39FB28C3D8EBE10FC9989D97CDC6624E32EBD222E222A2E93085FC2D05E4EB73375F7FC7B11E9B3024", + "010C530243ADE5EA7C557E9A2FF5B4573195665A89CB921F573267B15CD2BCB6467E925235AA752CC2D08B07D31497B497744CA3685A46E76247439826628589DD814AC9EEE9EF8B4B44BEE2DB6065BE3C51B788E4ECFF39FB28C3D8EBE10FC9989D97CDC6624E32EBD222E222A2E93085FC2D05E4EB73375F7FC7B11E9B3024", "A4F780E83C3FAC34878787D4876BA7582E48C7637A26C6E720974FC7416150A3865D44F6D08E3DA38EB4296928C564D9A0008D8A0D63E0B8EF54D14D54FBEAB540E43D2ED6BE54806D9150C1944437CC3D8B2486A1FB932A6691B529E0E2A46524CB0825BA4F4E1B9C24554DB1913169E5373173A3B7CBBF77C3403C8C7AE86A", "6520379E44C1A2C359342010E1038F8C3644D9A47A9346A80C92B48A6986872D74C3BDDB49B2D93C554B588D4A4448614FADBC066CC10F3EB20A2422EA857B7DD0BF60C9CB7D733B12761BD785BCD122D97ECA0A8F1D0F705BC094B66EE5C96712AE3B14B5AA6AD9E50C6A3020BA01DA4FB94E3934527ADCDB3DE51C368B37C2", "BE7070B80418E528FE66D89088E0F1B7C3D0D23EE64B9474B0FFB0F763A5AB7EAFB62BB738161A50BFF1CA873AD5B0DAF8437A15B97EEA2A80D251B035AF07F3F25D243A4B8756481B3C249ADA7080BD3C8B034A0C8371DEE30370A2B760091B5EC73DA06460E3A9068DD3FF42BB0A94272D57420DB02DE0BA182560921192F3", @@ -604,11 +604,11 @@ TEST_CASE("wolfssl mp mul test" , "[wolfssl]") ESP_LOGI(TAG, "mp test"); int verbose = 0; - TEST_ASSERT_EQUAL(0, mp_unitest_mul("A", "5", "2", verbose)); - TEST_ASSERT_EQUAL(0, mp_unitest_mul("-A", "-5", "2", verbose)); - TEST_ASSERT_EQUAL(0, mp_unitest_mul("A", "-5", "-2", verbose)); - TEST_ASSERT_EQUAL(0, mp_unitest_mul("6260060", "1234", "5678", verbose)); - TEST_ASSERT_EQUAL(0, mp_unitest_mul("38E83", "123", "321", verbose)); + TEST_ASSERT_EQUAL(0, mp_unitest_mul("0A", "5", "2", verbose)); + TEST_ASSERT_EQUAL(0, mp_unitest_mul("-0A", "-5", "2", verbose)); + TEST_ASSERT_EQUAL(0, mp_unitest_mul("0A", "-5", "-2", verbose)); + TEST_ASSERT_EQUAL(0, mp_unitest_mul("06260060", "1234", "5678", verbose)); + TEST_ASSERT_EQUAL(0, mp_unitest_mul("038E83", "123", "321", verbose)); TEST_ASSERT_EQUAL(0, mp_unitest_mul("75CD7FCBBC", "123456", "6789A", verbose)); TEST_ASSERT_EQUAL(0, mp_unitest_mul( @@ -618,7 +618,7 @@ TEST_CASE("wolfssl mp mul test" , "[wolfssl]") verbose)); TEST_ASSERT_EQUAL(0, mp_unitest_mul( - "33676FE7B625BF0759F7E8932B6B50D5F45E16E1C670AD20F1CDA5DFFA433685937CA8422A9CB916CC8", + "033676FE7B625BF0759F7E8932B6B50D5F45E16E1C670AD20F1CDA5DFFA433685937CA8422A9CB916CC8", "165196BA298CD54975DC483C4D21A51EA0A146783CFB41522E76E50C", "24D9D5CA7D9CCC06F5E70F1963E6", verbose)); diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 715821caa..d0d3fe2c5 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -694,8 +694,14 @@ extern void uITRON4_free(void *p) ; #endif /* FreeRTOS pvPortRealloc() implementation can be found here: https://github.com/wolfSSL/wolfssl-freertos/pull/3/files */ - #if !defined(USE_FAST_MATH) || defined(HAVE_ED25519) || defined(WOLFSSL_ESPIDF) - #define XREALLOC(p, n, h, t) pvPortRealloc((p), (n)) + #if !defined(USE_FAST_MATH) || defined(HAVE_ED25519) + #if defined(WOLFSSL_ESPIDF) + /*In IDF, realloc(p, n) is equivalent to + heap_caps_realloc(p, s, MALLOC_CAP_8BIT) */ + #define XREALLOC(p, n, h, t) realloc((p), (n)) + #else + #define XREALLOC(p, n, h, t) pvPortRealloc((p), (n)) + #endif #endif #ifndef NO_WRITEV #define NO_WRITEV From d4a9279a6cc188713ed0c7f87bc2a0301ff052aa Mon Sep 17 00:00:00 2001 From: Stanislav Klima Date: Thu, 20 Feb 2020 15:04:01 +0100 Subject: [PATCH 106/649] Revert "Resource leak." to resolve the conflict (this fix is unapplicable, because the leaking code was removed). This reverts commit 451d0a470a5de9cb27d408f127eb934cfe4d77a0. --- src/ssl.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ssl.c b/src/ssl.c index 96e3562b3..95191dac1 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -35836,7 +35836,6 @@ int wolfSSL_i2d_RSAPrivateKey(WOLFSSL_RSA *rsa, unsigned char **pp) /* create buffer and return it */ *pp = (unsigned char*)XMALLOC(ret, NULL, DYNAMIC_TYPE_OPENSSL); if (*pp == NULL) { - XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER); return WOLFSSL_FATAL_ERROR; } XMEMCPY(*pp, der, ret); From 1f003967dfb2daab5512d3e3212ffeae96f78d87 Mon Sep 17 00:00:00 2001 From: kaleb-himes Date: Thu, 20 Feb 2020 09:20:59 -0700 Subject: [PATCH 107/649] Fix failing FIPS tests in master stemming from PR #2733 --- wolfcrypt/src/asn.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 245470fc8..f70fe0f02 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -124,7 +124,9 @@ extern int wc_InitRsaHw(RsaKey* key); #define ERROR_OUT(err, eLabel) { ret = (err); goto eLabel; } -#if defined(HAVE_SELFTEST) || !defined(NO_SKID) +#if defined(HAVE_SELFTEST) || ( !defined(NO_SKID) && \ + ( !defined(HAVE_FIPS) || \ + !defined(HAVE_FIPS_VERSION) )) #ifndef WOLFSSL_AES_KEY_SIZE_ENUM #define WOLFSSL_AES_KEY_SIZE_ENUM enum Asn_Misc { From 70ef925a4811f3980c7d1754adf752139c41a6d5 Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Thu, 20 Feb 2020 18:32:56 +0100 Subject: [PATCH 108/649] Remove redundant wolfSSL_EVP_CIPHER_CTX_iv_length call --- src/ssl.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 3e8463cef..689377e1c 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -17194,7 +17194,6 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ctx->block_size = 16; } #ifdef HAVE_WOLFSSL_EVP_CIPHER_CTX_IV - ctx->ivSz = wolfSSL_EVP_CIPHER_CTX_iv_length(ctx); if (iv && iv != ctx->iv) { if (wolfSSL_StoreExternalIV(ctx) != WOLFSSL_SUCCESS) { return WOLFSSL_FAILURE; @@ -32444,7 +32443,7 @@ int wolfSSL_EVP_CIPHER_CTX_iv_length(const WOLFSSL_EVP_CIPHER_CTX* ctx) case AES_192_GCM_TYPE : case AES_256_GCM_TYPE : WOLFSSL_MSG("AES GCM"); - return AES_BLOCK_SIZE; + return GCM_NONCE_MID_SZ; #endif #ifdef WOLFSSL_AES_COUNTER case AES_128_CTR_TYPE : From ba25161f6ce7e4d85053217e2c11450d9b6fb760 Mon Sep 17 00:00:00 2001 From: Eric Blankenhorn Date: Wed, 8 Jan 2020 16:52:50 -0600 Subject: [PATCH 109/649] Adding BIO and EVP api --- doc/dox_comments/header_files/ssl.h | 23 ++ src/ssl.c | 344 +++++++++++++++++++++++++++- wolfssl/openssl/bio.h | 4 +- wolfssl/openssl/evp.h | 40 ++++ wolfssl/ssl.h | 14 +- 5 files changed, 415 insertions(+), 10 deletions(-) diff --git a/doc/dox_comments/header_files/ssl.h b/doc/dox_comments/header_files/ssl.h index 1ba412f60..27fe0e759 100644 --- a/doc/dox_comments/header_files/ssl.h +++ b/doc/dox_comments/header_files/ssl.h @@ -3868,6 +3868,29 @@ WOLFSSL_API int wolfSSL_BIO_get_mem_data(WOLFSSL_BIO* bio,void* p); */ WOLFSSL_API long wolfSSL_BIO_set_fd(WOLFSSL_BIO* b, int fd, int flag); +/*! + \ingroup IO + + \brief Sets the close flag, used to indicate that the i/o stream should be + closed when the BIO is freed + + \return SSL_SUCCESS(1) upon success. + + \param bio WOLFSSL_BIO structure. + \param flag flag for behavior when closing i/o stream. + + _Example_ + \code + WOLFSSL_BIO* bio; + // setup bio + wolfSSL_BIO_set_close(bio, BIO_NOCLOSE); + \endcode + + \sa wolfSSL_BIO_new + \sa wolfSSL_BIO_free +*/ +WOLFSSL_API int wolfSSL_BIO_set_close(WOLFSSL_BIO *b, long flag); + /*! \ingroup IO diff --git a/src/ssl.c b/src/ssl.c index 3e8463cef..b08c6be6d 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -4073,7 +4073,65 @@ const WOLFSSL_EVP_CIPHER *wolfSSL_EVP_get_cipherbynid(int id) static char *EVP_AES_256_CBC; #endif #endif /* HAVE_AES_CBC */ -#if defined(OPENSSL_EXTRA) + + #ifdef HAVE_AES_OFB + #ifdef WOLFSSL_AES_128 + static char *EVP_AES_128_OFB; + #endif + #ifdef WOLFSSL_AES_192 + static char *EVP_AES_192_OFB; + #endif + #ifdef WOLFSSL_AES_256 + static char *EVP_AES_256_OFB; + #endif + #endif /* HAVE_AES_OFB */ + + #ifdef HAVE_AES_XTS + #ifdef WOLFSSL_AES_128 + static char *EVP_AES_128_XTS; + #endif + #ifdef WOLFSSL_AES_256 + static char *EVP_AES_256_XTS; + #endif + #endif /* HAVE_AES_XTS */ + + #ifdef HAVE_AES_CFB1 + #ifdef WOLFSSL_AES_128 + static char *EVP_AES_128_CFB1; + #endif + #ifdef WOLFSSL_AES_192 + static char *EVP_AES_192_CFB1; + #endif + #ifdef WOLFSSL_AES_256 + static char *EVP_AES_256_CFB1; + #endif + #endif /* HAVE_AES_CFB1 */ + + #ifdef HAVE_AES_CFB8 + #ifdef WOLFSSL_AES_128 + static char *EVP_AES_128_CFB8; + #endif + #ifdef WOLFSSL_AES_192 + static char *EVP_AES_192_CFB8; + #endif + #ifdef WOLFSSL_AES_256 + static char *EVP_AES_256_CFB8; + #endif + #endif /* HAVE_AES_CFB8 */ + + #ifdef HAVE_AES_CFB128 + #ifdef WOLFSSL_AES_128 + static char *EVP_AES_128_CFB128; + #endif + #ifdef WOLFSSL_AES_192 + static char *EVP_AES_192_CFB128; + #endif + #ifdef WOLFSSL_AES_256 + static char *EVP_AES_256_CFB128; + #endif + #endif /* HAVE_AES_CFB128 */ + + #if defined(OPENSSL_EXTRA) #ifdef HAVE_AESGCM #ifdef WOLFSSL_AES_128 static char *EVP_AES_128_GCM; @@ -4144,6 +4202,72 @@ void wolfSSL_EVP_init(void) #endif #endif /* HAVE_AES_CBC */ + #ifdef HAVE_AES_CFB1 + #ifdef WOLFSSL_AES_128 + EVP_AES_128_CFB1 = (char *)EVP_get_cipherbyname("AES-128-CFB1"); + #endif + + #ifdef WOLFSSL_AES_192 + EVP_AES_192_CFB1 = (char *)EVP_get_cipherbyname("AES-192-CFB1"); + #endif + + #ifdef WOLFSSL_AES_256 + EVP_AES_256_CFB1 = (char *)EVP_get_cipherbyname("AES-256-CFB1"); + #endif + #endif /* HAVE_AES_CFB1 */ + + #ifdef HAVE_AES_CFB8 + #ifdef WOLFSSL_AES_128 + EVP_AES_128_CFB8 = (char *)EVP_get_cipherbyname("AES-128-CFB8"); + #endif + + #ifdef WOLFSSL_AES_192 + EVP_AES_192_CFB8 = (char *)EVP_get_cipherbyname("AES-192-CFB8"); + #endif + + #ifdef WOLFSSL_AES_256 + EVP_AES_256_CFB8 = (char *)EVP_get_cipherbyname("AES-256-CFB8"); + #endif + #endif /* HAVE_AES_CFB8 */ + + #ifdef HAVE_AES_CFB12828 + #ifdef WOLFSSL_AES_128 + EVP_AES_128_CFB128 = (char *)EVP_get_cipherbyname("AES-128-CFB128"); + #endif + + #ifdef WOLFSSL_AES_192 + EVP_AES_192_CFB128 = (char *)EVP_get_cipherbyname("AES-192-CFB128"); + #endif + + #ifdef WOLFSSL_AES_256 + EVP_AES_256_CFB128 = (char *)EVP_get_cipherbyname("AES-256-CFB128"); + #endif + #endif /* HAVE_AES_CFB128 */ + + #ifdef HAVE_AES_OFB + #ifdef WOLFSSL_AES_128 + EVP_AES_128_OFB = (char *)EVP_get_cipherbyname("AES-128-OFB"); + #endif + + #ifdef WOLFSSL_AES_192 + EVP_AES_192_OFB = (char *)EVP_get_cipherbyname("AES-192-OFB"); + #endif + + #ifdef WOLFSSL_AES_256 + EVP_AES_256_OFB = (char *)EVP_get_cipherbyname("AES-256-OFB"); + #endif + #endif /* HAVE_AES_OFB */ + + #ifdef HAVE_AES_XTS + #ifdef WOLFSSL_AES_128 + EVP_AES_128_XTS = (char *)EVP_get_cipherbyname("AES-128-XTS"); + #endif + + #ifdef WOLFSSL_AES_256 + EVP_AES_256_XTS = (char *)EVP_get_cipherbyname("AES-256-XTS"); + #endif + #endif /* HAVE_AES_XTS */ + #if defined(OPENSSL_EXTRA) #ifdef HAVE_AESGCM #ifdef WOLFSSL_AES_128 @@ -4176,7 +4300,7 @@ void wolfSSL_EVP_init(void) EVP_AES_256_ECB = (char *)EVP_get_cipherbyname("AES-256-ECB"); #endif #endif -#endif +#endif /* ifndef NO_AES*/ #ifndef NO_DES3 EVP_DES_CBC = (char *)EVP_get_cipherbyname("DES-CBC"); @@ -14981,6 +15105,30 @@ int wolfSSL_set_compression(WOLFSSL* ssl) #endif /* !NO_CERTS */ + WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_md(void) + { + static WOLFSSL_BIO_METHOD meth; + + WOLFSSL_ENTER("wolfSSL_BIO_f_md"); + meth.type = WOLFSSL_BIO_MD; + + return &meth; + } + + /* return the context and initialize the BIO state */ + int wolfSSL_BIO_get_md_ctx(WOLFSSL_BIO *bio, WOLFSSL_EVP_MD_CTX **mdcp) + { + int ret = WOLFSSL_FAILURE; + + if ((bio != NULL) && (mdcp != NULL)) { + *mdcp = bio->ptr; + + /* TODO: reset bio */ + } + + return ret; + } + WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_buffer(void) { static WOLFSSL_BIO_METHOD meth; @@ -15065,7 +15213,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) int wolfSSL_BIO_eof(WOLFSSL_BIO* b) { WOLFSSL_ENTER("BIO_eof"); - if (b->eof) + if ((b != NULL) && (b->eof)) return 1; return 0; @@ -15099,6 +15247,18 @@ int wolfSSL_set_compression(WOLFSSL* ssl) } #endif + /* Sets the close flag */ + int wolfSSL_BIO_set_close(WOLFSSL_BIO *b, long flag) + { + WOLFSSL_ENTER("wolfSSL_BIO_set_close"); + if (b != NULL) { + b->shutdown = (byte)flag; + } + + return WOLFSSL_SUCCESS; + } + + WOLFSSL_BIO* wolfSSL_BIO_new(WOLFSSL_BIO_METHOD* method) { WOLFSSL_BIO* bio; @@ -16327,6 +16487,156 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) #endif /* WOLFSSL_AES_256 */ #endif /* HAVE_AES_CBC */ + #ifdef HAVE_AES_CFB1 + #ifdef WOLFSSL_AES_128 + const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_cfb1(void) + { + WOLFSSL_ENTER("wolfSSL_EVP_aes_128_cfb1"); + if (EVP_AES_128_CFB1 == NULL) + wolfSSL_EVP_init(); + return EVP_AES_128_CFB1; + } + #endif /* WOLFSSL_AES_128 */ + + #ifdef WOLFSSL_AES_192 + const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_cfb1(void) + { + WOLFSSL_ENTER("wolfSSL_EVP_aes_192_cfb1"); + if (EVP_AES_192_CFB1 == NULL) + wolfSSL_EVP_init(); + return EVP_AES_192_CFB1; + } + #endif /* WOLFSSL_AES_192 */ + + #ifdef WOLFSSL_AES_256 + const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_cfb1(void) + { + WOLFSSL_ENTER("wolfSSL_EVP_aes_256_cfb1"); + if (EVP_AES_256_CFB1 == NULL) + wolfSSL_EVP_init(); + return EVP_AES_256_CFB1; + } + #endif /* WOLFSSL_AES_256 */ + #endif /* HAVE_AES_CFB1 */ + + #ifdef HAVE_AES_CFB8 + #ifdef WOLFSSL_AES_128 + const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_cfb8(void) + { + WOLFSSL_ENTER("wolfSSL_EVP_aes_128_cfb8"); + if (EVP_AES_128_CFB8 == NULL) + wolfSSL_EVP_init(); + return EVP_AES_128_CFB8; + } + #endif /* WOLFSSL_AES_128 */ + + #ifdef WOLFSSL_AES_192 + const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_cfb8(void) + { + WOLFSSL_ENTER("wolfSSL_EVP_aes_192_cfb8"); + if (EVP_AES_192_CFB8 == NULL) + wolfSSL_EVP_init(); + return EVP_AES_192_CFB8; + } + #endif /* WOLFSSL_AES_192 */ + + #ifdef WOLFSSL_AES_256 + const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_cfb8(void) + { + WOLFSSL_ENTER("wolfSSL_EVP_aes_256_cfb8"); + if (EVP_AES_256_CFB8 == NULL) + wolfSSL_EVP_init(); + return EVP_AES_256_CFB8; + } + #endif /* WOLFSSL_AES_256 */ + #endif /* HAVE_AES_CFB8 */ + + #ifdef HAVE_AES_CFB12828 + #ifdef WOLFSSL_AES_128 + const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_cfb128(void) + { + WOLFSSL_ENTER("wolfSSL_EVP_aes_128_cfb128"); + if (EVP_AES_128_CFB128 == NULL) + wolfSSL_EVP_init(); + return EVP_AES_128_CFB128; + } + #endif /* WOLFSSL_AES_128 */ + + #ifdef WOLFSSL_AES_192 + const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_cfb128(void) + { + WOLFSSL_ENTER("wolfSSL_EVP_aes_192_cfb128"); + if (EVP_AES_192_CFB128 == NULL) + wolfSSL_EVP_init(); + return EVP_AES_192_CFB128; + } + #endif /* WOLFSSL_AES_192 */ + + #ifdef WOLFSSL_AES_256 + const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_cfb128(void) + { + WOLFSSL_ENTER("wolfSSL_EVP_aes_256_cfb128"); + if (EVP_AES_256_CFB128 == NULL) + wolfSSL_EVP_init(); + return EVP_AES_256_CFB128; + } + #endif /* WOLFSSL_AES_256 */ + #endif /* HAVE_AES_CFB128 */ + + #ifdef HAVE_AES_OFB + #ifdef WOLFSSL_AES_128 + const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_ofb(void) + { + WOLFSSL_ENTER("wolfSSL_EVP_aes_128_ofb"); + if (EVP_AES_128_OFB == NULL) + wolfSSL_EVP_init(); + return EVP_AES_128_OFB; + } + #endif /* WOLFSSL_AES_128 */ + + #ifdef WOLFSSL_AES_192 + const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_ofb(void) + { + WOLFSSL_ENTER("wolfSSL_EVP_aes_192_ofb"); + if (EVP_AES_192_OFB == NULL) + wolfSSL_EVP_init(); + return EVP_AES_192_OFB; + } + #endif /* WOLFSSL_AES_192 */ + + #ifdef WOLFSSL_AES_256 + const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_ofb(void) + { + WOLFSSL_ENTER("wolfSSL_EVP_aes_256_ofb"); + if (EVP_AES_256_OFB == NULL) + wolfSSL_EVP_init(); + return EVP_AES_256_OFB; + } + #endif /* WOLFSSL_AES_256 */ + #endif /* HAVE_AES_OFB */ + + #ifdef HAVE_AES_XTS + #ifdef WOLFSSL_AES_128 + const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_xts(void) + { + WOLFSSL_ENTER("wolfSSL_EVP_aes_128_xts"); + if (EVP_AES_128_XTS == NULL) + wolfSSL_EVP_init(); + return EVP_AES_128_XTS; + } + #endif /* WOLFSSL_AES_128 */ + + #ifdef WOLFSSL_AES_256 + const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_xts(void) + { + WOLFSSL_ENTER("wolfSSL_EVP_aes_256_xts"); + if (EVP_AES_256_XTS == NULL) + wolfSSL_EVP_init(); + return EVP_AES_256_XTS; + } + #endif /* WOLFSSL_AES_256 */ + #endif /* HAVE_AES_XTS */ + #ifdef HAVE_AESGCM #ifdef WOLFSSL_AES_128 const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_gcm(void) @@ -27922,15 +28232,13 @@ void wolfSSL_AES_cfb128_encrypt(const unsigned char *in, unsigned char* out, #ifndef NO_FILESYSTEM /* returns amount printed on success, negative in fail case */ -int wolfSSL_BIO_printf(WOLFSSL_BIO* bio, const char* format, ...) +int wolfSSL_BIO_vprintf(WOLFSSL_BIO* bio, const char* format, va_list args) { int ret = -1; - va_list args; if (bio == NULL) return WOLFSSL_FATAL_ERROR; - va_start(args, format); switch (bio->type) { case WOLFSSL_BIO_FILE: if (bio->ptr == NULL) @@ -27971,10 +28279,24 @@ int wolfSSL_BIO_printf(WOLFSSL_BIO* bio, const char* format, ...) WOLFSSL_MSG("Unsupported WOLFSSL_BIO type for wolfSSL_BIO_printf"); break; } + + return ret; +} + +/* returns amount printed on success, negative in fail case */ +int wolfSSL_BIO_printf(WOLFSSL_BIO* bio, const char* format, ...) +{ + int ret; + va_list args; + va_start(args, format); + + ret = wolfSSL_BIO_vprintf(bio, format, args); + va_end(args); return ret; } + #endif #if !defined(NO_FILESYSTEM) && defined(__clang__) @@ -48608,6 +48930,16 @@ void wolfSSL_BIO_clear_retry_flags(WOLFSSL_BIO* bio) bio->flags &= ~(WOLFSSL_BIO_FLAG_READ|WOLFSSL_BIO_FLAG_RETRY); } +int wolfSSL_BIO_should_retry(WOLFSSL_BIO *bio) +{ + int ret = 0; + if (bio != NULL) { + ret = (int)(bio->flags & WOLFSSL_BIO_FLAG_RETRY); + } + + return ret; +} + /* DER data is PKCS#8 encrypted. */ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PKCS8PrivateKey_bio(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY** pkey, diff --git a/wolfssl/openssl/bio.h b/wolfssl/openssl/bio.h index 3e0d4beb6..01911df1b 100644 --- a/wolfssl/openssl/bio.h +++ b/wolfssl/openssl/bio.h @@ -52,8 +52,8 @@ #define BIO_s_bio wolfSSL_BIO_s_bio #define BIO_s_socket wolfSSL_BIO_s_socket #define BIO_set_fd wolfSSL_BIO_set_fd +#define BIO_set_close wolfSSL_BIO_set_close #define BIO_ctrl_reset_read_request wolfSSL_BIO_ctrl_reset_read_request - #define BIO_set_write_buf_size wolfSSL_BIO_set_write_buf_size #define BIO_make_bio_pair wolfSSL_BIO_make_bio_pair @@ -68,7 +68,7 @@ #define BIO_gets wolfSSL_BIO_gets #define BIO_puts wolfSSL_BIO_puts -#define BIO_should_retry(...) 1 +#define BIO_should_retry wolfSSL_BIO_should_retry #define BIO_TYPE_FILE WOLFSSL_BIO_FILE #define BIO_TYPE_BIO WOLFSSL_BIO_BIO diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index bdb765c04..6d270386a 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -94,6 +94,32 @@ WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_cbc(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_cbc(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_cbc(void); #endif +#ifndef NO_AES +#ifdef HAVE_AES_CFB1 +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_cfb1(void); +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_cfb1(void); +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_cfb1(void); +#endif +#ifdef HAVE_AES_CFB8 +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_cfb8(void); +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_cfb8(void); +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_cfb8(void); +#endif +#ifdef HAVE_AES_CFB128 +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_cfb128(void); +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_cfb128(void); +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_cfb128(void); +#endif +#ifdef HAVE_AES_OFB +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_ofb(void); +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_ofb(void); +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_ofb(void); +#endif +#ifdef HAVE_AES_XTS +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_xts(void); +WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_xts(void); +#endif +#endif /* NO_AES */ #if !defined(NO_AES) && defined(HAVE_AESGCM) WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_gcm(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_gcm(void); @@ -571,6 +597,20 @@ typedef WOLFSSL_EVP_CIPHER_CTX EVP_CIPHER_CTX; #define EVP_aes_128_cbc wolfSSL_EVP_aes_128_cbc #define EVP_aes_192_cbc wolfSSL_EVP_aes_192_cbc #define EVP_aes_256_cbc wolfSSL_EVP_aes_256_cbc +#define EVP_aes_128_cfb1 wolfSSL_EVP_aes_128_cfb1 +#define EVP_aes_192_cfb1 wolfSSL_EVP_aes_192_cfb1 +#define EVP_aes_256_cfb1 wolfSSL_EVP_aes_256_cfb1 +#define EVP_aes_128_cfb8 wolfSSL_EVP_aes_128_cfb8 +#define EVP_aes_192_cfb8 wolfSSL_EVP_aes_192_cfb8 +#define EVP_aes_256_cfb8 wolfSSL_EVP_aes_256_cfb8 +#define EVP_aes_128_cfb128 wolfSSL_EVP_aes_128_cfb128 +#define EVP_aes_192_cfb128 wolfSSL_EVP_aes_192_cfb128 +#define EVP_aes_256_cfb128 wolfSSL_EVP_aes_256_cfb128 +#define EVP_aes_128_ofb wolfSSL_EVP_aes_128_ofb +#define EVP_aes_192_ofb wolfSSL_EVP_aes_192_ofb +#define EVP_aes_256_ofb wolfSSL_EVP_aes_256_ofb +#define EVP_aes_128_xts wolfSSL_EVP_aes_128_xts +#define EVP_aes_256_xts wolfSSL_EVP_aes_256_xts #define EVP_aes_128_gcm wolfSSL_EVP_aes_128_gcm #define EVP_aes_192_gcm wolfSSL_EVP_aes_192_gcm #define EVP_aes_256_gcm wolfSSL_EVP_aes_256_gcm diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 2937e5608..67ec1368e 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -348,6 +348,7 @@ struct WOLFSSL_EVP_PKEY { #endif }; typedef struct WOLFSSL_EVP_PKEY WOLFSSL_PKCS8_PRIV_KEY_INFO; +typedef struct WOLFSSL_EVP_MD_CTX WOLFSSL_EVP_MD_CTX; #ifndef WOLFSSL_EVP_TYPE_DEFINED /* guard on redeclaration */ typedef struct WOLFSSL_EVP_PKEY WOLFSSL_EVP_PKEY; @@ -396,7 +397,8 @@ enum BIO_TYPE { WOLFSSL_BIO_MEMORY = 4, WOLFSSL_BIO_BIO = 5, WOLFSSL_BIO_FILE = 6, - WOLFSSL_BIO_BASE64 = 7 + WOLFSSL_BIO_BASE64 = 7, + WOLFSSL_BIO_MD = 8 }; enum BIO_FLAGS { @@ -463,7 +465,7 @@ struct WOLFSSL_BIO { WOLFSSL_BIO* next; /* next in chain */ WOLFSSL_BIO* pair; /* BIO paired with */ void* heap; /* user heap hint */ - void* ptr; /* WOLFSSL, file descriptor or memory buffer */ + void* ptr; /* WOLFSSL, file descriptor, MD, or mem buf */ void* usrCtx; /* user set pointer */ char* infoArg; /* BIO callback argument */ wolf_bio_info_cb infoCb; /* BIO callback */ @@ -1191,6 +1193,10 @@ WOLFSSL_API wolf_bio_info_cb wolfSSL_BIO_get_callback(WOLFSSL_BIO *bio); WOLFSSL_API void wolfSSL_BIO_set_callback_arg(WOLFSSL_BIO *bio, char *arg); WOLFSSL_API char* wolfSSL_BIO_get_callback_arg(const WOLFSSL_BIO *bio); +WOLFSSL_API WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_md(void); +WOLFSSL_API int wolfSSL_BIO_get_md_ctx(WOLFSSL_BIO *bio, + WOLFSSL_EVP_MD_CTX **mdcp); + WOLFSSL_API WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_buffer(void); WOLFSSL_API long wolfSSL_BIO_set_write_buffer_size(WOLFSSL_BIO*, long size); WOLFSSL_API WOLFSSL_BIO_METHOD* wolfSSL_BIO_f_ssl(void); @@ -1213,6 +1219,7 @@ WOLFSSL_API void* wolfSSL_BIO_get_data(WOLFSSL_BIO*); WOLFSSL_API void wolfSSL_BIO_set_shutdown(WOLFSSL_BIO*, int); WOLFSSL_API int wolfSSL_BIO_get_shutdown(WOLFSSL_BIO*); WOLFSSL_API void wolfSSL_BIO_clear_retry_flags(WOLFSSL_BIO*); +WOLFSSL_API int wolfSSL_BIO_should_retry(WOLFSSL_BIO *bio); WOLFSSL_API WOLFSSL_BIO_METHOD *wolfSSL_BIO_meth_new(int, const char*); WOLFSSL_API void wolfSSL_BIO_meth_free(WOLFSSL_BIO_METHOD*); @@ -1229,6 +1236,7 @@ WOLFSSL_API long wolfSSL_BIO_set_ssl(WOLFSSL_BIO*, WOLFSSL*, int flag); #ifndef NO_FILESYSTEM WOLFSSL_API long wolfSSL_BIO_set_fd(WOLFSSL_BIO* b, int fd, int flag); #endif +WOLFSSL_API int wolfSSL_BIO_set_close(WOLFSSL_BIO *b, long flag); WOLFSSL_API void wolfSSL_set_bio(WOLFSSL*, WOLFSSL_BIO* rd, WOLFSSL_BIO* wr); #ifndef NO_FILESYSTEM @@ -1999,6 +2007,8 @@ WOLFSSL_API int wolfSSL_want(WOLFSSL*); WOLFSSL_API int wolfSSL_want_read(WOLFSSL*); WOLFSSL_API int wolfSSL_want_write(WOLFSSL*); +WOLFSSL_API int wolfSSL_BIO_vprintf(WOLFSSL_BIO* bio, const char* format, + va_list args); WOLFSSL_API int wolfSSL_BIO_printf(WOLFSSL_BIO*, const char*, ...); WOLFSSL_API int wolfSSL_BIO_dump(WOLFSSL_BIO *bio, const char*, int); WOLFSSL_API int wolfSSL_ASN1_UTCTIME_print(WOLFSSL_BIO*, From 0abc81479292f898feed5626052f087f1fb639dc Mon Sep 17 00:00:00 2001 From: Eric Blankenhorn Date: Thu, 9 Jan 2020 13:21:14 -0600 Subject: [PATCH 110/649] EVP_MD_CTX_reset and EVP_aes fixes --- src/ssl.c | 138 +++++++++++++++++++++++++++++++++--------- wolfcrypt/src/evp.c | 20 ++++++ wolfssl/openssl/evp.h | 106 ++++++++++++++++++++------------ 3 files changed, 196 insertions(+), 68 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index b08c6be6d..0128073bb 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -3807,6 +3807,54 @@ static const struct cipher{ #ifdef WOLFSSL_AES_256 {AES_256_CBC_TYPE, "AES-256-CBC", NID_aes_256_cbc}, #endif + + #ifdef WOLFSSL_AES_128 + {AES_128_CFB1_TYPE, "AES-128-CFB1", NID_aes_128_cfb1}, + #endif + #ifdef WOLFSSL_AES_192 + {AES_192_CFB1_TYPE, "AES-192-CFB1", NID_aes_192_cfb1}, + #endif + #ifdef WOLFSSL_AES_256 + {AES_256_CFB1_TYPE, "AES-256-CFB1", NID_aes_256_cfb1}, + #endif + + #ifdef WOLFSSL_AES_128 + {AES_128_CFB8_TYPE, "AES-128-CFB8", NID_aes_128_cfb8}, + #endif + #ifdef WOLFSSL_AES_192 + {AES_192_CFB8_TYPE, "AES-192-CFB8", NID_aes_192_cfb8}, + #endif + #ifdef WOLFSSL_AES_256 + {AES_256_CFB8_TYPE, "AES-256-CFB8", NID_aes_256_cfb8}, + #endif + + #ifdef WOLFSSL_AES_128 + {AES_128_CFB128_TYPE, "AES-128-CFB128", NID_aes_128_cfb128}, + #endif + #ifdef WOLFSSL_AES_192 + {AES_192_CFB128_TYPE, "AES-192-CFB128", NID_aes_192_cfb128}, + #endif + #ifdef WOLFSSL_AES_256 + {AES_256_CFB128_TYPE, "AES-256-CFB128", NID_aes_256_cfb128}, + #endif + + #ifdef WOLFSSL_AES_128 + {AES_128_OFB_TYPE, "AES-128-OFB", NID_aes_128_ofb}, + #endif + #ifdef WOLFSSL_AES_192 + {AES_192_OFB_TYPE, "AES-192-OFB", NID_aes_192_ofb}, + #endif + #ifdef WOLFSSL_AES_256 + {AES_256_OFB_TYPE, "AES-256-OFB", NID_aes_256_ofb}, + #endif + + #ifdef WOLFSSL_AES_128 + {AES_128_XTS_TYPE, "AES-128-XTS", NID_aes_128_xts}, + #endif + #ifdef WOLFSSL_AES_256 + {AES_256_XTS_TYPE, "AES-256-XTS", NID_aes_256_xts}, + #endif + #if defined(OPENSSL_EXTRA) #ifdef WOLFSSL_AES_128 {AES_128_GCM_TYPE, "AES-128-GCM", NID_aes_128_gcm}, @@ -4074,7 +4122,7 @@ const WOLFSSL_EVP_CIPHER *wolfSSL_EVP_get_cipherbynid(int id) #endif #endif /* HAVE_AES_CBC */ - #ifdef HAVE_AES_OFB + #ifdef WOLFSSL_AES_OFB #ifdef WOLFSSL_AES_128 static char *EVP_AES_128_OFB; #endif @@ -4084,18 +4132,18 @@ const WOLFSSL_EVP_CIPHER *wolfSSL_EVP_get_cipherbynid(int id) #ifdef WOLFSSL_AES_256 static char *EVP_AES_256_OFB; #endif - #endif /* HAVE_AES_OFB */ + #endif /* WOLFSSL_AES_OFB */ - #ifdef HAVE_AES_XTS + #ifdef WOLFSSL_AES_XTS #ifdef WOLFSSL_AES_128 static char *EVP_AES_128_XTS; #endif #ifdef WOLFSSL_AES_256 static char *EVP_AES_256_XTS; #endif - #endif /* HAVE_AES_XTS */ + #endif /* WOLFSSL_AES_XTS */ - #ifdef HAVE_AES_CFB1 + #ifdef WOLFSSL_AES_CFB #ifdef WOLFSSL_AES_128 static char *EVP_AES_128_CFB1; #endif @@ -4105,9 +4153,7 @@ const WOLFSSL_EVP_CIPHER *wolfSSL_EVP_get_cipherbynid(int id) #ifdef WOLFSSL_AES_256 static char *EVP_AES_256_CFB1; #endif - #endif /* HAVE_AES_CFB1 */ - #ifdef HAVE_AES_CFB8 #ifdef WOLFSSL_AES_128 static char *EVP_AES_128_CFB8; #endif @@ -4117,9 +4163,7 @@ const WOLFSSL_EVP_CIPHER *wolfSSL_EVP_get_cipherbynid(int id) #ifdef WOLFSSL_AES_256 static char *EVP_AES_256_CFB8; #endif - #endif /* HAVE_AES_CFB8 */ - #ifdef HAVE_AES_CFB128 #ifdef WOLFSSL_AES_128 static char *EVP_AES_128_CFB128; #endif @@ -4129,7 +4173,7 @@ const WOLFSSL_EVP_CIPHER *wolfSSL_EVP_get_cipherbynid(int id) #ifdef WOLFSSL_AES_256 static char *EVP_AES_256_CFB128; #endif - #endif /* HAVE_AES_CFB128 */ + #endif /* WOLFSSL_AES_CFB */ #if defined(OPENSSL_EXTRA) #ifdef HAVE_AESGCM @@ -4202,7 +4246,7 @@ void wolfSSL_EVP_init(void) #endif #endif /* HAVE_AES_CBC */ - #ifdef HAVE_AES_CFB1 + #ifdef WOLFSSL_AES_CFB #ifdef WOLFSSL_AES_128 EVP_AES_128_CFB1 = (char *)EVP_get_cipherbyname("AES-128-CFB1"); #endif @@ -4214,9 +4258,7 @@ void wolfSSL_EVP_init(void) #ifdef WOLFSSL_AES_256 EVP_AES_256_CFB1 = (char *)EVP_get_cipherbyname("AES-256-CFB1"); #endif - #endif /* HAVE_AES_CFB1 */ - #ifdef HAVE_AES_CFB8 #ifdef WOLFSSL_AES_128 EVP_AES_128_CFB8 = (char *)EVP_get_cipherbyname("AES-128-CFB8"); #endif @@ -4228,9 +4270,7 @@ void wolfSSL_EVP_init(void) #ifdef WOLFSSL_AES_256 EVP_AES_256_CFB8 = (char *)EVP_get_cipherbyname("AES-256-CFB8"); #endif - #endif /* HAVE_AES_CFB8 */ - #ifdef HAVE_AES_CFB12828 #ifdef WOLFSSL_AES_128 EVP_AES_128_CFB128 = (char *)EVP_get_cipherbyname("AES-128-CFB128"); #endif @@ -4242,9 +4282,9 @@ void wolfSSL_EVP_init(void) #ifdef WOLFSSL_AES_256 EVP_AES_256_CFB128 = (char *)EVP_get_cipherbyname("AES-256-CFB128"); #endif - #endif /* HAVE_AES_CFB128 */ + #endif /* WOLFSSL_AES_CFB */ - #ifdef HAVE_AES_OFB + #ifdef WOLFSSL_AES_OFB #ifdef WOLFSSL_AES_128 EVP_AES_128_OFB = (char *)EVP_get_cipherbyname("AES-128-OFB"); #endif @@ -4256,9 +4296,9 @@ void wolfSSL_EVP_init(void) #ifdef WOLFSSL_AES_256 EVP_AES_256_OFB = (char *)EVP_get_cipherbyname("AES-256-OFB"); #endif - #endif /* HAVE_AES_OFB */ + #endif /* WOLFSSL_AES_OFB */ - #ifdef HAVE_AES_XTS + #ifdef WOLFSSL_AES_XTS #ifdef WOLFSSL_AES_128 EVP_AES_128_XTS = (char *)EVP_get_cipherbyname("AES-128-XTS"); #endif @@ -4266,7 +4306,7 @@ void wolfSSL_EVP_init(void) #ifdef WOLFSSL_AES_256 EVP_AES_256_XTS = (char *)EVP_get_cipherbyname("AES-256-XTS"); #endif - #endif /* HAVE_AES_XTS */ + #endif /* WOLFSSL_AES_XTS */ #if defined(OPENSSL_EXTRA) #ifdef HAVE_AESGCM @@ -16487,7 +16527,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) #endif /* WOLFSSL_AES_256 */ #endif /* HAVE_AES_CBC */ - #ifdef HAVE_AES_CFB1 + #ifdef WOLFSSL_AES_CFB #ifdef WOLFSSL_AES_128 const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_cfb1(void) { @@ -16517,9 +16557,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) return EVP_AES_256_CFB1; } #endif /* WOLFSSL_AES_256 */ - #endif /* HAVE_AES_CFB1 */ - #ifdef HAVE_AES_CFB8 #ifdef WOLFSSL_AES_128 const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_cfb8(void) { @@ -16549,9 +16587,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) return EVP_AES_256_CFB8; } #endif /* WOLFSSL_AES_256 */ - #endif /* HAVE_AES_CFB8 */ - #ifdef HAVE_AES_CFB12828 #ifdef WOLFSSL_AES_128 const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_cfb128(void) { @@ -16581,9 +16617,9 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) return EVP_AES_256_CFB128; } #endif /* WOLFSSL_AES_256 */ - #endif /* HAVE_AES_CFB128 */ + #endif /* WOLFSSL_AES_CFB */ - #ifdef HAVE_AES_OFB + #ifdef WOLFSSL_AES_OFB #ifdef WOLFSSL_AES_128 const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_ofb(void) { @@ -16613,9 +16649,9 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) return EVP_AES_256_OFB; } #endif /* WOLFSSL_AES_256 */ - #endif /* HAVE_AES_OFB */ + #endif /* WOLFSSL_AES_OFB */ - #ifdef HAVE_AES_XTS + #ifdef WOLFSSL_AES_XTS #ifdef WOLFSSL_AES_128 const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_xts(void) { @@ -16635,7 +16671,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) return EVP_AES_256_XTS; } #endif /* WOLFSSL_AES_256 */ - #endif /* HAVE_AES_XTS */ + #endif /* WOLFSSL_AES_XTS */ #ifdef HAVE_AESGCM #ifdef WOLFSSL_AES_128 @@ -17606,6 +17642,48 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ret = wc_AesCbcDecrypt(&ctx->cipher.aes, dst, src, len); break; #endif /* HAVE_AES_CBC */ + +#ifdef WOLFSSL_AES_CFB + case AES_128_CFB1_TYPE: + case AES_192_CFB1_TYPE: + case AES_256_CFB1_TYPE: + case AES_128_CFB8_TYPE: + case AES_192_CFB8_TYPE: + case AES_256_CFB8_TYPE: + case AES_128_CFB128_TYPE: + case AES_192_CFB128_TYPE: + case AES_256_CFB128_TYPE: + WOLFSSL_MSG("AES CFB"); + if (ctx->enc) + ret = wc_AesCfbEncrypt(&ctx->cipher.aes, dst, src, len); + else + ret = wc_AesCfbDecrypt(&ctx->cipher.aes, dst, src, len); + break; +#endif /* WOLFSSL_AES_CFB */ +#if defined(WOLFSSL_AES_OFB) + case AES_128_OFB_TYPE: + case AES_192_OFB_TYPE: + case AES_256_OFB_TYPE: + WOLFSSL_MSG("AES OFB"); + if (ctx->enc) + ret = wc_AesOfbEncrypt(&ctx->cipher.aes, dst, src, len); + else + ret = wc_AesOfbDecrypt(&ctx->cipher.aes, dst, src, len); + break; +#endif /* WOLFSSL_AES_OFB */ +#if defined(WOLFSSL_AES_XTS) + case AES_128_XTS_TYPE: + case AES_256_XTS_TYPE: + WOLFSSL_MSG("AES XTS"); + if (ctx->enc) + ret = wc_AesXtsEncrypt(&ctx->cipher.xts, dst, src, len, + ctx->cipher.tweak, ctx->cipher.tweakSz); + else + ret = wc_AesXtsDecrypt(&ctx->cipher.xts, dst, src, len, + ctx->cipher.tweak, ctx->cipher.tweakSz); + break; +#endif /* WOLFSSL_AES_XTS */ + #ifdef HAVE_AESGCM case AES_128_GCM_TYPE : case AES_192_GCM_TYPE : diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index b4ec5efab..cdf9bf712 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -54,6 +54,26 @@ int wolfSSL_EVP_Cipher_key_length(const WOLFSSL_EVP_CIPHER* c) case AES_192_CBC_TYPE: return 24; case AES_256_CBC_TYPE: return 32; #endif + #if defined(WOLFSSL_AES_CFB) + case AES_128_CFB1_TYPE: return 16; + case AES_192_CFB1_TYPE: return 24; + case AES_256_CFB1_TYPE: return 32; + case AES_128_CFB8_TYPE: return 16; + case AES_192_CFB8_TYPE: return 24; + case AES_256_CFB8_TYPE: return 32; + case AES_128_CFB128_TYPE: return 16; + case AES_192_CFB128_TYPE: return 24; + case AES_256_CFB128_TYPE: return 32; + #endif + #if defined(WOLFSSL_AES_OFB) + case AES_128_OFB_TYPE: return 16; + case AES_192_OFB_TYPE: return 24; + case AES_256_OFB_TYPE: return 32; + #endif + #if defined(WOLFSSL_AES_XTS) + case AES_128_XTS_TYPE: return 16; + case AES_256_XTS_TYPE: return 32; + #endif #if defined(HAVE_AESGCM) case AES_128_GCM_TYPE: return 16; case AES_192_GCM_TYPE: return 24; diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index 6d270386a..c0af83456 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -95,27 +95,23 @@ WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_cbc(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_cbc(void); #endif #ifndef NO_AES -#ifdef HAVE_AES_CFB1 +#ifdef WOLFSSL_AES_CFB WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_cfb1(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_cfb1(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_cfb1(void); -#endif -#ifdef HAVE_AES_CFB8 WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_cfb8(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_cfb8(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_cfb8(void); -#endif -#ifdef HAVE_AES_CFB128 WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_cfb128(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_cfb128(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_cfb128(void); #endif -#ifdef HAVE_AES_OFB +#ifdef WOLFSSL_AES_OFB WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_ofb(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_ofb(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_ofb(void); #endif -#ifdef HAVE_AES_XTS +#ifdef WOLFSSL_AES_XTS WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_xts(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_xts(void); #endif @@ -179,6 +175,11 @@ typedef struct WOLFSSL_EVP_MD_CTX { typedef union { #ifndef NO_AES Aes aes; +#ifdef WOLFSSL_AES_XTS + XtsAes xts; + byte* tweak; + word32 tweakSz; +#endif #endif #ifndef NO_DES3 Des des; @@ -226,7 +227,21 @@ enum { NID_hmac = 855, NID_dhKeyAgreement= 28, EVP_PKEY_DH = NID_dhKeyAgreement, - EVP_PKEY_HMAC = NID_hmac + EVP_PKEY_HMAC = NID_hmac, + AES_128_CFB1_TYPE = 24, + AES_192_CFB1_TYPE = 25, + AES_256_CFB1_TYPE = 26, + AES_128_CFB8_TYPE = 27, + AES_192_CFB8_TYPE = 28, + AES_256_CFB8_TYPE = 29, + AES_128_CFB128_TYPE = 30, + AES_192_CFB128_TYPE = 31, + AES_256_CFB128_TYPE = 32, + AES_128_OFB_TYPE = 33, + AES_192_OFB_TYPE = 34, + AES_256_OFB_TYPE = 35, + AES_128_XTS_TYPE = 36, + AES_256_XTS_TYPE = 37 }; enum { @@ -267,6 +282,20 @@ enum { NID_des_ede3_cbc= 44, NID_des_ede3_ecb= 33, NID_idea_cbc = 34, + NID_aes_128_cfb1= 650, + NID_aes_192_cfb1= 651, + NID_aes_256_cfb1= 652, + NID_aes_128_cfb8= 653, + NID_aes_192_cfb8= 654, + NID_aes_256_cfb8= 655, + NID_aes_128_cfb128 = 421, + NID_aes_192_cfb128 = 425, + NID_aes_256_cfb128 = 429, + NID_aes_128_ofb = 420, + NID_aes_192_ofb = 424, + NID_aes_256_ofb = 428, + NID_aes_128_xts = 913, + NID_aes_256_xts = 914 }; #define WOLFSSL_EVP_BUF_SIZE 16 @@ -594,39 +623,39 @@ typedef WOLFSSL_EVP_CIPHER_CTX EVP_CIPHER_CTX; #define EVP_sha512 wolfSSL_EVP_sha512 #define EVP_ripemd160 wolfSSL_EVP_ripemd160 -#define EVP_aes_128_cbc wolfSSL_EVP_aes_128_cbc -#define EVP_aes_192_cbc wolfSSL_EVP_aes_192_cbc -#define EVP_aes_256_cbc wolfSSL_EVP_aes_256_cbc -#define EVP_aes_128_cfb1 wolfSSL_EVP_aes_128_cfb1 -#define EVP_aes_192_cfb1 wolfSSL_EVP_aes_192_cfb1 -#define EVP_aes_256_cfb1 wolfSSL_EVP_aes_256_cfb1 -#define EVP_aes_128_cfb8 wolfSSL_EVP_aes_128_cfb8 -#define EVP_aes_192_cfb8 wolfSSL_EVP_aes_192_cfb8 -#define EVP_aes_256_cfb8 wolfSSL_EVP_aes_256_cfb8 +#define EVP_aes_128_cbc wolfSSL_EVP_aes_128_cbc +#define EVP_aes_192_cbc wolfSSL_EVP_aes_192_cbc +#define EVP_aes_256_cbc wolfSSL_EVP_aes_256_cbc +#define EVP_aes_128_cfb1 wolfSSL_EVP_aes_128_cfb1 +#define EVP_aes_192_cfb1 wolfSSL_EVP_aes_192_cfb1 +#define EVP_aes_256_cfb1 wolfSSL_EVP_aes_256_cfb1 +#define EVP_aes_128_cfb8 wolfSSL_EVP_aes_128_cfb8 +#define EVP_aes_192_cfb8 wolfSSL_EVP_aes_192_cfb8 +#define EVP_aes_256_cfb8 wolfSSL_EVP_aes_256_cfb8 #define EVP_aes_128_cfb128 wolfSSL_EVP_aes_128_cfb128 #define EVP_aes_192_cfb128 wolfSSL_EVP_aes_192_cfb128 #define EVP_aes_256_cfb128 wolfSSL_EVP_aes_256_cfb128 -#define EVP_aes_128_ofb wolfSSL_EVP_aes_128_ofb -#define EVP_aes_192_ofb wolfSSL_EVP_aes_192_ofb -#define EVP_aes_256_ofb wolfSSL_EVP_aes_256_ofb -#define EVP_aes_128_xts wolfSSL_EVP_aes_128_xts -#define EVP_aes_256_xts wolfSSL_EVP_aes_256_xts -#define EVP_aes_128_gcm wolfSSL_EVP_aes_128_gcm -#define EVP_aes_192_gcm wolfSSL_EVP_aes_192_gcm -#define EVP_aes_256_gcm wolfSSL_EVP_aes_256_gcm -#define EVP_aes_128_ecb wolfSSL_EVP_aes_128_ecb -#define EVP_aes_192_ecb wolfSSL_EVP_aes_192_ecb -#define EVP_aes_256_ecb wolfSSL_EVP_aes_256_ecb -#define EVP_aes_128_ctr wolfSSL_EVP_aes_128_ctr -#define EVP_aes_192_ctr wolfSSL_EVP_aes_192_ctr -#define EVP_aes_256_ctr wolfSSL_EVP_aes_256_ctr -#define EVP_des_cbc wolfSSL_EVP_des_cbc -#define EVP_des_ecb wolfSSL_EVP_des_ecb -#define EVP_des_ede3_cbc wolfSSL_EVP_des_ede3_cbc -#define EVP_des_ede3_ecb wolfSSL_EVP_des_ede3_ecb -#define EVP_rc4 wolfSSL_EVP_rc4 -#define EVP_idea_cbc wolfSSL_EVP_idea_cbc -#define EVP_enc_null wolfSSL_EVP_enc_null +#define EVP_aes_128_ofb wolfSSL_EVP_aes_128_ofb +#define EVP_aes_192_ofb wolfSSL_EVP_aes_192_ofb +#define EVP_aes_256_ofb wolfSSL_EVP_aes_256_ofb +#define EVP_aes_128_xts wolfSSL_EVP_aes_128_xts +#define EVP_aes_256_xts wolfSSL_EVP_aes_256_xts +#define EVP_aes_128_gcm wolfSSL_EVP_aes_128_gcm +#define EVP_aes_192_gcm wolfSSL_EVP_aes_192_gcm +#define EVP_aes_256_gcm wolfSSL_EVP_aes_256_gcm +#define EVP_aes_128_ecb wolfSSL_EVP_aes_128_ecb +#define EVP_aes_192_ecb wolfSSL_EVP_aes_192_ecb +#define EVP_aes_256_ecb wolfSSL_EVP_aes_256_ecb +#define EVP_aes_128_ctr wolfSSL_EVP_aes_128_ctr +#define EVP_aes_192_ctr wolfSSL_EVP_aes_192_ctr +#define EVP_aes_256_ctr wolfSSL_EVP_aes_256_ctr +#define EVP_des_cbc wolfSSL_EVP_des_cbc +#define EVP_des_ecb wolfSSL_EVP_des_ecb +#define EVP_des_ede3_cbc wolfSSL_EVP_des_ede3_cbc +#define EVP_des_ede3_ecb wolfSSL_EVP_des_ede3_ecb +#define EVP_rc4 wolfSSL_EVP_rc4 +#define EVP_idea_cbc wolfSSL_EVP_idea_cbc +#define EVP_enc_null wolfSSL_EVP_enc_null #define EVP_MD_size wolfSSL_EVP_MD_size #define EVP_MD_CTX_new wolfSSL_EVP_MD_CTX_new @@ -635,6 +664,7 @@ typedef WOLFSSL_EVP_CIPHER_CTX EVP_CIPHER_CTX; #define EVP_MD_CTX_destroy wolfSSL_EVP_MD_CTX_free #define EVP_MD_CTX_init wolfSSL_EVP_MD_CTX_init #define EVP_MD_CTX_cleanup wolfSSL_EVP_MD_CTX_cleanup +#define EVP_MD_CTX_reset wolfSSL_EVP_MD_CTX_cleanup #define EVP_MD_CTX_md wolfSSL_EVP_MD_CTX_md #define EVP_MD_CTX_type wolfSSL_EVP_MD_CTX_type #define EVP_MD_CTX_size wolfSSL_EVP_MD_CTX_size From 8f7af875a45324dcdd7f4a73c541dda0c714c15f Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Wed, 15 Jan 2020 14:10:34 -0700 Subject: [PATCH 111/649] add BIO_f_md and BIO_get_md_ctx tests --- tests/api.c | 94 +++++++++++++++++++++++++++++++++++++++++++ wolfssl/openssl/ssl.h | 2 + 2 files changed, 96 insertions(+) diff --git a/tests/api.c b/tests/api.c index 79ceab8ea..85e1128b8 100644 --- a/tests/api.c +++ b/tests/api.c @@ -24021,6 +24021,99 @@ static void test_wolfSSL_BIO_printf(void) #endif } +static void test_wolfSSL_BIO_f_md(void) +{ +/* tests not passing */ +#if 0 + #if defined(OPENSSL_ALL) && !defined(NO_SHA256) + BIO *bio, *mem; + char msg[] = "message to hash"; + char out[60]; + EVP_MD_CTX* ctx; + const unsigned char testKey[] = + { + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b + }; + const char testData[] = "Hi There"; + const unsigned char testResult[] = + { + 0xb0, 0x34, 0x4c, 0x61, 0xd8, 0xdb, 0x38, 0x53, + 0x5c, 0xa8, 0xaf, 0xce, 0xaf, 0x0b, 0xf1, 0x2b, + 0x88, 0x1d, 0xc2, 0x00, 0xc9, 0x83, 0x3d, 0xa7, + 0x26, 0xe9, 0x37, 0x6c, 0x2e, 0x32, 0xcf, 0xf7 + }; + const unsigned char expectedHash[] = + { + 0x66, 0x49, 0x3C, 0xE8, 0x8A, 0x57, 0xB0, 0x60, + 0xDC, 0x55, 0x7D, 0xFC, 0x1F, 0xA5, 0xE5, 0x07, + 0x70, 0x5A, 0xF6, 0xD7, 0xC4, 0x1F, 0x1A, 0xE4, + 0x2D, 0xA6, 0xFD, 0xD1, 0x29, 0x7D, 0x60, 0x0D + }; + unsigned char check[sizeof(testResult) + 1]; + size_t checkSz = -1; + EVP_PKEY* key; + + printf(testingFmt, "wolfSSL_BIO_f_md()"); + + XMEMSET(out, 0, sizeof(out)); + AssertNotNull(bio = BIO_new(BIO_f_md())); + AssertNotNull(mem = BIO_new(BIO_s_mem())); + + AssertIntEQ(BIO_get_md_ctx(bio, &ctx), 1); + AssertIntEQ(EVP_DigestInit(ctx, EVP_sha256()), 1); + + /* should not be able to write/read yet since just digest wrapper */ + AssertIntEQ(BIO_write(bio, msg, sizeof(msg)), 0); + AssertIntEQ(BIO_pending(bio), 0); + AssertIntEQ(BIO_read(bio, out, sizeof(out)), 0); + + /* append BIO mem to bio in order to read/write */ + AssertNotNull(bio = BIO_push(bio, mem)); + + XMEMSET(out, 0, sizeof(out)); + AssertIntEQ(BIO_write(mem, msg, sizeof(msg)), 16); + AssertIntEQ(BIO_pending(bio), 16); + + /* this just reads the message and does not hash it (gets calls final) */ + AssertIntEQ(BIO_read(bio, out, sizeof(out)), 16); + AssertIntEQ(XMEMCMP(out, msg, sizeof(msg)), 0); + + /* create a message digest using BIO */ + XMEMSET(out, 0, sizeof(out)); + AssertIntEQ(BIO_write(bio, msg, sizeof(msg)), 16); + AssertIntEQ(BIO_pending(mem), 16); + AssertIntEQ(BIO_pending(bio), 16); + AssertIntEQ(BIO_gets(bio, out, sizeof(out)), 32); + AssertIntEQ(XMEMCMP(expectedHash, out, 32), 0); + BIO_free(bio); + BIO_free(mem); + + /* test with HMAC */ + XMEMSET(out, 0, sizeof(out)); + AssertNotNull(bio = BIO_new(BIO_f_md())); + AssertNotNull(mem = BIO_new(BIO_s_mem())); + BIO_get_md_ctx(bio, &ctx); + AssertNotNull(key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, + testKey, (int)sizeof(testKey))); + EVP_DigestSignInit(ctx, NULL, EVP_sha256(), NULL, key); + AssertNotNull(bio = BIO_push(bio, mem)); + BIO_write(bio, testData, strlen(testData)); + EVP_DigestSignFinal(ctx, NULL, &checkSz); + EVP_DigestSignFinal(ctx, check, &checkSz); + + AssertIntEQ(XMEMCMP(check, testResult, sizeof(testResult)), 0); + + BIO_free(bio); + BIO_free(mem); + + printf(resultFmt, passed); + #endif +#endif +} + + static void test_wolfSSL_SESSION(void) { #if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \ @@ -30478,6 +30571,7 @@ void ApiTest(void) test_wolfSSL_d2i_PUBKEY(); test_wolfSSL_BIO_write(); test_wolfSSL_BIO_printf(); + test_wolfSSL_BIO_f_md(); test_wolfSSL_SESSION(); test_wolfSSL_DES_ecb_encrypt(); test_wolfSSL_sk_GENERAL_NAME(); diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 9feb76ea9..6edf2543d 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -603,6 +603,8 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define BIO_eof wolfSSL_BIO_eof #define BIO_set_ss wolfSSL_BIO_set_ss +#define BIO_f_md wolfSSL_BIO_f_md +#define BIO_get_md_ctx wolfSSL_BIO_get_md_ctx #define BIO_s_mem wolfSSL_BIO_s_mem #define BIO_f_base64 wolfSSL_BIO_f_base64 #define BIO_set_flags wolfSSL_BIO_set_flags From 62f20db48e3bb3399de17d807f49c122ea7ef3e3 Mon Sep 17 00:00:00 2001 From: Eric Blankenhorn Date: Wed, 15 Jan 2020 15:32:58 -0600 Subject: [PATCH 112/649] Adding more EVP and SSL API --- wolfcrypt/src/evp.c | 31 ++++++++++++++++++++++--------- wolfssl/openssl/evp.h | 2 ++ wolfssl/openssl/ssl.h | 1 + 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index cdf9bf712..16f733e5d 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -143,22 +143,35 @@ int wolfSSL_EVP_DecryptInit_ex(WOLFSSL_EVP_CIPHER_CTX* ctx, WOLFSSL_EVP_CIPHER_CTX *wolfSSL_EVP_CIPHER_CTX_new(void) { - WOLFSSL_EVP_CIPHER_CTX *ctx = (WOLFSSL_EVP_CIPHER_CTX*)XMALLOC(sizeof *ctx, + WOLFSSL_EVP_CIPHER_CTX *ctx = (WOLFSSL_EVP_CIPHER_CTX*)XMALLOC(sizeof *ctx, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (ctx) { - WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_new"); - wolfSSL_EVP_CIPHER_CTX_init(ctx); - } - return ctx; + if (ctx) { + WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_new"); + wolfSSL_EVP_CIPHER_CTX_init(ctx); + } + return ctx; } void wolfSSL_EVP_CIPHER_CTX_free(WOLFSSL_EVP_CIPHER_CTX *ctx) { if (ctx) { WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_free"); - wolfSSL_EVP_CIPHER_CTX_cleanup(ctx); - XFREE(ctx, NULL, DYNAMIC_TYPE_TMP_BUFFER); - } + wolfSSL_EVP_CIPHER_CTX_cleanup(ctx); + XFREE(ctx, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } +} + +int wolfSSL_EVP_CIPHER_CTX_reset(WOLFSSL_EVP_CIPHER_CTX *ctx) +{ + int ret = WOLFSSL_FAILURE; + + if (ctx != NULL) { + WOLFSSL_ENTER("wolfSSL_EVP_CIPHER_CTX_reset"); + wolfSSL_EVP_CIPHER_CTX_cleanup(ctx); + ret = WOLFSSL_SUCCESS; + } + + return ret; } unsigned long wolfSSL_EVP_CIPHER_CTX_mode(const WOLFSSL_EVP_CIPHER_CTX *ctx) diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index c0af83456..b8d61d257 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -462,6 +462,7 @@ WOLFSSL_API int wolfSSL_EVP_DecryptFinal_legacy(WOLFSSL_EVP_CIPHER_CTX *ctx, WOLFSSL_API WOLFSSL_EVP_CIPHER_CTX *wolfSSL_EVP_CIPHER_CTX_new(void); WOLFSSL_API void wolfSSL_EVP_CIPHER_CTX_free(WOLFSSL_EVP_CIPHER_CTX *ctx); +WOLFSSL_API int wolfSSL_EVP_CIPHER_CTX_reset(WOLFSSL_EVP_CIPHER_CTX *ctx); WOLFSSL_API int wolfSSL_EVP_CIPHER_CTX_key_length(WOLFSSL_EVP_CIPHER_CTX* ctx); WOLFSSL_API int wolfSSL_EVP_CIPHER_CTX_set_key_length(WOLFSSL_EVP_CIPHER_CTX* ctx, int keylen); @@ -718,6 +719,7 @@ typedef WOLFSSL_EVP_CIPHER_CTX EVP_CIPHER_CTX; #define EVP_DecryptFinal_ex wolfSSL_EVP_CipherFinal #define EVP_CIPHER_CTX_free wolfSSL_EVP_CIPHER_CTX_free +#define EVP_CIPHER_CTX_reset wolfSSL_EVP_CIPHER_CTX_reset #define EVP_CIPHER_CTX_new wolfSSL_EVP_CIPHER_CTX_new #define EVP_get_cipherbynid wolfSSL_EVP_get_cipherbynid diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 6edf2543d..e4940687d 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -287,6 +287,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define SSL_pending wolfSSL_pending #define SSL_load_error_strings wolfSSL_load_error_strings #define SSL_library_init wolfSSL_library_init +#define OpenSSL_add_ssl_algorithms wolfSSL_library_init #define SSL_CTX_set_session_cache_mode wolfSSL_CTX_set_session_cache_mode #define SSL_CTX_set_cipher_list wolfSSL_CTX_set_cipher_list #define SSL_CTX_set_ciphersuites wolfSSL_CTX_set_cipher_list From 3137312911269ab29084700ba92ec1968f5458e3 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Wed, 15 Jan 2020 16:20:02 -0700 Subject: [PATCH 113/649] update to implementation of BIO_MD type --- src/bio.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/ssl.c | 19 ++++++++++-- tests/api.c | 19 +++++++++--- 3 files changed, 119 insertions(+), 8 deletions(-) diff --git a/src/bio.c b/src/bio.c index 1f00af782..b7c6c5fe2 100644 --- a/src/bio.c +++ b/src/bio.c @@ -154,6 +154,23 @@ static int wolfSSL_BIO_SSL_read(WOLFSSL_BIO* bio, void* buf, } #endif /* WOLFCRYPT_ONLY */ +static int wolfSSL_BIO_MD_read(WOLFSSL_BIO* bio, void* buf, int sz) +{ + int ret = sz; + + if (wolfSSL_EVP_MD_CTX_type(bio->ptr) == (NID_hmac & 0xFF)) { + if (wolfSSL_EVP_DigestSignUpdate(bio->ptr, buf, sz) != WOLFSSL_SUCCESS) + { + ret = WOLFSSL_FATAL_ERROR; + } + } + else { + if (wolfSSL_EVP_DigestUpdate(bio->ptr, buf, ret) != WOLFSSL_SUCCESS) { + ret = WOLFSSL_FATAL_ERROR; + } + } + return ret; +} /* Used to read data from a WOLFSSL_BIO structure @@ -218,6 +235,11 @@ int wolfSSL_BIO_read(WOLFSSL_BIO* bio, void* buf, int len) } #endif + /* data passing through BIO MD wrapper */ + if (bio && bio->type == WOLFSSL_BIO_MD && ret > 0) { + ret = wolfSSL_BIO_MD_read(bio, buf, ret); + } + /* case where front of list is done */ if (bio == front) { break; /* at front of list so be done */ @@ -423,6 +445,33 @@ static int wolfSSL_BIO_MEMORY_write(WOLFSSL_BIO* bio, const void* data, } +/* Helper function for writing to a WOLFSSL_BIO_MD type + * + * returns the amount written in bytes on success (0) + */ +static int wolfSSL_BIO_MD_write(WOLFSSL_BIO* bio, const void* data, int len) +{ + int ret = 0; + + if (bio == NULL || data == NULL) { + return BAD_FUNC_ARG; + } + + if (wolfSSL_EVP_MD_CTX_type(bio->ptr) == (NID_hmac & 0xFF)) { + if (wolfSSL_EVP_DigestSignUpdate(bio->ptr, data, len) != + WOLFSSL_SUCCESS) { + ret = WOLFSSL_BIO_ERROR; + } + } + else { + if (wolfSSL_EVP_DigestUpdate(bio->ptr, data, len) != WOLFSSL_SUCCESS) { + ret = WOLFSSL_BIO_ERROR; + } + } + return ret; +} + + /* Writes data to a WOLFSSL_BIO structure * * bio structure to write to @@ -536,6 +585,12 @@ int wolfSSL_BIO_write(WOLFSSL_BIO* bio, const void* data, int len) } #endif /* WOLFCRYPT_ONLY */ + if (bio && bio->type == WOLFSSL_BIO_MD) { + if (bio->next != NULL) { /* data passing through MD BIO */ + ret = wolfSSL_BIO_MD_write(bio, data, len); + } + } + /* advance to the next bio in list */ bio = bio->next; } @@ -740,6 +795,22 @@ int wolfSSL_BIO_gets(WOLFSSL_BIO* bio, char* buf, int sz) break; } + /* call final on hash */ + case WOLFSSL_BIO_MD: + if (wolfSSL_EVP_MD_CTX_size(bio->ptr) > sz) { + WOLFSSL_MSG("Output buffer was too small for digest"); + ret = WOLFSSL_FAILURE; + } + else { + unsigned int szOut = 0; + ret = wolfSSL_EVP_DigestFinal(bio->ptr, (unsigned char*)buf, + &szOut); + if (ret == WOLFSSL_SUCCESS) { + ret = szOut; + } + } + break; + default: WOLFSSL_MSG("BIO type not supported yet with wolfSSL_BIO_gets"); } @@ -855,6 +926,16 @@ size_t wolfSSL_BIO_ctrl_pending(WOLFSSL_BIO *bio) return 0; } + if (bio->type == WOLFSSL_BIO_MD) { + /* MD is a wrapper only get next bio */ + while (bio->next != NULL) { + bio = bio->next; + if (bio->type != WOLFSSL_BIO_MD) { + break; + } + } + } + #ifndef WOLFCRYPT_ONLY if (bio->type == WOLFSSL_BIO_SSL && bio->ptr != NULL) { return (long)wolfSSL_pending((WOLFSSL*)bio->ptr); @@ -1205,6 +1286,14 @@ int wolfSSL_BIO_reset(WOLFSSL_BIO *bio) } return 0; + case WOLFSSL_BIO_MD: + if (bio->ptr != NULL) { + const WOLFSSL_EVP_MD* md = wolfSSL_EVP_MD_CTX_md(bio->ptr); + wolfSSL_EVP_MD_CTX_init(bio->ptr); + wolfSSL_EVP_DigestInit(bio->ptr, md); + } + return 0; + default: WOLFSSL_MSG("Unknown BIO type needs added to reset function"); } diff --git a/src/ssl.c b/src/ssl.c index 0128073bb..727a1dbcc 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -15162,8 +15162,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) if ((bio != NULL) && (mdcp != NULL)) { *mdcp = bio->ptr; - - /* TODO: reset bio */ + ret = WOLFSSL_SUCCESS; } return ret; @@ -15318,7 +15317,8 @@ int wolfSSL_set_compression(WOLFSSL* ssl) bio->shutdown = BIO_CLOSE; /* default to close things */ bio->init = 1; if (method->type != WOLFSSL_BIO_FILE && - method->type != WOLFSSL_BIO_SOCKET) { + method->type != WOLFSSL_BIO_SOCKET && + method->type != WOLFSSL_BIO_MD) { bio->mem_buf =(WOLFSSL_BUF_MEM*)XMALLOC(sizeof(WOLFSSL_BUF_MEM), 0, DYNAMIC_TYPE_OPENSSL); if (bio->mem_buf == NULL) { @@ -15329,6 +15329,15 @@ int wolfSSL_set_compression(WOLFSSL* ssl) bio->mem_buf->data = (char*)bio->ptr; } + if (method->type == WOLFSSL_BIO_MD) { + bio->ptr = wolfSSL_EVP_MD_CTX_new(); + if (bio->ptr == NULL) { + WOLFSSL_MSG("Memory error"); + wolfSSL_BIO_free(bio); + return NULL; + } + } + /* check if is custom method */ if (method->createCb) { method->createCb(bio); @@ -15433,6 +15442,10 @@ int wolfSSL_set_compression(WOLFSSL* ssl) } } + if (bio->type == WOLFSSL_BIO_MD) { + wolfSSL_EVP_MD_CTX_free(bio->ptr); + } + XFREE(bio, 0, DYNAMIC_TYPE_OPENSSL); } return 1; diff --git a/tests/api.c b/tests/api.c index 85e1128b8..139cbf93e 100644 --- a/tests/api.c +++ b/tests/api.c @@ -24023,8 +24023,6 @@ static void test_wolfSSL_BIO_printf(void) static void test_wolfSSL_BIO_f_md(void) { -/* tests not passing */ -#if 0 #if defined(OPENSSL_ALL) && !defined(NO_SHA256) BIO *bio, *mem; char msg[] = "message to hash"; @@ -24051,6 +24049,13 @@ static void test_wolfSSL_BIO_f_md(void) 0x70, 0x5A, 0xF6, 0xD7, 0xC4, 0x1F, 0x1A, 0xE4, 0x2D, 0xA6, 0xFD, 0xD1, 0x29, 0x7D, 0x60, 0x0D }; + const unsigned char emptyHash[] = + { + 0xE3, 0xB0, 0xC4, 0x42, 0x98, 0xFC, 0x1C, 0x14, + 0x9A, 0xFB, 0xF4, 0xC8, 0x99, 0x6F, 0xB9, 0x24, + 0x27, 0xAE, 0x41, 0xE4, 0x64, 0x9B, 0x93, 0x4C, + 0xA4, 0x95, 0x99, 0x1B, 0x78, 0x52, 0xB8, 0x55 + }; unsigned char check[sizeof(testResult) + 1]; size_t checkSz = -1; EVP_PKEY* key; @@ -24064,10 +24069,15 @@ static void test_wolfSSL_BIO_f_md(void) AssertIntEQ(BIO_get_md_ctx(bio, &ctx), 1); AssertIntEQ(EVP_DigestInit(ctx, EVP_sha256()), 1); - /* should not be able to write/read yet since just digest wrapper */ - AssertIntEQ(BIO_write(bio, msg, sizeof(msg)), 0); + /* should not be able to write/read yet since just digest wrapper and no + * data is passing through the bio */ + AssertIntEQ(BIO_write(bio, msg, 0), 0); AssertIntEQ(BIO_pending(bio), 0); AssertIntEQ(BIO_read(bio, out, sizeof(out)), 0); + AssertIntEQ(BIO_gets(bio, out, 3), 0); + AssertIntEQ(BIO_gets(bio, out, sizeof(out)), 32); + AssertIntEQ(XMEMCMP(emptyHash, out, 32), 0); + BIO_reset(bio); /* append BIO mem to bio in order to read/write */ AssertNotNull(bio = BIO_push(bio, mem)); @@ -24110,7 +24120,6 @@ static void test_wolfSSL_BIO_f_md(void) printf(resultFmt, passed); #endif -#endif } From 65732c22695402b88881f57d6d935671173a9ac1 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Fri, 17 Jan 2020 16:40:03 -0700 Subject: [PATCH 114/649] add bio retry and set close tests --- src/bio.c | 14 ++++++-- tests/api.c | 102 +++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 113 insertions(+), 3 deletions(-) diff --git a/src/bio.c b/src/bio.c index b7c6c5fe2..2158ff39c 100644 --- a/src/bio.c +++ b/src/bio.c @@ -141,13 +141,18 @@ static int wolfSSL_BIO_SSL_read(WOLFSSL_BIO* bio, void* buf, if ((front == NULL) || front->eof) return WOLFSSL_FATAL_ERROR; + bio->flags &= ~(WOLFSSL_BIO_FLAG_RETRY); /* default no retry */ ret = wolfSSL_read((WOLFSSL*)bio->ptr, buf, len); if (ret == 0) front->eof = 1; else if (ret < 0) { int err = wolfSSL_get_error((WOLFSSL*)bio->ptr, 0); - if ( !(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) ) + if ( !(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) ) { front->eof = 1; + } + else { + bio->flags |= WOLFSSL_BIO_FLAG_RETRY; /* should retry */ + } } return ret; @@ -335,13 +340,18 @@ static int wolfSSL_BIO_SSL_write(WOLFSSL_BIO* bio, const void* data, return BAD_FUNC_ARG; } + bio->flags &= ~(WOLFSSL_BIO_FLAG_RETRY); /* default no retry */ ret = wolfSSL_write((WOLFSSL*)bio->ptr, data, len); if (ret == 0) front->eof = 1; else if (ret < 0) { int err = wolfSSL_get_error((WOLFSSL*)bio->ptr, 0); - if ( !(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) ) + if ( !(err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) ) { front->eof = 1; + } + else { + bio->flags |= WOLFSSL_BIO_FLAG_RETRY; /* should retry */ + } } return ret; } diff --git a/tests/api.c b/tests/api.c index 139cbf93e..fd93059e2 100644 --- a/tests/api.c +++ b/tests/api.c @@ -22065,7 +22065,9 @@ static void test_wolfSSL_PEM_read_bio(void) AssertNull(x509 = PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL)); AssertNotNull(bio = BIO_new_mem_buf((void*)buff, bytes)); AssertNotNull(x509 = PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL)); - AssertIntEQ((int)BIO_set_fd(bio, 0, BIO_NOCLOSE), 1); + AssertIntEQ((int)BIO_set_fd(bio, 0, BIO_CLOSE), 1); + AssertIntEQ(BIO_set_close(bio, BIO_NOCLOSE), 1); + AssertIntEQ(BIO_set_close(NULL, BIO_NOCLOSE), 1); AssertIntEQ(SSL_SUCCESS, BIO_get_mem_ptr(bio, &buf)); BIO_free(bio); @@ -23923,6 +23925,103 @@ static void test_wolfSSL_BIO_puts(void) #endif } +#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \ + !defined(NO_RSA) && defined(HAVE_EXT_CACHE) && \ + defined(HAVE_IO_TESTS_DEPENDENCIES) +static int forceWantRead(WOLFSSL *ssl, char *buf, int sz, void *ctx) +{ + (void)ssl; + (void)buf; + (void)sz; + (void)ctx; + return WOLFSSL_CBIO_ERR_WANT_READ; +} +#endif + +static void test_wolfSSL_BIO_should_retry(void) +{ +#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \ + !defined(NO_RSA) && defined(HAVE_EXT_CACHE) && \ + defined(HAVE_IO_TESTS_DEPENDENCIES) + tcp_ready ready; + func_args server_args; + THREAD_TYPE serverThread; + SOCKET_T sockfd = 0; + WOLFSSL_CTX* ctx; + WOLFSSL* ssl; + char msg[64] = "hello wolfssl!"; + char reply[1024]; + int msgSz = (int)XSTRLEN(msg); + int ret; + BIO* bio; + + printf(testingFmt, "wolfSSL_BIO_should_retry()"); + + XMEMSET(&server_args, 0, sizeof(func_args)); +#ifdef WOLFSSL_TIRTOS + fdOpenSession(Task_self()); +#endif + + StartTCP(); + InitTcpReady(&ready); + +#if defined(USE_WINDOWS_API) + /* use RNG to get random port if using windows */ + ready.port = GetRandomPort(); +#endif + + server_args.signal = &ready; + start_thread(test_server_nofail, &server_args, &serverThread); + wait_tcp_ready(&server_args); + + + AssertNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method())); + AssertIntEQ(WOLFSSL_SUCCESS, + wolfSSL_CTX_load_verify_locations(ctx, caCertFile, 0)); + AssertIntEQ(WOLFSSL_SUCCESS, + wolfSSL_CTX_use_certificate_file(ctx, cliCertFile, SSL_FILETYPE_PEM)); + AssertIntEQ(WOLFSSL_SUCCESS, + wolfSSL_CTX_use_PrivateKey_file(ctx, cliKeyFile, SSL_FILETYPE_PEM)); + tcp_connect(&sockfd, wolfSSLIP, server_args.signal->port, 0, 0, NULL); + + /* force retry */ + AssertNotNull(ssl = wolfSSL_new(ctx)); + AssertIntEQ(wolfSSL_set_fd(ssl, sockfd), WOLFSSL_SUCCESS); + wolfSSL_SSLSetIORecv(ssl, forceWantRead); + + AssertNotNull(bio = BIO_new(BIO_f_ssl())); + BIO_set_ssl(bio, ssl, BIO_NOCLOSE); + + AssertIntLE(BIO_write(bio, msg, msgSz), 0); + AssertIntNE(BIO_should_retry(bio), 0); + + + /* now perform successful connection */ + wolfSSL_SSLSetIORecv(ssl, EmbedReceive); + AssertIntEQ(BIO_write(bio, msg, msgSz), msgSz); + BIO_read(bio, reply, sizeof(reply)); + ret = wolfSSL_get_error(ssl, -1); + if (ret == WOLFSSL_ERROR_WANT_READ || ret == WOLFSSL_ERROR_WANT_WRITE) { + AssertIntNE(BIO_should_retry(bio), 0); + } + else { + AssertIntEQ(BIO_should_retry(bio), 0); + } + AssertIntEQ(XMEMCMP(reply, "I hear you fa shizzle!", + XSTRLEN("I hear you fa shizzle!")), 0); + BIO_free(bio); + + join_thread(serverThread); + FreeTcpReady(&ready); + +#ifdef WOLFSSL_TIRTOS + fdOpenSession(Task_self()); +#endif + + printf(resultFmt, passed); +#endif +} + static void test_wolfSSL_BIO_write(void) { #if defined(OPENSSL_EXTRA) && defined(WOLFSSL_BASE64_ENCODE) @@ -30577,6 +30676,7 @@ void ApiTest(void) test_wolfSSL_X509_set_version(); test_wolfSSL_BIO_gets(); test_wolfSSL_BIO_puts(); + test_wolfSSL_BIO_should_retry(); test_wolfSSL_d2i_PUBKEY(); test_wolfSSL_BIO_write(); test_wolfSSL_BIO_printf(); From e83789457897877bf8f4c0587f7f31257281ba07 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Tue, 21 Jan 2020 15:51:12 -0800 Subject: [PATCH 115/649] add AES-OFB mode --- configure.ac | 14 +++ wolfcrypt/src/aes.c | 165 ++++++++++++++++++++++--- wolfcrypt/test/test.c | 258 ++++++++++++++++++++++++++++++++++++++++ wolfssl/wolfcrypt/aes.h | 18 ++- 4 files changed, 437 insertions(+), 18 deletions(-) diff --git a/configure.ac b/configure.ac index a6268fc51..ec7b35cd9 100644 --- a/configure.ac +++ b/configure.ac @@ -130,6 +130,7 @@ then enable_aesgcm=yes enable_aesccm=yes enable_aesctr=yes + enable_aesofb=yes enable_aescfb=yes enable_camellia=yes enable_ripemd=yes @@ -965,6 +966,19 @@ then fi +# AES-OFB +AC_ARG_ENABLE([aesofb], + [AS_HELP_STRING([--enable-aesofb],[Enable wolfSSL AES-OFB support (default: disabled)])], + [ ENABLED_AESOFB=$enableval ], + [ ENABLED_AESOFB=no ] + ) + +if test "$ENABLED_AESOFB" = "yes" +then + AM_CFLAGS="$AM_CFLAGS -DWOLFSSL_AES_OFB -DWOLFSSL_AES_DIRECT" +fi + + # AES-CFB AC_ARG_ENABLE([aescfb], [AS_HELP_STRING([--enable-aescfb],[Enable wolfSSL AES-CFB support (default: disabled)])], diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 2a968e246..61474ec13 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -1964,7 +1964,8 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) #if !defined(WOLFSSL_STM32_CUBEMX) || defined(STM32_HAL_V2) ByteReverseWords(rk, rk, keylen); #endif - #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER) + #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER) || \ + defined(WOLFSSL_AES_OFB) aes->left = 0; #endif @@ -2037,7 +2038,8 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) if (iv) XMEMCPY(aes->reg, iv, AES_BLOCK_SIZE); - #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER) + #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER) || \ + defined(WOLFSSL_AES_OFB) aes->left = 0; #endif @@ -2053,7 +2055,8 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) aes->rounds = keylen/4 + 6; XMEMCPY(aes->key, userKey, keylen); - #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER) + #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER) || \ + defined(WOLFSSL_AES_OFB) aes->left = 0; #endif @@ -2083,7 +2086,8 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) if (rk == NULL) return BAD_FUNC_ARG; - #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER) + #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER) || \ + defined(WOLFSSL_AES_OFB) aes->left = 0; #endif @@ -2150,7 +2154,8 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) aes->rounds = keylen/4 + 6; ret = nrf51_aes_set_key(userKey); - #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER) + #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER) || \ + defined(WOLFSSL_AES_OFB) aes->left = 0; #endif @@ -2288,7 +2293,8 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) #ifdef WOLFSSL_AESNI aes->use_aesni = 0; #endif /* WOLFSSL_AESNI */ - #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER) + #if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_COUNTER) || \ + defined(WOLFSSL_AES_OFB) aes->left = 0; #endif @@ -2497,7 +2503,8 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) checkAESNI = 1; } if (haveAESNI) { - #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) + #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \ + defined(WOLFSSL_AES_OFB) aes->left = 0; #endif /* WOLFSSL_AES_COUNTER */ aes->use_aesni = 1; @@ -7252,43 +7259,64 @@ int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) #endif #endif /* HAVE_AES_ECB */ -#ifdef WOLFSSL_AES_CFB -/* CFB 128 +#if defined(WOLFSSL_AES_CFB) || defined(WOLFSSL_AES_OFB) +/* Feedback AES mode * * aes structure holding key to use for encryption * out buffer to hold result of encryption (must be at least as large as input * buffer) * in buffer to encrypt * sz size of input buffer + * pre flag to xor after or before feedback. If 1 then add feedback before xor * * returns 0 on success and negative error values on failure */ /* Software AES - CFB Encrypt */ -int wc_AesCfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) +static int wc_AesFeedbackEncrypt(Aes* aes, byte* out, const byte* in, + word32 sz, byte mode) { byte* tmp = NULL; +#ifdef WOLFSSL_AES_CFB byte* reg = NULL; +#endif if (aes == NULL || out == NULL || in == NULL) { return BAD_FUNC_ARG; } +#ifdef WOLFSSL_AES_CFB if (aes->left && sz) { reg = (byte*)aes->reg + AES_BLOCK_SIZE - aes->left; } +#endif /* consume any unused bytes left in aes->tmp */ tmp = (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left; while (aes->left && sz) { - *(out++) = *(reg++) = *(in++) ^ *(tmp++); + *(out) = *(in++) ^ *(tmp++); + #ifdef WOLFSSL_AES_CFB + if (mode == AES_CFB_MODE) { + *(reg++) = *out; + } + #endif + out++; aes->left--; sz--; } while (sz >= AES_BLOCK_SIZE) { wc_AesEncryptDirect(aes, out, (byte*)aes->reg); + #ifdef WOLFSSL_AES_OFB + if (mode == AES_OFB_MODE) { + XMEMCPY(aes->reg, out, AES_BLOCK_SIZE); + } + #endif xorbuf(out, in, AES_BLOCK_SIZE); - XMEMCPY(aes->reg, out, AES_BLOCK_SIZE); + #ifdef WOLFSSL_AES_CFB + if (mode == AES_CFB_MODE) { + XMEMCPY(aes->reg, out, AES_BLOCK_SIZE); + } + #endif out += AES_BLOCK_SIZE; in += AES_BLOCK_SIZE; sz -= AES_BLOCK_SIZE; @@ -7300,10 +7328,23 @@ int wc_AesCfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg); aes->left = AES_BLOCK_SIZE; tmp = (byte*)aes->tmp; + #ifdef WOLFSSL_AES_OFB + if (mode == AES_OFB_MODE) { + XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE); + } + #endif + #ifdef WOLFSSL_AES_CFB reg = (byte*)aes->reg; + #endif while (sz--) { - *(out++) = *(reg++) = *(in++) ^ *(tmp++); + *(out) = *(in++) ^ *(tmp++); + #ifdef WOLFSSL_AES_CFB + if (mode == AES_CFB_MODE) { + *(reg++) = *out; + } + #endif + out++; aes->left--; } } @@ -7324,7 +7365,8 @@ int wc_AesCfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) * returns 0 on success and negative error values on failure */ /* Software AES - CFB Decrypt */ -int wc_AesCfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) +static int wc_AesFeedbackDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, + byte mode) { byte* tmp; @@ -7333,7 +7375,7 @@ int wc_AesCfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) } /* check if more input needs copied over to aes->reg */ - if (aes->left && sz) { + if (aes->left && sz && mode == AES_CFB_MODE) { int size = min(aes->left, sz); XMEMCPY((byte*)aes->reg + AES_BLOCK_SIZE - aes->left, in, size); } @@ -7348,8 +7390,17 @@ int wc_AesCfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) while (sz > AES_BLOCK_SIZE) { wc_AesEncryptDirect(aes, out, (byte*)aes->reg); + #ifdef WOLFSSL_AES_OFB + if (mode == AES_OFB_MODE) { + XMEMCPY(aes->reg, out, AES_BLOCK_SIZE); + } + #endif xorbuf(out, in, AES_BLOCK_SIZE); - XMEMCPY(aes->reg, in, AES_BLOCK_SIZE); + #ifdef WOLFSSL_AES_CFB + if (mode == AES_CFB_MODE) { + XMEMCPY(aes->reg, in, AES_BLOCK_SIZE); + } + #endif out += AES_BLOCK_SIZE; in += AES_BLOCK_SIZE; sz -= AES_BLOCK_SIZE; @@ -7359,7 +7410,13 @@ int wc_AesCfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) /* decrypt left over data */ if (sz) { wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg); - XMEMCPY(aes->reg, in, sz); + if (mode == AES_CFB_MODE) { + XMEMCPY(aes->reg, in, sz); + } + if (mode == AES_OFB_MODE) { + XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE); + } + aes->left = AES_BLOCK_SIZE; tmp = (byte*)aes->tmp; @@ -7374,6 +7431,80 @@ int wc_AesCfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) #endif /* HAVE_AES_DECRYPT */ #endif /* WOLFSSL_AES_CFB */ +#ifdef WOLFSSL_AES_CFB +/* CFB 128 + * + * aes structure holding key to use for encryption + * out buffer to hold result of encryption (must be at least as large as input + * buffer) + * in buffer to encrypt + * sz size of input buffer + * + * returns 0 on success and negative error values on failure + */ +/* Software AES - CFB Encrypt */ +int wc_AesCfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) +{ + return wc_AesFeedbackEncrypt(aes, out, in, sz, AES_CFB_MODE); +} + + +#ifdef HAVE_AES_DECRYPT +/* CFB 128 + * + * aes structure holding key to use for decryption + * out buffer to hold result of decryption (must be at least as large as input + * buffer) + * in buffer to decrypt + * sz size of input buffer + * + * returns 0 on success and negative error values on failure + */ +/* Software AES - CFB Decrypt */ +int wc_AesCfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) +{ + return wc_AesFeedbackDecrypt(aes, out, in, sz, AES_CFB_MODE); +} +#endif /* HAVE_AES_DECRYPT */ +#endif /* WOLFSSL_AES_CFB */ + +#ifdef WOLFSSL_AES_OFB +/* OFB + * + * aes structure holding key to use for encryption + * out buffer to hold result of encryption (must be at least as large as input + * buffer) + * in buffer to encrypt + * sz size of input buffer + * + * returns 0 on success and negative error values on failure + */ +/* Software AES - CFB Encrypt */ +int wc_AesOfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz) +{ + return wc_AesFeedbackEncrypt(aes, out, in, sz, AES_OFB_MODE); +} + + +#ifdef HAVE_AES_DECRYPT +/* OFB + * + * aes structure holding key to use for decryption + * out buffer to hold result of decryption (must be at least as large as input + * buffer) + * in buffer to decrypt + * sz size of input buffer + * + * returns 0 on success and negative error values on failure + */ +/* Software AES - OFB Decrypt */ +int wc_AesOfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) +{ + return wc_AesFeedbackDecrypt(aes, out, in, sz, AES_OFB_MODE); +} +#endif /* HAVE_AES_DECRYPT */ +#endif /* WOLFSSL_AES_CFB */ + #ifdef HAVE_AES_KEYWRAP diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index d0e28fbe5..1af133352 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -302,6 +302,7 @@ int des3_test(void); int aes_test(void); int aes192_test(void); int aes256_test(void); +int aesofb_test(void); int cmac_test(void); int poly1305_test(void); int aesgcm_test(void); @@ -865,6 +866,14 @@ initDefaultName(); else test_pass("AES256 test passed!\n"); #endif + +#ifdef WOLFSSL_AES_OFB + if ( (ret = aesofb_test()) != 0) + return err_sys("AES-OFB test failed!\n", ret); + else + test_pass("AESOFB test passed!\n"); +#endif + #ifdef HAVE_AESGCM #if !defined(WOLFSSL_AFALG) && !defined(WOLFSSL_DEVCRYPTO) if ( (ret = aesgcm_test()) != 0) @@ -5856,6 +5865,255 @@ int des3_test(void) } #endif /* WOLFSSL_AES_CFB */ +#ifdef WOLFSSL_AES_OFB + /* test vector from https://csrc.nist.gov/Projects/cryptographic-algorithm-validation-program/Block-Ciphers */ + int aesofb_test(void) + { + #ifdef WOLFSSL_AES_256 + const byte key1[] = + { + 0xc4,0xc7,0xfa,0xd6,0x53,0x5c,0xb8,0x71, + 0x4a,0x5c,0x40,0x77,0x9a,0x8b,0xa1,0xd2, + 0x53,0x3e,0x23,0xb4,0xb2,0x58,0x73,0x2a, + 0x5b,0x78,0x01,0xf4,0xe3,0x71,0xa7,0x94 + }; + const byte iv1[] = + { + 0x5e,0xb9,0x33,0x13,0xb8,0x71,0xff,0x16, + 0xb9,0x8a,0x9b,0xcb,0x43,0x33,0x0d,0x6f + }; + const byte plain1[] = + { + 0x6d,0x0b,0xb0,0x79,0x63,0x84,0x71,0xe9, + 0x39,0xd4,0x53,0x14,0x86,0xc1,0x4c,0x25, + 0x9a,0xee,0xc6,0xf3,0xc0,0x0d,0xfd,0xd6, + 0xc0,0x50,0xa8,0xba,0xa8,0x20,0xdb,0x71, + 0xcc,0x12,0x2c,0x4e,0x0c,0x17,0x15,0xef, + 0x55,0xf3,0x99,0x5a,0x6b,0xf0,0x2a,0x4c + }; + const byte cipher1[] = + { + 0x0f,0x54,0x61,0x71,0x59,0xd0,0x3f,0xfc, + 0x1b,0xfa,0xfb,0x60,0x29,0x30,0xd7,0x00, + 0xf4,0xa4,0xa8,0xe6,0xdd,0x93,0x94,0x46, + 0x64,0xd2,0x19,0xc4,0xc5,0x4d,0xde,0x1b, + 0x04,0x53,0xe1,0x73,0xf5,0x18,0x74,0xae, + 0xfd,0x64,0xa2,0xe1,0xe2,0x76,0x13,0xb0 + }; + #endif /* WOLFSSL_AES_256 */ + + + #ifdef WOLFSSL_AES_128 + const byte key2[] = + { + 0x10,0xa5,0x88,0x69,0xd7,0x4b,0xe5,0xa3, + 0x74,0xcf,0x86,0x7c,0xfb,0x47,0x38,0x59 + }; + const byte iv2[] = + { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + }; + const byte plain2[] = + { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + }; + const byte cipher2[] = + { + 0x6d,0x25,0x1e,0x69,0x44,0xb0,0x51,0xe0, + 0x4e,0xaa,0x6f,0xb4,0xdb,0xf7,0x84,0x65 + }; + #endif /* WOLFSSL_AES_128 */ + + + #ifdef WOLFSSL_AES_192 + const byte key3[] = { + 0xd0,0x77,0xa0,0x3b,0xd8,0xa3,0x89,0x73, + 0x92,0x8c,0xca,0xfe,0x4a,0x9d,0x2f,0x45, + 0x51,0x30,0xbd,0x0a,0xf5,0xae,0x46,0xa9 + }; + const byte iv3[] = + { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + }; + const byte cipher3[] = + { + 0xab,0xc7,0x86,0xfb,0x1e,0xdb,0x50,0x45, + 0x80,0xc4,0xd8,0x82,0xef,0x29,0xa0,0xc7 + }; + const byte plain3[] = + { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + }; + #endif /* WOLFSSL_AES_192 */ + + Aes enc; + byte cipher[AES_BLOCK_SIZE * 4]; + #ifdef HAVE_AES_DECRYPT + Aes dec; + byte plain [AES_BLOCK_SIZE * 4]; + #endif + int ret = 0; + +#ifdef WOLFSSL_AES_128 + /* 128 key size test */ + ret = wc_AesSetKey(&enc, key2, sizeof(key2), iv2, AES_ENCRYPTION); + if (ret != 0) + return -5000; + #ifdef HAVE_AES_DECRYPT + /* decrypt uses AES_ENCRYPTION */ + ret = wc_AesSetKey(&dec, key2, sizeof(key2), iv2, AES_ENCRYPTION); + if (ret != 0) + return -5001; + #endif + + XMEMSET(cipher, 0, sizeof(cipher)); + ret = wc_AesOfbEncrypt(&enc, cipher, plain2, AES_BLOCK_SIZE); + if (ret != 0) + return -5002; + + if (XMEMCMP(cipher, cipher2, AES_BLOCK_SIZE)) + return -5003; + + #ifdef HAVE_AES_DECRYPT + ret = wc_AesOfbDecrypt(&dec, plain, cipher2, AES_BLOCK_SIZE); + if (ret != 0) + return -5004; + + if (XMEMCMP(plain, plain2, AES_BLOCK_SIZE)) + return -5005; + #endif /* HAVE_AES_DECRYPT */ +#endif /* WOLFSSL_AES_128 */ + +#ifdef WOLFSSL_AES_192 + /* 192 key size test */ + ret = wc_AesSetKey(&enc, key3, sizeof(key3), iv3, AES_ENCRYPTION); + if (ret != 0) + return -5006; + #ifdef HAVE_AES_DECRYPT + /* decrypt uses AES_ENCRYPTION */ + ret = wc_AesSetKey(&dec, key3, sizeof(key3), iv3, AES_ENCRYPTION); + if (ret != 0) + return -5007; + #endif + + XMEMSET(cipher, 0, sizeof(cipher)); + ret = wc_AesOfbEncrypt(&enc, cipher, plain3, AES_BLOCK_SIZE); + if (ret != 0) + return -5008; + + if (XMEMCMP(cipher, cipher3, AES_BLOCK_SIZE)) + return -5009; + + #ifdef HAVE_AES_DECRYPT + ret = wc_AesOfbDecrypt(&dec, plain, cipher3, AES_BLOCK_SIZE); + if (ret != 0) + return -5010; + + if (XMEMCMP(plain, plain3, AES_BLOCK_SIZE)) + return -5011; + #endif /* HAVE_AES_DECRYPT */ +#endif /* WOLFSSL_AES_192 */ + +#ifdef WOLFSSL_AES_256 + /* 256 key size test */ + ret = wc_AesSetKey(&enc, key1, sizeof(key1), iv1, AES_ENCRYPTION); + if (ret != 0) + return -5012; + #ifdef HAVE_AES_DECRYPT + /* decrypt uses AES_ENCRYPTION */ + ret = wc_AesSetKey(&dec, key1, sizeof(key1), iv1, AES_ENCRYPTION); + if (ret != 0) + return -5013; + #endif + + XMEMSET(cipher, 0, sizeof(cipher)); + ret = wc_AesOfbEncrypt(&enc, cipher, plain1, AES_BLOCK_SIZE); + if (ret != 0) + return -5014; + + if (XMEMCMP(cipher, cipher1, AES_BLOCK_SIZE)) + return -5015; + + ret = wc_AesOfbEncrypt(&enc, cipher + AES_BLOCK_SIZE, + plain1 + AES_BLOCK_SIZE, AES_BLOCK_SIZE); + if (ret != 0) + return -5016; + + if (XMEMCMP(cipher + AES_BLOCK_SIZE, cipher1 + AES_BLOCK_SIZE, + AES_BLOCK_SIZE)) + return -5017; + + #ifdef HAVE_AES_DECRYPT + ret = wc_AesOfbDecrypt(&dec, plain, cipher1, AES_BLOCK_SIZE); + if (ret != 0) + return -5018; + + if (XMEMCMP(plain, plain1, AES_BLOCK_SIZE)) + return -5019; + + ret = wc_AesOfbDecrypt(&dec, plain + AES_BLOCK_SIZE, + cipher1 + AES_BLOCK_SIZE, AES_BLOCK_SIZE); + if (ret != 0) + return -5020; + + if (XMEMCMP(plain + AES_BLOCK_SIZE, plain1 + AES_BLOCK_SIZE, + AES_BLOCK_SIZE)) + return -5021; + #endif /* HAVE_AES_DECRYPT */ +#endif /* WOLFSSL_AES_256 */ + +#ifdef WOLFSSL_AES_256 + /* 256 key size test leftover support */ + ret = wc_AesSetKey(&enc, key1, sizeof(key1), iv1, AES_ENCRYPTION); + if (ret != 0) + return -5022; + #ifdef HAVE_AES_DECRYPT + /* decrypt uses AES_ENCRYPTION */ + ret = wc_AesSetKey(&dec, key1, sizeof(key1), iv1, AES_ENCRYPTION); + if (ret != 0) + return -5023; + #endif + + XMEMSET(cipher, 0, sizeof(cipher)); + ret = wc_AesOfbEncrypt(&enc, cipher, plain1, 3); + if (ret != 0) + return -5024; + + if (XMEMCMP(cipher, cipher1, 3)) + return -5025; + + ret = wc_AesOfbEncrypt(&enc, cipher + 3, plain1 + 3, AES_BLOCK_SIZE); + if (ret != 0) + return -5026; + + if (XMEMCMP(cipher + 3, cipher1 + 3, AES_BLOCK_SIZE)) + return -5027; + + #ifdef HAVE_AES_DECRYPT + ret = wc_AesOfbDecrypt(&dec, plain, cipher1, 6); + if (ret != 0) + return -5028; + + if (XMEMCMP(plain, plain1, 6)) + return -5029; + + ret = wc_AesOfbDecrypt(&dec, plain + 6, cipher1 + 6, AES_BLOCK_SIZE); + if (ret != 0) + return -5030; + + if (XMEMCMP(plain + 6, plain1 + 6, AES_BLOCK_SIZE)) + return -5031; + #endif /* HAVE_AES_DECRYPT */ +#endif /* WOLFSSL_AES_256 */ + return 0; + } +#endif /* WOLFSSL_AES_OFB */ + + static int aes_key_size_test(void) { int ret; diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index 5b5478bff..6204f5889 100644 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -130,6 +130,12 @@ enum { CCM_NONCE_MAX_SZ = 13, CTR_SZ = 4, AES_IV_FIXED_SZ = 4, +#ifdef WOLFSSL_AES_CFB + AES_CFB_MODE = 1, +#endif +#ifdef WOLFSSL_AES_OFB + AES_OFB_MODE = 2, +#endif #ifdef HAVE_PKCS11 AES_MAX_ID_LEN = 32, @@ -179,7 +185,8 @@ struct Aes { #ifdef WOLFSSL_ASYNC_CRYPT WC_ASYNC_DEV asyncDev; #endif /* WOLFSSL_ASYNC_CRYPT */ -#if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) +#if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \ + defined(WOLFSSL_AES_OFB) word32 left; /* unused bytes left from last call */ #endif #ifdef WOLFSSL_XILINX_CRYPT @@ -273,6 +280,15 @@ WOLFSSL_API int wc_AesCfbDecrypt(Aes* aes, byte* out, #endif /* HAVE_AES_DECRYPT */ #endif /* WOLFSSL_AES_CFB */ +#ifdef WOLFSSL_AES_OFB +WOLFSSL_API int wc_AesOfbEncrypt(Aes* aes, byte* out, + const byte* in, word32 sz); +#ifdef HAVE_AES_DECRYPT +WOLFSSL_API int wc_AesOfbDecrypt(Aes* aes, byte* out, + const byte* in, word32 sz); +#endif /* HAVE_AES_DECRYPT */ +#endif /* WOLFSSL_AES_OFB */ + #ifdef HAVE_AES_ECB WOLFSSL_API int wc_AesEcbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz); From df0d5f3b083240dd7bd2b7f965ef3e819b2ec3f4 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Fri, 24 Jan 2020 15:25:33 -0700 Subject: [PATCH 116/649] add EVP_aes_*_ofb implementation and tests, add support for inline with OFB --- src/ssl.c | 78 +++++++++++++++++++ wolfcrypt/src/aes.c | 24 ++++-- wolfcrypt/src/evp.c | 10 +++ wolfcrypt/test/test.c | 174 +++++++++++++++++++++++++++++++++++++++--- 4 files changed, 268 insertions(+), 18 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 727a1dbcc..c7ff328c3 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -17419,6 +17419,84 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) return ret; } #endif /* WOLFSSL_AES_256 */ + #ifdef WOLFSSL_AES_OFB + #ifdef WOLFSSL_AES_128 + if (ctx->cipherType == AES_128_OFB_TYPE || + (type && XSTRNCMP(type, EVP_AES_128_OFB, EVP_AES_SIZE) == 0)) { + WOLFSSL_MSG("EVP_AES_128_OFB"); + ctx->cipherType = AES_128_OFB_TYPE; + ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE; + ctx->flags |= WOLFSSL_EVP_CIPH_OFB_MODE; + ctx->keyLen = 16; + ctx->block_size = 1; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) { + ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv, + AES_ENCRYPTION, 0); + if (ret != 0) + return ret; + } + if (iv && key == NULL) { + ret = wc_AesSetIV(&ctx->cipher.aes, iv); + if (ret != 0) + return ret; + } + } + #endif /* WOLFSSL_AES_128 */ + #ifdef WOLFSSL_AES_192 + if (ctx->cipherType == AES_192_OFB_TYPE || + (type && XSTRNCMP(type, EVP_AES_192_OFB, EVP_AES_SIZE) == 0)) { + WOLFSSL_MSG("EVP_AES_192_OFB"); + ctx->cipherType = AES_192_OFB_TYPE; + ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE; + ctx->flags |= WOLFSSL_EVP_CIPH_OFB_MODE; + ctx->keyLen = 24; + ctx->block_size = 1; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) { + ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv, + AES_ENCRYPTION, 0); + if (ret != 0) + return ret; + } + if (iv && key == NULL) { + ret = wc_AesSetIV(&ctx->cipher.aes, iv); + if (ret != 0) + return ret; + } + } + #endif /* WOLFSSL_AES_192 */ + #ifdef WOLFSSL_AES_256 + if (ctx->cipherType == AES_256_OFB_TYPE || + (type && XSTRNCMP(type, EVP_AES_256_OFB, EVP_AES_SIZE) == 0)) { + WOLFSSL_MSG("EVP_AES_256_OFB"); + ctx->cipherType = AES_256_OFB_TYPE; + ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE; + ctx->flags |= WOLFSSL_EVP_CIPH_OFB_MODE; + ctx->keyLen = 32; + ctx->block_size = 1; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) { + ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv, + AES_ENCRYPTION, 0); + if (ret != 0){ + WOLFSSL_MSG("AesSetKey() failed"); + return ret; + } + } + if (iv && key == NULL) { + ret = wc_AesSetIV(&ctx->cipher.aes, iv); + if (ret != 0){ + WOLFSSL_MSG("wc_AesSetIV() failed"); + return ret; + } + } + } + #endif /* WOLFSSL_AES_256 */ + #endif /* HAVE_AES_CBC */ #endif /* NO_AES */ #ifndef NO_DES3 diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 61474ec13..3eb781f1f 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -7305,18 +7305,20 @@ static int wc_AesFeedbackEncrypt(Aes* aes, byte* out, const byte* in, } while (sz >= AES_BLOCK_SIZE) { - wc_AesEncryptDirect(aes, out, (byte*)aes->reg); + /* Using aes->tmp here for inline case i.e. in=out */ + wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg); #ifdef WOLFSSL_AES_OFB if (mode == AES_OFB_MODE) { - XMEMCPY(aes->reg, out, AES_BLOCK_SIZE); + XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE); } #endif - xorbuf(out, in, AES_BLOCK_SIZE); + xorbuf((byte*)aes->tmp, in, AES_BLOCK_SIZE); #ifdef WOLFSSL_AES_CFB if (mode == AES_CFB_MODE) { - XMEMCPY(aes->reg, out, AES_BLOCK_SIZE); + XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE); } #endif + XMEMCPY(out, aes->tmp, AES_BLOCK_SIZE); out += AES_BLOCK_SIZE; in += AES_BLOCK_SIZE; sz -= AES_BLOCK_SIZE; @@ -7374,11 +7376,13 @@ static int wc_AesFeedbackDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, return BAD_FUNC_ARG; } + #ifdef WOLFSSL_AES_CFB /* check if more input needs copied over to aes->reg */ if (aes->left && sz && mode == AES_CFB_MODE) { int size = min(aes->left, sz); XMEMCPY((byte*)aes->reg + AES_BLOCK_SIZE - aes->left, in, size); } + #endif /* consume any unused bytes left in aes->tmp */ tmp = (byte*)aes->tmp + AES_BLOCK_SIZE - aes->left; @@ -7389,18 +7393,20 @@ static int wc_AesFeedbackDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, } while (sz > AES_BLOCK_SIZE) { - wc_AesEncryptDirect(aes, out, (byte*)aes->reg); + /* Using aes->tmp here for inline case i.e. in=out */ + wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg); #ifdef WOLFSSL_AES_OFB if (mode == AES_OFB_MODE) { - XMEMCPY(aes->reg, out, AES_BLOCK_SIZE); + XMEMCPY((byte*)aes->reg, (byte*)aes->tmp, AES_BLOCK_SIZE); } #endif - xorbuf(out, in, AES_BLOCK_SIZE); + xorbuf((byte*)aes->tmp, in, AES_BLOCK_SIZE); #ifdef WOLFSSL_AES_CFB if (mode == AES_CFB_MODE) { XMEMCPY(aes->reg, in, AES_BLOCK_SIZE); } #endif + XMEMCPY(out, (byte*)aes->tmp, AES_BLOCK_SIZE); out += AES_BLOCK_SIZE; in += AES_BLOCK_SIZE; sz -= AES_BLOCK_SIZE; @@ -7410,12 +7416,16 @@ static int wc_AesFeedbackDecrypt(Aes* aes, byte* out, const byte* in, word32 sz, /* decrypt left over data */ if (sz) { wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg); + #ifdef WOLFSSL_AES_CFB if (mode == AES_CFB_MODE) { XMEMCPY(aes->reg, in, sz); } + #endif + #ifdef WOLFSSL_AES_OFB if (mode == AES_OFB_MODE) { XMEMCPY(aes->reg, aes->tmp, AES_BLOCK_SIZE); } + #endif aes->left = AES_BLOCK_SIZE; tmp = (byte*)aes->tmp; diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 16f733e5d..0d411e15c 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -347,6 +347,16 @@ static int evpCipherBlock(WOLFSSL_EVP_CIPHER_CTX *ctx, ret = wc_AesEcbDecrypt(&ctx->cipher.aes, out, in, inl); break; #endif + #if defined(WOLFSSL_AES_OFB) + case AES_128_OFB_TYPE: + case AES_192_OFB_TYPE: + case AES_256_OFB_TYPE: + if (ctx->enc) + ret = wc_AesOfbEncrypt(&ctx->cipher.aes, out, in, inl); + else + ret = wc_AesOfbDecrypt(&ctx->cipher.aes, out, in, inl); + break; + #endif #endif /* !NO_AES */ #ifndef NO_DES3 case DES_CBC_TYPE: diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 1af133352..7eacde33d 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -5866,6 +5866,77 @@ int des3_test(void) #endif /* WOLFSSL_AES_CFB */ #ifdef WOLFSSL_AES_OFB +#ifdef OPENSSL_EXTRA +/* pass in the function, key, iv, plain text and expected and this function + * tests that the encryption and decryption is successful */ +static int EVP_test(const WOLFSSL_EVP_CIPHER* type, const byte* key, + const byte* iv, const byte* plain, int plainSz, + const byte* expected, int expectedSz) +{ + EVP_CIPHER_CTX ctx; + int idx, ret = 0, cipherSz; + byte* cipher; + + cipher = (byte*)XMALLOC(plainSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (cipher == NULL) { + return -8000; + } + + + /* test encrypt */ + EVP_CIPHER_CTX_init(&ctx); + if (EVP_CipherInit(&ctx, type, key, iv, 1) == 0) { + ret = -8001; + goto EVP_TEST_END; + } + + if (EVP_CipherUpdate(&ctx, cipher, &idx, plain, plainSz) == 0) { + ret = -8002; + goto EVP_TEST_END; + } + + cipherSz = idx; + if (EVP_CipherFinal(&ctx, cipher + cipherSz, &idx) == 0) { + ret = -8003; + goto EVP_TEST_END; + } + cipherSz += idx; + + if (XMEMCMP(cipher, expected, expectedSz)) { + ret = -8004; + goto EVP_TEST_END; + } + + /* test decrypt */ + EVP_CIPHER_CTX_init(&ctx); + if (EVP_CipherInit(&ctx, type, key, iv, 0) == 0) { + ret = -8005; + goto EVP_TEST_END; + } + + if (EVP_CipherUpdate(&ctx, cipher, &idx, cipher, cipherSz) == 0) { + ret = -8006; + goto EVP_TEST_END; + } + + cipherSz = idx; + if (EVP_CipherFinal(&ctx, cipher + cipherSz, &idx) == 0) { + ret = -8007; + goto EVP_TEST_END; + } + cipherSz += idx; + + if ((plainSz != cipherSz) || XMEMCMP(plain, cipher, cipherSz)) { + ret = -8008; + goto EVP_TEST_END; + } + +EVP_TEST_END: + XFREE(cipher, NULL, DYNAMIC_TYPE_TMP_BUFFER); + return ret; +} +#endif /* OPENSSL_EXTRA */ + /* test vector from https://csrc.nist.gov/Projects/cryptographic-algorithm-validation-program/Block-Ciphers */ int aesofb_test(void) { @@ -5960,6 +6031,14 @@ int des3_test(void) #ifdef WOLFSSL_AES_128 /* 128 key size test */ + #ifdef OPENSSL_EXTRA + ret = EVP_test(EVP_aes_128_ofb(), key2, iv2, plain2, sizeof(plain2), + cipher2, sizeof(cipher2)); + if (ret != 0) { + return ret; + } + #endif + ret = wc_AesSetKey(&enc, key2, sizeof(key2), iv2, AES_ENCRYPTION); if (ret != 0) return -5000; @@ -5990,6 +6069,14 @@ int des3_test(void) #ifdef WOLFSSL_AES_192 /* 192 key size test */ + #ifdef OPENSSL_EXTRA + ret = EVP_test(EVP_aes_192_ofb(), key3, iv3, plain3, sizeof(plain3), + cipher3, sizeof(cipher3)); + if (ret != 0) { + return ret; + } + #endif + ret = wc_AesSetKey(&enc, key3, sizeof(key3), iv3, AES_ENCRYPTION); if (ret != 0) return -5006; @@ -6020,6 +6107,14 @@ int des3_test(void) #ifdef WOLFSSL_AES_256 /* 256 key size test */ + #ifdef OPENSSL_EXTRA + ret = EVP_test(EVP_aes_256_ofb(), key1, iv1, plain1, sizeof(plain1), + cipher1, sizeof(cipher1)); + if (ret != 0) { + return ret; + } + #endif + ret = wc_AesSetKey(&enc, key1, sizeof(key1), iv1, AES_ENCRYPTION); if (ret != 0) return -5012; @@ -6064,10 +6159,8 @@ int des3_test(void) AES_BLOCK_SIZE)) return -5021; #endif /* HAVE_AES_DECRYPT */ -#endif /* WOLFSSL_AES_256 */ -#ifdef WOLFSSL_AES_256 - /* 256 key size test leftover support */ + /* multiple blocks at once */ ret = wc_AesSetKey(&enc, key1, sizeof(key1), iv1, AES_ENCRYPTION); if (ret != 0) return -5022; @@ -6079,36 +6172,93 @@ int des3_test(void) #endif XMEMSET(cipher, 0, sizeof(cipher)); - ret = wc_AesOfbEncrypt(&enc, cipher, plain1, 3); + ret = wc_AesOfbEncrypt(&enc, cipher, plain1, AES_BLOCK_SIZE * 3); if (ret != 0) return -5024; - if (XMEMCMP(cipher, cipher1, 3)) + if (XMEMCMP(cipher, cipher1, AES_BLOCK_SIZE * 3)) return -5025; - ret = wc_AesOfbEncrypt(&enc, cipher + 3, plain1 + 3, AES_BLOCK_SIZE); + #ifdef HAVE_AES_DECRYPT + ret = wc_AesOfbDecrypt(&dec, plain, cipher1, AES_BLOCK_SIZE * 3); if (ret != 0) return -5026; - if (XMEMCMP(cipher + 3, cipher1 + 3, AES_BLOCK_SIZE)) + if (XMEMCMP(plain, plain1, AES_BLOCK_SIZE * 3)) return -5027; + #endif /* HAVE_AES_DECRYPT */ + + /* inline decrypt/encrypt*/ + ret = wc_AesSetKey(&enc, key1, sizeof(key1), iv1, AES_ENCRYPTION); + if (ret != 0) + return -5028; + #ifdef HAVE_AES_DECRYPT + /* decrypt uses AES_ENCRYPTION */ + ret = wc_AesSetKey(&dec, key1, sizeof(key1), iv1, AES_ENCRYPTION); + if (ret != 0) + return -5029; + #endif + + XMEMCPY(cipher, plain1, AES_BLOCK_SIZE * 2); + ret = wc_AesOfbEncrypt(&enc, cipher, cipher, AES_BLOCK_SIZE * 2); + if (ret != 0) + return -5030; + + if (XMEMCMP(cipher, cipher1, AES_BLOCK_SIZE * 2)) + return -5031; + + #ifdef HAVE_AES_DECRYPT + ret = wc_AesOfbDecrypt(&dec, cipher, cipher, AES_BLOCK_SIZE * 2); + if (ret != 0) + return -5032; + + if (XMEMCMP(cipher, plain1, AES_BLOCK_SIZE * 2)) + return -5033; + #endif /* HAVE_AES_DECRYPT */ + + /* 256 key size test leftover support */ + ret = wc_AesSetKey(&enc, key1, sizeof(key1), iv1, AES_ENCRYPTION); + if (ret != 0) + return -5034; + #ifdef HAVE_AES_DECRYPT + /* decrypt uses AES_ENCRYPTION */ + ret = wc_AesSetKey(&dec, key1, sizeof(key1), iv1, AES_ENCRYPTION); + if (ret != 0) + return -5035; + #endif + + XMEMSET(cipher, 0, sizeof(cipher)); + ret = wc_AesOfbEncrypt(&enc, cipher, plain1, 3); + if (ret != 0) + return -5036; + + if (XMEMCMP(cipher, cipher1, 3)) + return -5037; + + ret = wc_AesOfbEncrypt(&enc, cipher + 3, plain1 + 3, AES_BLOCK_SIZE); + if (ret != 0) + return -5038; + + if (XMEMCMP(cipher + 3, cipher1 + 3, AES_BLOCK_SIZE)) + return -5039; #ifdef HAVE_AES_DECRYPT ret = wc_AesOfbDecrypt(&dec, plain, cipher1, 6); if (ret != 0) - return -5028; + return -5040; if (XMEMCMP(plain, plain1, 6)) - return -5029; + return -5041; ret = wc_AesOfbDecrypt(&dec, plain + 6, cipher1 + 6, AES_BLOCK_SIZE); if (ret != 0) - return -5030; + return -5042; if (XMEMCMP(plain + 6, plain1 + 6, AES_BLOCK_SIZE)) - return -5031; + return -5043; #endif /* HAVE_AES_DECRYPT */ #endif /* WOLFSSL_AES_256 */ + return 0; } #endif /* WOLFSSL_AES_OFB */ @@ -14794,6 +14944,8 @@ static int openssl_aes_test(void) #endif /* WOLFSSL_AES_CFB && WOLFSSL_AES_128 */ return 0; } + + #endif /* !defined(NO_AES) && !defined(WOLFCRYPT_ONLY) */ int openssl_test(void) From ab491206521f72e70f79ee34be1554a7b20f61c1 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Fri, 24 Jan 2020 15:43:19 -0700 Subject: [PATCH 117/649] add aesofb benchmark --- wolfcrypt/benchmark/benchmark.c | 51 +++++++++++++++++++++++++++++++++ wolfcrypt/benchmark/benchmark.h | 1 + 2 files changed, 52 insertions(+) diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index d9c5cf81d..d1925ecd0 100755 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -223,6 +223,7 @@ #define BENCH_DES 0x00004000 #define BENCH_IDEA 0x00008000 #define BENCH_AES_CFB 0x00010000 +#define BENCH_AES_OFB 0x00020000 /* Digest algorithms. */ #define BENCH_MD5 0x00000001 #define BENCH_POLY1305 0x00000002 @@ -320,6 +321,9 @@ static const bench_alg bench_cipher_opt[] = { #ifdef WOLFSSL_AES_CFB { "-aes-cfb", BENCH_AES_CFB }, #endif +#ifdef WOLFSSL_AES_OFB + { "-aes-ofb", BENCH_AES_OFB }, +#endif #ifdef WOLFSSL_AES_COUNTER { "-aes-ctr", BENCH_AES_CTR }, #endif @@ -1443,6 +1447,10 @@ static void* benchmarks_do(void* args) if (bench_all || (bench_cipher_algs & BENCH_AES_CFB)) bench_aescfb(); #endif +#ifdef WOLFSSL_AES_OFB + if (bench_all || (bench_cipher_algs & BENCH_AES_OFB)) + bench_aesofb(); +#endif #ifdef WOLFSSL_AES_COUNTER if (bench_all || (bench_cipher_algs & BENCH_AES_CTR)) bench_aesctr(); @@ -2457,6 +2465,49 @@ void bench_aescfb(void) #endif /* WOLFSSL_AES_CFB */ +#ifdef WOLFSSL_AES_OFB +static void bench_aesofb_internal(const byte* key, word32 keySz, const byte* iv, + const char* label) +{ + Aes enc; + double start; + int i, ret, count; + + ret = wc_AesSetKey(&enc, key, keySz, iv, AES_ENCRYPTION); + if (ret != 0) { + printf("AesSetKey failed, ret = %d\n", ret); + return; + } + + bench_stats_start(&count, &start); + do { + for (i = 0; i < numBlocks; i++) { + if((ret = wc_AesOfbEncrypt(&enc, bench_plain, bench_cipher, + BENCH_SIZE)) != 0) { + printf("wc_AesCfbEncrypt failed, ret = %d\n", ret); + return; + } + } + count += i; + } while (bench_stats_sym_check(start)); + bench_stats_sym_finish(label, 0, count, bench_size, start, ret); +} + +void bench_aesofb(void) +{ +#ifdef WOLFSSL_AES_128 + bench_aesofb_internal(bench_key, 16, bench_iv, "AES-128-OFB"); +#endif +#ifdef WOLFSSL_AES_192 + bench_aesofb_internal(bench_key, 24, bench_iv, "AES-192-OFB"); +#endif +#ifdef WOLFSSL_AES_256 + bench_aesofb_internal(bench_key, 32, bench_iv, "AES-256-OFB"); +#endif +} +#endif /* WOLFSSL_AES_CFB */ + + #ifdef WOLFSSL_AES_XTS void bench_aesxts(void) { diff --git a/wolfcrypt/benchmark/benchmark.h b/wolfcrypt/benchmark/benchmark.h index 61cf96433..236225854 100644 --- a/wolfcrypt/benchmark/benchmark.h +++ b/wolfcrypt/benchmark/benchmark.h @@ -54,6 +54,7 @@ void bench_aesecb(int); void bench_aesxts(void); void bench_aesctr(void); void bench_aescfb(void); +void bench_aesofb(void); void bench_poly1305(void); void bench_camellia(void); void bench_md5(int); From c2c3e0d4aa9d43aa9e453809e090b3b299f5e190 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Fri, 24 Jan 2020 16:26:48 -0700 Subject: [PATCH 118/649] add initial implementation for wolfSSL_SESSION_get0_peer --- src/ssl.c | 22 +++++++++++++++++++++- wolfssl/openssl/ssl.h | 3 ++- wolfssl/ssl.h | 3 ++- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index c7ff328c3..16dc081e6 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -13437,7 +13437,7 @@ int wolfSSL_GetSessionAtIndex(int idx, WOLFSSL_SESSION* session) #endif /* SESSION_INDEX */ -#if defined(SESSION_INDEX) && defined(SESSION_CERTS) +#if defined(SESSION_CERTS) WOLFSSL_X509_CHAIN* wolfSSL_SESSION_get_peer_chain(WOLFSSL_SESSION* session) { @@ -13451,6 +13451,26 @@ WOLFSSL_X509_CHAIN* wolfSSL_SESSION_get_peer_chain(WOLFSSL_SESSION* session) return chain; } + +/* gets the peer certificate associated with the session passed in + * returns null on failure, the caller should not free the returned pointer */ +WOLFSSL_X509* wolfSSL_SESSION_get0_peer(WOLFSSL_SESSION* session) +{ + WOLFSSL_ENTER("wolfSSL_SESSION_get_peer_chain"); + if (session) { + int count; + + count = wolfSSL_get_chain_count(&session->chain); + if (count < 1 || count >= MAX_CHAIN_DEPTH) { + WOLFSSL_MSG("bad count found"); + return NULL; + } + return wolfSSL_get_chain_X509(&session->chain, count - 1); + } + WOLFSSL_MSG("No session passed in"); + return NULL; +} + #endif /* SESSION_INDEX && SESSION_CERTS */ diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index e4940687d..6c4c9757e 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -276,6 +276,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define SSL_get_error wolfSSL_get_error #define SSL_set_session wolfSSL_set_session #define SSL_get_session(x) wolfSSL_get_session((WOLFSSL*) (x)) +#define SSL_SESSION_get0_peer wolfSSL_SESSION_get0_peer #define SSL_flush_sessions wolfSSL_flush_sessions /* assume unlimited temporarily */ #define SSL_CTX_get_session_cache_mode(ctx) 0 @@ -294,7 +295,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define SSL_set_cipher_list wolfSSL_set_cipher_list /* wolfSSL does not support security levels */ #define SSL_CTX_set_security_level(...) -/* wolfSSL does not support expoting keying material */ +/* wolfSSL does not support exporting keying material */ #define SSL_export_keying_material(...) 0 #define SSL_CTX_set1_groups_list wolfSSL_CTX_set1_groups_list diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 67ec1368e..6e5186c3b 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -925,9 +925,10 @@ WOLFSSL_API int wolfSSL_GetSessionIndex(WOLFSSL* ssl); WOLFSSL_API int wolfSSL_GetSessionAtIndex(int index, WOLFSSL_SESSION* session); #endif /* SESSION_INDEX */ -#if defined(SESSION_INDEX) && defined(SESSION_CERTS) +#if defined(SESSION_CERTS) WOLFSSL_API WOLFSSL_X509_CHAIN* wolfSSL_SESSION_get_peer_chain(WOLFSSL_SESSION* session); +WOLFSSL_API WOLFSSL_X509* wolfSSL_SESSION_get0_peer(WOLFSSL_SESSION* session); #endif /* SESSION_INDEX && SESSION_CERTS */ typedef int (*VerifyCallback)(int, WOLFSSL_X509_STORE_CTX*); From b83a5840d66605705dd2e8e0dd44886d2f337a8e Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Fri, 24 Jan 2020 17:06:45 -0700 Subject: [PATCH 119/649] add stub function for wolfSSL_EVP_mdc2 --- src/ssl.c | 8 ++++++++ wolfssl/openssl/evp.h | 2 ++ 2 files changed, 10 insertions(+) diff --git a/src/ssl.c b/src/ssl.c index 16dc081e6..5d5969a57 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -16345,6 +16345,14 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) #endif /* !NO_MD5 */ +#ifndef NO_WOLFSSL_STUB + const WOLFSSL_EVP_MD* wolfSSL_EVP_mdc2(void) + { + WOLFSSL_STUB("EVP_mdc2"); + return NULL; + } +#endif + #ifndef NO_SHA const WOLFSSL_EVP_MD* wolfSSL_EVP_sha1(void) { diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index b8d61d257..b87d9b84b 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -79,6 +79,7 @@ typedef WOLFSSL_EVP_PKEY PKCS8_PRIV_KEY_INFO; #ifndef NO_MD5 WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_md5(void); #endif +WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_mdc2(void); WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_sha1(void); WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_sha224(void); WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_sha256(void); @@ -617,6 +618,7 @@ typedef WOLFSSL_EVP_CIPHER_CTX EVP_CIPHER_CTX; #define EVP_md5 wolfSSL_EVP_md5 #endif #define EVP_sha1 wolfSSL_EVP_sha1 +#define EVP_mdc2 wolfSSL_EVP_mdc2 #define EVP_dds1 wolfSSL_EVP_sha1 #define EVP_sha224 wolfSSL_EVP_sha224 #define EVP_sha256 wolfSSL_EVP_sha256 From 653235cd578307f007c9a243e748a20431469632 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Mon, 27 Jan 2020 09:08:37 -0700 Subject: [PATCH 120/649] add stub implementation for SSL_MODE_AUTO_RETRY --- src/ssl.c | 3 +++ wolfssl/ssl.h | 2 ++ 2 files changed, 5 insertions(+) diff --git a/src/ssl.c b/src/ssl.c index 5d5969a57..2e951a931 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -18788,6 +18788,9 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) WOLFSSL_MSG("Mode Not Implemented"); } + /* SSL_MODE_AUTO_RETRY + * Should not return -1 with renegotiation on read/write */ + return mode; } #endif diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 6e5186c3b..2155bedb5 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1698,6 +1698,8 @@ enum { SSL_CB_MODE_WRITE = 2, SSL_MODE_ENABLE_PARTIAL_WRITE = 2, + SSL_MODE_AUTO_RETRY = 3, /* wolfSSL default is to block with blocking io + * and auto retry */ SSL_MODE_RELEASE_BUFFERS = -1, /* For libwebsockets build. No current use. */ BIO_FLAGS_BASE64_NO_NL = 1, From 49def96998f962fbd6ee2b9a3b2599b310b7fe3b Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Mon, 27 Jan 2020 13:34:16 -0700 Subject: [PATCH 121/649] add test for get0 session peer certificate --- src/ssl.c | 2 +- tests/api.c | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/ssl.c b/src/ssl.c index 2e951a931..05b617d0a 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -13465,7 +13465,7 @@ WOLFSSL_X509* wolfSSL_SESSION_get0_peer(WOLFSSL_SESSION* session) WOLFSSL_MSG("bad count found"); return NULL; } - return wolfSSL_get_chain_X509(&session->chain, count - 1); + return wolfSSL_get_chain_X509(&session->chain, 0); } WOLFSSL_MSG("No session passed in"); return NULL; diff --git a/tests/api.c b/tests/api.c index fd93059e2..d46e813a8 100644 --- a/tests/api.c +++ b/tests/api.c @@ -24305,6 +24305,20 @@ static void test_wolfSSL_SESSION(void) fdOpenSession(Task_self()); #endif +#if defined(SESSION_CERTS) + { + X509 *x509; + char buf[30]; + int bufSz; + + AssertNotNull(x509 = SSL_SESSION_get0_peer(sess)); + AssertIntEQ((bufSz = X509_NAME_get_text_by_NID( + X509_get_subject_name(x509), NID_organizationalUnitName, + buf, sizeof(buf))), 7); + AssertIntEQ(XMEMCMP(buf, "Support", bufSz), 0); + } +#endif + AssertNotNull(sess_copy = wolfSSL_SESSION_dup(sess)); wolfSSL_SESSION_free(sess_copy); From 3197d67e62f6439240dfb569da956bb48a23300b Mon Sep 17 00:00:00 2001 From: Eric Blankenhorn Date: Tue, 28 Jan 2020 09:08:05 -0600 Subject: [PATCH 122/649] Testing aes_*_xts --- wolfcrypt/test/test.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 7eacde33d..d84e10717 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -6039,6 +6039,14 @@ EVP_TEST_END: } #endif +#ifdef OPENSSL_EXTRA + ret = EVP_test(EVP_aes_128_xts(), key2, iv2, plain2, sizeof(plain2), + cipher2, sizeof(cipher2)); + if (ret != 0) { + return ret; + } +#endif + ret = wc_AesSetKey(&enc, key2, sizeof(key2), iv2, AES_ENCRYPTION); if (ret != 0) return -5000; @@ -6115,6 +6123,14 @@ EVP_TEST_END: } #endif +#ifdef OPENSSL_EXTRA + ret = EVP_test(EVP_aes_256_xts(), key1, iv1, plain1, sizeof(plain1), + cipher1, sizeof(cipher1)); + if (ret != 0) { + return ret; + } +#endif + ret = wc_AesSetKey(&enc, key1, sizeof(key1), iv1, AES_ENCRYPTION); if (ret != 0) return -5012; From 16ce670897b987c5677ffceef51d27683f186187 Mon Sep 17 00:00:00 2001 From: Eric Blankenhorn Date: Tue, 28 Jan 2020 10:45:31 -0600 Subject: [PATCH 123/649] Revert "Testing aes_*_xts" This reverts commit 776eeb756c70b052849323d7645622a3f1d2b76a. --- wolfcrypt/test/test.c | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index d84e10717..7eacde33d 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -6039,14 +6039,6 @@ EVP_TEST_END: } #endif -#ifdef OPENSSL_EXTRA - ret = EVP_test(EVP_aes_128_xts(), key2, iv2, plain2, sizeof(plain2), - cipher2, sizeof(cipher2)); - if (ret != 0) { - return ret; - } -#endif - ret = wc_AesSetKey(&enc, key2, sizeof(key2), iv2, AES_ENCRYPTION); if (ret != 0) return -5000; @@ -6123,14 +6115,6 @@ EVP_TEST_END: } #endif -#ifdef OPENSSL_EXTRA - ret = EVP_test(EVP_aes_256_xts(), key1, iv1, plain1, sizeof(plain1), - cipher1, sizeof(cipher1)); - if (ret != 0) { - return ret; - } -#endif - ret = wc_AesSetKey(&enc, key1, sizeof(key1), iv1, AES_ENCRYPTION); if (ret != 0) return -5012; From 9c4e0807e25bbb5e92c0372080542256f332ca04 Mon Sep 17 00:00:00 2001 From: Eric Blankenhorn Date: Tue, 28 Jan 2020 21:46:04 -0600 Subject: [PATCH 124/649] Adding EVP_aes_###_xts tests (not complete) --- src/ssl.c | 56 ++++++++++++++++++++++++++++++++++++++++- wolfcrypt/src/evp.c | 11 ++++++++ wolfcrypt/test/test.c | 19 ++++++++++++++ wolfssl/openssl/evp.h | 2 ++ wolfssl/wolfcrypt/aes.h | 5 +++- 5 files changed, 91 insertions(+), 2 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 05b617d0a..5c192e84e 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -17524,7 +17524,61 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) } } #endif /* WOLFSSL_AES_256 */ - #endif /* HAVE_AES_CBC */ + #endif /* HAVE_AES_OFB */ + #ifdef WOLFSSL_AES_XTS + #ifdef WOLFSSL_AES_128 + if (ctx->cipherType == AES_128_XTS_TYPE || + (type && XSTRNCMP(type, EVP_AES_128_XTS, EVP_AES_SIZE) == 0)) { + WOLFSSL_MSG("EVP_AES_128_XTS"); + ctx->cipherType = AES_128_XTS_TYPE; + ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE; + ctx->flags |= WOLFSSL_EVP_CIPH_XTS_MODE; + ctx->keyLen = 16; + ctx->block_size = 1; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) { + ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv, + AES_ENCRYPTION, 0); + if (ret != 0) + return ret; + } + if (iv && key == NULL) { + ret = wc_AesSetIV(&ctx->cipher.aes, iv); + if (ret != 0) + return ret; + } + } + #endif /* WOLFSSL_AES_128 */ + #ifdef WOLFSSL_AES_256 + if (ctx->cipherType == AES_256_XTS_TYPE || + (type && XSTRNCMP(type, EVP_AES_256_XTS, EVP_AES_SIZE) == 0)) { + WOLFSSL_MSG("EVP_AES_256_XTS"); + ctx->cipherType = AES_256_XTS_TYPE; + ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE; + ctx->flags |= WOLFSSL_EVP_CIPH_XTS_MODE; + ctx->keyLen = 32; + ctx->block_size = 1; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) { + ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv, + AES_ENCRYPTION, 0); + if (ret != 0){ + WOLFSSL_MSG("AesSetKey() failed"); + return ret; + } + } + if (iv && key == NULL) { + ret = wc_AesSetIV(&ctx->cipher.aes, iv); + if (ret != 0){ + WOLFSSL_MSG("wc_AesSetIV() failed"); + return ret; + } + } + } + #endif /* WOLFSSL_AES_256 */ + #endif /* HAVE_AES_XTS */ #endif /* NO_AES */ #ifndef NO_DES3 diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 0d411e15c..9111fc5e3 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -357,6 +357,17 @@ static int evpCipherBlock(WOLFSSL_EVP_CIPHER_CTX *ctx, ret = wc_AesOfbDecrypt(&ctx->cipher.aes, out, in, inl); break; #endif +#if defined(WOLFSSL_AES_XTS) + case AES_128_XTS_TYPE: + case AES_256_XTS_TYPE: + if (ctx->enc) + ret = wc_AesXtsEncrypt(&ctx->cipher.xts, out, in, inl, + ctx->cipher.tweak, ctx->cipher.tweakSz); + else + ret = wc_AesXtsDecrypt(&ctx->cipher.xts, out, in, inl, + ctx->cipher.tweak, ctx->cipher.tweakSz); + break; +#endif #endif /* !NO_AES */ #ifndef NO_DES3 case DES_CBC_TYPE: diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 7eacde33d..e0655e27e 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -6444,6 +6444,16 @@ static int aes_xts_128_test(void) if (wc_AesXtsSetKey(&aes, k2, sizeof(k2), AES_ENCRYPTION, HEAP_HINT, devId) != 0) return -4900; + +#if 0 /* Enable after passes */ +//#ifdef OPENSSL_EXTRA + ret = EVP_test(EVP_aes_128_xts(), k2, i2, p2, sizeof(p2), c2, sizeof(c2)); + if (ret != 0) { + printf("EVP_aes_128_xts failed!\n"); + return ret; + } +#endif + ret = wc_AesXtsEncrypt(&aes, buf, p2, sizeof(p2), i2, sizeof(i2)); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes.aes.asyncDev, WC_ASYNC_FLAG_NONE); @@ -6612,6 +6622,15 @@ static int aes_xts_256_test(void) 0xc3, 0xea, 0xd8, 0x10, 0xe9, 0xc0, 0xaf, 0x92 }; +#if 0 /* Enable after passes */ +//#ifdef OPENSSL_EXTRA + ret = EVP_test(EVP_aes_256_xts(), k2, i2, p2, sizeof(p2), c2, sizeof(c2)); + if (ret != 0) { + printf("EVP_aes_256_xts failed\n"); + return ret; + } +#endif + XMEMSET(buf, 0, sizeof(buf)); if (wc_AesXtsSetKey(&aes, k2, sizeof(k2), AES_ENCRYPTION, HEAP_HINT, devId) != 0) diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index b87d9b84b..5c344922e 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -590,6 +590,7 @@ WOLFSSL_API int wolfSSL_PKCS5_PBKDF2_HMAC(const char *pass, int passlen, #define EVP_CIPH_CTR_MODE WOLFSSL_EVP_CIPH_CTR_MODE #define EVP_CIPH_GCM_MODE WOLFSSL_EVP_CIPH_GCM_MODE #define EVP_CIPH_CCM_MODE WOLFSSL_EVP_CIPH_CCM_MODE +#define EVP_CIPH_XTS_MODE WOLFSSL_EVP_CIPH_XTS_MODE #define WOLFSSL_EVP_CIPH_MODE 0x0007 #define WOLFSSL_EVP_CIPH_STREAM_CIPHER 0x0 @@ -600,6 +601,7 @@ WOLFSSL_API int wolfSSL_PKCS5_PBKDF2_HMAC(const char *pass, int passlen, #define WOLFSSL_EVP_CIPH_CTR_MODE 0x5 #define WOLFSSL_EVP_CIPH_GCM_MODE 0x6 #define WOLFSSL_EVP_CIPH_CCM_MODE 0x7 +#define WOLFSSL_EVP_CIPH_XTS_MODE 0x10 #define WOLFSSL_EVP_CIPH_NO_PADDING 0x100 #define EVP_CIPH_VARIABLE_LENGTH 0x200 #define WOLFSSL_EVP_CIPH_TYPE_INIT 0xff diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index 6204f5889..91aae2c09 100644 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -136,6 +136,9 @@ enum { #ifdef WOLFSSL_AES_OFB AES_OFB_MODE = 2, #endif +#ifdef WOLFSSL_AES_XTS + AES_XTS_MODE = 3, +#endif #ifdef HAVE_PKCS11 AES_MAX_ID_LEN = 32, @@ -186,7 +189,7 @@ struct Aes { WC_ASYNC_DEV asyncDev; #endif /* WOLFSSL_ASYNC_CRYPT */ #if defined(WOLFSSL_AES_COUNTER) || defined(WOLFSSL_AES_CFB) || \ - defined(WOLFSSL_AES_OFB) + defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_XTS) word32 left; /* unused bytes left from last call */ #endif #ifdef WOLFSSL_XILINX_CRYPT From 9d61ba6c62bd9d058a7b4d91d94cb1ac59df64de Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Wed, 29 Jan 2020 09:59:51 -0700 Subject: [PATCH 125/649] initial cfb1/cfb8 support added --- wolfcrypt/src/aes.c | 192 +++++++++++++++++++++++++++++++++++++++- wolfcrypt/test/test.c | 156 ++++++++++++++++++++++++++++++++ wolfssl/wolfcrypt/aes.h | 8 ++ 3 files changed, 355 insertions(+), 1 deletion(-) diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 3eb781f1f..51014cbf7 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -7476,6 +7476,196 @@ int wc_AesCfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) return wc_AesFeedbackDecrypt(aes, out, in, sz, AES_CFB_MODE); } #endif /* HAVE_AES_DECRYPT */ + + +/* shift the whole AES_BLOCK_SIZE array left by 8 or 1 bits */ +static void shiftLeftArray(byte* ary, byte shift) +{ + int i; + + if (shift == WOLFSSL_BIT_SIZE) { + /* shifting over by 8 bits */ + for (i = 0; i < AES_BLOCK_SIZE - 1; i++) { + ary[i] = ary[i+1]; + } + ary[i] = 0; + } + else { + byte carry = 0; + + /* shifting over by 7 or less bits */ + for (i = 0; i < AES_BLOCK_SIZE - 1; i++) { + carry = ary[i+1] & (0XFF << (WOLFSSL_BIT_SIZE - shift)); + carry >>= (WOLFSSL_BIT_SIZE - shift); + ary[i] = (ary[i] << shift) + carry; + } + ary[i] = ary[i] << shift; + } +} + + +/* returns 0 on success and negative values on failure */ +static int wc_AesFeedbackCFB8(Aes* aes, byte* out, const byte* in, + word32 sz, byte dir) +{ + byte *pt; + + if (aes == NULL || out == NULL || in == NULL) { + return BAD_FUNC_ARG; + } + + while (sz > 0) { + wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg); + if (dir == AES_DECRYPTION) { + pt = (byte*)aes->reg; + + /* LSB + CAT */ + shiftLeftArray(pt, WOLFSSL_BIT_SIZE); + pt[AES_BLOCK_SIZE - 1] = in[0]; + } + + /* MSB + XOR */ + out[0] = aes->tmp[0] ^ in[0]; + if (dir == AES_ENCRYPTION) { + pt = (byte*)aes->reg; + + /* LSB + CAT */ + shiftLeftArray(pt, WOLFSSL_BIT_SIZE); + pt[AES_BLOCK_SIZE - 1] = out[0]; + } + + out += 1; + in += 1; + sz -= 1; + } + + return 0; +} + + +/* returns 0 on success and negative values on failure */ +static int wc_AesFeedbackCFB1(Aes* aes, byte* out, const byte* in, + word32 sz, byte dir) +{ + byte tmp; + byte* pt; + int bit = 7; + + if (aes == NULL || out == NULL || in == NULL) { + return BAD_FUNC_ARG; + } + + out[0] = 0; + while (sz > 0) { + wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg); + if (dir == AES_DECRYPTION) { + pt = (byte*)aes->reg; + + /* LSB + CAT */ + tmp = (0X01 << bit) & in[0]; + tmp = tmp >> bit; + shiftLeftArray((byte*)aes->reg, 1); + pt[AES_BLOCK_SIZE - 1] |= tmp; + } + + /* MSB + XOR */ + tmp = (0X01 << bit) & in[0]; + pt = (byte*)aes->tmp; + tmp = pt[0] ^ (tmp >> bit); + tmp &= 0x01; + out[0] |= (tmp << bit); + + + if (dir == AES_ENCRYPTION) { + pt = (byte*)aes->reg; + + /* LSB + CAT */ + shiftLeftArray((byte*)aes->reg, 1); + pt[AES_BLOCK_SIZE - 1] |= tmp; + } + + bit--; + if (bit < 0) { + out += 1; + in += 1; + sz -= 1; + bit = 7; + if (sz > 0) { + out[0] = 0; + } + } + else { + sz -= 1; + } + } + + return 0; +} + + +/* CFB 1 + * + * aes structure holding key to use for encryption + * out buffer to hold result of encryption (must be at least as large as input + * buffer) + * in buffer to encrypt + * sz size of input buffer + * + * returns 0 on success and negative values on failure + */ +int wc_AesCfb1Encrypt(Aes* aes, byte* out, const byte* in, word32 sz) +{ + return wc_AesFeedbackCFB1(aes, out, in, sz, AES_ENCRYPTION); +} + + +/* CFB 8 + * + * aes structure holding key to use for encryption + * out buffer to hold result of encryption (must be at least as large as input + * buffer) + * in buffer to encrypt + * sz size of input buffer + * + * returns 0 on success and negative values on failure + */ +int wc_AesCfb8Encrypt(Aes* aes, byte* out, const byte* in, word32 sz) +{ + return wc_AesFeedbackCFB8(aes, out, in, sz, AES_ENCRYPTION); +} +#ifdef HAVE_AES_DECRYPT + +/* CFB 1 + * + * aes structure holding key to use for encryption + * out buffer to hold result of encryption (must be at least as large as input + * buffer) + * in buffer to encrypt + * sz size of input buffer + * + * returns 0 on success and negative values on failure + */ +int wc_AesCfb1Decrypt(Aes* aes, byte* out, const byte* in, word32 sz) +{ + return wc_AesFeedbackCFB1(aes, out, in, sz, AES_DECRYPTION); +} + + +/* CFB 8 + * + * aes structure holding key to use for encryption + * out buffer to hold result of encryption (must be at least as large as input + * buffer) + * in buffer to encrypt + * sz size of input buffer + * + * returns 0 on success and negative values on failure + */ +int wc_AesCfb8Decrypt(Aes* aes, byte* out, const byte* in, word32 sz) +{ + return wc_AesFeedbackCFB8(aes, out, in, sz, AES_DECRYPTION); +} +#endif /* HAVE_AES_DECRYPT */ #endif /* WOLFSSL_AES_CFB */ #ifdef WOLFSSL_AES_OFB @@ -7513,7 +7703,7 @@ int wc_AesOfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) return wc_AesFeedbackDecrypt(aes, out, in, sz, AES_OFB_MODE); } #endif /* HAVE_AES_DECRYPT */ -#endif /* WOLFSSL_AES_CFB */ +#endif /* WOLFSSL_AES_OFB */ #ifdef HAVE_AES_KEYWRAP diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index e0655e27e..31c01283b 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -5863,8 +5863,156 @@ int des3_test(void) return ret; } + + + static int aescfb1_test(void) + { + Aes enc; + byte cipher[AES_BLOCK_SIZE]; + #ifdef HAVE_AES_DECRYPT + Aes dec; + byte plain [AES_BLOCK_SIZE]; + #endif + int ret = 0; + + const byte iv[] = { + 0x4d,0xbb,0xdc,0xaa,0x59,0xf3,0x63,0xc9, + 0x2a,0x3b,0x98,0x43,0xad,0x20,0xe2,0xb7 + }; + +#ifdef WOLFSSL_AES_128 + const byte key1[] = + { + 0xcd,0xef,0x9d,0x06,0x61,0xba,0xe4,0x73, + 0x8d,0x1a,0x58,0xa2,0xa6,0x22,0x8b,0x66 + }; + + const byte cipher1[] = + { + 0x00 + }; + + const byte msg1[] = + { + 0xC0 + }; +#endif /* WOLFSSL_AES_128 */ + + if (wc_AesInit(&enc, HEAP_HINT, devId) != 0) + return -4739; +#ifdef HAVE_AES_DECRYPT + if (wc_AesInit(&dec, HEAP_HINT, devId) != 0) + return -4740; +#endif + +#ifdef WOLFSSL_AES_128 + /* 128 key tests */ + ret = wc_AesSetKey(&enc, key1, AES_BLOCK_SIZE, iv, AES_ENCRYPTION); + if (ret != 0) + return -4741; + #ifdef HAVE_AES_DECRYPT + /* decrypt uses AES_ENCRYPTION */ + ret = wc_AesSetKey(&dec, key1, AES_BLOCK_SIZE, iv, AES_ENCRYPTION); + if (ret != 0) + return -4742; + #endif + + XMEMSET(cipher, 0, sizeof(cipher)); + ret = wc_AesCfb1Encrypt(&enc, cipher, msg1, 2); + if (ret != 0) + return -4743; + + if (cipher[0] != cipher1[0]) + return -4744; + + #ifdef HAVE_AES_DECRYPT + ret = wc_AesCfb1Decrypt(&dec, plain, cipher, 2); + if (ret != 0) + return -4745; + + if (plain[0] != msg1[0]) + return -4746; + #endif /* HAVE_AES_DECRYPT */ +#endif /* WOLFSSL_AES_128 */ + + return ret; + } + + static int aescfb8_test(void) + { + Aes enc; + byte cipher[AES_BLOCK_SIZE]; + #ifdef HAVE_AES_DECRYPT + Aes dec; + byte plain [AES_BLOCK_SIZE]; + #endif + int ret = 0; + + const byte iv[] = { + 0xf4,0x75,0xc6,0x49,0x91,0xb2,0x0e,0xae, + 0xe1,0x83,0xa2,0x26,0x29,0xe2,0x1e,0x22 + }; + +#ifdef WOLFSSL_AES_128 + const byte key1[] = + { + 0xc8,0xfe,0x9b,0xf7,0x7b,0x93,0x0f,0x46, + 0xd2,0x07,0x8b,0x8c,0x0e,0x65,0x7c,0xd4 + }; + + const byte cipher1[] = + { + 0xd2,0x76,0x91 + }; + + const byte msg1[] = + { + 0xc9,0x06,0x35 + }; +#endif /* WOLFSSL_AES_128 */ + + if (wc_AesInit(&enc, HEAP_HINT, devId) != 0) + return -4739; +#ifdef HAVE_AES_DECRYPT + if (wc_AesInit(&dec, HEAP_HINT, devId) != 0) + return -4740; +#endif + +#ifdef WOLFSSL_AES_128 + /* 128 key tests */ + ret = wc_AesSetKey(&enc, key1, AES_BLOCK_SIZE, iv, AES_ENCRYPTION); + if (ret != 0) + return -4741; + #ifdef HAVE_AES_DECRYPT + /* decrypt uses AES_ENCRYPTION */ + ret = wc_AesSetKey(&dec, key1, AES_BLOCK_SIZE, iv, AES_ENCRYPTION); + if (ret != 0) + return -4742; + #endif + + XMEMSET(cipher, 0, sizeof(cipher)); + ret = wc_AesCfb8Encrypt(&enc, cipher, msg1, sizeof(msg1)); + if (ret != 0) + return -4743; + + if (XMEMCMP(cipher, cipher1, sizeof(cipher1)) != 0) + return -4744; + + #ifdef HAVE_AES_DECRYPT + ret = wc_AesCfb8Decrypt(&dec, plain, cipher, sizeof(msg1)); + if (ret != 0) + return -4745; + + if (XMEMCMP(plain, msg1, sizeof(msg1)) != 0) + return -4746; + #endif /* HAVE_AES_DECRYPT */ +#endif /* WOLFSSL_AES_128 */ + + return ret; + } #endif /* WOLFSSL_AES_CFB */ + #ifdef WOLFSSL_AES_OFB #ifdef OPENSSL_EXTRA /* pass in the function, key, iv, plain text and expected and this function @@ -7476,6 +7624,14 @@ int aes_test(void) ret = aescfb_test(); if (ret != 0) return ret; + + ret = aescfb1_test(); + if (ret != 0) + return ret; + + ret = aescfb8_test(); + if (ret != 0) + return ret; #endif diff --git a/wolfssl/wolfcrypt/aes.h b/wolfssl/wolfcrypt/aes.h index 91aae2c09..858291849 100644 --- a/wolfssl/wolfcrypt/aes.h +++ b/wolfssl/wolfcrypt/aes.h @@ -277,9 +277,17 @@ WOLFSSL_API int wc_AesCbcDecrypt(Aes* aes, byte* out, #ifdef WOLFSSL_AES_CFB WOLFSSL_API int wc_AesCfbEncrypt(Aes* aes, byte* out, const byte* in, word32 sz); +WOLFSSL_API int wc_AesCfb1Encrypt(Aes* aes, byte* out, + const byte* in, word32 sz); +WOLFSSL_API int wc_AesCfb8Encrypt(Aes* aes, byte* out, + const byte* in, word32 sz); #ifdef HAVE_AES_DECRYPT WOLFSSL_API int wc_AesCfbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz); +WOLFSSL_API int wc_AesCfb1Decrypt(Aes* aes, byte* out, + const byte* in, word32 sz); +WOLFSSL_API int wc_AesCfb8Decrypt(Aes* aes, byte* out, + const byte* in, word32 sz); #endif /* HAVE_AES_DECRYPT */ #endif /* WOLFSSL_AES_CFB */ From 887eeb3c47f420dfa68b7199ee8a07497b3aba9f Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Wed, 29 Jan 2020 10:36:28 -0700 Subject: [PATCH 126/649] add EVP tests for cfb128 --- src/ssl.c | 244 +++++++++++- wolfcrypt/src/aes.c | 8 + wolfcrypt/src/evp.c | 47 +++ wolfcrypt/test/test.c | 844 ++++++++++++++++++++++-------------------- 4 files changed, 732 insertions(+), 411 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 5c192e84e..0f928be97 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -17447,6 +17447,236 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) return ret; } #endif /* WOLFSSL_AES_256 */ + #ifdef WOLFSSL_AES_CFB + #ifdef WOLFSSL_AES_128 + if (ctx->cipherType == AES_128_CFB1_TYPE || + (type && XSTRNCMP(type, EVP_AES_128_CFB1, EVP_AES_SIZE) == 0)) { + WOLFSSL_MSG("EVP_AES_128_CFB1"); + ctx->cipherType = AES_128_CFB1_TYPE; + ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE; + ctx->flags |= WOLFSSL_EVP_CIPH_CFB_MODE; + ctx->keyLen = 16; + ctx->block_size = 1; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) { + ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv, + AES_ENCRYPTION, 0); + if (ret != 0) + return ret; + } + if (iv && key == NULL) { + ret = wc_AesSetIV(&ctx->cipher.aes, iv); + if (ret != 0) + return ret; + } + } + #endif /* WOLFSSL_AES_128 */ + #ifdef WOLFSSL_AES_192 + if (ctx->cipherType == AES_192_CFB1_TYPE || + (type && XSTRNCMP(type, EVP_AES_192_CFB1, EVP_AES_SIZE) == 0)) { + WOLFSSL_MSG("EVP_AES_192_CFB1"); + ctx->cipherType = AES_192_CFB1_TYPE; + ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE; + ctx->flags |= WOLFSSL_EVP_CIPH_CFB_MODE; + ctx->keyLen = 24; + ctx->block_size = 1; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) { + ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv, + AES_ENCRYPTION, 0); + if (ret != 0) + return ret; + } + if (iv && key == NULL) { + ret = wc_AesSetIV(&ctx->cipher.aes, iv); + if (ret != 0) + return ret; + } + } + #endif /* WOLFSSL_AES_192 */ + #ifdef WOLFSSL_AES_256 + if (ctx->cipherType == AES_256_CFB1_TYPE || + (type && XSTRNCMP(type, EVP_AES_256_CFB1, EVP_AES_SIZE) == 0)) { + WOLFSSL_MSG("EVP_AES_256_CFB1"); + ctx->cipherType = AES_256_CFB1_TYPE; + ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE; + ctx->flags |= WOLFSSL_EVP_CIPH_CFB_MODE; + ctx->keyLen = 32; + ctx->block_size = 1; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) { + ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv, + AES_ENCRYPTION, 0); + if (ret != 0){ + WOLFSSL_MSG("AesSetKey() failed"); + return ret; + } + } + if (iv && key == NULL) { + ret = wc_AesSetIV(&ctx->cipher.aes, iv); + if (ret != 0){ + WOLFSSL_MSG("wc_AesSetIV() failed"); + return ret; + } + } + } + #endif /* WOLFSSL_AES_256 */ + #ifdef WOLFSSL_AES_128 + if (ctx->cipherType == AES_128_CFB8_TYPE || + (type && XSTRNCMP(type, EVP_AES_128_CFB8, EVP_AES_SIZE) == 0)) { + WOLFSSL_MSG("EVP_AES_128_CFB8"); + ctx->cipherType = AES_128_CFB8_TYPE; + ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE; + ctx->flags |= WOLFSSL_EVP_CIPH_CFB_MODE; + ctx->keyLen = 16; + ctx->block_size = 1; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) { + ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv, + AES_ENCRYPTION, 0); + if (ret != 0) + return ret; + } + if (iv && key == NULL) { + ret = wc_AesSetIV(&ctx->cipher.aes, iv); + if (ret != 0) + return ret; + } + } + #endif /* WOLFSSL_AES_128 */ + #ifdef WOLFSSL_AES_192 + if (ctx->cipherType == AES_192_CFB8_TYPE || + (type && XSTRNCMP(type, EVP_AES_192_CFB8, EVP_AES_SIZE) == 0)) { + WOLFSSL_MSG("EVP_AES_192_CFB8"); + ctx->cipherType = AES_192_CFB8_TYPE; + ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE; + ctx->flags |= WOLFSSL_EVP_CIPH_CFB_MODE; + ctx->keyLen = 24; + ctx->block_size = 1; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) { + ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv, + AES_ENCRYPTION, 0); + if (ret != 0) + return ret; + } + if (iv && key == NULL) { + ret = wc_AesSetIV(&ctx->cipher.aes, iv); + if (ret != 0) + return ret; + } + } + #endif /* WOLFSSL_AES_192 */ + #ifdef WOLFSSL_AES_256 + if (ctx->cipherType == AES_256_CFB8_TYPE || + (type && XSTRNCMP(type, EVP_AES_256_CFB8, EVP_AES_SIZE) == 0)) { + WOLFSSL_MSG("EVP_AES_256_CFB8"); + ctx->cipherType = AES_256_CFB8_TYPE; + ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE; + ctx->flags |= WOLFSSL_EVP_CIPH_CFB_MODE; + ctx->keyLen = 32; + ctx->block_size = 1; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) { + ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv, + AES_ENCRYPTION, 0); + if (ret != 0){ + WOLFSSL_MSG("AesSetKey() failed"); + return ret; + } + } + if (iv && key == NULL) { + ret = wc_AesSetIV(&ctx->cipher.aes, iv); + if (ret != 0){ + WOLFSSL_MSG("wc_AesSetIV() failed"); + return ret; + } + } + } + #endif /* WOLFSSL_AES_256 */ + #ifdef WOLFSSL_AES_128 + if (ctx->cipherType == AES_128_CFB128_TYPE || + (type && XSTRNCMP(type, EVP_AES_128_CFB128, EVP_AES_SIZE) == 0)) { + WOLFSSL_MSG("EVP_AES_128_CFB128"); + ctx->cipherType = AES_128_CFB128_TYPE; + ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE; + ctx->flags |= WOLFSSL_EVP_CIPH_CFB_MODE; + ctx->keyLen = 16; + ctx->block_size = 1; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) { + ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv, + AES_ENCRYPTION, 0); + if (ret != 0) + return ret; + } + if (iv && key == NULL) { + ret = wc_AesSetIV(&ctx->cipher.aes, iv); + if (ret != 0) + return ret; + } + } + #endif /* WOLFSSL_AES_128 */ + #ifdef WOLFSSL_AES_192 + if (ctx->cipherType == AES_192_CFB128_TYPE || + (type && XSTRNCMP(type, EVP_AES_192_CFB128, EVP_AES_SIZE) == 0)) { + WOLFSSL_MSG("EVP_AES_192_CFB128"); + ctx->cipherType = AES_192_CFB128_TYPE; + ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE; + ctx->flags |= WOLFSSL_EVP_CIPH_CFB_MODE; + ctx->keyLen = 24; + ctx->block_size = 1; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) { + ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv, + AES_ENCRYPTION, 0); + if (ret != 0) + return ret; + } + if (iv && key == NULL) { + ret = wc_AesSetIV(&ctx->cipher.aes, iv); + if (ret != 0) + return ret; + } + } + #endif /* WOLFSSL_AES_192 */ + #ifdef WOLFSSL_AES_256 + if (ctx->cipherType == AES_256_CFB128_TYPE || + (type && XSTRNCMP(type, EVP_AES_256_CFB128, EVP_AES_SIZE) == 0)) { + WOLFSSL_MSG("EVP_AES_256_CFB128"); + ctx->cipherType = AES_256_CFB128_TYPE; + ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE; + ctx->flags |= WOLFSSL_EVP_CIPH_CFB_MODE; + ctx->keyLen = 32; + ctx->block_size = 1; + if (enc == 0 || enc == 1) + ctx->enc = enc ? 1 : 0; + if (key) { + ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv, + AES_ENCRYPTION, 0); + if (ret != 0){ + WOLFSSL_MSG("AesSetKey() failed"); + return ret; + } + } + if (iv && key == NULL) { + ret = wc_AesSetIV(&ctx->cipher.aes, iv); + if (ret != 0){ + WOLFSSL_MSG("wc_AesSetIV() failed"); + return ret; + } + } + } + #endif /* WOLFSSL_AES_256 */ + #endif /* HAVE_AES_CFB */ #ifdef WOLFSSL_AES_OFB #ifdef WOLFSSL_AES_128 if (ctx->cipherType == AES_128_OFB_TYPE || @@ -17820,13 +18050,25 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) case AES_128_CFB1_TYPE: case AES_192_CFB1_TYPE: case AES_256_CFB1_TYPE: + WOLFSSL_MSG("AES CFB1"); + if (ctx->enc) + ret = wc_AesCfb1Encrypt(&ctx->cipher.aes, dst, src, len); + else + ret = wc_AesCfb1Decrypt(&ctx->cipher.aes, dst, src, len); + break; case AES_128_CFB8_TYPE: case AES_192_CFB8_TYPE: case AES_256_CFB8_TYPE: + WOLFSSL_MSG("AES CFB8"); + if (ctx->enc) + ret = wc_AesCfb8Encrypt(&ctx->cipher.aes, dst, src, len); + else + ret = wc_AesCfb8Decrypt(&ctx->cipher.aes, dst, src, len); + break; case AES_128_CFB128_TYPE: case AES_192_CFB128_TYPE: case AES_256_CFB128_TYPE: - WOLFSSL_MSG("AES CFB"); + WOLFSSL_MSG("AES CFB128"); if (ctx->enc) ret = wc_AesCfbEncrypt(&ctx->cipher.aes, dst, src, len); else diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 51014cbf7..8ba1e0fd3 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -7514,6 +7514,10 @@ static int wc_AesFeedbackCFB8(Aes* aes, byte* out, const byte* in, return BAD_FUNC_ARG; } + if (sz == 0) { + return 0; + } + while (sz > 0) { wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg); if (dir == AES_DECRYPTION) { @@ -7555,6 +7559,10 @@ static int wc_AesFeedbackCFB1(Aes* aes, byte* out, const byte* in, return BAD_FUNC_ARG; } + if (sz == 0) { + return 0; + } + out[0] = 0; while (sz > 0) { wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg); diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 9111fc5e3..ec10dc2a5 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -357,6 +357,34 @@ static int evpCipherBlock(WOLFSSL_EVP_CIPHER_CTX *ctx, ret = wc_AesOfbDecrypt(&ctx->cipher.aes, out, in, inl); break; #endif + #if defined(WOLFSSL_AES_CFB) + case AES_128_CFB1_TYPE: + case AES_192_CFB1_TYPE: + case AES_256_CFB1_TYPE: + if (ctx->enc) + ret = wc_AesCfb1Encrypt(&ctx->cipher.aes, out, in, inl); + else + ret = wc_AesCfb1Decrypt(&ctx->cipher.aes, out, in, inl); + break; + + case AES_128_CFB8_TYPE: + case AES_192_CFB8_TYPE: + case AES_256_CFB8_TYPE: + if (ctx->enc) + ret = wc_AesCfb8Encrypt(&ctx->cipher.aes, out, in, inl); + else + ret = wc_AesCfb8Decrypt(&ctx->cipher.aes, out, in, inl); + break; + + case AES_128_CFB128_TYPE: + case AES_192_CFB128_TYPE: + case AES_256_CFB128_TYPE: + if (ctx->enc) + ret = wc_AesCfbEncrypt(&ctx->cipher.aes, out, in, inl); + else + ret = wc_AesCfbDecrypt(&ctx->cipher.aes, out, in, inl); + break; + #endif #if defined(WOLFSSL_AES_XTS) case AES_128_XTS_TYPE: case AES_256_XTS_TYPE: @@ -607,6 +635,7 @@ int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, padBlock(ctx); PRINT_BUF(ctx->buf, ctx->block_size); if (evpCipherBlock(ctx, out, ctx->buf, ctx->block_size) == 0) { + WOLFSSL_MSG("Final Cipher Block failed"); ret = WOLFSSL_FAILURE; } else { @@ -622,6 +651,7 @@ int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, else if ((ctx->bufUsed % ctx->block_size) != 0) { *outl = 0; /* not enough padding for decrypt */ + WOLFSSL_MSG("Final Cipher Block not enough padding"); ret = WOLFSSL_FAILURE; } else if (ctx->lastUsed) { @@ -631,6 +661,7 @@ int wolfSSL_EVP_CipherFinal(WOLFSSL_EVP_CIPHER_CTX *ctx, *outl = fl; if (ctx->lastUsed == 0 && ctx->bufUsed == 0) { /* return error in cases where the block length is incorrect */ + WOLFSSL_MSG("Final Cipher Block bad length"); ret = WOLFSSL_FAILURE; } } @@ -722,6 +753,22 @@ int wolfSSL_EVP_CIPHER_CTX_block_size(const WOLFSSL_EVP_CIPHER_CTX *ctx) case AES_192_CTR_TYPE: case AES_256_CTR_TYPE: #endif +#if defined(WOLFSSL_AES_CFB) + case AES_128_CFB1_TYPE: + case AES_192_CFB1_TYPE: + case AES_256_CFB1_TYPE: + case AES_128_CFB8_TYPE: + case AES_192_CFB8_TYPE: + case AES_256_CFB8_TYPE: + case AES_128_CFB128_TYPE: + case AES_192_CFB128_TYPE: + case AES_256_CFB128_TYPE: +#endif +#if defined(WOLFSSL_AES_OFB) + case AES_128_OFB_TYPE: + case AES_192_OFB_TYPE: + case AES_256_OFB_TYPE: +#endif case AES_128_ECB_TYPE: case AES_192_ECB_TYPE: diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 31c01283b..b2ac1b03c 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -5604,416 +5604,8 @@ int des3_test(void) #ifndef NO_AES -#ifdef WOLFSSL_AES_CFB - /* Test cases from NIST SP 800-38A, Recommendation for Block Cipher Modes of Operation Methods an*/ - static int aescfb_test(void) - { - Aes enc; - byte cipher[AES_BLOCK_SIZE * 4]; - #ifdef HAVE_AES_DECRYPT - Aes dec; - byte plain [AES_BLOCK_SIZE * 4]; - #endif - int ret = 0; - const byte iv[] = { - 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, - 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f - }; - -#ifdef WOLFSSL_AES_128 - const byte key1[] = - { - 0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6, - 0xab,0xf7,0x15,0x88,0x09,0xcf,0x4f,0x3c - }; - - const byte cipher1[] = - { - 0x3b,0x3f,0xd9,0x2e,0xb7,0x2d,0xad,0x20, - 0x33,0x34,0x49,0xf8,0xe8,0x3c,0xfb,0x4a, - 0xc8,0xa6,0x45,0x37,0xa0,0xb3,0xa9,0x3f, - 0xcd,0xe3,0xcd,0xad,0x9f,0x1c,0xe5,0x8b, - 0x26,0x75,0x1f,0x67,0xa3,0xcb,0xb1,0x40, - 0xb1,0x80,0x8c,0xf1,0x87,0xa4,0xf4,0xdf - }; - - const byte msg1[] = - { - 0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96, - 0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a, - 0xae,0x2d,0x8a,0x57,0x1e,0x03,0xac,0x9c, - 0x9e,0xb7,0x6f,0xac,0x45,0xaf,0x8e,0x51, - 0x30,0xc8,0x1c,0x46,0xa3,0x5c,0xe4,0x11, - 0xe5,0xfb,0xc1,0x19,0x1a,0x0a,0x52,0xef - }; -#endif /* WOLFSSL_AES_128 */ - -#ifdef WOLFSSL_AES_192 - /* 192 size key test */ - const byte key2[] = - { - 0x8e,0x73,0xb0,0xf7,0xda,0x0e,0x64,0x52, - 0xc8,0x10,0xf3,0x2b,0x80,0x90,0x79,0xe5, - 0x62,0xf8,0xea,0xd2,0x52,0x2c,0x6b,0x7b - }; - - const byte cipher2[] = - { - 0xcd,0xc8,0x0d,0x6f,0xdd,0xf1,0x8c,0xab, - 0x34,0xc2,0x59,0x09,0xc9,0x9a,0x41,0x74, - 0x67,0xce,0x7f,0x7f,0x81,0x17,0x36,0x21, - 0x96,0x1a,0x2b,0x70,0x17,0x1d,0x3d,0x7a, - 0x2e,0x1e,0x8a,0x1d,0xd5,0x9b,0x88,0xb1, - 0xc8,0xe6,0x0f,0xed,0x1e,0xfa,0xc4,0xc9, - 0xc0,0x5f,0x9f,0x9c,0xa9,0x83,0x4f,0xa0, - 0x42,0xae,0x8f,0xba,0x58,0x4b,0x09,0xff - }; - - const byte msg2[] = - { - 0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96, - 0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a, - 0xae,0x2d,0x8a,0x57,0x1e,0x03,0xac,0x9c, - 0x9e,0xb7,0x6f,0xac,0x45,0xaf,0x8e,0x51, - 0x30,0xc8,0x1c,0x46,0xa3,0x5c,0xe4,0x11, - 0xe5,0xfb,0xc1,0x19,0x1a,0x0a,0x52,0xef, - 0xf6,0x9f,0x24,0x45,0xdf,0x4f,0x9b,0x17, - 0xad,0x2b,0x41,0x7b,0xe6,0x6c,0x37,0x10 - }; -#endif /* WOLFSSL_AES_192 */ - -#ifdef WOLFSSL_AES_256 - /* 256 size key simple test */ - const byte key3[] = - { - 0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe, - 0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81, - 0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7, - 0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4 - }; - - const byte cipher3[] = - { - 0xdc,0x7e,0x84,0xbf,0xda,0x79,0x16,0x4b, - 0x7e,0xcd,0x84,0x86,0x98,0x5d,0x38,0x60, - 0x39,0xff,0xed,0x14,0x3b,0x28,0xb1,0xc8, - 0x32,0x11,0x3c,0x63,0x31,0xe5,0x40,0x7b, - 0xdf,0x10,0x13,0x24,0x15,0xe5,0x4b,0x92, - 0xa1,0x3e,0xd0,0xa8,0x26,0x7a,0xe2,0xf9, - 0x75,0xa3,0x85,0x74,0x1a,0xb9,0xce,0xf8, - 0x20,0x31,0x62,0x3d,0x55,0xb1,0xe4,0x71 - }; - - const byte msg3[] = - { - 0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96, - 0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a, - 0xae,0x2d,0x8a,0x57,0x1e,0x03,0xac,0x9c, - 0x9e,0xb7,0x6f,0xac,0x45,0xaf,0x8e,0x51, - 0x30,0xc8,0x1c,0x46,0xa3,0x5c,0xe4,0x11, - 0xe5,0xfb,0xc1,0x19,0x1a,0x0a,0x52,0xef, - 0xf6,0x9f,0x24,0x45,0xdf,0x4f,0x9b,0x17, - 0xad,0x2b,0x41,0x7b,0xe6,0x6c,0x37,0x10 - }; -#endif /* WOLFSSL_AES_256 */ - - - if (wc_AesInit(&enc, HEAP_HINT, devId) != 0) - return -4750; -#ifdef HAVE_AES_DECRYPT - if (wc_AesInit(&dec, HEAP_HINT, devId) != 0) - return -4751; -#endif - -#ifdef WOLFSSL_AES_128 - /* 128 key tests */ - ret = wc_AesSetKey(&enc, key1, AES_BLOCK_SIZE, iv, AES_ENCRYPTION); - if (ret != 0) - return -4710; - #ifdef HAVE_AES_DECRYPT - /* decrypt uses AES_ENCRYPTION */ - ret = wc_AesSetKey(&dec, key1, AES_BLOCK_SIZE, iv, AES_ENCRYPTION); - if (ret != 0) - return -4711; - #endif - - XMEMSET(cipher, 0, sizeof(cipher)); - ret = wc_AesCfbEncrypt(&enc, cipher, msg1, AES_BLOCK_SIZE * 2); - if (ret != 0) - return -4712; - - if (XMEMCMP(cipher, cipher1, AES_BLOCK_SIZE * 2)) - return -4713; - - /* test restarting encryption process */ - ret = wc_AesCfbEncrypt(&enc, cipher + (AES_BLOCK_SIZE * 2), - msg1 + (AES_BLOCK_SIZE * 2), AES_BLOCK_SIZE); - if (ret != 0) - return -4714; - - if (XMEMCMP(cipher + (AES_BLOCK_SIZE * 2), - cipher1 + (AES_BLOCK_SIZE * 2), AES_BLOCK_SIZE)) - return -4715; - - #ifdef HAVE_AES_DECRYPT - ret = wc_AesCfbDecrypt(&dec, plain, cipher, AES_BLOCK_SIZE * 3); - if (ret != 0) - return -4716; - - if (XMEMCMP(plain, msg1, AES_BLOCK_SIZE * 3)) - return -4717; - #endif /* HAVE_AES_DECRYPT */ -#endif /* WOLFSSL_AES_128 */ - -#ifdef WOLFSSL_AES_192 - /* 192 key size test */ - ret = wc_AesSetKey(&enc, key2, sizeof(key2), iv, AES_ENCRYPTION); - if (ret != 0) - return -4718; - #ifdef HAVE_AES_DECRYPT - /* decrypt uses AES_ENCRYPTION */ - ret = wc_AesSetKey(&dec, key2, sizeof(key2), iv, AES_ENCRYPTION); - if (ret != 0) - return -4719; - #endif - - XMEMSET(cipher, 0, sizeof(cipher)); - ret = wc_AesCfbEncrypt(&enc, cipher, msg2, AES_BLOCK_SIZE * 4); - if (ret != 0) - return -4720; - - if (XMEMCMP(cipher, cipher2, AES_BLOCK_SIZE * 4)) - return -4721; - - #ifdef HAVE_AES_DECRYPT - ret = wc_AesCfbDecrypt(&dec, plain, cipher, AES_BLOCK_SIZE * 4); - if (ret != 0) - return -4722; - - if (XMEMCMP(plain, msg2, AES_BLOCK_SIZE * 4)) - return -4723; - #endif /* HAVE_AES_DECRYPT */ -#endif /* WOLFSSL_AES_192 */ - -#ifdef WOLFSSL_AES_256 - /* 256 key size test */ - ret = wc_AesSetKey(&enc, key3, sizeof(key3), iv, AES_ENCRYPTION); - if (ret != 0) - return -4724; - #ifdef HAVE_AES_DECRYPT - /* decrypt uses AES_ENCRYPTION */ - ret = wc_AesSetKey(&dec, key3, sizeof(key3), iv, AES_ENCRYPTION); - if (ret != 0) - return -4725; - #endif - - /* test with data left overs, magic lengths are checking near edges */ - XMEMSET(cipher, 0, sizeof(cipher)); - ret = wc_AesCfbEncrypt(&enc, cipher, msg3, 4); - if (ret != 0) - return -4726; - - if (XMEMCMP(cipher, cipher3, 4)) - return -4727; - - ret = wc_AesCfbEncrypt(&enc, cipher + 4, msg3 + 4, 27); - if (ret != 0) - return -4728; - - if (XMEMCMP(cipher + 4, cipher3 + 4, 27)) - return -4729; - - ret = wc_AesCfbEncrypt(&enc, cipher + 31, msg3 + 31, - (AES_BLOCK_SIZE * 4) - 31); - if (ret != 0) - return -4730; - - if (XMEMCMP(cipher, cipher3, AES_BLOCK_SIZE * 4)) - return -4731; - - #ifdef HAVE_AES_DECRYPT - ret = wc_AesCfbDecrypt(&dec, plain, cipher, 4); - if (ret != 0) - return -4732; - - if (XMEMCMP(plain, msg3, 4)) - return -4733; - - ret = wc_AesCfbDecrypt(&dec, plain + 4, cipher + 4, 4); - if (ret != 0) - return -4734; - - ret = wc_AesCfbDecrypt(&dec, plain + 8, cipher + 8, 23); - if (ret != 0) - return -4735; - - if (XMEMCMP(plain + 4, msg3 + 4, 27)) - return -4736; - - ret = wc_AesCfbDecrypt(&dec, plain + 31, cipher + 31, - (AES_BLOCK_SIZE * 4) - 31); - if (ret != 0) - return -4737; - - if (XMEMCMP(plain, msg3, AES_BLOCK_SIZE * 4)) - return -4738; - #endif /* HAVE_AES_DECRYPT */ -#endif /* WOLFSSL_AES_256 */ - - return ret; - } - - - static int aescfb1_test(void) - { - Aes enc; - byte cipher[AES_BLOCK_SIZE]; - #ifdef HAVE_AES_DECRYPT - Aes dec; - byte plain [AES_BLOCK_SIZE]; - #endif - int ret = 0; - - const byte iv[] = { - 0x4d,0xbb,0xdc,0xaa,0x59,0xf3,0x63,0xc9, - 0x2a,0x3b,0x98,0x43,0xad,0x20,0xe2,0xb7 - }; - -#ifdef WOLFSSL_AES_128 - const byte key1[] = - { - 0xcd,0xef,0x9d,0x06,0x61,0xba,0xe4,0x73, - 0x8d,0x1a,0x58,0xa2,0xa6,0x22,0x8b,0x66 - }; - - const byte cipher1[] = - { - 0x00 - }; - - const byte msg1[] = - { - 0xC0 - }; -#endif /* WOLFSSL_AES_128 */ - - if (wc_AesInit(&enc, HEAP_HINT, devId) != 0) - return -4739; -#ifdef HAVE_AES_DECRYPT - if (wc_AesInit(&dec, HEAP_HINT, devId) != 0) - return -4740; -#endif - -#ifdef WOLFSSL_AES_128 - /* 128 key tests */ - ret = wc_AesSetKey(&enc, key1, AES_BLOCK_SIZE, iv, AES_ENCRYPTION); - if (ret != 0) - return -4741; - #ifdef HAVE_AES_DECRYPT - /* decrypt uses AES_ENCRYPTION */ - ret = wc_AesSetKey(&dec, key1, AES_BLOCK_SIZE, iv, AES_ENCRYPTION); - if (ret != 0) - return -4742; - #endif - - XMEMSET(cipher, 0, sizeof(cipher)); - ret = wc_AesCfb1Encrypt(&enc, cipher, msg1, 2); - if (ret != 0) - return -4743; - - if (cipher[0] != cipher1[0]) - return -4744; - - #ifdef HAVE_AES_DECRYPT - ret = wc_AesCfb1Decrypt(&dec, plain, cipher, 2); - if (ret != 0) - return -4745; - - if (plain[0] != msg1[0]) - return -4746; - #endif /* HAVE_AES_DECRYPT */ -#endif /* WOLFSSL_AES_128 */ - - return ret; - } - - static int aescfb8_test(void) - { - Aes enc; - byte cipher[AES_BLOCK_SIZE]; - #ifdef HAVE_AES_DECRYPT - Aes dec; - byte plain [AES_BLOCK_SIZE]; - #endif - int ret = 0; - - const byte iv[] = { - 0xf4,0x75,0xc6,0x49,0x91,0xb2,0x0e,0xae, - 0xe1,0x83,0xa2,0x26,0x29,0xe2,0x1e,0x22 - }; - -#ifdef WOLFSSL_AES_128 - const byte key1[] = - { - 0xc8,0xfe,0x9b,0xf7,0x7b,0x93,0x0f,0x46, - 0xd2,0x07,0x8b,0x8c,0x0e,0x65,0x7c,0xd4 - }; - - const byte cipher1[] = - { - 0xd2,0x76,0x91 - }; - - const byte msg1[] = - { - 0xc9,0x06,0x35 - }; -#endif /* WOLFSSL_AES_128 */ - - if (wc_AesInit(&enc, HEAP_HINT, devId) != 0) - return -4739; -#ifdef HAVE_AES_DECRYPT - if (wc_AesInit(&dec, HEAP_HINT, devId) != 0) - return -4740; -#endif - -#ifdef WOLFSSL_AES_128 - /* 128 key tests */ - ret = wc_AesSetKey(&enc, key1, AES_BLOCK_SIZE, iv, AES_ENCRYPTION); - if (ret != 0) - return -4741; - #ifdef HAVE_AES_DECRYPT - /* decrypt uses AES_ENCRYPTION */ - ret = wc_AesSetKey(&dec, key1, AES_BLOCK_SIZE, iv, AES_ENCRYPTION); - if (ret != 0) - return -4742; - #endif - - XMEMSET(cipher, 0, sizeof(cipher)); - ret = wc_AesCfb8Encrypt(&enc, cipher, msg1, sizeof(msg1)); - if (ret != 0) - return -4743; - - if (XMEMCMP(cipher, cipher1, sizeof(cipher1)) != 0) - return -4744; - - #ifdef HAVE_AES_DECRYPT - ret = wc_AesCfb8Decrypt(&dec, plain, cipher, sizeof(msg1)); - if (ret != 0) - return -4745; - - if (XMEMCMP(plain, msg1, sizeof(msg1)) != 0) - return -4746; - #endif /* HAVE_AES_DECRYPT */ -#endif /* WOLFSSL_AES_128 */ - - return ret; - } -#endif /* WOLFSSL_AES_CFB */ - - -#ifdef WOLFSSL_AES_OFB +#if defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_CFB) #ifdef OPENSSL_EXTRA /* pass in the function, key, iv, plain text and expected and this function * tests that the encryption and decryption is successful */ @@ -6030,7 +5622,6 @@ static int EVP_test(const WOLFSSL_EVP_CIPHER* type, const byte* key, return -8000; } - /* test encrypt */ EVP_CIPHER_CTX_init(&ctx); if (EVP_CipherInit(&ctx, type, key, iv, 1) == 0) { @@ -6084,7 +5675,9 @@ EVP_TEST_END: return ret; } #endif /* OPENSSL_EXTRA */ +#endif /* WOLFSSL_AES_OFB || WOLFSSL_AES_CFB */ +#ifdef WOLFSSL_AES_OFB /* test vector from https://csrc.nist.gov/Projects/cryptographic-algorithm-validation-program/Block-Ciphers */ int aesofb_test(void) { @@ -6411,6 +6004,437 @@ EVP_TEST_END: } #endif /* WOLFSSL_AES_OFB */ +#ifdef WOLFSSL_AES_CFB + /* Test cases from NIST SP 800-38A, Recommendation for Block Cipher Modes of Operation Methods an*/ + static int aescfb_test(void) + { + Aes enc; + byte cipher[AES_BLOCK_SIZE * 4]; + #ifdef HAVE_AES_DECRYPT + Aes dec; + byte plain [AES_BLOCK_SIZE * 4]; + #endif + int ret = 0; + + const byte iv[] = { + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, + 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f + }; + +#ifdef WOLFSSL_AES_128 + const byte key1[] = + { + 0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6, + 0xab,0xf7,0x15,0x88,0x09,0xcf,0x4f,0x3c + }; + + const byte cipher1[] = + { + 0x3b,0x3f,0xd9,0x2e,0xb7,0x2d,0xad,0x20, + 0x33,0x34,0x49,0xf8,0xe8,0x3c,0xfb,0x4a, + 0xc8,0xa6,0x45,0x37,0xa0,0xb3,0xa9,0x3f, + 0xcd,0xe3,0xcd,0xad,0x9f,0x1c,0xe5,0x8b, + 0x26,0x75,0x1f,0x67,0xa3,0xcb,0xb1,0x40, + 0xb1,0x80,0x8c,0xf1,0x87,0xa4,0xf4,0xdf + }; + + const byte msg1[] = + { + 0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96, + 0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a, + 0xae,0x2d,0x8a,0x57,0x1e,0x03,0xac,0x9c, + 0x9e,0xb7,0x6f,0xac,0x45,0xaf,0x8e,0x51, + 0x30,0xc8,0x1c,0x46,0xa3,0x5c,0xe4,0x11, + 0xe5,0xfb,0xc1,0x19,0x1a,0x0a,0x52,0xef + }; +#endif /* WOLFSSL_AES_128 */ + +#ifdef WOLFSSL_AES_192 + /* 192 size key test */ + const byte key2[] = + { + 0x8e,0x73,0xb0,0xf7,0xda,0x0e,0x64,0x52, + 0xc8,0x10,0xf3,0x2b,0x80,0x90,0x79,0xe5, + 0x62,0xf8,0xea,0xd2,0x52,0x2c,0x6b,0x7b + }; + + const byte cipher2[] = + { + 0xcd,0xc8,0x0d,0x6f,0xdd,0xf1,0x8c,0xab, + 0x34,0xc2,0x59,0x09,0xc9,0x9a,0x41,0x74, + 0x67,0xce,0x7f,0x7f,0x81,0x17,0x36,0x21, + 0x96,0x1a,0x2b,0x70,0x17,0x1d,0x3d,0x7a, + 0x2e,0x1e,0x8a,0x1d,0xd5,0x9b,0x88,0xb1, + 0xc8,0xe6,0x0f,0xed,0x1e,0xfa,0xc4,0xc9, + 0xc0,0x5f,0x9f,0x9c,0xa9,0x83,0x4f,0xa0, + 0x42,0xae,0x8f,0xba,0x58,0x4b,0x09,0xff + }; + + const byte msg2[] = + { + 0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96, + 0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a, + 0xae,0x2d,0x8a,0x57,0x1e,0x03,0xac,0x9c, + 0x9e,0xb7,0x6f,0xac,0x45,0xaf,0x8e,0x51, + 0x30,0xc8,0x1c,0x46,0xa3,0x5c,0xe4,0x11, + 0xe5,0xfb,0xc1,0x19,0x1a,0x0a,0x52,0xef, + 0xf6,0x9f,0x24,0x45,0xdf,0x4f,0x9b,0x17, + 0xad,0x2b,0x41,0x7b,0xe6,0x6c,0x37,0x10 + }; +#endif /* WOLFSSL_AES_192 */ + +#ifdef WOLFSSL_AES_256 + /* 256 size key simple test */ + const byte key3[] = + { + 0x60,0x3d,0xeb,0x10,0x15,0xca,0x71,0xbe, + 0x2b,0x73,0xae,0xf0,0x85,0x7d,0x77,0x81, + 0x1f,0x35,0x2c,0x07,0x3b,0x61,0x08,0xd7, + 0x2d,0x98,0x10,0xa3,0x09,0x14,0xdf,0xf4 + }; + + const byte cipher3[] = + { + 0xdc,0x7e,0x84,0xbf,0xda,0x79,0x16,0x4b, + 0x7e,0xcd,0x84,0x86,0x98,0x5d,0x38,0x60, + 0x39,0xff,0xed,0x14,0x3b,0x28,0xb1,0xc8, + 0x32,0x11,0x3c,0x63,0x31,0xe5,0x40,0x7b, + 0xdf,0x10,0x13,0x24,0x15,0xe5,0x4b,0x92, + 0xa1,0x3e,0xd0,0xa8,0x26,0x7a,0xe2,0xf9, + 0x75,0xa3,0x85,0x74,0x1a,0xb9,0xce,0xf8, + 0x20,0x31,0x62,0x3d,0x55,0xb1,0xe4,0x71 + }; + + const byte msg3[] = + { + 0x6b,0xc1,0xbe,0xe2,0x2e,0x40,0x9f,0x96, + 0xe9,0x3d,0x7e,0x11,0x73,0x93,0x17,0x2a, + 0xae,0x2d,0x8a,0x57,0x1e,0x03,0xac,0x9c, + 0x9e,0xb7,0x6f,0xac,0x45,0xaf,0x8e,0x51, + 0x30,0xc8,0x1c,0x46,0xa3,0x5c,0xe4,0x11, + 0xe5,0xfb,0xc1,0x19,0x1a,0x0a,0x52,0xef, + 0xf6,0x9f,0x24,0x45,0xdf,0x4f,0x9b,0x17, + 0xad,0x2b,0x41,0x7b,0xe6,0x6c,0x37,0x10 + }; +#endif /* WOLFSSL_AES_256 */ + + + if (wc_AesInit(&enc, HEAP_HINT, devId) != 0) + return -4750; +#ifdef HAVE_AES_DECRYPT + if (wc_AesInit(&dec, HEAP_HINT, devId) != 0) + return -4751; +#endif + +#ifdef WOLFSSL_AES_128 + /* 128 key tests */ + #ifdef OPENSSL_EXTRA + ret = EVP_test(EVP_aes_128_cfb128(), key1, iv, msg1, sizeof(msg1), + cipher1, sizeof(cipher1)); + if (ret != 0) { + return ret; + } + #endif + + ret = wc_AesSetKey(&enc, key1, AES_BLOCK_SIZE, iv, AES_ENCRYPTION); + if (ret != 0) + return -4710; + #ifdef HAVE_AES_DECRYPT + /* decrypt uses AES_ENCRYPTION */ + ret = wc_AesSetKey(&dec, key1, AES_BLOCK_SIZE, iv, AES_ENCRYPTION); + if (ret != 0) + return -4711; + #endif + + XMEMSET(cipher, 0, sizeof(cipher)); + ret = wc_AesCfbEncrypt(&enc, cipher, msg1, AES_BLOCK_SIZE * 2); + if (ret != 0) + return -4712; + + if (XMEMCMP(cipher, cipher1, AES_BLOCK_SIZE * 2)) + return -4713; + + /* test restarting encryption process */ + ret = wc_AesCfbEncrypt(&enc, cipher + (AES_BLOCK_SIZE * 2), + msg1 + (AES_BLOCK_SIZE * 2), AES_BLOCK_SIZE); + if (ret != 0) + return -4714; + + if (XMEMCMP(cipher + (AES_BLOCK_SIZE * 2), + cipher1 + (AES_BLOCK_SIZE * 2), AES_BLOCK_SIZE)) + return -4715; + + #ifdef HAVE_AES_DECRYPT + ret = wc_AesCfbDecrypt(&dec, plain, cipher, AES_BLOCK_SIZE * 3); + if (ret != 0) + return -4716; + + if (XMEMCMP(plain, msg1, AES_BLOCK_SIZE * 3)) + return -4717; + #endif /* HAVE_AES_DECRYPT */ +#endif /* WOLFSSL_AES_128 */ + +#ifdef WOLFSSL_AES_192 + /* 192 key size test */ + #ifdef OPENSSL_EXTRA + ret = EVP_test(EVP_aes_192_cfb128(), key2, iv, msg2, sizeof(msg2), + cipher2, sizeof(cipher2)); + if (ret != 0) { + return ret; + } + #endif + + ret = wc_AesSetKey(&enc, key2, sizeof(key2), iv, AES_ENCRYPTION); + if (ret != 0) + return -4718; + #ifdef HAVE_AES_DECRYPT + /* decrypt uses AES_ENCRYPTION */ + ret = wc_AesSetKey(&dec, key2, sizeof(key2), iv, AES_ENCRYPTION); + if (ret != 0) + return -4719; + #endif + + XMEMSET(cipher, 0, sizeof(cipher)); + ret = wc_AesCfbEncrypt(&enc, cipher, msg2, AES_BLOCK_SIZE * 4); + if (ret != 0) + return -4720; + + if (XMEMCMP(cipher, cipher2, AES_BLOCK_SIZE * 4)) + return -4721; + + #ifdef HAVE_AES_DECRYPT + ret = wc_AesCfbDecrypt(&dec, plain, cipher, AES_BLOCK_SIZE * 4); + if (ret != 0) + return -4722; + + if (XMEMCMP(plain, msg2, AES_BLOCK_SIZE * 4)) + return -4723; + #endif /* HAVE_AES_DECRYPT */ +#endif /* WOLFSSL_AES_192 */ + +#ifdef WOLFSSL_AES_256 + /* 256 key size test */ + #ifdef OPENSSL_EXTRA + ret = EVP_test(EVP_aes_256_cfb128(), key3, iv, msg3, sizeof(msg3), + cipher3, sizeof(cipher3)); + if (ret != 0) { + return ret; + } + #endif + ret = wc_AesSetKey(&enc, key3, sizeof(key3), iv, AES_ENCRYPTION); + if (ret != 0) + return -4724; + #ifdef HAVE_AES_DECRYPT + /* decrypt uses AES_ENCRYPTION */ + ret = wc_AesSetKey(&dec, key3, sizeof(key3), iv, AES_ENCRYPTION); + if (ret != 0) + return -4725; + #endif + + /* test with data left overs, magic lengths are checking near edges */ + XMEMSET(cipher, 0, sizeof(cipher)); + ret = wc_AesCfbEncrypt(&enc, cipher, msg3, 4); + if (ret != 0) + return -4726; + + if (XMEMCMP(cipher, cipher3, 4)) + return -4727; + + ret = wc_AesCfbEncrypt(&enc, cipher + 4, msg3 + 4, 27); + if (ret != 0) + return -4728; + + if (XMEMCMP(cipher + 4, cipher3 + 4, 27)) + return -4729; + + ret = wc_AesCfbEncrypt(&enc, cipher + 31, msg3 + 31, + (AES_BLOCK_SIZE * 4) - 31); + if (ret != 0) + return -4730; + + if (XMEMCMP(cipher, cipher3, AES_BLOCK_SIZE * 4)) + return -4731; + + #ifdef HAVE_AES_DECRYPT + ret = wc_AesCfbDecrypt(&dec, plain, cipher, 4); + if (ret != 0) + return -4732; + + if (XMEMCMP(plain, msg3, 4)) + return -4733; + + ret = wc_AesCfbDecrypt(&dec, plain + 4, cipher + 4, 4); + if (ret != 0) + return -4734; + + ret = wc_AesCfbDecrypt(&dec, plain + 8, cipher + 8, 23); + if (ret != 0) + return -4735; + + if (XMEMCMP(plain + 4, msg3 + 4, 27)) + return -4736; + + ret = wc_AesCfbDecrypt(&dec, plain + 31, cipher + 31, + (AES_BLOCK_SIZE * 4) - 31); + if (ret != 0) + return -4737; + + if (XMEMCMP(plain, msg3, AES_BLOCK_SIZE * 4)) + return -4738; + #endif /* HAVE_AES_DECRYPT */ +#endif /* WOLFSSL_AES_256 */ + + return ret; + } + + + static int aescfb1_test(void) + { + Aes enc; + byte cipher[AES_BLOCK_SIZE]; + #ifdef HAVE_AES_DECRYPT + Aes dec; + byte plain [AES_BLOCK_SIZE]; + #endif + int ret = 0; + + const byte iv[] = { + 0x4d,0xbb,0xdc,0xaa,0x59,0xf3,0x63,0xc9, + 0x2a,0x3b,0x98,0x43,0xad,0x20,0xe2,0xb7 + }; + +#ifdef WOLFSSL_AES_128 + const byte key1[] = + { + 0xcd,0xef,0x9d,0x06,0x61,0xba,0xe4,0x73, + 0x8d,0x1a,0x58,0xa2,0xa6,0x22,0x8b,0x66 + }; + + const byte cipher1[] = + { + 0x00 + }; + + const byte msg1[] = + { + 0xC0 + }; +#endif /* WOLFSSL_AES_128 */ + + if (wc_AesInit(&enc, HEAP_HINT, devId) != 0) + return -4739; +#ifdef HAVE_AES_DECRYPT + if (wc_AesInit(&dec, HEAP_HINT, devId) != 0) + return -4740; +#endif + +#ifdef WOLFSSL_AES_128 + /* 128 key tests */ + ret = wc_AesSetKey(&enc, key1, AES_BLOCK_SIZE, iv, AES_ENCRYPTION); + if (ret != 0) + return -4741; + #ifdef HAVE_AES_DECRYPT + /* decrypt uses AES_ENCRYPTION */ + ret = wc_AesSetKey(&dec, key1, AES_BLOCK_SIZE, iv, AES_ENCRYPTION); + if (ret != 0) + return -4742; + #endif + + XMEMSET(cipher, 0, sizeof(cipher)); + ret = wc_AesCfb1Encrypt(&enc, cipher, msg1, 2); + if (ret != 0) + return -4743; + + if (cipher[0] != cipher1[0]) + return -4744; + + #ifdef HAVE_AES_DECRYPT + ret = wc_AesCfb1Decrypt(&dec, plain, cipher, 2); + if (ret != 0) + return -4745; + + if (plain[0] != msg1[0]) + return -4746; + #endif /* HAVE_AES_DECRYPT */ +#endif /* WOLFSSL_AES_128 */ + + return ret; + } + + static int aescfb8_test(void) + { + Aes enc; + byte cipher[AES_BLOCK_SIZE]; + #ifdef HAVE_AES_DECRYPT + Aes dec; + byte plain [AES_BLOCK_SIZE]; + #endif + int ret = 0; + + const byte iv[] = { + 0xf4,0x75,0xc6,0x49,0x91,0xb2,0x0e,0xae, + 0xe1,0x83,0xa2,0x26,0x29,0xe2,0x1e,0x22 + }; + +#ifdef WOLFSSL_AES_128 + const byte key1[] = + { + 0xc8,0xfe,0x9b,0xf7,0x7b,0x93,0x0f,0x46, + 0xd2,0x07,0x8b,0x8c,0x0e,0x65,0x7c,0xd4 + }; + + const byte cipher1[] = + { + 0xd2,0x76,0x91 + }; + + const byte msg1[] = + { + 0xc9,0x06,0x35 + }; +#endif /* WOLFSSL_AES_128 */ + + if (wc_AesInit(&enc, HEAP_HINT, devId) != 0) + return -4739; +#ifdef HAVE_AES_DECRYPT + if (wc_AesInit(&dec, HEAP_HINT, devId) != 0) + return -4740; +#endif + +#ifdef WOLFSSL_AES_128 + /* 128 key tests */ + ret = wc_AesSetKey(&enc, key1, AES_BLOCK_SIZE, iv, AES_ENCRYPTION); + if (ret != 0) + return -4741; + #ifdef HAVE_AES_DECRYPT + /* decrypt uses AES_ENCRYPTION */ + ret = wc_AesSetKey(&dec, key1, AES_BLOCK_SIZE, iv, AES_ENCRYPTION); + if (ret != 0) + return -4742; + #endif + + XMEMSET(cipher, 0, sizeof(cipher)); + ret = wc_AesCfb8Encrypt(&enc, cipher, msg1, sizeof(msg1)); + if (ret != 0) + return -4743; + + if (XMEMCMP(cipher, cipher1, sizeof(cipher1)) != 0) + return -4744; + + #ifdef HAVE_AES_DECRYPT + ret = wc_AesCfb8Decrypt(&dec, plain, cipher, sizeof(msg1)); + if (ret != 0) + return -4745; + + if (XMEMCMP(plain, msg1, sizeof(msg1)) != 0) + return -4746; + #endif /* HAVE_AES_DECRYPT */ +#endif /* WOLFSSL_AES_128 */ + + return ret; + } +#endif /* WOLFSSL_AES_CFB */ + static int aes_key_size_test(void) { From d4428ebc0c3e888d29fc265c55a58685b665230d Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Wed, 29 Jan 2020 11:23:54 -0700 Subject: [PATCH 127/649] add EVP cfb1 test and update some EVP code --- src/ssl.c | 21 +++++++++++-------- wolfcrypt/src/evp.c | 48 +++++++++++++++++++++++++++++++++++++++++++ wolfcrypt/test/test.c | 15 ++++++++++---- 3 files changed, 71 insertions(+), 13 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 0f928be97..6c02976db 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -4207,6 +4207,9 @@ const WOLFSSL_EVP_CIPHER *wolfSSL_EVP_get_cipherbynid(int id) static char *EVP_AES_256_ECB; #endif static const int EVP_AES_SIZE = 11; + #ifdef WOLFSSL_AES_CFB + static const int EVP_AESCFB_SIZE = 14; + #endif #endif #endif @@ -17450,7 +17453,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) #ifdef WOLFSSL_AES_CFB #ifdef WOLFSSL_AES_128 if (ctx->cipherType == AES_128_CFB1_TYPE || - (type && XSTRNCMP(type, EVP_AES_128_CFB1, EVP_AES_SIZE) == 0)) { + (type && XSTRNCMP(type, EVP_AES_128_CFB1, EVP_AESCFB_SIZE) == 0)) { WOLFSSL_MSG("EVP_AES_128_CFB1"); ctx->cipherType = AES_128_CFB1_TYPE; ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE; @@ -17474,7 +17477,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) #endif /* WOLFSSL_AES_128 */ #ifdef WOLFSSL_AES_192 if (ctx->cipherType == AES_192_CFB1_TYPE || - (type && XSTRNCMP(type, EVP_AES_192_CFB1, EVP_AES_SIZE) == 0)) { + (type && XSTRNCMP(type, EVP_AES_192_CFB1, EVP_AESCFB_SIZE) == 0)) { WOLFSSL_MSG("EVP_AES_192_CFB1"); ctx->cipherType = AES_192_CFB1_TYPE; ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE; @@ -17498,7 +17501,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) #endif /* WOLFSSL_AES_192 */ #ifdef WOLFSSL_AES_256 if (ctx->cipherType == AES_256_CFB1_TYPE || - (type && XSTRNCMP(type, EVP_AES_256_CFB1, EVP_AES_SIZE) == 0)) { + (type && XSTRNCMP(type, EVP_AES_256_CFB1, EVP_AESCFB_SIZE) == 0)) { WOLFSSL_MSG("EVP_AES_256_CFB1"); ctx->cipherType = AES_256_CFB1_TYPE; ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE; @@ -17526,7 +17529,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) #endif /* WOLFSSL_AES_256 */ #ifdef WOLFSSL_AES_128 if (ctx->cipherType == AES_128_CFB8_TYPE || - (type && XSTRNCMP(type, EVP_AES_128_CFB8, EVP_AES_SIZE) == 0)) { + (type && XSTRNCMP(type, EVP_AES_128_CFB8, EVP_AESCFB_SIZE) == 0)) { WOLFSSL_MSG("EVP_AES_128_CFB8"); ctx->cipherType = AES_128_CFB8_TYPE; ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE; @@ -17550,7 +17553,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) #endif /* WOLFSSL_AES_128 */ #ifdef WOLFSSL_AES_192 if (ctx->cipherType == AES_192_CFB8_TYPE || - (type && XSTRNCMP(type, EVP_AES_192_CFB8, EVP_AES_SIZE) == 0)) { + (type && XSTRNCMP(type, EVP_AES_192_CFB8, EVP_AESCFB_SIZE) == 0)) { WOLFSSL_MSG("EVP_AES_192_CFB8"); ctx->cipherType = AES_192_CFB8_TYPE; ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE; @@ -17574,7 +17577,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) #endif /* WOLFSSL_AES_192 */ #ifdef WOLFSSL_AES_256 if (ctx->cipherType == AES_256_CFB8_TYPE || - (type && XSTRNCMP(type, EVP_AES_256_CFB8, EVP_AES_SIZE) == 0)) { + (type && XSTRNCMP(type, EVP_AES_256_CFB8, EVP_AESCFB_SIZE) == 0)) { WOLFSSL_MSG("EVP_AES_256_CFB8"); ctx->cipherType = AES_256_CFB8_TYPE; ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE; @@ -17602,7 +17605,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) #endif /* WOLFSSL_AES_256 */ #ifdef WOLFSSL_AES_128 if (ctx->cipherType == AES_128_CFB128_TYPE || - (type && XSTRNCMP(type, EVP_AES_128_CFB128, EVP_AES_SIZE) == 0)) { + (type && XSTRNCMP(type, EVP_AES_128_CFB128, EVP_AESCFB_SIZE) == 0)) { WOLFSSL_MSG("EVP_AES_128_CFB128"); ctx->cipherType = AES_128_CFB128_TYPE; ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE; @@ -17626,7 +17629,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) #endif /* WOLFSSL_AES_128 */ #ifdef WOLFSSL_AES_192 if (ctx->cipherType == AES_192_CFB128_TYPE || - (type && XSTRNCMP(type, EVP_AES_192_CFB128, EVP_AES_SIZE) == 0)) { + (type && XSTRNCMP(type, EVP_AES_192_CFB128, EVP_AESCFB_SIZE) == 0)) { WOLFSSL_MSG("EVP_AES_192_CFB128"); ctx->cipherType = AES_192_CFB128_TYPE; ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE; @@ -17650,7 +17653,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) #endif /* WOLFSSL_AES_192 */ #ifdef WOLFSSL_AES_256 if (ctx->cipherType == AES_256_CFB128_TYPE || - (type && XSTRNCMP(type, EVP_AES_256_CFB128, EVP_AES_SIZE) == 0)) { + (type && XSTRNCMP(type, EVP_AES_256_CFB128, EVP_AESCFB_SIZE) == 0)) { WOLFSSL_MSG("EVP_AES_256_CFB128"); ctx->cipherType = AES_256_CFB128_TYPE; ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE; diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index ec10dc2a5..cb8c272ca 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -859,6 +859,54 @@ static unsigned int cipherType(const WOLFSSL_EVP_CIPHER *cipher) return AES_256_ECB_TYPE; #endif #endif /*HAVE_AES_CBC */ + #if defined(WOLFSSL_AES_XTS) + #ifdef WOLFSSL_AES_128 + else if (XSTRNCMP(cipher, EVP_AES_128_XTS, EVP_AES_SIZE) == 0) + return AES_128_XTS_TYPE; + #endif + #ifdef WOLFSSL_AES_256 + else if (XSTRNCMP(cipher, EVP_AES_256_XTS, EVP_AES_SIZE) == 0) + return AES_256_XTS_TYPE; + #endif + #endif /* WOLFSSL_AES_XTS */ + #if defined(WOLFSSL_AES_CFB) + #ifdef WOLFSSL_AES_128 + else if (XSTRNCMP(cipher, EVP_AES_128_CFB1, EVP_AESCFB_SIZE) == 0) + return AES_128_CFB1_TYPE; + #endif + #ifdef WOLFSSL_AES_192 + else if (XSTRNCMP(cipher, EVP_AES_192_CFB1, EVP_AESCFB_SIZE) == 0) + return AES_192_CFB1_TYPE; + #endif + #ifdef WOLFSSL_AES_256 + else if (XSTRNCMP(cipher, EVP_AES_256_CFB1, EVP_AESCFB_SIZE) == 0) + return AES_256_CFB1_TYPE; + #endif + #ifdef WOLFSSL_AES_128 + else if (XSTRNCMP(cipher, EVP_AES_128_CFB8, EVP_AESCFB_SIZE) == 0) + return AES_128_CFB8_TYPE; + #endif + #ifdef WOLFSSL_AES_192 + else if (XSTRNCMP(cipher, EVP_AES_192_CFB8, EVP_AESCFB_SIZE) == 0) + return AES_192_CFB8_TYPE; + #endif + #ifdef WOLFSSL_AES_256 + else if (XSTRNCMP(cipher, EVP_AES_256_CFB8, EVP_AESCFB_SIZE) == 0) + return AES_256_CFB8_TYPE; + #endif + #ifdef WOLFSSL_AES_128 + else if (XSTRNCMP(cipher, EVP_AES_128_CFB128, EVP_AESCFB_SIZE) == 0) + return AES_128_CFB128_TYPE; + #endif + #ifdef WOLFSSL_AES_192 + else if (XSTRNCMP(cipher, EVP_AES_192_CFB128, EVP_AESCFB_SIZE) == 0) + return AES_192_CFB128_TYPE; + #endif + #ifdef WOLFSSL_AES_256 + else if (XSTRNCMP(cipher, EVP_AES_256_CFB128, EVP_AESCFB_SIZE) == 0) + return AES_256_CFB128_TYPE; + #endif + #endif /*HAVE_AES_CBC */ #endif /* !NO_AES */ else return 0; } diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index b2ac1b03c..20bdb47dc 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -5629,7 +5629,7 @@ static int EVP_test(const WOLFSSL_EVP_CIPHER* type, const byte* key, goto EVP_TEST_END; } - if (EVP_CipherUpdate(&ctx, cipher, &idx, plain, plainSz) == 0) { + if (EVP_CipherUpdate(&ctx, cipher, &idx, plain, expectedSz) == 0) { ret = -8002; goto EVP_TEST_END; } @@ -5641,7 +5641,7 @@ static int EVP_test(const WOLFSSL_EVP_CIPHER* type, const byte* key, } cipherSz += idx; - if (XMEMCMP(cipher, expected, expectedSz)) { + if (XMEMCMP(cipher, expected, plainSz)) { ret = -8004; goto EVP_TEST_END; } @@ -5653,7 +5653,7 @@ static int EVP_test(const WOLFSSL_EVP_CIPHER* type, const byte* key, goto EVP_TEST_END; } - if (EVP_CipherUpdate(&ctx, cipher, &idx, cipher, cipherSz) == 0) { + if (EVP_CipherUpdate(&ctx, cipher, &idx, cipher, expectedSz) == 0) { ret = -8006; goto EVP_TEST_END; } @@ -5665,7 +5665,7 @@ static int EVP_test(const WOLFSSL_EVP_CIPHER* type, const byte* key, } cipherSz += idx; - if ((plainSz != cipherSz) || XMEMCMP(plain, cipher, cipherSz)) { + if ((expectedSz != cipherSz) || XMEMCMP(plain, cipher, plainSz)) { ret = -8008; goto EVP_TEST_END; } @@ -6330,6 +6330,13 @@ EVP_TEST_END: #ifdef WOLFSSL_AES_128 /* 128 key tests */ + #ifdef OPENSSL_EXTRA + ret = EVP_test(EVP_aes_128_cfb1(), key1, iv, msg1, sizeof(msg1), + cipher1, 2); + if (ret != 0) { + return ret; + } + #endif ret = wc_AesSetKey(&enc, key1, AES_BLOCK_SIZE, iv, AES_ENCRYPTION); if (ret != 0) return -4741; From d6be24c4f7b822109d57f8aac989ffd9d890a55c Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Wed, 29 Jan 2020 11:39:15 -0700 Subject: [PATCH 128/649] add 192/256 key size tests of EVP cfb8 --- wolfcrypt/test/test.c | 78 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 1 deletion(-) diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 20bdb47dc..c11c3b2d2 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -6364,6 +6364,26 @@ EVP_TEST_END: return -4746; #endif /* HAVE_AES_DECRYPT */ #endif /* WOLFSSL_AES_128 */ +#ifdef WOLFSSL_AES_192 + /* 192 key tests */ + #ifdef OPENSSL_EXTRA + ret = EVP_test(EVP_aes_192_cfb8(), key2, iv2, msg2, sizeof(msg2), + cipher2, sizeof(cipher2)); + if (ret != 0) { + return ret; + } + #endif +#endif /* WOLFSSL_AES_192 */ +#ifdef WOLFSSL_AES_256 + /* 192 key tests */ + #ifdef OPENSSL_EXTRA + ret = EVP_test(EVP_aes_256_cfb8(), key3, iv3, msg3, sizeof(msg3), + cipher3, sizeof(cipher3)); + if (ret != 0) { + return ret; + } + #endif +#endif /* WOLFSSL_AES_256 */ return ret; } @@ -6378,12 +6398,12 @@ EVP_TEST_END: #endif int ret = 0; +#ifdef WOLFSSL_AES_128 const byte iv[] = { 0xf4,0x75,0xc6,0x49,0x91,0xb2,0x0e,0xae, 0xe1,0x83,0xa2,0x26,0x29,0xe2,0x1e,0x22 }; -#ifdef WOLFSSL_AES_128 const byte key1[] = { 0xc8,0xfe,0x9b,0xf7,0x7b,0x93,0x0f,0x46, @@ -6400,6 +6420,55 @@ EVP_TEST_END: 0xc9,0x06,0x35 }; #endif /* WOLFSSL_AES_128 */ +#ifdef WOLFSSL_AES_192 + const byte iv2[] = { + 0x0a,0x02,0x84,0x6b,0x62,0xab,0xb6,0x93, + 0xef,0x31,0xd7,0x54,0x84,0x2e,0xed,0x29 + }; + + const byte key2[] = + { + 0xba,0xf0,0x8b,0x76,0x31,0x7a,0x65,0xc5, + 0xf0,0x7a,0xe6,0xf5,0x7e,0xb0,0xe6,0x54, + 0x88,0x65,0x93,0x24,0xd2,0x97,0x09,0xe3 + }; + + const byte cipher2[] = + { + 0x72,0x9c,0x0b,0x6d,0xeb,0x75,0xfa,0x6e, + 0xb5,0xe8 + }; + + const byte msg2[] = + { + 0x98,0x95,0x93,0x24,0x02,0x39,0x3d,0xc3, + 0x3a,0x60 + }; +#endif +#ifdef WOLFSSL_AES_256 + const byte iv3[] = { + 0x33,0x8c,0x55,0x2f,0xf1,0xec,0xa1,0x44, + 0x08,0xe0,0x5d,0x8c,0xf9,0xf3,0xb3,0x1b + }; + + const byte key3[] = + { + 0x06,0x48,0x74,0x09,0x2f,0x7a,0x13,0xcc, + 0x44,0x62,0x24,0x7a,0xd4,0x23,0xd0,0xe9, + 0x6e,0xdf,0x42,0xe8,0xb6,0x7a,0x5a,0x23, + 0xb7,0xa0,0xa6,0x47,0x7b,0x09,0x8e,0x66 + }; + + const byte cipher3[] = + { + 0x1c,0xff,0x95 + }; + + const byte msg3[] = + { + 0xb9,0x74,0xfa + }; +#endif if (wc_AesInit(&enc, HEAP_HINT, devId) != 0) return -4739; @@ -6410,6 +6479,13 @@ EVP_TEST_END: #ifdef WOLFSSL_AES_128 /* 128 key tests */ + #ifdef OPENSSL_EXTRA + ret = EVP_test(EVP_aes_128_cfb8(), key1, iv, msg1, sizeof(msg1), + cipher1, sizeof(cipher1)); + if (ret != 0) { + return ret; + } + #endif ret = wc_AesSetKey(&enc, key1, AES_BLOCK_SIZE, iv, AES_ENCRYPTION); if (ret != 0) return -4741; From d7c1b9561f619fc35b1268257ff4ff6abd04f752 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Wed, 29 Jan 2020 14:04:58 -0700 Subject: [PATCH 129/649] fix for cfb1 mode and add EVP tests --- wolfcrypt/src/aes.c | 18 ++++++----- wolfcrypt/test/test.c | 70 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 80 insertions(+), 8 deletions(-) diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 8ba1e0fd3..0f7bcaa37 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -7552,6 +7552,7 @@ static int wc_AesFeedbackCFB1(Aes* aes, byte* out, const byte* in, word32 sz, byte dir) { byte tmp; + byte cur = 0; /* hold current work in order to handle inline in=out */ byte* pt; int bit = 7; @@ -7563,7 +7564,6 @@ static int wc_AesFeedbackCFB1(Aes* aes, byte* out, const byte* in, return 0; } - out[0] = 0; while (sz > 0) { wc_AesEncryptDirect(aes, (byte*)aes->tmp, (byte*)aes->reg); if (dir == AES_DECRYPTION) { @@ -7572,6 +7572,7 @@ static int wc_AesFeedbackCFB1(Aes* aes, byte* out, const byte* in, /* LSB + CAT */ tmp = (0X01 << bit) & in[0]; tmp = tmp >> bit; + tmp &= 0x01; shiftLeftArray((byte*)aes->reg, 1); pt[AES_BLOCK_SIZE - 1] |= tmp; } @@ -7579,9 +7580,9 @@ static int wc_AesFeedbackCFB1(Aes* aes, byte* out, const byte* in, /* MSB + XOR */ tmp = (0X01 << bit) & in[0]; pt = (byte*)aes->tmp; - tmp = pt[0] ^ (tmp >> bit); + tmp = (pt[0] >> 7) ^ (tmp >> bit); tmp &= 0x01; - out[0] |= (tmp << bit); + cur |= (tmp << bit); if (dir == AES_ENCRYPTION) { @@ -7594,19 +7595,22 @@ static int wc_AesFeedbackCFB1(Aes* aes, byte* out, const byte* in, bit--; if (bit < 0) { + out[0] = cur; out += 1; in += 1; sz -= 1; bit = 7; - if (sz > 0) { - out[0] = 0; - } + cur = 0; } else { sz -= 1; } } + if (bit > 0) { + out[0] = cur; + } + return 0; } @@ -7616,7 +7620,7 @@ static int wc_AesFeedbackCFB1(Aes* aes, byte* out, const byte* in, * aes structure holding key to use for encryption * out buffer to hold result of encryption (must be at least as large as input * buffer) - * in buffer to encrypt + * in buffer to encrypt (packed to left, i.e. 101 is 0x90) * sz size of input buffer * * returns 0 on success and negative values on failure diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index c11c3b2d2..8929f8f09 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -6298,12 +6298,12 @@ EVP_TEST_END: #endif int ret = 0; +#ifdef WOLFSSL_AES_128 const byte iv[] = { 0x4d,0xbb,0xdc,0xaa,0x59,0xf3,0x63,0xc9, 0x2a,0x3b,0x98,0x43,0xad,0x20,0xe2,0xb7 }; -#ifdef WOLFSSL_AES_128 const byte key1[] = { 0xcd,0xef,0x9d,0x06,0x61,0xba,0xe4,0x73, @@ -6320,6 +6320,53 @@ EVP_TEST_END: 0xC0 }; #endif /* WOLFSSL_AES_128 */ +#ifdef WOLFSSL_AES_192 + const byte iv2[] = { + 0x57,0xc6,0x89,0x7c,0x99,0x52,0x28,0x13, + 0xbf,0x67,0x9c,0xe1,0x13,0x70,0xaf,0x5e + }; + + const byte key2[] = + { + 0xba,0xa1,0x58,0xa1,0x6b,0x50,0x4a,0x10, + 0x8e,0xd4,0x33,0x2e,0xe7,0xf2,0x9b,0xf6, + 0xd1,0xac,0x46,0xa8,0xde,0x5a,0xfe,0x7a + }; + + const byte cipher2[] = + { + 0x30 + }; + + const byte msg2[] = + { + 0x80 + }; +#endif /* WOLFSSL_AES_192 */ +#ifdef WOLFSSL_AES_256 + const byte iv3[] = { + 0x63,0x2e,0x9f,0x83,0x1f,0xa3,0x80,0x5e, + 0x52,0x02,0xbc,0xe0,0x6d,0x04,0xf9,0xa0 + }; + + const byte key3[] = + { + 0xf6,0xfa,0xe4,0xf1,0x5d,0x91,0xfc,0x50, + 0x88,0x78,0x4f,0x84,0xa5,0x37,0x12,0x7e, + 0x32,0x63,0x55,0x9c,0x62,0x73,0x88,0x20, + 0xc2,0xcf,0x3d,0xe1,0x1c,0x2a,0x30,0x40 + }; + + const byte cipher3[] = + { + 0xF7, 0x00 + }; + + const byte msg3[] = + { + 0x41, 0xC0 + }; +#endif /* WOLFSSL_AES_256 */ if (wc_AesInit(&enc, HEAP_HINT, devId) != 0) return -4739; @@ -6385,6 +6432,27 @@ EVP_TEST_END: #endif #endif /* WOLFSSL_AES_256 */ +#ifdef WOLFSSL_AES_192 + /* 192 key tests */ + #ifdef OPENSSL_EXTRA + ret = EVP_test(EVP_aes_192_cfb1(), key2, iv2, msg2, sizeof(msg2), + cipher2, 4); + if (ret != 0) { + return ret; + } + #endif +#endif /* WOLFSSL_AES_192 */ + +#ifdef WOLFSSL_AES_256 + /* 256 key tests */ + #ifdef OPENSSL_EXTRA + ret = EVP_test(EVP_aes_256_cfb1(), key3, iv3, msg3, sizeof(msg3), + cipher3, 10); + if (ret != 0) { + return ret; + } + #endif +#endif /* WOLFSSL_AES_192 */ return ret; } From e421d9f52c2c2dc2edb01d7c8b78b34c0d85b1d7 Mon Sep 17 00:00:00 2001 From: Eric Blankenhorn Date: Wed, 29 Jan 2020 15:30:45 -0600 Subject: [PATCH 130/649] Fix in evp_aes_xts init --- src/ssl.c | 40 +++++++++++++++++++--------------------- wolfssl/openssl/evp.h | 2 +- 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 6c02976db..7376fc939 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -17766,20 +17766,21 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ctx->cipherType = AES_128_XTS_TYPE; ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE; ctx->flags |= WOLFSSL_EVP_CIPH_XTS_MODE; - ctx->keyLen = 16; + ctx->keyLen = 32; ctx->block_size = 1; if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; - if (key) { - ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv, - AES_ENCRYPTION, 0); - if (ret != 0) - return ret; + if (iv) { + ctx->cipher.tweak = iv; + ctx->cipher.tweakSz = 16; } - if (iv && key == NULL) { - ret = wc_AesSetIV(&ctx->cipher.aes, iv); - if (ret != 0) + if (key) { + ret = wc_AesXtsSetKey(&ctx->cipher.xts, key, ctx->keyLen, + AES_ENCRYPTION, NULL, 0); + if (ret != 0) { + WOLFSSL_MSG("wc_AesXtsSetKey() failed"); return ret; + } } } #endif /* WOLFSSL_AES_128 */ @@ -17790,22 +17791,19 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ctx->cipherType = AES_256_XTS_TYPE; ctx->flags &= ~WOLFSSL_EVP_CIPH_MODE; ctx->flags |= WOLFSSL_EVP_CIPH_XTS_MODE; - ctx->keyLen = 32; + ctx->keyLen = 64; ctx->block_size = 1; if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; - if (key) { - ret = AesSetKey_ex(&ctx->cipher.aes, key, ctx->keyLen, iv, - AES_ENCRYPTION, 0); - if (ret != 0){ - WOLFSSL_MSG("AesSetKey() failed"); - return ret; - } + if (iv) { + ctx->cipher.tweak = iv; + ctx->cipher.tweakSz = 16; } - if (iv && key == NULL) { - ret = wc_AesSetIV(&ctx->cipher.aes, iv); - if (ret != 0){ - WOLFSSL_MSG("wc_AesSetIV() failed"); + if (key) { + ret = wc_AesXtsSetKey(&ctx->cipher.xts, key, ctx->keyLen, + AES_ENCRYPTION, NULL, 0); + if (ret != 0) { + WOLFSSL_MSG("wc_AesXtsSetKey() failed"); return ret; } } diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index 5c344922e..d32a65ce4 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -178,7 +178,7 @@ typedef union { Aes aes; #ifdef WOLFSSL_AES_XTS XtsAes xts; - byte* tweak; + const byte* tweak; word32 tweakSz; #endif #endif From 64dcf5740adcf805a7e2f910f8cae65b8ba4c71d Mon Sep 17 00:00:00 2001 From: Eric Blankenhorn Date: Wed, 29 Jan 2020 21:07:57 -0600 Subject: [PATCH 131/649] Fix for AES_XTS --- src/ssl.c | 30 ++++++++++++++++++------------ wolfcrypt/src/evp.c | 4 ++-- wolfcrypt/test/test.c | 16 +++++++--------- wolfssl/openssl/evp.h | 5 ++--- 4 files changed, 29 insertions(+), 26 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 7376fc939..18f09bc15 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -17768,15 +17768,18 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ctx->flags |= WOLFSSL_EVP_CIPH_XTS_MODE; ctx->keyLen = 32; ctx->block_size = 1; + ctx->ivSz = 16; + + if (iv) + XMEMCPY(ctx->iv, iv, ctx->ivSz); + else + XMEMSET(ctx->iv, 0, AES_BLOCK_SIZE); + if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; - if (iv) { - ctx->cipher.tweak = iv; - ctx->cipher.tweakSz = 16; - } if (key) { ret = wc_AesXtsSetKey(&ctx->cipher.xts, key, ctx->keyLen, - AES_ENCRYPTION, NULL, 0); + ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION, NULL, 0); if (ret != 0) { WOLFSSL_MSG("wc_AesXtsSetKey() failed"); return ret; @@ -17793,15 +17796,18 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ctx->flags |= WOLFSSL_EVP_CIPH_XTS_MODE; ctx->keyLen = 64; ctx->block_size = 1; + ctx->ivSz = 16; + + if (iv) + XMEMCPY(ctx->iv, iv, ctx->ivSz); + else + XMEMSET(ctx->iv, 0, AES_BLOCK_SIZE); + if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; - if (iv) { - ctx->cipher.tweak = iv; - ctx->cipher.tweakSz = 16; - } if (key) { ret = wc_AesXtsSetKey(&ctx->cipher.xts, key, ctx->keyLen, - AES_ENCRYPTION, NULL, 0); + ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION, NULL, 0); if (ret != 0) { WOLFSSL_MSG("wc_AesXtsSetKey() failed"); return ret; @@ -18093,10 +18099,10 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) WOLFSSL_MSG("AES XTS"); if (ctx->enc) ret = wc_AesXtsEncrypt(&ctx->cipher.xts, dst, src, len, - ctx->cipher.tweak, ctx->cipher.tweakSz); + ctx->iv, ctx->ivSz); else ret = wc_AesXtsDecrypt(&ctx->cipher.xts, dst, src, len, - ctx->cipher.tweak, ctx->cipher.tweakSz); + ctx->iv, ctx->ivSz); break; #endif /* WOLFSSL_AES_XTS */ diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index cb8c272ca..2bc22099d 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -390,10 +390,10 @@ static int evpCipherBlock(WOLFSSL_EVP_CIPHER_CTX *ctx, case AES_256_XTS_TYPE: if (ctx->enc) ret = wc_AesXtsEncrypt(&ctx->cipher.xts, out, in, inl, - ctx->cipher.tweak, ctx->cipher.tweakSz); + ctx->iv, ctx->ivSz); else ret = wc_AesXtsDecrypt(&ctx->cipher.xts, out, in, inl, - ctx->cipher.tweak, ctx->cipher.tweakSz); + ctx->iv, ctx->ivSz); break; #endif #endif /* !NO_AES */ diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 8929f8f09..6b1e5e035 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -6763,13 +6763,7 @@ static int aes_xts_128_test(void) 0xff, 0x8d, 0xbc, 0x1d, 0x9f, 0x7f, 0xc8, 0x22 }; - XMEMSET(buf, 0, sizeof(buf)); - if (wc_AesXtsSetKey(&aes, k2, sizeof(k2), AES_ENCRYPTION, - HEAP_HINT, devId) != 0) - return -4900; - -#if 0 /* Enable after passes */ -//#ifdef OPENSSL_EXTRA +#ifdef OPENSSL_EXTRA ret = EVP_test(EVP_aes_128_xts(), k2, i2, p2, sizeof(p2), c2, sizeof(c2)); if (ret != 0) { printf("EVP_aes_128_xts failed!\n"); @@ -6777,6 +6771,11 @@ static int aes_xts_128_test(void) } #endif + XMEMSET(buf, 0, sizeof(buf)); + if (wc_AesXtsSetKey(&aes, k2, sizeof(k2), AES_ENCRYPTION, + HEAP_HINT, devId) != 0) + return -4900; + ret = wc_AesXtsEncrypt(&aes, buf, p2, sizeof(p2), i2, sizeof(i2)); #if defined(WOLFSSL_ASYNC_CRYPT) ret = wc_AsyncWait(ret, &aes.aes.asyncDev, WC_ASYNC_FLAG_NONE); @@ -6945,8 +6944,7 @@ static int aes_xts_256_test(void) 0xc3, 0xea, 0xd8, 0x10, 0xe9, 0xc0, 0xaf, 0x92 }; -#if 0 /* Enable after passes */ -//#ifdef OPENSSL_EXTRA +#ifdef OPENSSL_EXTRA ret = EVP_test(EVP_aes_256_xts(), k2, i2, p2, sizeof(p2), c2, sizeof(c2)); if (ret != 0) { printf("EVP_aes_256_xts failed\n"); diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index d32a65ce4..1b0260bcb 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -178,8 +178,6 @@ typedef union { Aes aes; #ifdef WOLFSSL_AES_XTS XtsAes xts; - const byte* tweak; - word32 tweakSz; #endif #endif #ifndef NO_DES3 @@ -321,7 +319,8 @@ struct WOLFSSL_EVP_CIPHER_CTX { int bufUsed; ALIGN16 byte lastBlock[WOLFSSL_EVP_BUF_SIZE]; int lastUsed; -#if !defined(NO_AES) || !defined(NO_DES3) || defined(HAVE_IDEA) +#if !defined(NO_AES) || !defined(NO_DES3) || defined(HAVE_IDEA) || \ + defined(HAVE_AESGCM) || defined (WOLFSSL_AES_XTS) #define HAVE_WOLFSSL_EVP_CIPHER_CTX_IV int ivSz; ALIGN16 unsigned char authTag[AES_BLOCK_SIZE]; From 5a87dbe094f78b3a74bf51b904f31f06a8ffe214 Mon Sep 17 00:00:00 2001 From: Eric Blankenhorn Date: Wed, 29 Jan 2020 21:24:48 -0600 Subject: [PATCH 132/649] Adding tests for EVP_CIPHER_CTX_reset --- tests/api.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/api.c b/tests/api.c index d46e813a8..8deba8706 100644 --- a/tests/api.c +++ b/tests/api.c @@ -2091,6 +2091,9 @@ static void test_wolfSSL_EVP_CIPHER_CTX() AssertTrue(init == test); AssertIntEQ(EVP_CIPHER_nid(test), NID_aes_128_cbc); + AssertIntEQ(EVP_CIPHER_CTX_reset(ctx), WOLFSSL_SUCCESS); + AssertIntEQ(EVP_CIPHER_CTX_reset(NULL), WOLFSSL_FAILURE); + EVP_CIPHER_CTX_free(ctx); #endif /* !NO_AES && HAVE_AES_CBC && WOLFSSL_AES_128 */ } From 018f313ccaf73e131de50c346a34503b8f88f5c3 Mon Sep 17 00:00:00 2001 From: Eric Blankenhorn Date: Wed, 29 Jan 2020 21:45:58 -0600 Subject: [PATCH 133/649] Fix clang warning --- tests/api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/api.c b/tests/api.c index 8deba8706..81e7b0df0 100644 --- a/tests/api.c +++ b/tests/api.c @@ -24211,7 +24211,7 @@ static void test_wolfSSL_BIO_f_md(void) testKey, (int)sizeof(testKey))); EVP_DigestSignInit(ctx, NULL, EVP_sha256(), NULL, key); AssertNotNull(bio = BIO_push(bio, mem)); - BIO_write(bio, testData, strlen(testData)); + BIO_write(bio, testData, (int)strlen(testData)); EVP_DigestSignFinal(ctx, NULL, &checkSz); EVP_DigestSignFinal(ctx, check, &checkSz); From 258382048d35185e4c3770bd6a8dc920945b5b69 Mon Sep 17 00:00:00 2001 From: Eric Blankenhorn Date: Thu, 30 Jan 2020 11:07:04 -0600 Subject: [PATCH 134/649] Fix test failures --- src/bio.c | 13 +++++++++---- src/ssl.c | 1 - wolfcrypt/test/test.c | 1 + wolfssl/ssl.h | 3 +++ 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/bio.c b/src/bio.c index 2158ff39c..27193df26 100644 --- a/src/bio.c +++ b/src/bio.c @@ -124,7 +124,6 @@ static int wolfSSL_BIO_MEMORY_read(WOLFSSL_BIO* bio, void* buf, int len) return sz; } - #ifndef WOLFCRYPT_ONLY /* Helper function to read from WOLFSSL_BIO_SSL type * @@ -157,7 +156,6 @@ static int wolfSSL_BIO_SSL_read(WOLFSSL_BIO* bio, void* buf, return ret; } -#endif /* WOLFCRYPT_ONLY */ static int wolfSSL_BIO_MD_read(WOLFSSL_BIO* bio, void* buf, int sz) { @@ -176,6 +174,7 @@ static int wolfSSL_BIO_MD_read(WOLFSSL_BIO* bio, void* buf, int sz) } return ret; } +#endif /* WOLFCRYPT_ONLY */ /* Used to read data from a WOLFSSL_BIO structure @@ -238,12 +237,12 @@ int wolfSSL_BIO_read(WOLFSSL_BIO* bio, void* buf, int len) if (bio && bio->type == WOLFSSL_BIO_SSL) { ret = wolfSSL_BIO_SSL_read(bio, buf, len, front); } - #endif /* data passing through BIO MD wrapper */ if (bio && bio->type == WOLFSSL_BIO_MD && ret > 0) { ret = wolfSSL_BIO_MD_read(bio, buf, ret); } + #endif /* case where front of list is done */ if (bio == front) { @@ -455,6 +454,7 @@ static int wolfSSL_BIO_MEMORY_write(WOLFSSL_BIO* bio, const void* data, } +#ifndef WOLFCRYPT_ONLY /* Helper function for writing to a WOLFSSL_BIO_MD type * * returns the amount written in bytes on success (0) @@ -480,6 +480,7 @@ static int wolfSSL_BIO_MD_write(WOLFSSL_BIO* bio, const void* data, int len) } return ret; } +#endif /* WOLFCRYPT_ONLY */ /* Writes data to a WOLFSSL_BIO structure @@ -593,13 +594,13 @@ int wolfSSL_BIO_write(WOLFSSL_BIO* bio, const void* data, int len) ret = wolfSSL_BIO_SSL_write(bio, data, len, front); } } - #endif /* WOLFCRYPT_ONLY */ if (bio && bio->type == WOLFSSL_BIO_MD) { if (bio->next != NULL) { /* data passing through MD BIO */ ret = wolfSSL_BIO_MD_write(bio, data, len); } } + #endif /* WOLFCRYPT_ONLY */ /* advance to the next bio in list */ bio = bio->next; @@ -805,6 +806,7 @@ int wolfSSL_BIO_gets(WOLFSSL_BIO* bio, char* buf, int sz) break; } +#ifndef WOLFCRYPT_ONLY /* call final on hash */ case WOLFSSL_BIO_MD: if (wolfSSL_EVP_MD_CTX_size(bio->ptr) > sz) { @@ -820,6 +822,7 @@ int wolfSSL_BIO_gets(WOLFSSL_BIO* bio, char* buf, int sz) } } break; +#endif /* WOLFCRYPT_ONLY */ default: WOLFSSL_MSG("BIO type not supported yet with wolfSSL_BIO_gets"); @@ -1296,6 +1299,7 @@ int wolfSSL_BIO_reset(WOLFSSL_BIO *bio) } return 0; +#ifndef WOLFCRYPT_ONLY case WOLFSSL_BIO_MD: if (bio->ptr != NULL) { const WOLFSSL_EVP_MD* md = wolfSSL_EVP_MD_CTX_md(bio->ptr); @@ -1303,6 +1307,7 @@ int wolfSSL_BIO_reset(WOLFSSL_BIO *bio) wolfSSL_EVP_DigestInit(bio->ptr, md); } return 0; +#endif /* WOLFCRYPT_ONLY */ default: WOLFSSL_MSG("Unknown BIO type needs added to reset function"); diff --git a/src/ssl.c b/src/ssl.c index 18f09bc15..1f40611dd 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -28726,7 +28726,6 @@ void wolfSSL_AES_cfb128_encrypt(const unsigned char *in, unsigned char* out, #endif /* NO_AES */ #ifndef NO_FILESYSTEM - #include /* var_arg */ #ifdef __clang__ #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wformat-nonliteral" diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 6b1e5e035..4050da655 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -5672,6 +5672,7 @@ static int EVP_test(const WOLFSSL_EVP_CIPHER* type, const byte* key, EVP_TEST_END: XFREE(cipher, NULL, DYNAMIC_TYPE_TMP_BUFFER); + (void)cipherSz; return ret; } #endif /* OPENSSL_EXTRA */ diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 2155bedb5..c009911dd 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -2010,8 +2010,11 @@ WOLFSSL_API int wolfSSL_want(WOLFSSL*); WOLFSSL_API int wolfSSL_want_read(WOLFSSL*); WOLFSSL_API int wolfSSL_want_write(WOLFSSL*); +#ifndef NO_FILESYSTEM +#include /* var_arg */ WOLFSSL_API int wolfSSL_BIO_vprintf(WOLFSSL_BIO* bio, const char* format, va_list args); +#endif WOLFSSL_API int wolfSSL_BIO_printf(WOLFSSL_BIO*, const char*, ...); WOLFSSL_API int wolfSSL_BIO_dump(WOLFSSL_BIO *bio, const char*, int); WOLFSSL_API int wolfSSL_ASN1_UTCTIME_print(WOLFSSL_BIO*, From 76eec8884bd59e5ef81f363cdce0a3075ce077a7 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Thu, 30 Jan 2020 10:22:01 -0700 Subject: [PATCH 135/649] clean up memory after test and don't leak x509 with get session peer --- src/ssl.c | 16 +++++++++++++++- tests/api.c | 4 +++- wolfssl/internal.h | 3 +++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 1f40611dd..67c1e4759 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -13468,9 +13468,14 @@ WOLFSSL_X509* wolfSSL_SESSION_get0_peer(WOLFSSL_SESSION* session) WOLFSSL_MSG("bad count found"); return NULL; } - return wolfSSL_get_chain_X509(&session->chain, 0); + + if (session->peer == NULL) { + session->peer = wolfSSL_get_chain_X509(&session->chain, 0); + } + return session->peer; } WOLFSSL_MSG("No session passed in"); + return NULL; } @@ -21638,6 +21643,9 @@ WOLFSSL_SESSION* wolfSSL_SESSION_dup(WOLFSSL_SESSION* session) } else { copy->ticket = copy->staticTicket; } +#endif +#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA) + copy->peer = wolfSSL_X509_dup(session->peer); #endif } return copy; @@ -21654,6 +21662,12 @@ void wolfSSL_SESSION_free(WOLFSSL_SESSION* session) if (session == NULL) return; +#if defined(SESSION_CERTS) && defined(OPENSSL_EXTRA) + if (session->peer) { + wolfSSL_X509_free(session->peer); + } +#endif + #ifdef HAVE_EXT_CACHE if (session->isAlloced) { #ifdef HAVE_SESSION_TICKET diff --git a/tests/api.c b/tests/api.c index 81e7b0df0..5974c90ef 100644 --- a/tests/api.c +++ b/tests/api.c @@ -23993,7 +23993,7 @@ static void test_wolfSSL_BIO_should_retry(void) wolfSSL_SSLSetIORecv(ssl, forceWantRead); AssertNotNull(bio = BIO_new(BIO_f_ssl())); - BIO_set_ssl(bio, ssl, BIO_NOCLOSE); + BIO_set_ssl(bio, ssl, BIO_CLOSE); AssertIntLE(BIO_write(bio, msg, msgSz), 0); AssertIntNE(BIO_should_retry(bio), 0); @@ -24013,6 +24013,7 @@ static void test_wolfSSL_BIO_should_retry(void) AssertIntEQ(XMEMCMP(reply, "I hear you fa shizzle!", XSTRLEN("I hear you fa shizzle!")), 0); BIO_free(bio); + wolfSSL_CTX_free(ctx); join_thread(serverThread); FreeTcpReady(&ready); @@ -24217,6 +24218,7 @@ static void test_wolfSSL_BIO_f_md(void) AssertIntEQ(XMEMCMP(check, testResult, sizeof(testResult)), 0); + EVP_PKEY_free(key); BIO_free(bio); BIO_free(mem); diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 17d9fc496..ec054c0ee 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -3076,6 +3076,9 @@ struct WOLFSSL_SESSION { byte masterSecret[SECRET_LEN]; /* stored secret */ word16 haveEMS; /* ext master secret flag */ #ifdef SESSION_CERTS +#ifdef OPENSSL_EXTRA + WOLFSSL_X509* peer; /* peer cert */ +#endif WOLFSSL_X509_CHAIN chain; /* peer cert chain, static */ #ifdef WOLFSSL_ALT_CERT_CHAINS WOLFSSL_X509_CHAIN altChain; /* peer alt cert chain, static */ From b67ade5164987be87cb8ca27ca52d3431e85a94f Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Thu, 30 Jan 2020 10:50:32 -0700 Subject: [PATCH 136/649] account for cavp build --- src/ssl.c | 4 ++++ wolfcrypt/src/evp.c | 2 ++ wolfcrypt/test/test.c | 16 +++++++++------- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 67c1e4759..5bd76f09c 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -16577,6 +16577,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) #endif /* HAVE_AES_CBC */ #ifdef WOLFSSL_AES_CFB +#if !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS) #ifdef WOLFSSL_AES_128 const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_cfb1(void) { @@ -16636,6 +16637,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) return EVP_AES_256_CFB8; } #endif /* WOLFSSL_AES_256 */ +#endif /* !HAVE_SELFTEST && !HAVE_FIPS */ #ifdef WOLFSSL_AES_128 const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_cfb128(void) @@ -18059,6 +18061,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) #endif /* HAVE_AES_CBC */ #ifdef WOLFSSL_AES_CFB +#if !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS) case AES_128_CFB1_TYPE: case AES_192_CFB1_TYPE: case AES_256_CFB1_TYPE: @@ -18077,6 +18080,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) else ret = wc_AesCfb8Decrypt(&ctx->cipher.aes, dst, src, len); break; +#endif /* !HAVE_SELFTEST && !HAVE_FIPS */ case AES_128_CFB128_TYPE: case AES_192_CFB128_TYPE: case AES_256_CFB128_TYPE: diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 2bc22099d..56421d54f 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -358,6 +358,7 @@ static int evpCipherBlock(WOLFSSL_EVP_CIPHER_CTX *ctx, break; #endif #if defined(WOLFSSL_AES_CFB) + #if !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS) case AES_128_CFB1_TYPE: case AES_192_CFB1_TYPE: case AES_256_CFB1_TYPE: @@ -375,6 +376,7 @@ static int evpCipherBlock(WOLFSSL_EVP_CIPHER_CTX *ctx, else ret = wc_AesCfb8Decrypt(&ctx->cipher.aes, out, in, inl); break; + #endif /* !HAVE_SELFTEST && !HAVE_FIPS */ case AES_128_CFB128_TYPE: case AES_192_CFB128_TYPE: diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 4050da655..c6a94307b 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -5606,7 +5606,7 @@ int des3_test(void) #ifndef NO_AES #if defined(WOLFSSL_AES_OFB) || defined(WOLFSSL_AES_CFB) -#ifdef OPENSSL_EXTRA +#if defined(OPENSSL_EXTRA) && !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS) /* pass in the function, key, iv, plain text and expected and this function * tests that the encryption and decryption is successful */ static int EVP_test(const WOLFSSL_EVP_CIPHER* type, const byte* key, @@ -6005,7 +6005,7 @@ EVP_TEST_END: } #endif /* WOLFSSL_AES_OFB */ -#ifdef WOLFSSL_AES_CFB +#if defined(WOLFSSL_AES_CFB) /* Test cases from NIST SP 800-38A, Recommendation for Block Cipher Modes of Operation Methods an*/ static int aescfb_test(void) { @@ -6129,7 +6129,7 @@ EVP_TEST_END: #ifdef WOLFSSL_AES_128 /* 128 key tests */ - #ifdef OPENSSL_EXTRA + #if defined(OPENSSL_EXTRA) && !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS) ret = EVP_test(EVP_aes_128_cfb128(), key1, iv, msg1, sizeof(msg1), cipher1, sizeof(cipher1)); if (ret != 0) { @@ -6177,7 +6177,7 @@ EVP_TEST_END: #ifdef WOLFSSL_AES_192 /* 192 key size test */ - #ifdef OPENSSL_EXTRA + #if defined(OPENSSL_EXTRA) && !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS) ret = EVP_test(EVP_aes_192_cfb128(), key2, iv, msg2, sizeof(msg2), cipher2, sizeof(cipher2)); if (ret != 0) { @@ -6215,7 +6215,7 @@ EVP_TEST_END: #ifdef WOLFSSL_AES_256 /* 256 key size test */ - #ifdef OPENSSL_EXTRA + #if defined(OPENSSL_EXTRA) && !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS) ret = EVP_test(EVP_aes_256_cfb128(), key3, iv, msg3, sizeof(msg3), cipher3, sizeof(cipher3)); if (ret != 0) { @@ -6288,7 +6288,7 @@ EVP_TEST_END: return ret; } - +#if !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS) static int aescfb1_test(void) { Aes enc; @@ -6585,6 +6585,7 @@ EVP_TEST_END: return ret; } +#endif /* !HAVE_SELFTEST && !HAVE_FIPS */ #endif /* WOLFSSL_AES_CFB */ @@ -7798,7 +7799,7 @@ int aes_test(void) ret = aescfb_test(); if (ret != 0) return ret; - +#if !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS) ret = aescfb1_test(); if (ret != 0) return ret; @@ -7807,6 +7808,7 @@ int aes_test(void) if (ret != 0) return ret; #endif +#endif #if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_COUNTER) From a9accb6c39380c533d409d36d53fe309fd90d73b Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Thu, 30 Jan 2020 11:54:44 -0700 Subject: [PATCH 137/649] add more macro guards for builds --- src/ssl.c | 3 ++- tests/api.c | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 5bd76f09c..f6ce6773d 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -13455,6 +13455,7 @@ WOLFSSL_X509_CHAIN* wolfSSL_SESSION_get_peer_chain(WOLFSSL_SESSION* session) } +#ifdef OPENSSL_EXTRA /* gets the peer certificate associated with the session passed in * returns null on failure, the caller should not free the returned pointer */ WOLFSSL_X509* wolfSSL_SESSION_get0_peer(WOLFSSL_SESSION* session) @@ -13478,7 +13479,7 @@ WOLFSSL_X509* wolfSSL_SESSION_get0_peer(WOLFSSL_SESSION* session) return NULL; } - +#endif /* OPENSSL_EXTRA */ #endif /* SESSION_INDEX && SESSION_CERTS */ diff --git a/tests/api.c b/tests/api.c index 5974c90ef..1646b4684 100644 --- a/tests/api.c +++ b/tests/api.c @@ -23928,7 +23928,7 @@ static void test_wolfSSL_BIO_puts(void) #endif } -#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \ +#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \ !defined(NO_RSA) && defined(HAVE_EXT_CACHE) && \ defined(HAVE_IO_TESTS_DEPENDENCIES) static int forceWantRead(WOLFSSL *ssl, char *buf, int sz, void *ctx) @@ -23943,7 +23943,7 @@ static int forceWantRead(WOLFSSL *ssl, char *buf, int sz, void *ctx) static void test_wolfSSL_BIO_should_retry(void) { -#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \ +#if defined(OPENSSL_ALL) && !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && \ !defined(NO_RSA) && defined(HAVE_EXT_CACHE) && \ defined(HAVE_IO_TESTS_DEPENDENCIES) tcp_ready ready; From 51d55ed1c86212e16fc1c807c5cfb30f7db4457b Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Thu, 30 Jan 2020 14:12:45 -0700 Subject: [PATCH 138/649] account for different peer certificate in test case, g++ build fix, static memory size increase --- src/bio.c | 32 +++++++++++++++++++------------- src/ssl.c | 4 ++-- tests/api.c | 12 +++++++++--- wolfssl/wolfcrypt/memory.h | 2 +- 4 files changed, 31 insertions(+), 19 deletions(-) diff --git a/src/bio.c b/src/bio.c index 27193df26..7a8e7db27 100644 --- a/src/bio.c +++ b/src/bio.c @@ -161,14 +161,17 @@ static int wolfSSL_BIO_MD_read(WOLFSSL_BIO* bio, void* buf, int sz) { int ret = sz; - if (wolfSSL_EVP_MD_CTX_type(bio->ptr) == (NID_hmac & 0xFF)) { - if (wolfSSL_EVP_DigestSignUpdate(bio->ptr, buf, sz) != WOLFSSL_SUCCESS) + if (wolfSSL_EVP_MD_CTX_type((WOLFSSL_EVP_MD_CTX*)bio->ptr) == + (NID_hmac & 0xFF)) { + if (wolfSSL_EVP_DigestSignUpdate((WOLFSSL_EVP_MD_CTX*)bio->ptr, buf, + sz) != WOLFSSL_SUCCESS) { ret = WOLFSSL_FATAL_ERROR; } } else { - if (wolfSSL_EVP_DigestUpdate(bio->ptr, buf, ret) != WOLFSSL_SUCCESS) { + if (wolfSSL_EVP_DigestUpdate((WOLFSSL_EVP_MD_CTX*)bio->ptr, buf, ret) + != WOLFSSL_SUCCESS) { ret = WOLFSSL_FATAL_ERROR; } } @@ -467,14 +470,16 @@ static int wolfSSL_BIO_MD_write(WOLFSSL_BIO* bio, const void* data, int len) return BAD_FUNC_ARG; } - if (wolfSSL_EVP_MD_CTX_type(bio->ptr) == (NID_hmac & 0xFF)) { - if (wolfSSL_EVP_DigestSignUpdate(bio->ptr, data, len) != - WOLFSSL_SUCCESS) { + if (wolfSSL_EVP_MD_CTX_type((WOLFSSL_EVP_MD_CTX*)bio->ptr) == + (NID_hmac & 0xFF)) { + if (wolfSSL_EVP_DigestSignUpdate((WOLFSSL_EVP_MD_CTX*)bio->ptr, data, + len) != WOLFSSL_SUCCESS) { ret = WOLFSSL_BIO_ERROR; } } else { - if (wolfSSL_EVP_DigestUpdate(bio->ptr, data, len) != WOLFSSL_SUCCESS) { + if (wolfSSL_EVP_DigestUpdate((WOLFSSL_EVP_MD_CTX*)bio->ptr, data, len) + != WOLFSSL_SUCCESS) { ret = WOLFSSL_BIO_ERROR; } } @@ -809,14 +814,14 @@ int wolfSSL_BIO_gets(WOLFSSL_BIO* bio, char* buf, int sz) #ifndef WOLFCRYPT_ONLY /* call final on hash */ case WOLFSSL_BIO_MD: - if (wolfSSL_EVP_MD_CTX_size(bio->ptr) > sz) { + if (wolfSSL_EVP_MD_CTX_size((WOLFSSL_EVP_MD_CTX*)bio->ptr) > sz) { WOLFSSL_MSG("Output buffer was too small for digest"); ret = WOLFSSL_FAILURE; } else { unsigned int szOut = 0; - ret = wolfSSL_EVP_DigestFinal(bio->ptr, (unsigned char*)buf, - &szOut); + ret = wolfSSL_EVP_DigestFinal((WOLFSSL_EVP_MD_CTX*)bio->ptr, + (unsigned char*)buf, &szOut); if (ret == WOLFSSL_SUCCESS) { ret = szOut; } @@ -1302,9 +1307,10 @@ int wolfSSL_BIO_reset(WOLFSSL_BIO *bio) #ifndef WOLFCRYPT_ONLY case WOLFSSL_BIO_MD: if (bio->ptr != NULL) { - const WOLFSSL_EVP_MD* md = wolfSSL_EVP_MD_CTX_md(bio->ptr); - wolfSSL_EVP_MD_CTX_init(bio->ptr); - wolfSSL_EVP_DigestInit(bio->ptr, md); + const WOLFSSL_EVP_MD* md = + wolfSSL_EVP_MD_CTX_md((WOLFSSL_EVP_MD_CTX*)bio->ptr); + wolfSSL_EVP_MD_CTX_init((WOLFSSL_EVP_MD_CTX*)bio->ptr); + wolfSSL_EVP_DigestInit((WOLFSSL_EVP_MD_CTX*)bio->ptr, md); } return 0; #endif /* WOLFCRYPT_ONLY */ diff --git a/src/ssl.c b/src/ssl.c index f6ce6773d..fbd0c47e4 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -15190,7 +15190,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) int ret = WOLFSSL_FAILURE; if ((bio != NULL) && (mdcp != NULL)) { - *mdcp = bio->ptr; + *mdcp = (WOLFSSL_EVP_MD_CTX*)bio->ptr; ret = WOLFSSL_SUCCESS; } @@ -15472,7 +15472,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) } if (bio->type == WOLFSSL_BIO_MD) { - wolfSSL_EVP_MD_CTX_free(bio->ptr); + wolfSSL_EVP_MD_CTX_free((WOLFSSL_EVP_MD_CTX*)bio->ptr); } XFREE(bio, 0, DYNAMIC_TYPE_OPENSSL); diff --git a/tests/api.c b/tests/api.c index 1646b4684..a2807e9aa 100644 --- a/tests/api.c +++ b/tests/api.c @@ -24317,10 +24317,16 @@ static void test_wolfSSL_SESSION(void) int bufSz; AssertNotNull(x509 = SSL_SESSION_get0_peer(sess)); - AssertIntEQ((bufSz = X509_NAME_get_text_by_NID( + AssertIntGT((bufSz = X509_NAME_get_text_by_NID( X509_get_subject_name(x509), NID_organizationalUnitName, - buf, sizeof(buf))), 7); - AssertIntEQ(XMEMCMP(buf, "Support", bufSz), 0); + buf, sizeof(buf))), 0); + AssertIntNE((bufSz == 7 || bufSz == 16), 0); /* should be one of these*/ + if (bufSz == 7) { + AssertIntEQ(XMEMCMP(buf, "Support", bufSz), 0); + } + if (bufSz == 16) { + AssertIntEQ(XMEMCMP(buf, "Programming-2048", bufSz), 0); + } } #endif diff --git a/wolfssl/wolfcrypt/memory.h b/wolfssl/wolfcrypt/memory.h index 0cf73aa48..486fd39ab 100644 --- a/wolfssl/wolfcrypt/memory.h +++ b/wolfssl/wolfcrypt/memory.h @@ -110,7 +110,7 @@ WOLFSSL_API int wolfSSL_GetAllocators(wolfSSL_Malloc_cb*, #elif defined (OPENSSL_EXTRA) /* extra storage in structs for multiple attributes and order */ #ifndef LARGEST_MEM_BUCKET - #define LARGEST_MEM_BUCKET 25536 + #define LARGEST_MEM_BUCKET 25600 #endif #define WOLFMEM_BUCKETS 64,128,256,512,1024,2432,3360,4480,\ LARGEST_MEM_BUCKET From 3eee891cf5c8b779077f56aed2b292d306374629 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Thu, 30 Jan 2020 14:39:12 -0700 Subject: [PATCH 139/649] fix redefinition warning on older clang compiler --- wolfssl/openssl/evp.h | 7 ++++--- wolfssl/ssl.h | 3 +-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index 1b0260bcb..ed6cc569e 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -66,7 +66,8 @@ typedef char WOLFSSL_EVP_CIPHER; #ifndef WOLFSSL_EVP_TYPE_DEFINED /* guard on redeclaration */ typedef char WOLFSSL_EVP_MD; -typedef struct WOLFSSL_EVP_PKEY WOLFSSL_EVP_PKEY; +typedef struct WOLFSSL_EVP_PKEY WOLFSSL_EVP_PKEY; +typedef struct WOLFSSL_EVP_MD_CTX WOLFSSL_EVP_MD_CTX; #define WOLFSSL_EVP_TYPE_DEFINED #endif @@ -161,7 +162,7 @@ typedef union { typedef struct WOLFSSL_EVP_PKEY_CTX WOLFSSL_EVP_PKEY_CTX; typedef struct WOLFSSL_EVP_CIPHER_CTX WOLFSSL_EVP_CIPHER_CTX; -typedef struct WOLFSSL_EVP_MD_CTX { +struct WOLFSSL_EVP_MD_CTX { union { WOLFSSL_Hasher digest; #ifndef NO_HMAC @@ -170,7 +171,7 @@ typedef struct WOLFSSL_EVP_MD_CTX { } hash; unsigned char macType; WOLFSSL_EVP_PKEY_CTX *pctx; -} WOLFSSL_EVP_MD_CTX; +}; typedef union { diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index c009911dd..cfa4c1195 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -348,10 +348,9 @@ struct WOLFSSL_EVP_PKEY { #endif }; typedef struct WOLFSSL_EVP_PKEY WOLFSSL_PKCS8_PRIV_KEY_INFO; -typedef struct WOLFSSL_EVP_MD_CTX WOLFSSL_EVP_MD_CTX; - #ifndef WOLFSSL_EVP_TYPE_DEFINED /* guard on redeclaration */ typedef struct WOLFSSL_EVP_PKEY WOLFSSL_EVP_PKEY; +typedef struct WOLFSSL_EVP_MD_CTX WOLFSSL_EVP_MD_CTX; typedef char WOLFSSL_EVP_MD; #define WOLFSSL_EVP_TYPE_DEFINED #endif From 922b308029bbbd676b2f9e05a7fe5498d5449c74 Mon Sep 17 00:00:00 2001 From: Eric Blankenhorn Date: Wed, 5 Feb 2020 10:10:17 -0600 Subject: [PATCH 140/649] Fix from review --- src/ssl.c | 4 ++-- wolfcrypt/src/aes.c | 2 +- wolfssl/ssl.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index fbd0c47e4..e537bd88d 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -28751,7 +28751,7 @@ void wolfSSL_AES_cfb128_encrypt(const unsigned char *in, unsigned char* out, #endif #endif -#ifndef NO_FILESYSTEM +#if !defined(NO_FILESYSTEM) && defined (OPENSSL_EXTRA) /* returns amount printed on success, negative in fail case */ int wolfSSL_BIO_vprintf(WOLFSSL_BIO* bio, const char* format, va_list args) { @@ -28818,7 +28818,7 @@ int wolfSSL_BIO_printf(WOLFSSL_BIO* bio, const char* format, ...) return ret; } -#endif +#endif /* !defined(NO_FILESYSTEM) && defined (OPENSSL_EXTRA) */ #if !defined(NO_FILESYSTEM) && defined(__clang__) #pragma clang diagnostic pop diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index 0f7bcaa37..b90f9ae30 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -7267,7 +7267,7 @@ int wc_AesEcbDecrypt(Aes* aes, byte* out, const byte* in, word32 sz) * buffer) * in buffer to encrypt * sz size of input buffer - * pre flag to xor after or before feedback. If 1 then add feedback before xor + * mode flag to specify AES mode * * returns 0 on success and negative error values on failure */ diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index cfa4c1195..867ca7815 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -2009,7 +2009,7 @@ WOLFSSL_API int wolfSSL_want(WOLFSSL*); WOLFSSL_API int wolfSSL_want_read(WOLFSSL*); WOLFSSL_API int wolfSSL_want_write(WOLFSSL*); -#ifndef NO_FILESYSTEM +#if !defined(NO_FILESYSTEM) && defined (OPENSSL_EXTRA) #include /* var_arg */ WOLFSSL_API int wolfSSL_BIO_vprintf(WOLFSSL_BIO* bio, const char* format, va_list args); From 1a96558b6e9efe5ab26e303d853ad441cdd516ce Mon Sep 17 00:00:00 2001 From: Eric Blankenhorn Date: Tue, 11 Feb 2020 17:20:11 -0600 Subject: [PATCH 141/649] Adding macro and XTS support functions --- src/ssl.c | 12 ++++++++++++ wolfcrypt/src/evp.c | 4 ++++ wolfssl/openssl/bio.h | 5 +++-- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index e537bd88d..3da79be3c 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -33375,6 +33375,18 @@ int wolfSSL_EVP_CIPHER_iv_length(const WOLFSSL_EVP_CIPHER* cipher) return AES_BLOCK_SIZE; #endif #endif +#ifdef WOLFSSL_AES_XTS + #ifdef WOLFSSL_AES_128 + if (XSTRNCMP(name, EVP_AES_128_XTS, XSTRLEN(EVP_AES_128_XTS)) == 0) + return AES_BLOCK_SIZE; + #endif /* WOLFSSL_AES_128 */ + + #ifdef WOLFSSL_AES_256 + if (XSTRNCMP(name, EVP_AES_256_XTS, XSTRLEN(EVP_AES_256_XTS)) == 0) + return AES_BLOCK_SIZE; + #endif /* WOLFSSL_AES_256 */ +#endif /* WOLFSSL_AES_XTS */ + #endif #ifndef NO_DES3 diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 56421d54f..959c9d6d3 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -771,6 +771,10 @@ int wolfSSL_EVP_CIPHER_CTX_block_size(const WOLFSSL_EVP_CIPHER_CTX *ctx) case AES_192_OFB_TYPE: case AES_256_OFB_TYPE: #endif +#if defined(WOLFSSL_AES_XTS) + case AES_128_XTS_TYPE: + case AES_256_XTS_TYPE: +#endif case AES_128_ECB_TYPE: case AES_192_ECB_TYPE: diff --git a/wolfssl/openssl/bio.h b/wolfssl/openssl/bio.h index 01911df1b..1eb55b149 100644 --- a/wolfssl/openssl/bio.h +++ b/wolfssl/openssl/bio.h @@ -75,8 +75,9 @@ #define BIO_TYPE_MEM WOLFSSL_BIO_MEMORY #define BIO_TYPE_BASE64 WOLFSSL_BIO_BASE64 -#define BIO_printf wolfSSL_BIO_printf -#define BIO_dump wolfSSL_BIO_dump +#define BIO_vprintf wolfSSL_BIO_vprintf +#define BIO_printf wolfSSL_BIO_printf +#define BIO_dump wolfSSL_BIO_dump /* BIO info callback */ #define BIO_CB_FREE WOLFSSL_BIO_CB_FREE From a0ddb05a07e53f681460ab9d9e316e4042454623 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Wed, 12 Feb 2020 17:45:09 -0700 Subject: [PATCH 142/649] change evp with cfb1 expect input size in bytes --- wolfcrypt/src/aes.c | 6 ++-- wolfcrypt/src/evp.c | 6 ++-- wolfcrypt/test/test.c | 73 +++++++++++++++++++++++++++++++++++++------ 3 files changed, 70 insertions(+), 15 deletions(-) diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index b90f9ae30..bba2ddecf 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -7607,7 +7607,7 @@ static int wc_AesFeedbackCFB1(Aes* aes, byte* out, const byte* in, } } - if (bit > 0) { + if (bit > 0 && bit < 7) { out[0] = cur; } @@ -7621,7 +7621,7 @@ static int wc_AesFeedbackCFB1(Aes* aes, byte* out, const byte* in, * out buffer to hold result of encryption (must be at least as large as input * buffer) * in buffer to encrypt (packed to left, i.e. 101 is 0x90) - * sz size of input buffer + * sz size of input buffer in bits (0x1 would be size of 1 and 0xFF size of 8) * * returns 0 on success and negative values on failure */ @@ -7653,7 +7653,7 @@ int wc_AesCfb8Encrypt(Aes* aes, byte* out, const byte* in, word32 sz) * out buffer to hold result of encryption (must be at least as large as input * buffer) * in buffer to encrypt - * sz size of input buffer + * sz size of input buffer in bits (0x1 would be size of 1 and 0xFF size of 8) * * returns 0 on success and negative values on failure */ diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 959c9d6d3..e4ea1577b 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -363,9 +363,11 @@ static int evpCipherBlock(WOLFSSL_EVP_CIPHER_CTX *ctx, case AES_192_CFB1_TYPE: case AES_256_CFB1_TYPE: if (ctx->enc) - ret = wc_AesCfb1Encrypt(&ctx->cipher.aes, out, in, inl); + ret = wc_AesCfb1Encrypt(&ctx->cipher.aes, out, in, + inl * WOLFSSL_BIT_SIZE); else - ret = wc_AesCfb1Decrypt(&ctx->cipher.aes, out, in, inl); + ret = wc_AesCfb1Decrypt(&ctx->cipher.aes, out, in, + inl * WOLFSSL_BIT_SIZE); break; case AES_128_CFB8_TYPE: diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index c6a94307b..6daf0edfb 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -6378,13 +6378,6 @@ EVP_TEST_END: #ifdef WOLFSSL_AES_128 /* 128 key tests */ - #ifdef OPENSSL_EXTRA - ret = EVP_test(EVP_aes_128_cfb1(), key1, iv, msg1, sizeof(msg1), - cipher1, 2); - if (ret != 0) { - return ret; - } - #endif ret = wc_AesSetKey(&enc, key1, AES_BLOCK_SIZE, iv, AES_ENCRYPTION); if (ret != 0) return -4741; @@ -6411,6 +6404,24 @@ EVP_TEST_END: if (plain[0] != msg1[0]) return -4746; #endif /* HAVE_AES_DECRYPT */ + + #ifdef OPENSSL_EXTRA + ret = wc_AesSetKey(&enc, key1, AES_BLOCK_SIZE, iv, AES_ENCRYPTION); + if (ret != 0) + return -4747; + + XMEMSET(cipher, 0, sizeof(cipher)); + ret = wc_AesCfb1Encrypt(&enc, cipher, msg1, + sizeof(msg1) * WOLFSSL_BIT_SIZE); + if (ret != 0) + return -4748; + + ret = EVP_test(EVP_aes_128_cfb1(), key1, iv, msg1, sizeof(msg1), + cipher, sizeof(msg1)); + if (ret != 0) { + return ret; + } + #endif #endif /* WOLFSSL_AES_128 */ #ifdef WOLFSSL_AES_192 /* 192 key tests */ @@ -6435,9 +6446,30 @@ EVP_TEST_END: #ifdef WOLFSSL_AES_192 /* 192 key tests */ + ret = wc_AesSetKey(&enc, key2, sizeof(key2), iv2, AES_ENCRYPTION); + if (ret != 0) + return -4749; + + XMEMSET(cipher, 0, sizeof(cipher)); + ret = wc_AesCfb1Encrypt(&enc, cipher, msg2, 4); + if (ret != 0) + return -4750; + if (XMEMCMP(cipher, cipher2, sizeof(cipher2)) != 0) + return -4751; + #ifdef OPENSSL_EXTRA + ret = wc_AesSetKey(&enc, key2, sizeof(key2), iv2, AES_ENCRYPTION); + if (ret != 0) + return -4752; + + XMEMSET(cipher, 0, sizeof(cipher)); + ret = wc_AesCfb1Encrypt(&enc, cipher, msg2, + sizeof(msg2) * WOLFSSL_BIT_SIZE); + if (ret != 0) + return -4753; + ret = EVP_test(EVP_aes_192_cfb1(), key2, iv2, msg2, sizeof(msg2), - cipher2, 4); + cipher, sizeof(msg2)); if (ret != 0) { return ret; } @@ -6446,14 +6478,35 @@ EVP_TEST_END: #ifdef WOLFSSL_AES_256 /* 256 key tests */ + ret = wc_AesSetKey(&enc, key3, sizeof(key3), iv3, AES_ENCRYPTION); + if (ret != 0) + return -4754; + + XMEMSET(cipher, 0, sizeof(cipher)); + ret = wc_AesCfb1Encrypt(&enc, cipher, msg3, 10); + if (ret != 0) + return -4755; + if (XMEMCMP(cipher, cipher3, sizeof(cipher3)) != 0) + return -4756; + #ifdef OPENSSL_EXTRA + ret = wc_AesSetKey(&enc, key3, sizeof(key3), iv3, AES_ENCRYPTION); + if (ret != 0) + return -4757; + + XMEMSET(cipher, 0, sizeof(cipher)); + ret = wc_AesCfb1Encrypt(&enc, cipher, msg3, + sizeof(msg3) * WOLFSSL_BIT_SIZE); + if (ret != 0) + return -4758; + ret = EVP_test(EVP_aes_256_cfb1(), key3, iv3, msg3, sizeof(msg3), - cipher3, 10); + cipher, sizeof(msg3)); if (ret != 0) { return ret; } #endif -#endif /* WOLFSSL_AES_192 */ +#endif /* WOLFSSL_AES_256 */ return ret; } From 936312f77e9cbc0e04427a0c3479068ce7e88792 Mon Sep 17 00:00:00 2001 From: Eric Blankenhorn Date: Thu, 13 Feb 2020 12:32:59 -0600 Subject: [PATCH 143/649] Adding ERR_print_errors_cb --- src/ssl.c | 6 ++++ wolfcrypt/src/logging.c | 72 ++++++++++++++++++++++--------------- wolfssl/openssl/ssl.h | 1 + wolfssl/ssl.h | 2 ++ wolfssl/wolfcrypt/logging.h | 4 ++- 5 files changed, 56 insertions(+), 29 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 3da79be3c..bf3cfba2d 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -4377,6 +4377,12 @@ void wolfSSL_ERR_dump_errors_fp(XFILE fp) { wc_ERR_print_errors_fp(fp); } + +void wolfSSL_ERR_print_errors_cb (int (*cb)(const char *str, size_t len, + void *u), void *u) +{ + wc_ERR_print_errors_cb(cb, u); +} #endif #endif diff --git a/wolfcrypt/src/logging.c b/wolfcrypt/src/logging.c index 6b6ab7512..b606ddb55 100644 --- a/wolfcrypt/src/logging.c +++ b/wolfcrypt/src/logging.c @@ -782,41 +782,57 @@ int wc_ERR_remove_state(void) return 0; } - #if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) /* empties out the error queue into the file */ +static int wc_ERR_dump_to_file (const char *str, size_t len, void *u) +{ + XFILE fp = (XFILE ) u; + fprintf(fp, "%-*.*s\n", (int)len, (int)len, str); + return 0; +} + +/* This callback allows the application to provide a custom error printing + * function. */ +void wc_ERR_print_errors_cb(int (*cb)(const char *str, size_t len, void *u), + void *u) +{ + WOLFSSL_ENTER("wc_ERR_print_errors_cb"); + + if (wc_LockMutex(&debug_mutex) != 0) + { + WOLFSSL_MSG("Lock debug mutex failed"); + } + else + { + /* free all nodes from error queue and print them to file */ + struct wc_error_queue *current; + struct wc_error_queue *next; + + current = (struct wc_error_queue *)wc_errors; + while (current != NULL) + { + next = current->next; + cb(current->error, strlen(current->error), u); + XFREE(current, current->heap, DYNAMIC_TYPE_LOG); + current = next; + } + + /* set global pointers to match having been freed */ + wc_errors = NULL; + wc_last_node = NULL; + + wc_UnLockMutex(&debug_mutex); + } +} + void wc_ERR_print_errors_fp(XFILE fp) { WOLFSSL_ENTER("wc_ERR_print_errors_fp"); - if (wc_LockMutex(&debug_mutex) != 0) - { - WOLFSSL_MSG("Lock debug mutex failed"); - } - else - { - /* free all nodes from error queue and print them to file */ - { - struct wc_error_queue *current; - struct wc_error_queue *next; - - current = (struct wc_error_queue *)wc_errors; - while (current != NULL) - { - next = current->next; - fprintf(fp, "%s\n", current->error); - XFREE(current, current->heap, DYNAMIC_TYPE_LOG); - current = next; - } - - /* set global pointers to match having been freed */ - wc_errors = NULL; - wc_last_node = NULL; - } - - wc_UnLockMutex(&debug_mutex); - } + /* Send all errors to the wc_ERR_dump_to_file function */ + wc_ERR_print_errors_cb(wc_ERR_dump_to_file,fp); } + #endif /* !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) */ #endif /* defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) */ diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 6c4c9757e..0edecbab5 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -769,6 +769,7 @@ wolfSSL_X509_STORE_set_verify_cb((WOLFSSL_X509_STORE *)(s), (WOLFSSL_X509_STORE_ #define ERR_get_error_line_data wolfSSL_ERR_get_error_line_data #define ERR_get_error wolfSSL_ERR_get_error #define ERR_print_errors_fp(file) wolfSSL_ERR_dump_errors_fp((file)) +#define ERR_print_errors_cb wolfSSL_ERR_print_errors_cb #define ERR_print_errors wolfSSL_ERR_print_errors #define ERR_clear_error wolfSSL_ERR_clear_error #define ERR_free_strings wolfSSL_ERR_free_strings diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 867ca7815..5d53934c7 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1781,6 +1781,8 @@ enum { WOLFSSL_API void wolfSSL_ERR_print_errors_fp(XFILE, int err); #if defined(OPENSSL_EXTRA) || defined(DEBUG_WOLFSSL_VERBOSE) WOLFSSL_API void wolfSSL_ERR_dump_errors_fp(XFILE fp); +WOLFSSL_API void wolfSSL_ERR_print_errors_cb(int (*cb)(const char *str, + size_t len, void *u), void *u); #endif #endif WOLFSSL_API void wolfSSL_ERR_print_errors(WOLFSSL_BIO *bio); diff --git a/wolfssl/wolfcrypt/logging.h b/wolfssl/wolfcrypt/logging.h index 51d9b23b9..3dcd7de29 100644 --- a/wolfssl/wolfcrypt/logging.h +++ b/wolfssl/wolfcrypt/logging.h @@ -115,7 +115,9 @@ WOLFSSL_API void wolfSSL_Debugging_OFF(void); WOLFSSL_API int wc_SetLoggingHeap(void* h); WOLFSSL_API int wc_ERR_remove_state(void); #if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) - WOLFSSL_API void wc_ERR_print_errors_fp(XFILE fp); + WOLFSSL_API void wc_ERR_print_errors_fp(XFILE fp); + WOLFSSL_API void wc_ERR_print_errors_cb(int (*cb)(const char *str, + size_t len, void *u), void *u); #endif #endif /* OPENSSL_EXTRA || DEBUG_WOLFSSL_VERBOSE */ From 95f973a5beebcf03515e45ec36c761e2b0b3d5d9 Mon Sep 17 00:00:00 2001 From: Eric Blankenhorn Date: Thu, 13 Feb 2020 16:58:06 -0600 Subject: [PATCH 144/649] Adding test and dox for ERR_print_errors_cb --- doc/dox_comments/header_files/ssl.h | 29 +++++++++++++++++++++++ tests/api.c | 36 +++++++++++++++++++++++++++++ wolfcrypt/src/logging.c | 7 +++++- 3 files changed, 71 insertions(+), 1 deletion(-) diff --git a/doc/dox_comments/header_files/ssl.h b/doc/dox_comments/header_files/ssl.h index 27fe0e759..ca208ce56 100644 --- a/doc/dox_comments/header_files/ssl.h +++ b/doc/dox_comments/header_files/ssl.h @@ -4881,6 +4881,35 @@ WOLFSSL_API long wolfSSL_get_verify_result(const WOLFSSL *ssl); */ WOLFSSL_API void wolfSSL_ERR_print_errors_fp(FILE*, int err); +/*! + \ingroup Debug + + \brief This function uses the provided callback to handle error reporting. + The callback function is executed for each error line. The string, length, + and userdata are passed into the callback parameters. + + \return none No returns. + + \param cb the callback function. + \param u userdata to pass into the callback function. + + _Example_ + \code + int error_cb(const char *str, size_t len, void *u) + { fprintf((FILE*)u, "%-*.*s\n", (int)len, (int)len, str); return 0; } + ... + FILE* fp = ... + wolfSSL_ERR_print_errors_cb(error_cb, fp); + \endcode + + \sa wolfSSL_get_error + \sa wolfSSL_ERR_error_string + \sa wolfSSL_ERR_error_string_n + \sa wolfSSL_load_error_strings +*/ +WOLFSSL_API void wolfSSL_ERR_print_errors_cb ( + int (*cb)(const char *str, size_t len, void *u), void *u); + /*! \brief The function sets the client_psk_cb member of the WOLFSSL_CTX structure. diff --git a/tests/api.c b/tests/api.c index a2807e9aa..c1043bc5b 100644 --- a/tests/api.c +++ b/tests/api.c @@ -23229,6 +23229,41 @@ static void test_wolfSSL_ERR_print_errors(void) #endif } +#if !defined(NO_ERROR_QUEUE) && defined(OPENSSL_EXTRA) && \ + defined(DEBUG_WOLFSSL) +static int test_wolfSSL_error_cb(const char *str, size_t len, void *u) +{ + wolfSSL_BIO_write((BIO*)u, str, len); + return 0; +} +#endif + +static void test_wolfSSL_ERR_print_errors_cb(void) +{ + #if !defined(NO_ERROR_QUEUE) && defined(OPENSSL_EXTRA) && \ + defined(DEBUG_WOLFSSL) + BIO* bio; + char buf[1024]; + + printf(testingFmt, "wolfSSL_ERR_print_errors_cb()"); + + 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); + ERR_put_error(0,SYS_F_BIND, -275, "asn.c", 100); + + ERR_print_errors_cb(test_wolfSSL_error_cb, bio); + AssertIntEQ(BIO_gets(bio, buf, sizeof(buf)), 108); + AssertIntEQ(XSTRNCMP("wolfSSL error occurred, error = 173 line:0 file:ssl.c", + buf, 53), 0); + AssertIntEQ(XSTRNCMP("wolfSSL error occurred, error = 275 line:100 file:asn.c", + buf + 53, 55), 0); + AssertIntEQ(BIO_gets(bio, buf, sizeof(buf)), 0); + + BIO_free(bio); + printf(resultFmt, passed); + #endif +} static void test_wolfSSL_HMAC(void) { @@ -30644,6 +30679,7 @@ void ApiTest(void) #if !defined(NO_WOLFSSL_CLIENT) && !defined(NO_WOLFSSL_SERVER) test_wolfSSL_ERR_peek_last_error_line(); #endif + test_wolfSSL_ERR_print_errors_cb(); test_wolfSSL_set_options(); test_wolfSSL_sk_SSL_CIPHER(); test_wolfSSL_X509_STORE_CTX(); diff --git a/wolfcrypt/src/logging.c b/wolfcrypt/src/logging.c index b606ddb55..0c818aa71 100644 --- a/wolfcrypt/src/logging.c +++ b/wolfcrypt/src/logging.c @@ -798,6 +798,11 @@ void wc_ERR_print_errors_cb(int (*cb)(const char *str, size_t len, void *u), { WOLFSSL_ENTER("wc_ERR_print_errors_cb"); + if (cb == NULL) { + /* Invalid param */ + return; + } + if (wc_LockMutex(&debug_mutex) != 0) { WOLFSSL_MSG("Lock debug mutex failed"); @@ -830,7 +835,7 @@ void wc_ERR_print_errors_fp(XFILE fp) WOLFSSL_ENTER("wc_ERR_print_errors_fp"); /* Send all errors to the wc_ERR_dump_to_file function */ - wc_ERR_print_errors_cb(wc_ERR_dump_to_file,fp); + wc_ERR_print_errors_cb(wc_ERR_dump_to_file, fp); } #endif /* !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM) */ From 6eda4e7b46593ea9ba6aaac86a426d2225960511 Mon Sep 17 00:00:00 2001 From: Eric Blankenhorn Date: Fri, 14 Feb 2020 08:11:45 -0600 Subject: [PATCH 145/649] Fix in test --- tests/api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/api.c b/tests/api.c index c1043bc5b..39fccc391 100644 --- a/tests/api.c +++ b/tests/api.c @@ -23233,7 +23233,7 @@ static void test_wolfSSL_ERR_print_errors(void) defined(DEBUG_WOLFSSL) static int test_wolfSSL_error_cb(const char *str, size_t len, void *u) { - wolfSSL_BIO_write((BIO*)u, str, len); + wolfSSL_BIO_write((BIO*)u, str, (int)len); return 0; } #endif From a64e1540ba0f03b5eb16d441372f6f04b885e456 Mon Sep 17 00:00:00 2001 From: Eric Blankenhorn Date: Wed, 19 Feb 2020 14:10:28 -0600 Subject: [PATCH 146/649] Adding EVP support for SHA3 --- src/ssl.c | 383 +++++++++++++++++++++++++++++++++++++++++ wolfcrypt/test/test.c | 76 ++++++++ wolfssl/openssl/evp.h | 25 +++ wolfssl/openssl/sha3.h | 150 ++++++++++++++++ 4 files changed, 634 insertions(+) create mode 100644 wolfssl/openssl/sha3.h diff --git a/src/ssl.c b/src/ssl.c index bf3cfba2d..93c68b146 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -16249,6 +16249,212 @@ size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out, #endif /* WOLFSSL_SHA512 */ +#ifndef WOLFSSL_NOSHA3_224 + + int wolfSSL_SHA3_224_Init(WOLFSSL_SHA3_224_CTX* sha) + { + int ret; + + typedef char sha_test[sizeof(SHA3_224_CTX) >= sizeof(wc_Sha3) ? 1 : -1]; + (void)sizeof(sha_test); + + WOLFSSL_ENTER("SHA3_224_Init"); + ret = wc_InitSha3_224((wc_Sha3*)sha, NULL, 0); + + /* return 1 on success, 0 otherwise */ + if (ret == 0) + return 1; + + return 0; + } + + + int wolfSSL_SHA3_224_Update(WOLFSSL_SHA3_224_CTX* sha, const void* input, + unsigned long sz) + { + int ret; + + WOLFSSL_ENTER("SHA3_224_Update"); + ret = wc_Sha3_224_Update((wc_Sha3*)sha, (const byte*)input, (word32)sz); + + /* return 1 on success, 0 otherwise */ + if (ret == 0) + return 1; + + return 0; + } + + + int wolfSSL_SHA3_224_Final(byte* input, WOLFSSL_SHA3_224_CTX* sha) + { + int ret; + + WOLFSSL_ENTER("SHA3_224_Final"); + ret = wc_Sha3_224_Final((wc_Sha3*)sha, input); + + /* return 1 on success, 0 otherwise */ + if (ret == 0) + return 1; + + return 0; + } + +#endif /* WOLFSSL_NOSHA3_224 */ + + +#ifndef WOLFSSL_NOSHA3_256 + int wolfSSL_SHA3_256_Init(WOLFSSL_SHA3_256_CTX* sha3_256) + { + int ret; + + typedef char sha_test[sizeof(SHA3_256_CTX) >= sizeof(wc_Sha3) ? 1 : -1]; + (void)sizeof(sha_test); + + WOLFSSL_ENTER("SHA3_256_Init"); + ret = wc_InitSha3_256((wc_Sha3*)sha3_256, NULL, 0); + + /* return 1 on success, 0 otherwise */ + if (ret == 0) + return 1; + + return 0; + } + + + int wolfSSL_SHA3_256_Update(WOLFSSL_SHA3_256_CTX* sha, const void* input, + unsigned long sz) + { + int ret; + + WOLFSSL_ENTER("SHA3_256_Update"); + ret = wc_Sha3_256_Update((wc_Sha3*)sha, (const byte*)input, (word32)sz); + + /* return 1 on success, 0 otherwise */ + if (ret == 0) + return 1; + + return 0; + } + + + int wolfSSL_SHA3_256_Final(byte* input, WOLFSSL_SHA3_256_CTX* sha) + { + int ret; + + WOLFSSL_ENTER("SHA3_256_Final"); + ret = wc_Sha3_256_Final((wc_Sha3*)sha, input); + + /* return 1 on success, 0 otherwise */ + if (ret == 0) + return 1; + + return 0; + } +#endif /* WOLFSSL_NOSHA3_256 */ + + + int wolfSSL_SHA3_384_Init(WOLFSSL_SHA3_384_CTX* sha) + { + int ret; + + typedef char sha_test[sizeof(SHA3_384_CTX) >= sizeof(wc_Sha3) ? 1 : -1]; + (void)sizeof(sha_test); + + WOLFSSL_ENTER("SHA3_384_Init"); + ret = wc_InitSha3_384((wc_Sha3*)sha, NULL, 0); + + /* return 1 on success, 0 otherwise */ + if (ret == 0) + return 1; + + return 0; + } + + + int wolfSSL_SHA3_384_Update(WOLFSSL_SHA3_384_CTX* sha, const void* input, + unsigned long sz) + { + int ret; + + WOLFSSL_ENTER("SHA3_384_Update"); + ret = wc_Sha3_384_Update((wc_Sha3*)sha, (const byte*)input, (word32)sz); + + /* return 1 on success, 0 otherwise */ + if (ret == 0) + return 1; + + return 0; + } + + + int wolfSSL_SHA3_384_Final(byte* input, WOLFSSL_SHA3_384_CTX* sha) + { + int ret; + + WOLFSSL_ENTER("SHA3_384_Final"); + ret = wc_Sha3_384_Final((wc_Sha3*)sha, input); + + /* return 1 on success, 0 otherwise */ + if (ret == 0) + return 1; + + return 0; + } + + + +#ifndef WOLFSSL_NOSHA3_512 + + int wolfSSL_SHA3_512_Init(WOLFSSL_SHA3_512_CTX* sha) + { + int ret; + + typedef char sha_test[sizeof(SHA3_512_CTX) >= sizeof(wc_Sha3) ? 1 : -1]; + (void)sizeof(sha_test); + + WOLFSSL_ENTER("SHA3_512_Init"); + ret = wc_InitSha3_512((wc_Sha3*)sha, NULL, 0); + + /* return 1 on success, 0 otherwise */ + if (ret == 0) + return 1; + + return 0; + } + + + int wolfSSL_SHA3_512_Update(WOLFSSL_SHA3_512_CTX* sha, const void* input, + unsigned long sz) + { + int ret; + + WOLFSSL_ENTER("SHA3_512_Update"); + ret = wc_Sha3_512_Update((wc_Sha3*)sha, (const byte*)input, (word32)sz); + + /* return 1 on success, 0 otherwise */ + if (ret == 0) + return 1; + + return 0; + } + + + int wolfSSL_SHA3_512_Final(byte* input, WOLFSSL_SHA3_512_CTX* sha) + { + int ret; + + WOLFSSL_ENTER("SHA3_512_Final"); + ret = wc_Sha3_512_Final((wc_Sha3*)sha, input); + + /* return 1 on success, 0 otherwise */ + if (ret == 0) + return 1; + + return 0; + } + +#endif /* WOLFSSL_NOSHA3_512 */ + static const struct s_ent { const unsigned char macType; const char *name; @@ -16278,6 +16484,16 @@ size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out, #ifdef WOLFSSL_SHA512 {WC_HASH_TYPE_SHA512, "SHA512"}, #endif /* WOLFSSL_SHA512 */ +#ifndef WOLFSSL_NOSHA3_224 + {WC_HASH_TYPE_SHA3_224, "SHA3_224"}, +#endif +#ifndef WOLFSSL_NOSHA3_256 + {WC_HASH_TYPE_SHA3_256, "SHA3_256"}, +#endif + {WC_HASH_TYPE_SHA3_384, "SHA3_384"}, +#ifndef WOLFSSL_NOSHA3_512 + {WC_HASH_TYPE_SHA3_512, "SHA3_512"}, +#endif {0, NULL} }; @@ -16413,6 +16629,37 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) #endif /* WOLFSSL_SHA512 */ +#ifndef WOLFSSL_NOSHA3_224 + const WOLFSSL_EVP_MD* wolfSSL_EVP_sha3_224(void) + { + WOLFSSL_ENTER("EVP_sha3_224"); + return EVP_get_digestbyname("SHA3_224"); + } +#endif /* WOLFSSL_NOSHA3_224 */ + + +#ifndef WOLFSSL_NOSHA3_256 + const WOLFSSL_EVP_MD* wolfSSL_EVP_sha3_256(void) + { + WOLFSSL_ENTER("EVP_sha3_256"); + return EVP_get_digestbyname("SHA3_256"); + } +#endif /* WOLFSSL_NOSHA3_256 */ + + const WOLFSSL_EVP_MD* wolfSSL_EVP_sha3_384(void) + { + WOLFSSL_ENTER("EVP_sha3_384"); + return EVP_get_digestbyname("SHA3_384"); + } + +#ifndef WOLFSSL_NOSHA3_512 + const WOLFSSL_EVP_MD* wolfSSL_EVP_sha3_512(void) + { + WOLFSSL_ENTER("EVP_sha3_512"); + return EVP_get_digestbyname("SHA3_512"); + } +#endif /* WOLFSSL_NOSHA3_512 */ + WOLFSSL_EVP_MD_CTX *wolfSSL_EVP_MD_CTX_new(void) { @@ -16509,6 +16756,32 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) break; #endif /* WOLFSSL_SHA512 */ + #ifndef WOLFSSL_NOSHA3_224 + case WC_HASH_TYPE_SHA3_224: + wc_Sha3_224_Copy((wc_Sha3*)&src->hash.digest, + (wc_Sha3*)&des->hash.digest); + break; + #endif + + #ifndef WOLFSSL_NOSHA3_256 + case WC_HASH_TYPE_SHA3_256: + wc_Sha3_256_Copy((wc_Sha3*)&src->hash.digest, + (wc_Sha3*)&des->hash.digest); + break; + #endif + + case WC_HASH_TYPE_SHA3_384: + wc_Sha3_384_Copy((wc_Sha3*)&src->hash.digest, + (wc_Sha3*)&des->hash.digest); + break; + + #ifndef WOLFSSL_NOSHA3_512 + case WC_HASH_TYPE_SHA3_512: + wc_Sha3_512_Copy((wc_Sha3*)&src->hash.digest, + (wc_Sha3*)&des->hash.digest); + break; + #endif + default: return WOLFSSL_FAILURE; } @@ -16934,6 +17207,28 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) break; #endif /* WOLFSSL_SHA512 */ + #ifndef WOLFSSL_NOSHA3_224 + case WC_HASH_TYPE_SHA3_224: + wc_Sha3_224_Free((wc_Sha3*)&ctx->hash.digest); + break; + #endif + + #ifndef WOLFSSL_NOSHA3_256 + case WC_HASH_TYPE_SHA3_256: + wc_Sha3_256_Free((wc_Sha3*)&ctx->hash.digest); + break; + #endif + + case WC_HASH_TYPE_SHA3_384: + wc_Sha3_384_Free((wc_Sha3*)&ctx->hash.digest); + break; + + #ifndef WOLFSSL_NOSHA3_512 + case WC_HASH_TYPE_SHA3_512: + wc_Sha3_512_Free((wc_Sha3*)&ctx->hash.digest); + break; + #endif + default: return WOLFSSL_FAILURE; } @@ -18491,6 +18786,28 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ret = wolfSSL_MD5_Init(&(ctx->hash.digest.md5)); } #endif + #ifndef WOLFSSL_NOSHA3_224 + else if (XSTRNCMP(type, "SHA3_224", 8) == 0) { + ctx->macType = WC_HASH_TYPE_SHA3_224; + ret = wolfSSL_SHA3_224_Init(&(ctx->hash.digest.sha3_224)); + } + #endif + #ifndef WOLFSSL_NOSHA3_256 + else if (XSTRNCMP(type, "SHA3_256", 8) == 0) { + ctx->macType = WC_HASH_TYPE_SHA3_256; + ret = wolfSSL_SHA3_256_Init(&(ctx->hash.digest.sha3_256)); + } + #endif + else if (XSTRNCMP(type, "SHA3_384", 8) == 0) { + ctx->macType = WC_HASH_TYPE_SHA3_384; + ret = wolfSSL_SHA3_384_Init(&(ctx->hash.digest.sha3_384)); + } + #ifndef WOLFSSL_NOSHA3_512 + else if (XSTRNCMP(type, "SHA3_512", 8) == 0) { + ctx->macType = WC_HASH_TYPE_SHA3_512; + ret = wolfSSL_SHA3_512_Init(&(ctx->hash.digest.sha3_512)); + } + #endif #ifndef NO_SHA /* has to be last since would pick or 224, 256, 384, or 512 too */ else if (XSTRNCMP(type, "SHA", 3) == 0) { @@ -18556,6 +18873,28 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) (unsigned long)sz); break; #endif /* WOLFSSL_SHA512 */ +#ifndef WOLFSSL_NOSHA3_224 + case WC_HASH_TYPE_SHA3_224: + wolfSSL_SHA3_224_Update((SHA3_224_CTX*)&ctx->hash, data, + (unsigned long)sz); + break; +#endif +#ifndef WOLFSSL_NOSHA3_256 + case WC_HASH_TYPE_SHA3_256: + wolfSSL_SHA3_256_Update((SHA3_256_CTX*)&ctx->hash, data, + (unsigned long)sz); + break; +#endif + case WC_HASH_TYPE_SHA3_384: + wolfSSL_SHA3_384_Update((SHA3_384_CTX*)&ctx->hash, data, + (unsigned long)sz); + break; +#ifndef WOLFSSL_NOSHA3_512 + case WC_HASH_TYPE_SHA3_512: + wolfSSL_SHA3_512_Update((SHA3_512_CTX*)&ctx->hash, data, + (unsigned long)sz); + break; +#endif default: return WOLFSSL_FAILURE; } @@ -18612,6 +18951,28 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) if (s) *s = WC_SHA512_DIGEST_SIZE; break; #endif /* WOLFSSL_SHA512 */ +#ifndef WOLFSSL_NOSHA3_224 + case WC_HASH_TYPE_SHA3_224: + wolfSSL_SHA3_224_Final(md, (SHA3_224_CTX*)&ctx->hash); + if (s) *s = WC_SHA3_224_DIGEST_SIZE; + break; +#endif +#ifndef WOLFSSL_NOSHA3_256 + case WC_HASH_TYPE_SHA3_256: + wolfSSL_SHA3_256_Final(md, (SHA3_256_CTX*)&ctx->hash); + if (s) *s = WC_SHA3_256_DIGEST_SIZE; + break; +#endif + case WC_HASH_TYPE_SHA3_384: + wolfSSL_SHA3_384_Final(md, (SHA3_384_CTX*)&ctx->hash); + if (s) *s = WC_SHA3_384_DIGEST_SIZE; + break; +#ifndef WOLFSSL_NOSHA3_512 + case WC_HASH_TYPE_SHA3_512: + wolfSSL_SHA3_512_Final(md, (SHA3_512_CTX*)&ctx->hash); + if (s) *s = WC_SHA3_512_DIGEST_SIZE; + break; +#endif default: return WOLFSSL_FAILURE; } @@ -18679,6 +19040,28 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) mdlen = WC_SHA512_DIGEST_SIZE; } else #endif +#ifndef WOLFSSL_NOSHA3_224 + if (XSTRNCMP(evp_md, "SHA3_224", 8) == 0) { + type = WC_SHA3_224; + mdlen = WC_SHA3_224_DIGEST_SIZE; + } else +#endif +#ifndef WOLFSSL_NOSHA3_256 + if (XSTRNCMP(evp_md, "SHA3_256", 8) == 0) { + type = WC_SHA3_256; + mdlen = WC_SHA3_256_DIGEST_SIZE; + } else +#endif + if (XSTRNCMP(evp_md, "SHA3_384", 8) == 0) { + type = WC_SHA3_384; + mdlen = WC_SHA3_384_DIGEST_SIZE; + } else +#ifndef WOLFSSL_NOSHA3_512 + if (XSTRNCMP(evp_md, "SHA3_512", 8) == 0) { + type = WC_SHA3_512; + mdlen = WC_SHA3_512_DIGEST_SIZE; + } else +#endif #ifndef NO_SHA if (XSTRNCMP(evp_md, "SHA", 3) == 0) { type = WC_SHA; diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 6daf0edfb..cf185c78e 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -15507,6 +15507,82 @@ int openssl_test(void) #endif /* WOLFSSL_SHA512 */ +#ifndef WOLFSSL_NOSHA3_224 + + e.input = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhi" + "jklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"; + e.output = "\x54\x3e\x68\x68\xe1\x66\x6c\x1a\x64\x36\x30\xdf\x77\x36\x7a\xe5\xa6\x2a\x85\x07\x0a\x51\xc1\x4c\xbf\x66\x5c\xbc"; + e.inLen = XSTRLEN(e.input); + e.outLen = WC_SHA3_224_DIGEST_SIZE; + + EVP_MD_CTX_init(&md_ctx); + EVP_DigestInit(&md_ctx, EVP_sha3_224()); + + EVP_DigestUpdate(&md_ctx, e.input, (unsigned long)e.inLen); + EVP_DigestFinal(&md_ctx, hash, 0); + + if (XMEMCMP(hash, e.output, WC_SHA3_224_DIGEST_SIZE) != 0) + return -7403; + +#endif /* WOLFSSL_NOSHA3_224 */ + + +#ifndef WOLFSSL_NOSHA3_256 + d.input = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhi" + "jklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"; + d.output = "\x91\x6f\x60\x61\xfe\x87\x97\x41\xca\x64\x69\xb4\x39\x71\xdf" + "\xdb\x28\xb1\xa3\x2d\xc3\x6c\xb3\x25\x4e\x81\x2b\xe2\x7a\xad" + "\x1d\x18"; + d.inLen = XSTRLEN(d.input); + d.outLen = WC_SHA3_256_DIGEST_SIZE; + + EVP_MD_CTX_init(&md_ctx); + EVP_DigestInit(&md_ctx, EVP_sha3_256()); + + EVP_DigestUpdate(&md_ctx, d.input, (unsigned long)d.inLen); + EVP_DigestFinal(&md_ctx, hash, 0); + + if (XMEMCMP(hash, d.output, WC_SHA3_256_DIGEST_SIZE) != 0) + return -7404; +#endif /* WOLFSSL_NOSHA3_256 */ + + + e.input = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhi" + "jklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"; + e.output = "\x79\x40\x7d\x3b\x59\x16\xb5\x9c\x3e\x30\xb0\x98\x22\x97\x47\x91\xc3\x13\xfb\x9e\xcc\x84\x9e\x40\x6f\x23\x59\x2d\x04\xf6\x25\xdc\x8c\x70\x9b\x98\xb4\x3b\x38\x52\xb3\x37\x21\x61\x79\xaa\x7f\xc7"; + e.inLen = XSTRLEN(e.input); + e.outLen = WC_SHA3_384_DIGEST_SIZE; + + EVP_MD_CTX_init(&md_ctx); + EVP_DigestInit(&md_ctx, EVP_sha3_384()); + + EVP_DigestUpdate(&md_ctx, e.input, (unsigned long)e.inLen); + EVP_DigestFinal(&md_ctx, hash, 0); + + if (XMEMCMP(hash, e.output, WC_SHA3_384_DIGEST_SIZE) != 0) + return -7405; + + + +#ifndef WOLFSSL_NOSHA3_512 + + f.input = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhi" + "jklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"; + f.output = "\xaf\xeb\xb2\xef\x54\x2e\x65\x79\xc5\x0c\xad\x06\xd2\xe5\x78\xf9\xf8\xdd\x68\x81\xd7\xdc\x82\x4d\x26\x36\x0f\xee\xbf\x18\xa4\xfa\x73\xe3\x26\x11\x22\x94\x8e\xfc\xfd\x49\x2e\x74\xe8\x2e\x21\x89\xed\x0f\xb4\x40\xd1\x87\xf3\x82\x27\x0c\xb4\x55\xf2\x1d\xd1\x85"; + f.inLen = XSTRLEN(f.input); + f.outLen = WC_SHA3_512_DIGEST_SIZE; + + EVP_MD_CTX_init(&md_ctx); + EVP_DigestInit(&md_ctx, EVP_sha3_512()); + + EVP_DigestUpdate(&md_ctx, f.input, (unsigned long)f.inLen); + EVP_DigestFinal(&md_ctx, hash, 0); + + if (XMEMCMP(hash, f.output, WC_SHA3_512_DIGEST_SIZE) != 0) + return -7406; + +#endif /* WOLFSSL_NOSHA3_512 */ + #ifndef NO_MD5 if (RAND_bytes(hash, sizeof(hash)) != 1) diff --git a/wolfssl/openssl/evp.h b/wolfssl/openssl/evp.h index ed6cc569e..1a3da097f 100644 --- a/wolfssl/openssl/evp.h +++ b/wolfssl/openssl/evp.h @@ -43,6 +43,7 @@ #include #endif #include +#include #include #include #include @@ -88,6 +89,11 @@ WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_sha384(void); WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_sha512(void); WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_ripemd160(void); +WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_sha3_224(void); +WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_sha3_256(void); +WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_sha3_384(void); +WOLFSSL_API const WOLFSSL_EVP_MD* wolfSSL_EVP_sha3_512(void); + WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_128_ecb(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_192_ecb(void); WOLFSSL_API const WOLFSSL_EVP_CIPHER* wolfSSL_EVP_aes_256_ecb(void); @@ -157,6 +163,16 @@ typedef union { #ifdef WOLFSSL_RIPEMD WOLFSSL_RIPEMD_CTX ripemd; #endif + #ifndef WOLFSSL_NOSHA3_224 + WOLFSSL_SHA3_224_CTX sha3_224; + #endif + #ifndef WOLFSSL_NOSHA3_256 + WOLFSSL_SHA3_256_CTX sha3_256; + #endif + WOLFSSL_SHA3_384_CTX sha3_384; + #ifndef WOLFSSL_NOSHA3_512 + WOLFSSL_SHA3_512_CTX sha3_512; + #endif } WOLFSSL_Hasher; typedef struct WOLFSSL_EVP_PKEY_CTX WOLFSSL_EVP_PKEY_CTX; @@ -262,6 +278,10 @@ enum { NID_ecdsa_with_SHA512 = 796, NID_dsa_with_SHA224 = 802, NID_dsa_with_SHA256 = 803, + NID_sha3_224 = 1096, + NID_sha3_256 = 1097, + NID_sha3_384 = 1098, + NID_sha3_512 = 1099, }; enum { @@ -628,6 +648,11 @@ typedef WOLFSSL_EVP_CIPHER_CTX EVP_CIPHER_CTX; #define EVP_sha512 wolfSSL_EVP_sha512 #define EVP_ripemd160 wolfSSL_EVP_ripemd160 +#define EVP_sha3_224 wolfSSL_EVP_sha3_224 +#define EVP_sha3_256 wolfSSL_EVP_sha3_256 +#define EVP_sha3_384 wolfSSL_EVP_sha3_384 +#define EVP_sha3_512 wolfSSL_EVP_sha3_512 + #define EVP_aes_128_cbc wolfSSL_EVP_aes_128_cbc #define EVP_aes_192_cbc wolfSSL_EVP_aes_192_cbc #define EVP_aes_256_cbc wolfSSL_EVP_aes_256_cbc diff --git a/wolfssl/openssl/sha3.h b/wolfssl/openssl/sha3.h new file mode 100644 index 000000000..2039104d2 --- /dev/null +++ b/wolfssl/openssl/sha3.h @@ -0,0 +1,150 @@ +/* sha3.h + * + * 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 + */ + +/* sha3.h for openssl */ + + +#ifndef WOLFSSL_SHA3_H_ +#define WOLFSSL_SHA3_H_ + +#include +#include + +#ifdef WOLFSSL_PREFIX +#include "prefix_sha.h" +#endif + +#ifdef __cplusplus + extern "C" { +#endif + + +/* Using ALIGN16 because when AES-NI is enabled digest and buffer in Sha3 + * struct are 16 byte aligned. Any dereference to those elements after casting + * to Sha3 is expected to also be 16 byte aligned addresses. */ +struct WOLFSSL_SHA3_CTX { + /* big enough to hold wolfcrypt Sha3, but check on init */ + ALIGN16 void* holder[(424 + WC_ASYNC_DEV_SIZE) / sizeof(void*)]; +}; + +#ifndef WOLFSSL_NOSHA3_224 +typedef struct WOLFSSL_SHA3_CTX WOLFSSL_SHA3_224_CTX; + +WOLFSSL_API int wolfSSL_SHA3_224_Init(WOLFSSL_SHA3_224_CTX*); +WOLFSSL_API int wolfSSL_SHA3_224_Update(WOLFSSL_SHA3_224_CTX*, const void*, + unsigned long); +WOLFSSL_API int wolfSSL_SHA3_224_Final(unsigned char*, WOLFSSL_SHA3_224_CTX*); + +enum { + SHA3_224_DIGEST_LENGTH = 28 +}; + +typedef WOLFSSL_SHA3_224_CTX SHA3_224_CTX; + +#define SHA3_224_Init wolfSSL_SHA3_224_Init +#define SHA3_224_Update wolfSSL_SHA3_224_Update +#define SHA3_224_Final wolfSSL_SHA3_224_Final +#if defined(NO_OLD_WC_NAMES) && !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) + #define SHA3_224 wolfSSL_SHA3_224 +#endif +#endif /* WOLFSSL_NOSHA3_224 */ + + +#ifndef WOLFSSL_NOSHA3_256 +typedef struct WOLFSSL_SHA3_CTX WOLFSSL_SHA3_256_CTX; + + +WOLFSSL_API int wolfSSL_SHA3_256_Init(WOLFSSL_SHA3_256_CTX*); +WOLFSSL_API int wolfSSL_SHA3_256_Update(WOLFSSL_SHA3_256_CTX*, const void*, + unsigned long); +WOLFSSL_API int wolfSSL_SHA3_256_Final(unsigned char*, WOLFSSL_SHA3_256_CTX*); + +enum { + SHA3_256_DIGEST_LENGTH = 32 +}; + + +typedef WOLFSSL_SHA3_256_CTX SHA3_256_CTX; + +#define SHA3_256_Init wolfSSL_SHA3_256_Init +#define SHA3_256_Update wolfSSL_SHA3_256_Update +#define SHA3_256_Final wolfSSL_SHA3_256_Final +#if defined(NO_OLD_WC_NAMES) && !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) + #define SHA3_256 wolfSSL_SHA3_256 +#endif +#endif /* WOLFSSL_NOSHA3_256 */ + + +typedef struct WOLFSSL_SHA3_CTX WOLFSSL_SHA3_384_CTX; + +WOLFSSL_API int wolfSSL_SHA3_384_Init(WOLFSSL_SHA3_384_CTX*); +WOLFSSL_API int wolfSSL_SHA3_384_Update(WOLFSSL_SHA3_384_CTX*, const void*, + unsigned long); +WOLFSSL_API int wolfSSL_SHA3_384_Final(unsigned char*, WOLFSSL_SHA3_384_CTX*); + +enum { + SHA3_384_DIGEST_LENGTH = 48 +}; + +typedef WOLFSSL_SHA3_384_CTX SHA3_384_CTX; + +#define SHA3_384_Init wolfSSL_SHA3_384_Init +#define SHA3_384_Update wolfSSL_SHA3_384_Update +#define SHA3_384_Final wolfSSL_SHA3_384_Final +#if defined(NO_OLD_WC_NAMES) && !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) + #define SHA3_384 wolfSSL_SHA3_384 +#endif + + +#ifndef WOLFSSL_NOSHA3_512 + +typedef struct WOLFSSL_SHA3_CTX WOLFSSL_SHA3_512_CTX; + +WOLFSSL_API int wolfSSL_SHA3_512_Init(WOLFSSL_SHA3_512_CTX*); +WOLFSSL_API int wolfSSL_SHA3_512_Update(WOLFSSL_SHA3_512_CTX*, const void*, + unsigned long); +WOLFSSL_API int wolfSSL_SHA3_512_Final(unsigned char*, WOLFSSL_SHA3_512_CTX*); + +enum { + SHA3_512_DIGEST_LENGTH = 64 +}; + + +typedef WOLFSSL_SHA3_512_CTX SHA3_512_CTX; + +#define SHA3_512_Init wolfSSL_SHA3_512_Init +#define SHA3_512_Update wolfSSL_SHA3_512_Update +#define SHA3_512_Final wolfSSL_SHA3_512_Final +#if defined(NO_OLD_WC_NAMES) && !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) + #define SHA3_512 wolfSSL_SHA3_512 +#endif +#endif /* WOLFSSL_NOSHA3_512 */ + + + + +#ifdef __cplusplus + } /* extern "C" */ +#endif + + +#endif /* WOLFSSL_SHA3_H_ */ + From 61ebfd571c60f0cb854f649c2eabf9885232af7c Mon Sep 17 00:00:00 2001 From: Eric Blankenhorn Date: Wed, 19 Feb 2020 14:22:53 -0600 Subject: [PATCH 147/649] Fix new file error --- wolfssl/openssl/include.am | 1 + 1 file changed, 1 insertion(+) diff --git a/wolfssl/openssl/include.am b/wolfssl/openssl/include.am index 82f499cae..3b77bcc08 100644 --- a/wolfssl/openssl/include.am +++ b/wolfssl/openssl/include.am @@ -37,6 +37,7 @@ nobase_include_HEADERS+= \ wolfssl/openssl/rand.h \ wolfssl/openssl/rsa.h \ wolfssl/openssl/sha.h \ + wolfssl/openssl/sha3.h \ wolfssl/openssl/ssl23.h \ wolfssl/openssl/ssl.h \ wolfssl/openssl/stack.h \ From b4563e6af3ce888e19a6ddceb1f5179c322d054b Mon Sep 17 00:00:00 2001 From: Eric Blankenhorn Date: Wed, 19 Feb 2020 18:32:12 -0600 Subject: [PATCH 148/649] Fix CFB and OFB --- src/ssl.c | 69 +++++++++++++++++++++++++++++++++++++++++-- wolfcrypt/test/test.c | 64 ++++++++++++++++++++++++++------------- 2 files changed, 109 insertions(+), 24 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 93c68b146..19726f263 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -18077,7 +18077,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ctx->flags |= WOLFSSL_EVP_CIPH_XTS_MODE; ctx->keyLen = 32; ctx->block_size = 1; - ctx->ivSz = 16; + ctx->ivSz = AES_BLOCK_SIZE; if (iv) XMEMCPY(ctx->iv, iv, ctx->ivSz); @@ -18105,7 +18105,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ctx->flags |= WOLFSSL_EVP_CIPH_XTS_MODE; ctx->keyLen = 64; ctx->block_size = 1; - ctx->ivSz = 16; + ctx->ivSz = AES_BLOCK_SIZE; if (iv) XMEMCPY(ctx->iv, iv, ctx->ivSz); @@ -18595,7 +18595,38 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) XMEMCPY(ctx->iv, &ctx->cipher.aes.reg, AES_BLOCK_SIZE); break; #endif /* WOLFSSL_AES_COUNTER */ - +#ifdef WOLFSSL_AES_CFB +#if !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS) + case AES_128_CFB1_TYPE: + case AES_192_CFB1_TYPE: + case AES_256_CFB1_TYPE: + WOLFSSL_MSG("AES CFB1"); + break; + case AES_128_CFB8_TYPE: + case AES_192_CFB8_TYPE: + case AES_256_CFB8_TYPE: + WOLFSSL_MSG("AES CFB8"); + break; +#endif /* !HAVE_SELFTEST && !HAVE_FIPS */ + case AES_128_CFB128_TYPE: + case AES_192_CFB128_TYPE: + case AES_256_CFB128_TYPE: + WOLFSSL_MSG("AES CFB128"); + break; +#endif /* WOLFSSL_AES_CFB */ +#if defined(WOLFSSL_AES_OFB) + case AES_128_OFB_TYPE: + case AES_192_OFB_TYPE: + case AES_256_OFB_TYPE: + WOLFSSL_MSG("AES OFB"); + break; +#endif /* WOLFSSL_AES_OFB */ +#ifdef WOLFSSL_AES_XTS + case AES_128_XTS_TYPE: + case AES_256_XTS_TYPE: + WOLFSSL_MSG("AES XTS"); + break; +#endif /* WOLFSSL_AES_XTS */ #endif /* NO_AES */ #ifndef NO_DES3 @@ -33704,6 +33735,38 @@ int wolfSSL_EVP_CIPHER_CTX_iv_length(const WOLFSSL_EVP_CIPHER_CTX* ctx) WOLFSSL_MSG("ARC4"); return 0; #endif +#ifdef WOLFSSL_AES_CFB +#if !defined(HAVE_SELFTEST) && !defined(HAVE_FIPS) + case AES_128_CFB1_TYPE: + case AES_192_CFB1_TYPE: + case AES_256_CFB1_TYPE: + WOLFSSL_MSG("AES CFB1"); + return AES_BLOCK_SIZE; + case AES_128_CFB8_TYPE: + case AES_192_CFB8_TYPE: + case AES_256_CFB8_TYPE: + WOLFSSL_MSG("AES CFB8"); + return AES_BLOCK_SIZE; +#endif /* !HAVE_SELFTEST && !HAVE_FIPS */ + case AES_128_CFB128_TYPE: + case AES_192_CFB128_TYPE: + case AES_256_CFB128_TYPE: + WOLFSSL_MSG("AES CFB128"); + return AES_BLOCK_SIZE; +#endif /* WOLFSSL_AES_CFB */ +#if defined(WOLFSSL_AES_OFB) + case AES_128_OFB_TYPE: + case AES_192_OFB_TYPE: + case AES_256_OFB_TYPE: + WOLFSSL_MSG("AES OFB"); + return AES_BLOCK_SIZE; +#endif /* WOLFSSL_AES_OFB */ +#ifdef WOLFSSL_AES_XTS + case AES_128_XTS_TYPE: + case AES_256_XTS_TYPE: + WOLFSSL_MSG("AES XTS"); + return AES_BLOCK_SIZE; +#endif /* WOLFSSL_AES_XTS */ case NULL_CIPHER_TYPE : WOLFSSL_MSG("NULL"); diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index cf185c78e..24361cdc2 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -6423,27 +6423,6 @@ EVP_TEST_END: } #endif #endif /* WOLFSSL_AES_128 */ -#ifdef WOLFSSL_AES_192 - /* 192 key tests */ - #ifdef OPENSSL_EXTRA - ret = EVP_test(EVP_aes_192_cfb8(), key2, iv2, msg2, sizeof(msg2), - cipher2, sizeof(cipher2)); - if (ret != 0) { - return ret; - } - #endif -#endif /* WOLFSSL_AES_192 */ -#ifdef WOLFSSL_AES_256 - /* 192 key tests */ - #ifdef OPENSSL_EXTRA - ret = EVP_test(EVP_aes_256_cfb8(), key3, iv3, msg3, sizeof(msg3), - cipher3, sizeof(cipher3)); - if (ret != 0) { - return ret; - } - #endif -#endif /* WOLFSSL_AES_256 */ - #ifdef WOLFSSL_AES_192 /* 192 key tests */ ret = wc_AesSetKey(&enc, key2, sizeof(key2), iv2, AES_ENCRYPTION); @@ -6635,6 +6614,49 @@ EVP_TEST_END: return -4746; #endif /* HAVE_AES_DECRYPT */ #endif /* WOLFSSL_AES_128 */ +#ifdef WOLFSSL_AES_192 + /* 192 key tests */ + ret = wc_AesSetKey(&enc, key2, sizeof(key2), iv2, AES_ENCRYPTION); + if (ret != 0) + return -4749; + + XMEMSET(cipher, 0, sizeof(cipher)); + ret = wc_AesCfb8Encrypt(&enc, cipher, msg2, sizeof(msg2)); + if (ret != 0) + return -4750; + if (XMEMCMP(cipher, cipher2, sizeof(msg2)) != 0) + return -4751; +#ifdef OPENSSL_EXTRA + ret = EVP_test(EVP_aes_192_cfb8(), key2, iv2, msg2, sizeof(msg2), + cipher2, sizeof(msg2)); + if (ret != 0) { + return ret; + } +#endif + +#endif /* WOLFSSL_AES_192 */ + +#ifdef WOLFSSL_AES_256 + /* 256 key tests */ + ret = wc_AesSetKey(&enc, key3, sizeof(key3), iv3, AES_ENCRYPTION); + if (ret != 0) + return -4754; + + XMEMSET(cipher, 0, sizeof(cipher)); + ret = wc_AesCfb8Encrypt(&enc, cipher, msg3, sizeof(msg3)); + if (ret != 0) + return -4755; + if (XMEMCMP(cipher, cipher3, sizeof(cipher3)) != 0) + return -4756; + + #ifdef OPENSSL_EXTRA + ret = EVP_test(EVP_aes_256_cfb8(), key3, iv3, msg3, sizeof(msg3), + cipher3, sizeof(msg3)); + if (ret != 0) { + return ret; + } + #endif +#endif /* WOLFSSL_AES_256 */ return ret; } From e4188d935b6037f3eacbb60b2bcfde3254d32b54 Mon Sep 17 00:00:00 2001 From: Eric Blankenhorn Date: Wed, 19 Feb 2020 19:52:06 -0600 Subject: [PATCH 149/649] Fix WIN error --- src/ssl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ssl.c b/src/ssl.c index 19726f263..36b4e3ca6 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -16249,6 +16249,7 @@ size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out, #endif /* WOLFSSL_SHA512 */ +#ifdef WOLFSSL_SHA3 #ifndef WOLFSSL_NOSHA3_224 int wolfSSL_SHA3_224_Init(WOLFSSL_SHA3_224_CTX* sha) @@ -16454,6 +16455,7 @@ size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out, } #endif /* WOLFSSL_NOSHA3_512 */ +#endif /* WOLFSSL_SHA3 */ static const struct s_ent { const unsigned char macType; @@ -18817,6 +18819,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ret = wolfSSL_MD5_Init(&(ctx->hash.digest.md5)); } #endif +#ifdef WOLFSSL_SHA3 #ifndef WOLFSSL_NOSHA3_224 else if (XSTRNCMP(type, "SHA3_224", 8) == 0) { ctx->macType = WC_HASH_TYPE_SHA3_224; @@ -18839,6 +18842,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ret = wolfSSL_SHA3_512_Init(&(ctx->hash.digest.sha3_512)); } #endif +#endif #ifndef NO_SHA /* has to be last since would pick or 224, 256, 384, or 512 too */ else if (XSTRNCMP(type, "SHA", 3) == 0) { From 60dea0c53a439f76748fa6989c94dcd7ac5ba622 Mon Sep 17 00:00:00 2001 From: Eric Blankenhorn Date: Thu, 20 Feb 2020 08:23:45 -0600 Subject: [PATCH 150/649] Fix VS error --- src/ssl.c | 51 +++++++++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 36b4e3ca6..d7d5a6231 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -16631,6 +16631,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) #endif /* WOLFSSL_SHA512 */ +#ifdef WOLFSSL_SHA3 #ifndef WOLFSSL_NOSHA3_224 const WOLFSSL_EVP_MD* wolfSSL_EVP_sha3_224(void) { @@ -16661,7 +16662,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) return EVP_get_digestbyname("SHA3_512"); } #endif /* WOLFSSL_NOSHA3_512 */ - +#endif /* WOLFSSL_SHA3 */ WOLFSSL_EVP_MD_CTX *wolfSSL_EVP_MD_CTX_new(void) { @@ -16757,7 +16758,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) (wc_Sha512*)&des->hash.digest); break; #endif /* WOLFSSL_SHA512 */ - + #ifdef WOLFSSL_SHA3 #ifndef WOLFSSL_NOSHA3_224 case WC_HASH_TYPE_SHA3_224: wc_Sha3_224_Copy((wc_Sha3*)&src->hash.digest, @@ -16783,7 +16784,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) (wc_Sha3*)&des->hash.digest); break; #endif - + #endif default: return WOLFSSL_FAILURE; } @@ -17208,7 +17209,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) wc_Sha512Free((wc_Sha512*)&ctx->hash.digest); break; #endif /* WOLFSSL_SHA512 */ - + #ifdef WOLFSSL_SHA3 #ifndef WOLFSSL_NOSHA3_224 case WC_HASH_TYPE_SHA3_224: wc_Sha3_224_Free((wc_Sha3*)&ctx->hash.digest); @@ -17230,7 +17231,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) wc_Sha3_512_Free((wc_Sha3*)&ctx->hash.digest); break; #endif - + #endif default: return WOLFSSL_FAILURE; } @@ -18908,28 +18909,30 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) (unsigned long)sz); break; #endif /* WOLFSSL_SHA512 */ -#ifndef WOLFSSL_NOSHA3_224 + #ifdef WOLFSSL_SHA3 + #ifndef WOLFSSL_NOSHA3_224 case WC_HASH_TYPE_SHA3_224: wolfSSL_SHA3_224_Update((SHA3_224_CTX*)&ctx->hash, data, (unsigned long)sz); break; -#endif -#ifndef WOLFSSL_NOSHA3_256 + #endif + #ifndef WOLFSSL_NOSHA3_256 case WC_HASH_TYPE_SHA3_256: wolfSSL_SHA3_256_Update((SHA3_256_CTX*)&ctx->hash, data, (unsigned long)sz); break; -#endif + #endif case WC_HASH_TYPE_SHA3_384: wolfSSL_SHA3_384_Update((SHA3_384_CTX*)&ctx->hash, data, (unsigned long)sz); break; -#ifndef WOLFSSL_NOSHA3_512 + #ifndef WOLFSSL_NOSHA3_512 case WC_HASH_TYPE_SHA3_512: wolfSSL_SHA3_512_Update((SHA3_512_CTX*)&ctx->hash, data, (unsigned long)sz); break; -#endif + #endif + #endif default: return WOLFSSL_FAILURE; } @@ -18986,28 +18989,30 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) if (s) *s = WC_SHA512_DIGEST_SIZE; break; #endif /* WOLFSSL_SHA512 */ -#ifndef WOLFSSL_NOSHA3_224 + #ifdef WOLFSSL_SHA3 + #ifndef WOLFSSL_NOSHA3_224 case WC_HASH_TYPE_SHA3_224: wolfSSL_SHA3_224_Final(md, (SHA3_224_CTX*)&ctx->hash); if (s) *s = WC_SHA3_224_DIGEST_SIZE; break; -#endif -#ifndef WOLFSSL_NOSHA3_256 + #endif + #ifndef WOLFSSL_NOSHA3_256 case WC_HASH_TYPE_SHA3_256: wolfSSL_SHA3_256_Final(md, (SHA3_256_CTX*)&ctx->hash); if (s) *s = WC_SHA3_256_DIGEST_SIZE; break; -#endif + #endif case WC_HASH_TYPE_SHA3_384: wolfSSL_SHA3_384_Final(md, (SHA3_384_CTX*)&ctx->hash); if (s) *s = WC_SHA3_384_DIGEST_SIZE; break; -#ifndef WOLFSSL_NOSHA3_512 + #ifndef WOLFSSL_NOSHA3_512 case WC_HASH_TYPE_SHA3_512: wolfSSL_SHA3_512_Final(md, (SHA3_512_CTX*)&ctx->hash); if (s) *s = WC_SHA3_512_DIGEST_SIZE; break; -#endif + #endif + #endif default: return WOLFSSL_FAILURE; } @@ -19075,27 +19080,29 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) mdlen = WC_SHA512_DIGEST_SIZE; } else #endif -#ifndef WOLFSSL_NOSHA3_224 +#ifdef WOLFSSL_SHA3 + #ifndef WOLFSSL_NOSHA3_224 if (XSTRNCMP(evp_md, "SHA3_224", 8) == 0) { type = WC_SHA3_224; mdlen = WC_SHA3_224_DIGEST_SIZE; } else -#endif -#ifndef WOLFSSL_NOSHA3_256 + #endif + #ifndef WOLFSSL_NOSHA3_256 if (XSTRNCMP(evp_md, "SHA3_256", 8) == 0) { type = WC_SHA3_256; mdlen = WC_SHA3_256_DIGEST_SIZE; } else -#endif + #endif if (XSTRNCMP(evp_md, "SHA3_384", 8) == 0) { type = WC_SHA3_384; mdlen = WC_SHA3_384_DIGEST_SIZE; } else -#ifndef WOLFSSL_NOSHA3_512 + #ifndef WOLFSSL_NOSHA3_512 if (XSTRNCMP(evp_md, "SHA3_512", 8) == 0) { type = WC_SHA3_512; mdlen = WC_SHA3_512_DIGEST_SIZE; } else + #endif #endif #ifndef NO_SHA if (XSTRNCMP(evp_md, "SHA", 3) == 0) { From b74dac6171ce72c72fa4d106643a9e3c67bb6119 Mon Sep 17 00:00:00 2001 From: Eric Blankenhorn Date: Thu, 20 Feb 2020 08:32:37 -0600 Subject: [PATCH 151/649] Fix WIN test --- wolfcrypt/test/test.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 24361cdc2..70736f325 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -3012,7 +3012,7 @@ int sha3_test(void) return 0; } -#endif +#endif /* WOLFSSL_SHA3 */ int hash_test(void) @@ -15528,7 +15528,7 @@ int openssl_test(void) return -7406; #endif /* WOLFSSL_SHA512 */ - +#ifdef WOLFSSL_SHA3 #ifndef WOLFSSL_NOSHA3_224 e.input = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhi" @@ -15604,7 +15604,7 @@ int openssl_test(void) return -7406; #endif /* WOLFSSL_NOSHA3_512 */ - +#endif /* WOLFSSL_SHA3 */ #ifndef NO_MD5 if (RAND_bytes(hash, sizeof(hash)) != 1) From 403c263e0b5279a786d8eb4c187b8eb9d9ca4705 Mon Sep 17 00:00:00 2001 From: Eric Blankenhorn Date: Thu, 20 Feb 2020 17:28:17 -0600 Subject: [PATCH 152/649] Fix valgrind issue --- src/ssl.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index d7d5a6231..4a4c49756 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -18082,8 +18082,10 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ctx->block_size = 1; ctx->ivSz = AES_BLOCK_SIZE; - if (iv) - XMEMCPY(ctx->iv, iv, ctx->ivSz); + if (iv != NULL) { + if (iv != ctx->iv) /* Valgrind error when src == dst */ + XMEMCPY(ctx->iv, iv, ctx->ivSz); + } else XMEMSET(ctx->iv, 0, AES_BLOCK_SIZE); @@ -18110,8 +18112,10 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) ctx->block_size = 1; ctx->ivSz = AES_BLOCK_SIZE; - if (iv) - XMEMCPY(ctx->iv, iv, ctx->ivSz); + if (iv != NULL) { + if (iv != ctx->iv) /* Valgrind error when src == dst */ + XMEMCPY(ctx->iv, iv, ctx->ivSz); + } else XMEMSET(ctx->iv, 0, AES_BLOCK_SIZE); From c9ce065f8a739b827f3b317c7ae2374fdc289e08 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Fri, 21 Feb 2020 11:37:45 +1000 Subject: [PATCH 153/649] Curve25519 x64 asm: Fix negate and add fe_sq_n --- wolfcrypt/src/fe_x25519_asm.S | 786 +++++++++++++++++++--------------- 1 file changed, 449 insertions(+), 337 deletions(-) diff --git a/wolfcrypt/src/fe_x25519_asm.S b/wolfcrypt/src/fe_x25519_asm.S index 5f8251815..6d0f638b5 100644 --- a/wolfcrypt/src/fe_x25519_asm.S +++ b/wolfcrypt/src/fe_x25519_asm.S @@ -364,45 +364,6 @@ _fe_copy: #endif /* __APPLE__ */ #ifndef __APPLE__ .text -.globl fe_cswap -.type fe_cswap,@function -.align 4 -fe_cswap: -#else -.section __TEXT,__text -.globl _fe_cswap -.p2align 2 -_fe_cswap: -#endif /* __APPLE__ */ - # Conditional Swap - movslq %edx, %rax - movq (%rdi), %rcx - movq 8(%rdi), %r8 - movq 16(%rdi), %r9 - movq 24(%rdi), %r10 - negq %rax - xorq (%rsi), %rcx - xorq 8(%rsi), %r8 - xorq 16(%rsi), %r9 - xorq 24(%rsi), %r10 - andq %rax, %rcx - andq %rax, %r8 - andq %rax, %r9 - andq %rax, %r10 - xorq %rcx, (%rdi) - xorq %r8, 8(%rdi) - xorq %r9, 16(%rdi) - xorq %r10, 24(%rdi) - xorq %rcx, (%rsi) - xorq %r8, 8(%rsi) - xorq %r9, 16(%rsi) - xorq %r10, 24(%rsi) - repz retq -#ifndef __APPLE__ -.size fe_cswap,.-fe_cswap -#endif /* __APPLE__ */ -#ifndef __APPLE__ -.text .globl fe_sub .type fe_sub,@function .align 4 @@ -504,9 +465,9 @@ _fe_neg: movq $-1, %rcx movq $0x7fffffffffffffff, %r8 subq (%rsi), %rdx - subq 8(%rsi), %rax - subq 16(%rsi), %rcx - subq 24(%rsi), %r8 + sbbq 8(%rsi), %rax + sbbq 16(%rsi), %rcx + sbbq 24(%rsi), %r8 movq %rdx, (%rdi) movq %rax, 8(%rdi) movq %rcx, 16(%rdi) @@ -595,19 +556,19 @@ fe_isnegative: .p2align 2 _fe_isnegative: #endif /* __APPLE__ */ - movq $0x7fffffffffffffff, %r10 - movq (%rdi), %rax - movq 8(%rdi), %rdx - movq 16(%rdi), %rcx - movq 24(%rdi), %r8 - addq $19, %rax - adcq $0x00, %rdx + movq $0x7fffffffffffffff, %r11 + movq (%rdi), %rdx + movq 8(%rdi), %rcx + movq 16(%rdi), %r8 + movq 24(%rdi), %r9 + movq %rdx, %rax + addq $19, %rdx adcq $0x00, %rcx adcq $0x00, %r8 - shrq $63, %r8 - imulq $19, %r8, %r9 - movq (%rdi), %rax - addq %r9, %rax + adcq $0x00, %r9 + shrq $63, %r9 + imulq $19, %r9, %r10 + addq %r10, %rax andq $0x01, %rax repz retq #ifndef __APPLE__ @@ -1705,6 +1666,162 @@ _fe_sq_x64: #endif /* __APPLE__ */ #ifndef __APPLE__ .text +.globl fe_sq_n_x64 +.type fe_sq_n_x64,@function +.align 4 +fe_sq_n_x64: +#else +.section __TEXT,__text +.globl _fe_sq_n_x64 +.p2align 2 +_fe_sq_n_x64: +#endif /* __APPLE__ */ + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + pushq %rbx + movq %rdx, %rcx +L_fe_sq_n_x64: + # Square + # A[0] * A[1] + movq (%rsi), %rax + mulq 8(%rsi) + movq %rax, %r9 + movq %rdx, %r10 + # A[0] * A[2] + movq (%rsi), %rax + mulq 16(%rsi) + xorq %r11, %r11 + addq %rax, %r10 + adcq %rdx, %r11 + # A[0] * A[3] + movq (%rsi), %rax + mulq 24(%rsi) + xorq %r12, %r12 + addq %rax, %r11 + adcq %rdx, %r12 + # A[1] * A[2] + movq 8(%rsi), %rax + mulq 16(%rsi) + xorq %r13, %r13 + addq %rax, %r11 + adcq %rdx, %r12 + adcq $0x00, %r13 + # A[1] * A[3] + movq 8(%rsi), %rax + mulq 24(%rsi) + addq %rax, %r12 + adcq %rdx, %r13 + # A[2] * A[3] + movq 16(%rsi), %rax + mulq 24(%rsi) + xorq %r14, %r14 + addq %rax, %r13 + adcq %rdx, %r14 + # Double + xorq %r15, %r15 + addq %r9, %r9 + adcq %r10, %r10 + adcq %r11, %r11 + adcq %r12, %r12 + adcq %r13, %r13 + adcq %r14, %r14 + adcq $0x00, %r15 + # A[0] * A[0] + movq (%rsi), %rax + mulq %rax + movq %rax, %r8 + movq %rdx, %rbx + # A[1] * A[1] + movq 8(%rsi), %rax + mulq %rax + addq %rbx, %r9 + adcq %rax, %r10 + adcq $0x00, %rdx + movq %rdx, %rbx + # A[2] * A[2] + movq 16(%rsi), %rax + mulq %rax + addq %rbx, %r11 + adcq %rax, %r12 + adcq $0x00, %rdx + movq %rdx, %rbx + # A[3] * A[3] + movq 24(%rsi), %rax + mulq %rax + addq %rax, %r14 + adcq %rdx, %r15 + addq %rbx, %r13 + adcq $0x00, %r14 + adcq $0x00, %r15 + # Reduce + movq $0x7fffffffffffffff, %rbx + # Move top half into t4-t7 and remove top bit from t3 + shldq $0x01, %r14, %r15 + shldq $0x01, %r13, %r14 + shldq $0x01, %r12, %r13 + shldq $0x01, %r11, %r12 + andq %rbx, %r11 + # Multiply top half by 19 + movq $19, %rax + mulq %r12 + xorq %r12, %r12 + addq %rax, %r8 + movq $19, %rax + adcq %rdx, %r12 + mulq %r13 + xorq %r13, %r13 + addq %rax, %r9 + movq $19, %rax + adcq %rdx, %r13 + mulq %r14 + xorq %r14, %r14 + addq %rax, %r10 + movq $19, %rax + adcq %rdx, %r14 + mulq %r15 + # Add remaining product results in + addq %r12, %r9 + adcq %r13, %r10 + adcq %r14, %r11 + adcq %rax, %r11 + adcq $0x00, %rdx + # Overflow + shldq $0x01, %r11, %rdx + imulq $19, %rdx, %rax + andq %rbx, %r11 + addq %rax, %r8 + adcq $0x00, %r9 + adcq $0x00, %r10 + adcq $0x00, %r11 + # Reduce if top bit set + movq %r11, %rdx + shrq $63, %rdx + imulq $19, %rdx, %rax + andq %rbx, %r11 + addq %rax, %r8 + adcq $0x00, %r9 + adcq $0x00, %r10 + adcq $0x00, %r11 + # Store + movq %r8, (%rdi) + movq %r9, 8(%rdi) + movq %r10, 16(%rdi) + movq %r11, 24(%rdi) + decb %cl + jnz L_fe_sq_n_x64 + popq %rbx + popq %r15 + popq %r14 + popq %r13 + popq %r12 + repz retq +#ifndef __APPLE__ +.size fe_sq_n_x64,.-fe_sq_n_x64 +#endif /* __APPLE__ */ +#ifndef __APPLE__ +.text .globl fe_mul121666_x64 .type fe_mul121666_x64,@function .align 4 @@ -1929,7 +2046,7 @@ fe_invert_x64: .p2align 2 _fe_invert_x64: #endif /* __APPLE__ */ - subq $0x98, %rsp + subq $0x90, %rsp # Invert movq %rdi, 128(%rsp) movq %rsi, 136(%rsp) @@ -1992,17 +2109,14 @@ _fe_invert_x64: #else callq _fe_sq_x64 #endif /* __APPLE__ */ - movb $4, 144(%rsp) leaq 64(%rsp), %rdi leaq 64(%rsp), %rsi -L_fe_invert_x64_1: + movq $4, %rdx #ifndef __APPLE__ - callq fe_sq_x64@plt + callq fe_sq_n_x64@plt #else - callq _fe_sq_x64 + callq _fe_sq_n_x64 #endif /* __APPLE__ */ - decb 144(%rsp) - jnz L_fe_invert_x64_1 leaq 32(%rsp), %rdi leaq 64(%rsp), %rsi leaq 32(%rsp), %rdx @@ -2018,17 +2132,14 @@ L_fe_invert_x64_1: #else callq _fe_sq_x64 #endif /* __APPLE__ */ - movb $9, 144(%rsp) leaq 64(%rsp), %rdi leaq 64(%rsp), %rsi -L_fe_invert_x64_2: + movq $9, %rdx #ifndef __APPLE__ - callq fe_sq_x64@plt + callq fe_sq_n_x64@plt #else - callq _fe_sq_x64 + callq _fe_sq_n_x64 #endif /* __APPLE__ */ - decb 144(%rsp) - jnz L_fe_invert_x64_2 leaq 64(%rsp), %rdi leaq 64(%rsp), %rsi leaq 32(%rsp), %rdx @@ -2044,17 +2155,14 @@ L_fe_invert_x64_2: #else callq _fe_sq_x64 #endif /* __APPLE__ */ - movb $19, 144(%rsp) leaq 96(%rsp), %rdi leaq 96(%rsp), %rsi -L_fe_invert_x64_3: + movq $19, %rdx #ifndef __APPLE__ - callq fe_sq_x64@plt + callq fe_sq_n_x64@plt #else - callq _fe_sq_x64 + callq _fe_sq_n_x64 #endif /* __APPLE__ */ - decb 144(%rsp) - jnz L_fe_invert_x64_3 leaq 64(%rsp), %rdi leaq 96(%rsp), %rsi leaq 64(%rsp), %rdx @@ -2070,17 +2178,14 @@ L_fe_invert_x64_3: #else callq _fe_sq_x64 #endif /* __APPLE__ */ - movb $9, 144(%rsp) leaq 64(%rsp), %rdi leaq 64(%rsp), %rsi -L_fe_invert_x64_4: + movq $9, %rdx #ifndef __APPLE__ - callq fe_sq_x64@plt + callq fe_sq_n_x64@plt #else - callq _fe_sq_x64 + callq _fe_sq_n_x64 #endif /* __APPLE__ */ - decb 144(%rsp) - jnz L_fe_invert_x64_4 leaq 32(%rsp), %rdi leaq 64(%rsp), %rsi leaq 32(%rsp), %rdx @@ -2096,17 +2201,14 @@ L_fe_invert_x64_4: #else callq _fe_sq_x64 #endif /* __APPLE__ */ - movb $49, 144(%rsp) leaq 64(%rsp), %rdi leaq 64(%rsp), %rsi -L_fe_invert_x64_5: + movq $49, %rdx #ifndef __APPLE__ - callq fe_sq_x64@plt + callq fe_sq_n_x64@plt #else - callq _fe_sq_x64 + callq _fe_sq_n_x64 #endif /* __APPLE__ */ - decb 144(%rsp) - jnz L_fe_invert_x64_5 leaq 64(%rsp), %rdi leaq 64(%rsp), %rsi leaq 32(%rsp), %rdx @@ -2122,17 +2224,14 @@ L_fe_invert_x64_5: #else callq _fe_sq_x64 #endif /* __APPLE__ */ - movb $0x63, 144(%rsp) leaq 96(%rsp), %rdi leaq 96(%rsp), %rsi -L_fe_invert_x64_6: + movq $0x63, %rdx #ifndef __APPLE__ - callq fe_sq_x64@plt + callq fe_sq_n_x64@plt #else - callq _fe_sq_x64 + callq _fe_sq_n_x64 #endif /* __APPLE__ */ - decb 144(%rsp) - jnz L_fe_invert_x64_6 leaq 64(%rsp), %rdi leaq 96(%rsp), %rsi leaq 64(%rsp), %rdx @@ -2148,17 +2247,14 @@ L_fe_invert_x64_6: #else callq _fe_sq_x64 #endif /* __APPLE__ */ - movb $49, 144(%rsp) leaq 64(%rsp), %rdi leaq 64(%rsp), %rsi -L_fe_invert_x64_7: + movq $49, %rdx #ifndef __APPLE__ - callq fe_sq_x64@plt + callq fe_sq_n_x64@plt #else - callq _fe_sq_x64 + callq _fe_sq_n_x64 #endif /* __APPLE__ */ - decb 144(%rsp) - jnz L_fe_invert_x64_7 leaq 32(%rsp), %rdi leaq 64(%rsp), %rsi leaq 32(%rsp), %rdx @@ -2174,17 +2270,14 @@ L_fe_invert_x64_7: #else callq _fe_sq_x64 #endif /* __APPLE__ */ - movb $4, 144(%rsp) leaq 32(%rsp), %rdi leaq 32(%rsp), %rsi -L_fe_invert_x64_8: + movq $4, %rdx #ifndef __APPLE__ - callq fe_sq_x64@plt + callq fe_sq_n_x64@plt #else - callq _fe_sq_x64 + callq _fe_sq_n_x64 #endif /* __APPLE__ */ - decb 144(%rsp) - jnz L_fe_invert_x64_8 movq 128(%rsp), %rdi leaq 32(%rsp), %rsi movq %rsp, %rdx @@ -2195,7 +2288,7 @@ L_fe_invert_x64_8: #endif /* __APPLE__ */ movq 136(%rsp), %rsi movq 128(%rsp), %rdi - addq $0x98, %rsp + addq $0x90, %rsp repz retq #ifndef __APPLE__ .text @@ -3864,17 +3957,14 @@ L_curve25519_x64_bits: #else callq _fe_sq_x64 #endif /* __APPLE__ */ - movb $4, 160(%rsp) leaq 96(%rsp), %rdi leaq 96(%rsp), %rsi -L_curve25519_x64_inv_1: + movq $4, %rdx #ifndef __APPLE__ - callq fe_sq_x64@plt + callq fe_sq_n_x64@plt #else - callq _fe_sq_x64 + callq _fe_sq_n_x64 #endif /* __APPLE__ */ - decb 160(%rsp) - jnz L_curve25519_x64_inv_1 leaq 64(%rsp), %rdi leaq 96(%rsp), %rsi leaq 64(%rsp), %rdx @@ -3890,17 +3980,14 @@ L_curve25519_x64_inv_1: #else callq _fe_sq_x64 #endif /* __APPLE__ */ - movb $9, 160(%rsp) leaq 96(%rsp), %rdi leaq 96(%rsp), %rsi -L_curve25519_x64_inv_2: + movq $9, %rdx #ifndef __APPLE__ - callq fe_sq_x64@plt + callq fe_sq_n_x64@plt #else - callq _fe_sq_x64 + callq _fe_sq_n_x64 #endif /* __APPLE__ */ - decb 160(%rsp) - jnz L_curve25519_x64_inv_2 leaq 96(%rsp), %rdi leaq 96(%rsp), %rsi leaq 64(%rsp), %rdx @@ -3916,17 +4003,14 @@ L_curve25519_x64_inv_2: #else callq _fe_sq_x64 #endif /* __APPLE__ */ - movb $19, 160(%rsp) leaq 128(%rsp), %rdi leaq 128(%rsp), %rsi -L_curve25519_x64_inv_3: + movq $19, %rdx #ifndef __APPLE__ - callq fe_sq_x64@plt + callq fe_sq_n_x64@plt #else - callq _fe_sq_x64 + callq _fe_sq_n_x64 #endif /* __APPLE__ */ - decb 160(%rsp) - jnz L_curve25519_x64_inv_3 leaq 96(%rsp), %rdi leaq 128(%rsp), %rsi leaq 96(%rsp), %rdx @@ -3942,17 +4026,14 @@ L_curve25519_x64_inv_3: #else callq _fe_sq_x64 #endif /* __APPLE__ */ - movb $9, 160(%rsp) leaq 96(%rsp), %rdi leaq 96(%rsp), %rsi -L_curve25519_x64_inv_4: + movq $9, %rdx #ifndef __APPLE__ - callq fe_sq_x64@plt + callq fe_sq_n_x64@plt #else - callq _fe_sq_x64 + callq _fe_sq_n_x64 #endif /* __APPLE__ */ - decb 160(%rsp) - jnz L_curve25519_x64_inv_4 leaq 64(%rsp), %rdi leaq 96(%rsp), %rsi leaq 64(%rsp), %rdx @@ -3968,17 +4049,14 @@ L_curve25519_x64_inv_4: #else callq _fe_sq_x64 #endif /* __APPLE__ */ - movb $49, 160(%rsp) leaq 96(%rsp), %rdi leaq 96(%rsp), %rsi -L_curve25519_x64_inv_5: + movq $49, %rdx #ifndef __APPLE__ - callq fe_sq_x64@plt + callq fe_sq_n_x64@plt #else - callq _fe_sq_x64 + callq _fe_sq_n_x64 #endif /* __APPLE__ */ - decb 160(%rsp) - jnz L_curve25519_x64_inv_5 leaq 96(%rsp), %rdi leaq 96(%rsp), %rsi leaq 64(%rsp), %rdx @@ -3994,17 +4072,14 @@ L_curve25519_x64_inv_5: #else callq _fe_sq_x64 #endif /* __APPLE__ */ - movb $0x63, 160(%rsp) leaq 128(%rsp), %rdi leaq 128(%rsp), %rsi -L_curve25519_x64_inv_6: + movq $0x63, %rdx #ifndef __APPLE__ - callq fe_sq_x64@plt + callq fe_sq_n_x64@plt #else - callq _fe_sq_x64 + callq _fe_sq_n_x64 #endif /* __APPLE__ */ - decb 160(%rsp) - jnz L_curve25519_x64_inv_6 leaq 96(%rsp), %rdi leaq 128(%rsp), %rsi leaq 96(%rsp), %rdx @@ -4020,17 +4095,14 @@ L_curve25519_x64_inv_6: #else callq _fe_sq_x64 #endif /* __APPLE__ */ - movb $49, 160(%rsp) leaq 96(%rsp), %rdi leaq 96(%rsp), %rsi -L_curve25519_x64_inv_7: + movq $49, %rdx #ifndef __APPLE__ - callq fe_sq_x64@plt + callq fe_sq_n_x64@plt #else - callq _fe_sq_x64 + callq _fe_sq_n_x64 #endif /* __APPLE__ */ - decb 160(%rsp) - jnz L_curve25519_x64_inv_7 leaq 64(%rsp), %rdi leaq 96(%rsp), %rsi leaq 64(%rsp), %rdx @@ -4046,17 +4118,14 @@ L_curve25519_x64_inv_7: #else callq _fe_sq_x64 #endif /* __APPLE__ */ - movb $4, 160(%rsp) leaq 64(%rsp), %rdi leaq 64(%rsp), %rsi -L_curve25519_x64_inv_8: + movq $4, %rdx #ifndef __APPLE__ - callq fe_sq_x64@plt + callq fe_sq_n_x64@plt #else - callq _fe_sq_x64 + callq _fe_sq_n_x64 #endif /* __APPLE__ */ - decb 160(%rsp) - jnz L_curve25519_x64_inv_8 movq %rsp, %rdi leaq 64(%rsp), %rsi leaq 32(%rsp), %rdx @@ -4243,7 +4312,7 @@ fe_pow22523_x64: .p2align 2 _fe_pow22523_x64: #endif /* __APPLE__ */ - subq $0x78, %rsp + subq $0x70, %rsp # pow22523 movq %rdi, 96(%rsp) movq %rsi, 104(%rsp) @@ -4306,17 +4375,14 @@ _fe_pow22523_x64: #else callq _fe_sq_x64 #endif /* __APPLE__ */ - movb $4, 112(%rsp) leaq 32(%rsp), %rdi leaq 32(%rsp), %rsi -L_fe_pow22523_x64_1: + movq $4, %rdx #ifndef __APPLE__ - callq fe_sq_x64@plt + callq fe_sq_n_x64@plt #else - callq _fe_sq_x64 + callq _fe_sq_n_x64 #endif /* __APPLE__ */ - decb 112(%rsp) - jnz L_fe_pow22523_x64_1 movq %rsp, %rdi leaq 32(%rsp), %rsi movq %rsp, %rdx @@ -4332,17 +4398,14 @@ L_fe_pow22523_x64_1: #else callq _fe_sq_x64 #endif /* __APPLE__ */ - movb $9, 112(%rsp) leaq 32(%rsp), %rdi leaq 32(%rsp), %rsi -L_fe_pow22523_x64_2: + movq $9, %rdx #ifndef __APPLE__ - callq fe_sq_x64@plt + callq fe_sq_n_x64@plt #else - callq _fe_sq_x64 + callq _fe_sq_n_x64 #endif /* __APPLE__ */ - decb 112(%rsp) - jnz L_fe_pow22523_x64_2 leaq 32(%rsp), %rdi leaq 32(%rsp), %rsi movq %rsp, %rdx @@ -4358,17 +4421,14 @@ L_fe_pow22523_x64_2: #else callq _fe_sq_x64 #endif /* __APPLE__ */ - movb $19, 112(%rsp) leaq 64(%rsp), %rdi leaq 64(%rsp), %rsi -L_fe_pow22523_x64_3: + movq $19, %rdx #ifndef __APPLE__ - callq fe_sq_x64@plt + callq fe_sq_n_x64@plt #else - callq _fe_sq_x64 + callq _fe_sq_n_x64 #endif /* __APPLE__ */ - decb 112(%rsp) - jnz L_fe_pow22523_x64_3 leaq 32(%rsp), %rdi leaq 64(%rsp), %rsi leaq 32(%rsp), %rdx @@ -4384,17 +4444,14 @@ L_fe_pow22523_x64_3: #else callq _fe_sq_x64 #endif /* __APPLE__ */ - movb $9, 112(%rsp) leaq 32(%rsp), %rdi leaq 32(%rsp), %rsi -L_fe_pow22523_x64_4: + movq $9, %rdx #ifndef __APPLE__ - callq fe_sq_x64@plt + callq fe_sq_n_x64@plt #else - callq _fe_sq_x64 + callq _fe_sq_n_x64 #endif /* __APPLE__ */ - decb 112(%rsp) - jnz L_fe_pow22523_x64_4 movq %rsp, %rdi leaq 32(%rsp), %rsi movq %rsp, %rdx @@ -4410,17 +4467,14 @@ L_fe_pow22523_x64_4: #else callq _fe_sq_x64 #endif /* __APPLE__ */ - movb $49, 112(%rsp) leaq 32(%rsp), %rdi leaq 32(%rsp), %rsi -L_fe_pow22523_x64_5: + movq $49, %rdx #ifndef __APPLE__ - callq fe_sq_x64@plt + callq fe_sq_n_x64@plt #else - callq _fe_sq_x64 + callq _fe_sq_n_x64 #endif /* __APPLE__ */ - decb 112(%rsp) - jnz L_fe_pow22523_x64_5 leaq 32(%rsp), %rdi leaq 32(%rsp), %rsi movq %rsp, %rdx @@ -4436,17 +4490,14 @@ L_fe_pow22523_x64_5: #else callq _fe_sq_x64 #endif /* __APPLE__ */ - movb $0x63, 112(%rsp) leaq 64(%rsp), %rdi leaq 64(%rsp), %rsi -L_fe_pow22523_x64_6: + movq $0x63, %rdx #ifndef __APPLE__ - callq fe_sq_x64@plt + callq fe_sq_n_x64@plt #else - callq _fe_sq_x64 + callq _fe_sq_n_x64 #endif /* __APPLE__ */ - decb 112(%rsp) - jnz L_fe_pow22523_x64_6 leaq 32(%rsp), %rdi leaq 64(%rsp), %rsi leaq 32(%rsp), %rdx @@ -4462,17 +4513,14 @@ L_fe_pow22523_x64_6: #else callq _fe_sq_x64 #endif /* __APPLE__ */ - movb $49, 112(%rsp) leaq 32(%rsp), %rdi leaq 32(%rsp), %rsi -L_fe_pow22523_x64_7: + movq $49, %rdx #ifndef __APPLE__ - callq fe_sq_x64@plt + callq fe_sq_n_x64@plt #else - callq _fe_sq_x64 + callq _fe_sq_n_x64 #endif /* __APPLE__ */ - decb 112(%rsp) - jnz L_fe_pow22523_x64_7 movq %rsp, %rdi leaq 32(%rsp), %rsi movq %rsp, %rdx @@ -4505,7 +4553,7 @@ L_fe_pow22523_x64_7: #endif /* __APPLE__ */ movq 104(%rsp), %rsi movq 96(%rsp), %rdi - addq $0x78, %rsp + addq $0x70, %rsp repz retq #ifndef __APPLE__ .text @@ -9746,6 +9794,139 @@ _fe_sq_avx2: #endif /* __APPLE__ */ #ifndef __APPLE__ .text +.globl fe_sq_n_avx2 +.type fe_sq_n_avx2,@function +.align 4 +fe_sq_n_avx2: +#else +.section __TEXT,__text +.globl _fe_sq_n_avx2 +.p2align 2 +_fe_sq_n_avx2: +#endif /* __APPLE__ */ + pushq %rbx + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + pushq %rbp + movq %rdx, %rbp +L_fe_sq_n_avx2: + # Square + # A[0] * A[1] + movq (%rsi), %rdx + mulxq 8(%rsi), %r9, %r10 + # A[0] * A[3] + mulxq 24(%rsi), %r11, %r12 + # A[2] * A[1] + movq 16(%rsi), %rdx + mulxq 8(%rsi), %rcx, %rbx + xorq %r15, %r15 + adoxq %rcx, %r11 + # A[2] * A[3] + mulxq 24(%rsi), %r13, %r14 + adoxq %rbx, %r12 + # A[2] * A[0] + mulxq (%rsi), %rcx, %rbx + adoxq %r15, %r13 + adcxq %rcx, %r10 + adoxq %r15, %r14 + # A[1] * A[3] + movq 8(%rsi), %rdx + mulxq 24(%rsi), %rax, %r8 + adcxq %rbx, %r11 + adcxq %rax, %r12 + adcxq %r8, %r13 + adcxq %r15, %r14 + # Double with Carry Flag + xorq %r15, %r15 + # A[0] * A[0] + movq (%rsi), %rdx + mulxq %rdx, %r8, %rax + adcxq %r9, %r9 + # A[1] * A[1] + movq 8(%rsi), %rdx + mulxq %rdx, %rcx, %rbx + adcxq %r10, %r10 + adoxq %rax, %r9 + adcxq %r11, %r11 + adoxq %rcx, %r10 + # A[2] * A[2] + movq 16(%rsi), %rdx + mulxq %rdx, %rax, %rcx + adcxq %r12, %r12 + adoxq %rbx, %r11 + adcxq %r13, %r13 + adoxq %rax, %r12 + # A[3] * A[3] + movq 24(%rsi), %rdx + mulxq %rdx, %rax, %rbx + adcxq %r14, %r14 + adoxq %rcx, %r13 + adcxq %r15, %r15 + adoxq %rax, %r14 + adoxq %rbx, %r15 + # Reduce + movq $0x7fffffffffffffff, %rcx + # Move top half into t4-t7 and remove top bit from t3 + shldq $0x01, %r14, %r15 + shldq $0x01, %r13, %r14 + shldq $0x01, %r12, %r13 + shldq $0x01, %r11, %r12 + andq %rcx, %r11 + # Multiply top half by 19 + movq $19, %rdx + xorq %rcx, %rcx + mulxq %r12, %rax, %r12 + adcxq %rax, %r8 + adoxq %r12, %r9 + mulxq %r13, %rax, %r13 + adcxq %rax, %r9 + adoxq %r13, %r10 + mulxq %r14, %rax, %r14 + adcxq %rax, %r10 + adoxq %r14, %r11 + mulxq %r15, %r15, %rdx + adcxq %r15, %r11 + adoxq %rcx, %rdx + adcxq %rcx, %rdx + # Overflow + shldq $0x01, %r11, %rdx + movq $0x7fffffffffffffff, %rcx + imulq $19, %rdx, %rax + andq %rcx, %r11 + addq %rax, %r8 + adcq $0x00, %r9 + adcq $0x00, %r10 + adcq $0x00, %r11 + # Reduce if top bit set + movq %r11, %rdx + shrq $63, %rdx + imulq $19, %rdx, %rax + andq %rcx, %r11 + addq %rax, %r8 + adcq $0x00, %r9 + adcq $0x00, %r10 + adcq $0x00, %r11 + # Store + movq %r8, (%rdi) + movq %r9, 8(%rdi) + movq %r10, 16(%rdi) + movq %r11, 24(%rdi) + decb %bpl + jnz L_fe_sq_n_avx2 + popq %rbp + popq %r15 + popq %r14 + popq %r13 + popq %r12 + popq %rbx + repz retq +#ifndef __APPLE__ +.size fe_sq_n_avx2,.-fe_sq_n_avx2 +#endif /* __APPLE__ */ +#ifndef __APPLE__ +.text .globl fe_mul121666_avx2 .type fe_mul121666_avx2,@function .align 4 @@ -9935,7 +10116,7 @@ fe_invert_avx2: .p2align 2 _fe_invert_avx2: #endif /* __APPLE__ */ - subq $0x98, %rsp + subq $0x90, %rsp # Invert movq %rdi, 128(%rsp) movq %rsi, 136(%rsp) @@ -9998,17 +10179,14 @@ _fe_invert_avx2: #else callq _fe_sq_avx2 #endif /* __APPLE__ */ - movb $4, 144(%rsp) leaq 64(%rsp), %rdi leaq 64(%rsp), %rsi -L_fe_invert_avx2_1: + movq $4, %rdx #ifndef __APPLE__ - callq fe_sq_avx2@plt + callq fe_sq_n_avx2@plt #else - callq _fe_sq_avx2 + callq _fe_sq_n_avx2 #endif /* __APPLE__ */ - decb 144(%rsp) - jnz L_fe_invert_avx2_1 leaq 32(%rsp), %rdi leaq 64(%rsp), %rsi leaq 32(%rsp), %rdx @@ -10024,17 +10202,14 @@ L_fe_invert_avx2_1: #else callq _fe_sq_avx2 #endif /* __APPLE__ */ - movb $9, 144(%rsp) leaq 64(%rsp), %rdi leaq 64(%rsp), %rsi -L_fe_invert_avx2_2: + movq $9, %rdx #ifndef __APPLE__ - callq fe_sq_avx2@plt + callq fe_sq_n_avx2@plt #else - callq _fe_sq_avx2 + callq _fe_sq_n_avx2 #endif /* __APPLE__ */ - decb 144(%rsp) - jnz L_fe_invert_avx2_2 leaq 64(%rsp), %rdi leaq 64(%rsp), %rsi leaq 32(%rsp), %rdx @@ -10050,17 +10225,14 @@ L_fe_invert_avx2_2: #else callq _fe_sq_avx2 #endif /* __APPLE__ */ - movb $19, 144(%rsp) leaq 96(%rsp), %rdi leaq 96(%rsp), %rsi -L_fe_invert_avx2_3: + movq $19, %rdx #ifndef __APPLE__ - callq fe_sq_avx2@plt + callq fe_sq_n_avx2@plt #else - callq _fe_sq_avx2 + callq _fe_sq_n_avx2 #endif /* __APPLE__ */ - decb 144(%rsp) - jnz L_fe_invert_avx2_3 leaq 64(%rsp), %rdi leaq 96(%rsp), %rsi leaq 64(%rsp), %rdx @@ -10076,17 +10248,14 @@ L_fe_invert_avx2_3: #else callq _fe_sq_avx2 #endif /* __APPLE__ */ - movb $9, 144(%rsp) leaq 64(%rsp), %rdi leaq 64(%rsp), %rsi -L_fe_invert_avx2_4: + movq $9, %rdx #ifndef __APPLE__ - callq fe_sq_avx2@plt + callq fe_sq_n_avx2@plt #else - callq _fe_sq_avx2 + callq _fe_sq_n_avx2 #endif /* __APPLE__ */ - decb 144(%rsp) - jnz L_fe_invert_avx2_4 leaq 32(%rsp), %rdi leaq 64(%rsp), %rsi leaq 32(%rsp), %rdx @@ -10102,17 +10271,14 @@ L_fe_invert_avx2_4: #else callq _fe_sq_avx2 #endif /* __APPLE__ */ - movb $49, 144(%rsp) leaq 64(%rsp), %rdi leaq 64(%rsp), %rsi -L_fe_invert_avx2_5: + movq $49, %rdx #ifndef __APPLE__ - callq fe_sq_avx2@plt + callq fe_sq_n_avx2@plt #else - callq _fe_sq_avx2 + callq _fe_sq_n_avx2 #endif /* __APPLE__ */ - decb 144(%rsp) - jnz L_fe_invert_avx2_5 leaq 64(%rsp), %rdi leaq 64(%rsp), %rsi leaq 32(%rsp), %rdx @@ -10128,17 +10294,14 @@ L_fe_invert_avx2_5: #else callq _fe_sq_avx2 #endif /* __APPLE__ */ - movb $0x63, 144(%rsp) leaq 96(%rsp), %rdi leaq 96(%rsp), %rsi -L_fe_invert_avx2_6: + movq $0x63, %rdx #ifndef __APPLE__ - callq fe_sq_avx2@plt + callq fe_sq_n_avx2@plt #else - callq _fe_sq_avx2 + callq _fe_sq_n_avx2 #endif /* __APPLE__ */ - decb 144(%rsp) - jnz L_fe_invert_avx2_6 leaq 64(%rsp), %rdi leaq 96(%rsp), %rsi leaq 64(%rsp), %rdx @@ -10154,17 +10317,14 @@ L_fe_invert_avx2_6: #else callq _fe_sq_avx2 #endif /* __APPLE__ */ - movb $49, 144(%rsp) leaq 64(%rsp), %rdi leaq 64(%rsp), %rsi -L_fe_invert_avx2_7: + movq $49, %rdx #ifndef __APPLE__ - callq fe_sq_avx2@plt + callq fe_sq_n_avx2@plt #else - callq _fe_sq_avx2 + callq _fe_sq_n_avx2 #endif /* __APPLE__ */ - decb 144(%rsp) - jnz L_fe_invert_avx2_7 leaq 32(%rsp), %rdi leaq 64(%rsp), %rsi leaq 32(%rsp), %rdx @@ -10180,17 +10340,14 @@ L_fe_invert_avx2_7: #else callq _fe_sq_avx2 #endif /* __APPLE__ */ - movb $4, 144(%rsp) leaq 32(%rsp), %rdi leaq 32(%rsp), %rsi -L_fe_invert_avx2_8: + movq $4, %rdx #ifndef __APPLE__ - callq fe_sq_avx2@plt + callq fe_sq_n_avx2@plt #else - callq _fe_sq_avx2 + callq _fe_sq_n_avx2 #endif /* __APPLE__ */ - decb 144(%rsp) - jnz L_fe_invert_avx2_8 movq 128(%rsp), %rdi leaq 32(%rsp), %rsi movq %rsp, %rdx @@ -10201,7 +10358,7 @@ L_fe_invert_avx2_8: #endif /* __APPLE__ */ movq 136(%rsp), %rsi movq 128(%rsp), %rdi - addq $0x98, %rsp + addq $0x90, %rsp repz retq #ifndef __APPLE__ .text @@ -11619,17 +11776,14 @@ L_curve25519_avx2_bits: #else callq _fe_sq_avx2 #endif /* __APPLE__ */ - movb $4, 160(%rsp) leaq 96(%rsp), %rdi leaq 96(%rsp), %rsi -L_curve25519_avx2_inv_1: + movq $4, %rdx #ifndef __APPLE__ - callq fe_sq_avx2@plt + callq fe_sq_n_avx2@plt #else - callq _fe_sq_avx2 + callq _fe_sq_n_avx2 #endif /* __APPLE__ */ - decb 160(%rsp) - jnz L_curve25519_avx2_inv_1 leaq 64(%rsp), %rdi leaq 96(%rsp), %rsi leaq 64(%rsp), %rdx @@ -11645,17 +11799,14 @@ L_curve25519_avx2_inv_1: #else callq _fe_sq_avx2 #endif /* __APPLE__ */ - movb $9, 160(%rsp) leaq 96(%rsp), %rdi leaq 96(%rsp), %rsi -L_curve25519_avx2_inv_2: + movq $9, %rdx #ifndef __APPLE__ - callq fe_sq_avx2@plt + callq fe_sq_n_avx2@plt #else - callq _fe_sq_avx2 + callq _fe_sq_n_avx2 #endif /* __APPLE__ */ - decb 160(%rsp) - jnz L_curve25519_avx2_inv_2 leaq 96(%rsp), %rdi leaq 96(%rsp), %rsi leaq 64(%rsp), %rdx @@ -11671,17 +11822,14 @@ L_curve25519_avx2_inv_2: #else callq _fe_sq_avx2 #endif /* __APPLE__ */ - movb $19, 160(%rsp) leaq 128(%rsp), %rdi leaq 128(%rsp), %rsi -L_curve25519_avx2_inv_3: + movq $19, %rdx #ifndef __APPLE__ - callq fe_sq_avx2@plt + callq fe_sq_n_avx2@plt #else - callq _fe_sq_avx2 + callq _fe_sq_n_avx2 #endif /* __APPLE__ */ - decb 160(%rsp) - jnz L_curve25519_avx2_inv_3 leaq 96(%rsp), %rdi leaq 128(%rsp), %rsi leaq 96(%rsp), %rdx @@ -11697,17 +11845,14 @@ L_curve25519_avx2_inv_3: #else callq _fe_sq_avx2 #endif /* __APPLE__ */ - movb $9, 160(%rsp) leaq 96(%rsp), %rdi leaq 96(%rsp), %rsi -L_curve25519_avx2_inv_4: + movq $9, %rdx #ifndef __APPLE__ - callq fe_sq_avx2@plt + callq fe_sq_n_avx2@plt #else - callq _fe_sq_avx2 + callq _fe_sq_n_avx2 #endif /* __APPLE__ */ - decb 160(%rsp) - jnz L_curve25519_avx2_inv_4 leaq 64(%rsp), %rdi leaq 96(%rsp), %rsi leaq 64(%rsp), %rdx @@ -11723,17 +11868,14 @@ L_curve25519_avx2_inv_4: #else callq _fe_sq_avx2 #endif /* __APPLE__ */ - movb $49, 160(%rsp) leaq 96(%rsp), %rdi leaq 96(%rsp), %rsi -L_curve25519_avx2_inv_5: + movq $49, %rdx #ifndef __APPLE__ - callq fe_sq_avx2@plt + callq fe_sq_n_avx2@plt #else - callq _fe_sq_avx2 + callq _fe_sq_n_avx2 #endif /* __APPLE__ */ - decb 160(%rsp) - jnz L_curve25519_avx2_inv_5 leaq 96(%rsp), %rdi leaq 96(%rsp), %rsi leaq 64(%rsp), %rdx @@ -11749,17 +11891,14 @@ L_curve25519_avx2_inv_5: #else callq _fe_sq_avx2 #endif /* __APPLE__ */ - movb $0x63, 160(%rsp) leaq 128(%rsp), %rdi leaq 128(%rsp), %rsi -L_curve25519_avx2_inv_6: + movq $0x63, %rdx #ifndef __APPLE__ - callq fe_sq_avx2@plt + callq fe_sq_n_avx2@plt #else - callq _fe_sq_avx2 + callq _fe_sq_n_avx2 #endif /* __APPLE__ */ - decb 160(%rsp) - jnz L_curve25519_avx2_inv_6 leaq 96(%rsp), %rdi leaq 128(%rsp), %rsi leaq 96(%rsp), %rdx @@ -11775,17 +11914,14 @@ L_curve25519_avx2_inv_6: #else callq _fe_sq_avx2 #endif /* __APPLE__ */ - movb $49, 160(%rsp) leaq 96(%rsp), %rdi leaq 96(%rsp), %rsi -L_curve25519_avx2_inv_7: + movq $49, %rdx #ifndef __APPLE__ - callq fe_sq_avx2@plt + callq fe_sq_n_avx2@plt #else - callq _fe_sq_avx2 + callq _fe_sq_n_avx2 #endif /* __APPLE__ */ - decb 160(%rsp) - jnz L_curve25519_avx2_inv_7 leaq 64(%rsp), %rdi leaq 96(%rsp), %rsi leaq 64(%rsp), %rdx @@ -11801,17 +11937,14 @@ L_curve25519_avx2_inv_7: #else callq _fe_sq_avx2 #endif /* __APPLE__ */ - movb $4, 160(%rsp) leaq 64(%rsp), %rdi leaq 64(%rsp), %rsi -L_curve25519_avx2_inv_8: + movq $4, %rdx #ifndef __APPLE__ - callq fe_sq_avx2@plt + callq fe_sq_n_avx2@plt #else - callq _fe_sq_avx2 + callq _fe_sq_n_avx2 #endif /* __APPLE__ */ - decb 160(%rsp) - jnz L_curve25519_avx2_inv_8 movq %rsp, %rdi leaq 64(%rsp), %rsi leaq 32(%rsp), %rdx @@ -11970,7 +12103,7 @@ fe_pow22523_avx2: .p2align 2 _fe_pow22523_avx2: #endif /* __APPLE__ */ - subq $0x78, %rsp + subq $0x70, %rsp # pow22523 movq %rdi, 96(%rsp) movq %rsi, 104(%rsp) @@ -12033,17 +12166,14 @@ _fe_pow22523_avx2: #else callq _fe_sq_avx2 #endif /* __APPLE__ */ - movb $4, 112(%rsp) leaq 32(%rsp), %rdi leaq 32(%rsp), %rsi -L_fe_pow22523_avx2_1: + movb $4, %dl #ifndef __APPLE__ - callq fe_sq_avx2@plt + callq fe_sq_n_avx2@plt #else - callq _fe_sq_avx2 + callq _fe_sq_n_avx2 #endif /* __APPLE__ */ - decb 112(%rsp) - jnz L_fe_pow22523_avx2_1 movq %rsp, %rdi leaq 32(%rsp), %rsi movq %rsp, %rdx @@ -12059,17 +12189,14 @@ L_fe_pow22523_avx2_1: #else callq _fe_sq_avx2 #endif /* __APPLE__ */ - movb $9, 112(%rsp) leaq 32(%rsp), %rdi leaq 32(%rsp), %rsi -L_fe_pow22523_avx2_2: + movb $9, %dl #ifndef __APPLE__ - callq fe_sq_avx2@plt + callq fe_sq_n_avx2@plt #else - callq _fe_sq_avx2 + callq _fe_sq_n_avx2 #endif /* __APPLE__ */ - decb 112(%rsp) - jnz L_fe_pow22523_avx2_2 leaq 32(%rsp), %rdi leaq 32(%rsp), %rsi movq %rsp, %rdx @@ -12085,17 +12212,14 @@ L_fe_pow22523_avx2_2: #else callq _fe_sq_avx2 #endif /* __APPLE__ */ - movb $19, 112(%rsp) leaq 64(%rsp), %rdi leaq 64(%rsp), %rsi -L_fe_pow22523_avx2_3: + movb $19, %dl #ifndef __APPLE__ - callq fe_sq_avx2@plt + callq fe_sq_n_avx2@plt #else - callq _fe_sq_avx2 + callq _fe_sq_n_avx2 #endif /* __APPLE__ */ - decb 112(%rsp) - jnz L_fe_pow22523_avx2_3 leaq 32(%rsp), %rdi leaq 64(%rsp), %rsi leaq 32(%rsp), %rdx @@ -12111,17 +12235,14 @@ L_fe_pow22523_avx2_3: #else callq _fe_sq_avx2 #endif /* __APPLE__ */ - movb $9, 112(%rsp) leaq 32(%rsp), %rdi leaq 32(%rsp), %rsi -L_fe_pow22523_avx2_4: + movb $9, %dl #ifndef __APPLE__ - callq fe_sq_avx2@plt + callq fe_sq_n_avx2@plt #else - callq _fe_sq_avx2 + callq _fe_sq_n_avx2 #endif /* __APPLE__ */ - decb 112(%rsp) - jnz L_fe_pow22523_avx2_4 movq %rsp, %rdi leaq 32(%rsp), %rsi movq %rsp, %rdx @@ -12137,17 +12258,14 @@ L_fe_pow22523_avx2_4: #else callq _fe_sq_avx2 #endif /* __APPLE__ */ - movb $49, 112(%rsp) leaq 32(%rsp), %rdi leaq 32(%rsp), %rsi -L_fe_pow22523_avx2_5: + movb $49, %dl #ifndef __APPLE__ - callq fe_sq_avx2@plt + callq fe_sq_n_avx2@plt #else - callq _fe_sq_avx2 + callq _fe_sq_n_avx2 #endif /* __APPLE__ */ - decb 112(%rsp) - jnz L_fe_pow22523_avx2_5 leaq 32(%rsp), %rdi leaq 32(%rsp), %rsi movq %rsp, %rdx @@ -12163,17 +12281,14 @@ L_fe_pow22523_avx2_5: #else callq _fe_sq_avx2 #endif /* __APPLE__ */ - movb $0x63, 112(%rsp) leaq 64(%rsp), %rdi leaq 64(%rsp), %rsi -L_fe_pow22523_avx2_6: + movb $0x63, %dl #ifndef __APPLE__ - callq fe_sq_avx2@plt + callq fe_sq_n_avx2@plt #else - callq _fe_sq_avx2 + callq _fe_sq_n_avx2 #endif /* __APPLE__ */ - decb 112(%rsp) - jnz L_fe_pow22523_avx2_6 leaq 32(%rsp), %rdi leaq 64(%rsp), %rsi leaq 32(%rsp), %rdx @@ -12189,17 +12304,14 @@ L_fe_pow22523_avx2_6: #else callq _fe_sq_avx2 #endif /* __APPLE__ */ - movb $49, 112(%rsp) leaq 32(%rsp), %rdi leaq 32(%rsp), %rsi -L_fe_pow22523_avx2_7: + movb $49, %dl #ifndef __APPLE__ - callq fe_sq_avx2@plt + callq fe_sq_n_avx2@plt #else - callq _fe_sq_avx2 + callq _fe_sq_n_avx2 #endif /* __APPLE__ */ - decb 112(%rsp) - jnz L_fe_pow22523_avx2_7 movq %rsp, %rdi leaq 32(%rsp), %rsi movq %rsp, %rdx @@ -12232,7 +12344,7 @@ L_fe_pow22523_avx2_7: #endif /* __APPLE__ */ movq 104(%rsp), %rsi movq 96(%rsp), %rdi - addq $0x78, %rsp + addq $0x70, %rsp repz retq #ifndef __APPLE__ .text From 3187624d9e268a9e15c4973e5b25c2bd5c3aca10 Mon Sep 17 00:00:00 2001 From: Hideki Miyazaki Date: Sat, 22 Feb 2020 11:35:02 +0900 Subject: [PATCH 154/649] rename common naming enum --- wolfssl/wolfcrypt/port/Renesas/renesas-tsip-crypt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wolfssl/wolfcrypt/port/Renesas/renesas-tsip-crypt.h b/wolfssl/wolfcrypt/port/Renesas/renesas-tsip-crypt.h index 31162be42..2055ee024 100644 --- a/wolfssl/wolfcrypt/port/Renesas/renesas-tsip-crypt.h +++ b/wolfssl/wolfcrypt/port/Renesas/renesas-tsip-crypt.h @@ -42,7 +42,7 @@ typedef enum { tsip_Key_RSA1024 = 4, tsip_Key_RSA2048 = 5, tsip_Key_tls_Rsa2048 = 6, - UNKNOWN = -1, + tsip_Key_unknown = -1, } wolfssl_TSIP_KEY_IV; enum { From e80c696d5f40fd5540fd5d5a1c067073fec455c0 Mon Sep 17 00:00:00 2001 From: David Garske Date: Sun, 23 Feb 2020 13:54:48 -0800 Subject: [PATCH 155/649] Fix for RSA with SHA3 only (resolves warning with unsed RsaMGF1. --- wolfcrypt/src/rsa.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index bdf8f698e..ad600c4f7 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -768,6 +768,7 @@ int wc_CheckRsaKey(RsaKey* key) out: mask output after generation outSz: size of output buffer */ +#if !defined(NO_SHA) || !defined(NO_SHA256) || defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512) static int RsaMGF1(enum wc_HashType hType, byte* seed, word32 seedSz, byte* out, word32 outSz, void* heap) { @@ -841,9 +842,10 @@ static int RsaMGF1(enum wc_HashType hType, byte* seed, word32 seedSz, return 0; } +#endif /* SHA2 Hashes */ /* helper function to direct which mask generation function is used - switeched on type input + switched on type input */ static int RsaMGF(int type, byte* seed, word32 seedSz, byte* out, word32 outSz, void* heap) @@ -890,7 +892,7 @@ static int RsaMGF(int type, byte* seed, word32 seedSz, byte* out, return ret; } -#endif /* !WC_NO_RSA_OAEP */ +#endif /* !WC_NO_RSA_OAEP || WC_RSA_PSS */ /* Padding */ From c8e618a817bfbb25d4e92e5143bd1ceb4e8562aa Mon Sep 17 00:00:00 2001 From: David Garske Date: Sun, 23 Feb 2020 15:58:28 -0800 Subject: [PATCH 156/649] Fix build for `WOLFSSL_RSA_VERIFY_ONLY`. --- wolfcrypt/src/rsa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index ad600c4f7..5ceddbbbb 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -3471,7 +3471,7 @@ int wc_RsaPSS_VerifyCheck(byte* in, word32 inLen, byte* out, word32 outLen, #endif -#ifndef WOLFSSL_RSA_PUBLIC_ONLY +#if !defined(WOLFSSL_RSA_PUBLIC_ONLY) && !defined(WOLFSSL_RSA_VERIFY_ONLY) int wc_RsaSSL_Sign(const byte* in, word32 inLen, byte* out, word32 outLen, RsaKey* key, WC_RNG* rng) { From da882f3912b29611cfd3cfd9aaeea780265c5695 Mon Sep 17 00:00:00 2001 From: David Garske Date: Sun, 23 Feb 2020 18:40:13 -0800 Subject: [PATCH 157/649] Added wolfCrypt RSA 4096-bit test support using `USE_CERT_BUFFERS_4096` build option (`./configure CFLAGS="-DUSE_CERT_BUFFERS_4096"`). --- certs/4096/client-cert.der | Bin 0 -> 1764 bytes certs/4096/client-key.der | Bin 0 -> 2348 bytes certs/4096/client-keyPub.der | Bin 0 -> 550 bytes certs/4096/include.am | 5 +- certs/renewcerts.sh | 5 +- gencertbuf.pl | 30 ++- wolfcrypt/test/test.c | 42 ++- wolfssl/certs_test.h | 490 +++++++++++++++++++++++++++++++++++ 8 files changed, 559 insertions(+), 13 deletions(-) create mode 100644 certs/4096/client-cert.der create mode 100644 certs/4096/client-key.der create mode 100644 certs/4096/client-keyPub.der diff --git a/certs/4096/client-cert.der b/certs/4096/client-cert.der new file mode 100644 index 0000000000000000000000000000000000000000..c31698f65563655baadeecc0e895fd7c7f2803a1 GIT binary patch literal 1764 zcmXqLVtZiF#ByQ*GZP~dlZZb5YUMqPMc5~@g_<%Z*E{X~{mI#YmyJ`a&7=SQdU}~=H?LyD9TSSO3cm8%uCk=OGy}rfuxvu_{+=7^+39c zi*xjn^K%X54P@aC;$##P$jnR2cR*5LAScdiXlY<>U}<1%U}j(xCC+PPWME=o0_6^V z4>U0;AqP4mD+6;A6F-AN6B8Fx6B8rD*9(SE3L_&nvj^N2tNe3pYQP^izHp(o!rsTT zy^LS^-xL?l^~k&*DagSzcfIy;gMB=A+OI?jaVp0?EQ?AqcPn|%%(`1HSFaH)jgV95B7(@Y3w;k*igX z1^i~Om->mbUM-bQNvg8v)$quAyk^dd{+DmRpH*3~aRKw1$IM^tFHZZfRmZXM@&gHx zH>u_U&WEykzC`~!a=O>Pk?H%PyH5`GHSn;g>NZ5_@hh2neQA9gcw=>L{~~J@hP=i{ za%I=n7z*9~+{eD~UZG{%eDBt@D%X zKTR@>ysmR)i{iCZVQ#zM|5;w|Y~6X|hK7HP__W1=`~KB(OM5t|mQA_i_xRr`SUxea@Z=c} z|9AJ}q^0hsUsibL;yR=5IbX6^^GUVX2?w8Q#khtDZ)%iaQ_#~(i`rV9ca6udlQFDd z_quy8XU1LJX|+8^d>ivhj=OWdh@3nbX<2loj>+8cEZ=h5AD_-=i>_v3W@KPo+{7qk z(8S1RAj`%aD$BTYM}kOl)bMLE}A;yfRDUHG{^>4OrDI zY+SOWap9oP7fslUCmxXhgjrY(m>C)WBj+1#aK2$=23uCvd0q!p( zlUA6?ZU1|5Pe6>->uFN6oj0V%ehDmZH|Cy@|Kf6!uhgo^@wF8jA5_2VV0^y$R~>iR zoOz9APZl3^Oj^QKr*dKS{9QNXEY^M$3gZ1Vt&3ZAk*9q}^eg3dHKnSZ3E9`GI?UIk z%$5jbe|4W>TEWzgx&7<++4vog3l+7Mf1-QmiC+kj`;&NsWlyf4xUp(YOc8)o1AcxS)3 z>~h^!#%q^0g@w&9ZhiZ0@i)8bFU(6K`i@4gPJ6*`BCcy}R>-sCX2o;1KezlB{<>Xq z?p3S$&(f7^1KRRlF)~W>YIwb6+m~9fiOo$+U*Fk@x?M^#Zfj#R+44mHmWH1GfxV?KbnG83b*^Q4 zt-AAld)M{wM6nn1np1xYe2I&fsZzb>zE|_8fA`KTkE+>nx#fLDIXvwDe2$(E-Lp4+FLp1iu1GbzA6_)iX-*da D4qUSQ literal 0 HcmV?d00001 diff --git a/certs/4096/client-key.der b/certs/4096/client-key.der new file mode 100644 index 0000000000000000000000000000000000000000..34a6f1b7cca4bd8196453bf92cb5b0982af2bd56 GIT binary patch literal 2348 zcmXqL;?!VbWMFDyVr2Mw!SG38WW;9nfV*Oqe~wKJ_~XVGF4R`o`*^mO@hktE;=;Ke znfD_FIhf|I*FJ8rkLOPNl_()j<=BU1QAy@*CGVM8cgy8!mgeZqZRhQ8KP@tK_CE3K zz>7Y&u1`!mYWDg8yHuI)hTjLj#pzwaT%8-|Y2LKXKNp zrP3)$Rrb6Z9$Amq%vsU@^6mGtDhoC)U|#c>`K$fKY5%qAI5u8>AR+Q5)jYuYP*%^E z=zm8}_u4lyeLr;f$-%w`9u`&IhA2ILB~!02t#1Qwtj_IUWUa!G*Z4@T?AjVbq1&JP z*caaG^s-DSKf3B;;4`+5Q^T|#_DwRF|1ZL2joYWcv;M4*U3fXv+^hS~9OEC$6FnSj z=9JriZBVXt-g32r>tyM57fIjp9BwYpRWkb5qFk1_`#v?B<}gzyOl{+*NrsWvb*^kt zyp}4=ZTI^>%j=!3J8#_3@Q)Fnwm5L#zgli-4+qt}l$nH!$vTW{o?SQ=x?<=hxk{% zERCprb=7y0-JcST_Jg)N6({*>G_|Z)Bslp~kEV>|k6e58z^%HAk88*t`7>k6iVOcg z@Zb6QcJrcbZ+YYQSHxUjzjyKbwwHlvw}Z^x>tDv(Olj7AF~|60&dblsrvF>M-*>jc zRsDNQ*ml25^UVG#&^o^*D#(s!ftSxM#-mAw8{ho6yV&}iqm@wQ&*{l1rRR{S{9 znIiD;*@3gNmI~LRI-CEPKN3n?A#|o_x7_cn$2Em@JN5cn(jM--pgJpmuH>`27dJi} zRTi6-p(7i*u5ZG-zBh4ha}$D$#5E$1cxoxwO+9-5o9*|b=QkcYS@y$r-6Us+72(djOw_C$|~UaV`E#B`mCVd|(0JeoE^XYt$R z&XU}VoVGl8;JW|cf={K~eYJCo(=Q8f9=+MK)+(iF?KIPg{N5+``lq@t(|v9KXl7BG z(A(FSYW`a(m}^~54V-;=mBdE*ytxkUOXQno-ww!b)BkO6xU*4^MI^b+-$Co^&zgl5 zlEN1P1NkdEdPNrB+h(lkwDUz|*>`8DZOiU+9dtTwFH;wzGtpb_hucK?cVV0PPFyg& zZ2Q*s=1~Klh#T9tz7bjDn3DVCSma+3)`Zj>M_OF!q_->)D?O+_ZIk3R%a8+;KVO$W zD}DcmP>0C;8LaMZg^fA)C%zAUd~{={{zGse{Fv;eQ9kAU%OhNeUj#*NlkGhx^4$5@ zTTb=Z&wU(OlG!@bXLkf^-}>i0C9UP^%5zJd3w|?3<)8h2acGC+tHeveHWfq5@)m-?Ye92h8@$lo?)+h@B=4TzZPxxH;zR6eJ zxb>`6Npp5n#LfHfzFvO$Pv$+Fkl00^bs^roQhOhr58GU_&&7X9G1rXV#1;#;J5$fw zXFpGEXWH)_{>b)-woH@k8R7Z^Y(hQx(*vq|8V@UrzAj+zTgWaK`Agtb9si@<@7mPl zLU+zcYki}B^k#BzVEL*AW}(Icig9n;(+e-I|6>>Mb>Fo~&$*eJ7#S36x{e&v49!@+ z_AYB`@`pcc%bW`O!^6$8CT?a8n{#s3!|v<#{_~gdI*Oib(dA86Wl9dckoITx%~g(W z(^lzc=!lyr#9z3qF*}{laIVPVM}3vo_X=Hn|Kr##_MbkVZn$pUcJUW0kHSmmn@1m5 z-8=V_X{TH2flRO79xH*rqJ^qEy38EC4P@4zY0)@atKAvdA(bfT+@%L0ScsI5~QrvE;8`ux&{mPI-Y-#UBl{7)#1 zX-_!*X~nUhkv!&pQ{SE6VPFutUUq8Jvg^k^|Lre*J%!Uib}!%bjTKyW>TACpjL)1> z!+d^IoD}=zU!S^5Cl&nrH|u^Qze%j?o*jSt&&Re1yqi@YF8NjbPHi#wnru_iZk5wT z2d?X_TXp;N{PZ@F-A^Wn)=YI-YLP3Gp-kmQRsw5_+TNocB$Ia{;rg(Ek-v6WqNv6onqnxb$sLw7Xm2rjuG4Stl<_ zn~FuL#)pc|nt=`r4ml+p|!_*nH~hS+7~Xi5{LU5Ei^h<5R}1+UY^bYi5V7T&*WJ zkFnstb}oa5#mbL#Dm-Jkw~@1jd-gDjU~ b|J1S#e;ZShD*qgt z8t})BFI=dtu=nw7FXLDKH^qf>Ju>e{3UV;bU9WxIU?0z&_A60BoXW8e%c7FZ-Adjw zv+kD5)hx}?o7>LY-+o$T>g;{u*?|{*Ze5?4cGT?k19qu0-wnSHevM%8S^2iM8c>n@VMHIuj^ddqIfM;nA`66f0oxfTX){Lq2V7RK5cQ}zJImc(jE?~ zWmE1r{@!0)cI)-#q~`}ugk(*A*lYO0&hGx6b|wR*@FNc-sxGg4!Zdr;UO!LwqL;nG zx*@X}mQPG9JbA{$|K0sKX{r0^mldA5xX!41&X+9Kd{QlT!ojCnF|HxPn;Iq96!i4c zqPAA&UE}fVWDG0Vz3$%2nQ<3)T5Zn}-^RR>NAdlL literal 0 HcmV?d00001 diff --git a/certs/4096/include.am b/certs/4096/include.am index 259fa2213..ec3777aaa 100644 --- a/certs/4096/include.am +++ b/certs/4096/include.am @@ -4,4 +4,7 @@ EXTRA_DIST += \ certs/4096/client-cert.pem \ - certs/4096/client-key.pem + certs/4096/client-key.pem \ + certs/4096/client-cert.der \ + certs/4096/client-key.der \ + certs/4096/client-keyPub.der diff --git a/certs/renewcerts.sh b/certs/renewcerts.sh index ffd82b80b..73b04714a 100755 --- a/certs/renewcerts.sh +++ b/certs/renewcerts.sh @@ -180,7 +180,6 @@ run_renewcerts(){ echo -e "US\\nMontana\\nBozeman\\nwolfSSL_4096\\nProgramming-4096\\nwww.wolfssl.com\\ninfo@wolfssl.com\\n.\\n.\\n" | openssl req -new -key ./4096/client-key.pem -config ./wolfssl.cnf -nodes -out ./4096/client-cert.csr check_result $? "Step 1" - openssl x509 -req -in ./4096/client-cert.csr -days 1000 -extfile wolfssl.cnf -extensions wolfssl_opts -signkey ./4096/client-key.pem -out ./4096/client-cert.pem check_result $? "Step 2" rm ./4096/client-cert.csr @@ -188,6 +187,10 @@ run_renewcerts(){ openssl x509 -in ./4096/client-cert.pem -text > ./4096/tmp.pem check_result $? "Step 3" mv ./4096/tmp.pem ./4096/client-cert.pem + + openssl rsa -in ./4096/client-key.pem -outform der -out ./4096/client-key.der + openssl rsa -inform pem -in ./4096/client-key.pem -outform der -out ./4096/client-keyPub.der -pubout + openssl x509 -in ./4096/client-cert.pem -outform der -out ./4096/client-cert.der echo "End of section" echo "---------------------------------------------------------------------" diff --git a/gencertbuf.pl b/gencertbuf.pl index 3e8462021..433be1e70 100755 --- a/gencertbuf.pl +++ b/gencertbuf.pl @@ -62,7 +62,6 @@ my @fileList_1024 = ( # 2048-bit certs/keys to be converted # Used with USE_CERT_BUFFERS_2048 define. - my @fileList_2048 = ( [ "./certs/client-key.der", "client_key_der_2048" ], [ "./certs/client-keyPub.der", "client_keypub_der_2048" ], @@ -77,6 +76,8 @@ my @fileList_2048 = ( [ "./certs/server-cert.der", "server_cert_der_2048" ] ); +# 3072-bit certs/keys to be converted +# Used with USE_CERT_BUFFERS_3072 define. my @fileList_3072 = ( [ "./certs/dh3072.der", "dh_key_der_3072" ], [ "./certs/dsa3072.der", "dsa_key_der_3072" ], @@ -86,6 +87,14 @@ my @fileList_3072 = ( [ "./certs/3072/client-cert.der", "client_cert_der_3072" ], ); +# 4096-bit certs/keys to be converted +# Used with USE_CERT_BUFFERS_4096 define. +my @fileList_4096 = ( + [ "./certs/4096/client-key.der", "client_key_der_4096" ], + [ "./certs/4096/client-keyPub.der", "client_keypub_der_4096" ], + [ "./certs/4096/client-cert.der", "client_cert_der_4096" ], + ); + # ---------------------------------------------------------------------------- my $num_ecc = @fileList_ecc; @@ -93,6 +102,7 @@ my $num_ed = @fileList_ed; my $num_1024 = @fileList_1024; my $num_2048 = @fileList_2048; my $num_3072 = @fileList_3072; +my $num_4096 = @fileList_4096; # open our output file, "+>" creates and/or truncates open OUT_FILE, "+>", $outputFile or die $!; @@ -156,6 +166,24 @@ for (my $i = 0; $i < $num_3072; $i++) { print OUT_FILE "#endif /* USE_CERT_BUFFERS_3072 */\n\n"; +# convert and print 4096-bit certs/keys +print OUT_FILE "#ifdef USE_CERT_BUFFERS_4096\n\n"; +for (my $i = 0; $i < $num_4096; $i++) { + + my $fname = $fileList_4096[$i][0]; + my $sname = $fileList_4096[$i][1]; + + print OUT_FILE "/* $fname, 4096-bit */\n"; + print OUT_FILE "static const unsigned char $sname\[] =\n"; + print OUT_FILE "{\n"; + file_to_hex($fname); + print OUT_FILE "};\n"; + print OUT_FILE "static const int sizeof_$sname = sizeof($sname);\n\n"; +} + +print OUT_FILE "#endif /* USE_CERT_BUFFERS_4096 */\n\n"; + + # convert and print 256-bit cert/keys print OUT_FILE "#if defined(HAVE_ECC) && defined(USE_CERT_BUFFERS_256)\n\n"; for (my $i = 0; $i < $num_ecc; $i++) { diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index d0e28fbe5..175e8e749 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -9280,18 +9280,17 @@ byte GetEntropy(ENTROPY_CMD cmd, byte* out) /* Generated Test Certs */ #if !defined(USE_CERT_BUFFERS_1024) && !defined(USE_CERT_BUFFERS_2048) && \ - !defined(USE_CERT_BUFFERS_3072) && !defined(NO_ASN) - #ifndef NO_RSA + !defined(USE_CERT_BUFFERS_3072) && !defined(USE_CERT_BUFFERS_4096) + #if !defined(NO_RSA) && !defined(NO_ASN) static const char* clientKey = CERT_ROOT "client-key.der"; static const char* clientCert = CERT_ROOT "client-cert.der"; #ifdef WOLFSSL_CERT_EXT static const char* clientKeyPub = CERT_ROOT "client-keyPub.der"; #endif - #endif + #endif /* !NO_RSA && !NO_ASN */ #endif -#if !defined(USE_CERT_BUFFERS_1024) && !defined(USE_CERT_BUFFERS_2048) && \ - !defined(NO_ASN) - #ifndef NO_RSA +#if !defined(USE_CERT_BUFFERS_1024) && !defined(USE_CERT_BUFFERS_2048) + #if !defined(NO_RSA) && !defined(NO_ASN) #if defined(WOLFSSL_CERT_GEN) || defined(HAVE_PKCS7) static const char* rsaCaKeyFile = CERT_ROOT "ca-key.der"; #ifdef WOLFSSL_CERT_GEN @@ -9307,7 +9306,7 @@ byte GetEntropy(ENTROPY_CMD cmd, byte* out) CERT_ROOT "server-key.der"; #endif #endif - #endif /* !NO_RSA */ + #endif /* !NO_RSA && !NO_ASN */ #endif /* !USE_CERT_BUFFER_* */ #if !defined(USE_CERT_BUFFERS_1024) && !defined(USE_CERT_BUFFERS_2048) && \ !defined(NO_ASN) @@ -9964,7 +9963,7 @@ int decodedCertCache_test(void) #endif /* defined(WOLFSSL_CERT_GEN_CACHE) && defined(WOLFSSL_TEST_CERT) && defined(WOLFSSL_CERT_EXT) && defined(WOLFSSL_CERT_GEN) */ -#define RSA_TEST_BYTES 384 +#define RSA_TEST_BYTES 512 /* up to 4096-bit key */ #if !defined(NO_ASN) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) static int rsa_flatten_test(RsaKey* key) @@ -10996,7 +10995,8 @@ int rsa_no_pad_test(void) word32 outSz = RSA_TEST_BYTES; word32 plainSz = RSA_TEST_BYTES; #if !defined(USE_CERT_BUFFERS_1024) && !defined(USE_CERT_BUFFERS_2048) && \ - !defined(USE_CERT_BUFFERS_3072) && !defined(NO_FILESYSTEM) + !defined(USE_CERT_BUFFERS_3072) && !defined(USE_CERT_BUFFERS_4096) && \ + !defined(NO_FILESYSTEM) XFILE file; #endif DECLARE_VAR(out, byte, RSA_TEST_BYTES, HEAP_HINT); @@ -11032,6 +11032,8 @@ int rsa_no_pad_test(void) XMEMCPY(tmp, client_key_der_2048, (size_t)sizeof_client_key_der_2048); #elif defined(USE_CERT_BUFFERS_3072) XMEMCPY(tmp, client_key_der_3072, (size_t)sizeof_client_key_der_3072); +#elif defined(USE_CERT_BUFFERS_4096) + XMEMCPY(tmp, client_key_der_4096, (size_t)sizeof_client_key_der_4096); #elif !defined(NO_FILESYSTEM) file = XFOPEN(clientKey, "rb"); if (!file) { @@ -11819,7 +11821,8 @@ int rsa_test(void) int modLen; #endif #if !defined(USE_CERT_BUFFERS_1024) && !defined(USE_CERT_BUFFERS_2048) && \ - !defined(USE_CERT_BUFFERS_3072) && !defined(NO_FILESYSTEM) + !defined(USE_CERT_BUFFERS_3072) && !defined(USE_CERT_BUFFERS_4096) && \ + !defined(NO_FILESYSTEM) XFILE file; XFILE file2; #endif @@ -11866,6 +11869,10 @@ int rsa_test(void) bytes = (size_t)sizeof_client_key_der_3072; if (bytes < (size_t)sizeof_client_cert_der_3072) bytes = (size_t)sizeof_client_cert_der_3072; +#elif defined(USE_CERT_BUFFERS_4096) + bytes = (size_t)sizeof_client_key_der_4096; + if (bytes < (size_t)sizeof_client_cert_der_4096) + bytes = (size_t)sizeof_client_cert_der_4096; #else bytes = FOURK_BUF; #endif @@ -11885,6 +11892,8 @@ int rsa_test(void) XMEMCPY(tmp, client_key_der_2048, (size_t)sizeof_client_key_der_2048); #elif defined(USE_CERT_BUFFERS_3072) XMEMCPY(tmp, client_key_der_3072, (size_t)sizeof_client_key_der_3072); +#elif defined(USE_CERT_BUFFERS_4096) + XMEMCPY(tmp, client_key_der_4096, (size_t)sizeof_client_key_der_4096); #elif !defined(NO_FILESYSTEM) file = XFOPEN(clientKey, "rb"); if (!file) { @@ -12452,6 +12461,9 @@ int rsa_test(void) #elif defined(USE_CERT_BUFFERS_3072) XMEMCPY(tmp, client_cert_der_3072, (size_t)sizeof_client_cert_der_3072); bytes = (size_t)sizeof_client_cert_der_3072; +#elif defined(USE_CERT_BUFFERS_4096) + XMEMCPY(tmp, client_cert_der_4096, (size_t)sizeof_client_cert_der_4096); + bytes = (size_t)sizeof_client_cert_der_4096; #elif !defined(NO_FILESYSTEM) file2 = XFOPEN(clientCert, "rb"); if (!file2) { @@ -12494,6 +12506,9 @@ int rsa_test(void) #elif defined(USE_CERT_BUFFERS_3072) XMEMCPY(tmp, client_keypub_der_3072, sizeof_client_keypub_der_3072); bytes = sizeof_client_keypub_der_3072; +#elif defined(USE_CERT_BUFFERS_4096) + XMEMCPY(tmp, client_keypub_der_4096, sizeof_client_keypub_der_4096); + bytes = sizeof_client_keypub_der_4096; #else file = XFOPEN(clientKeyPub, "rb"); if (!file) { @@ -15808,6 +15823,13 @@ int openssl_pkey1_test(void) x509 = wolfSSL_X509_load_certificate_buffer(client_cert_der_3072, sizeof_client_cert_der_3072, SSL_FILETYPE_ASN1); keyLenBits = 3072; +#elif defined(USE_CERT_BUFFERS_4096) + XMEMCPY(tmp, client_key_der_4096, sizeof_client_key_der_4096); + cliKeySz = (long)sizeof_client_key_der_4096; + + x509 = wolfSSL_X509_load_certificate_buffer(client_cert_der_4096, + sizeof_client_cert_der_4096, SSL_FILETYPE_ASN1); + keyLenBits = 4096; #else XFILE f; diff --git a/wolfssl/certs_test.h b/wolfssl/certs_test.h index 18f1e6bc5..734f0a1c0 100644 --- a/wolfssl/certs_test.h +++ b/wolfssl/certs_test.h @@ -2702,6 +2702,496 @@ static const int sizeof_client_cert_der_3072 = sizeof(client_cert_der_3072); #endif /* USE_CERT_BUFFERS_3072 */ +#ifdef USE_CERT_BUFFERS_4096 + +/* ./certs/4096/client-key.der, 4096-bit */ +static const unsigned char client_key_der_4096[] = +{ + 0x30, 0x82, 0x09, 0x28, 0x02, 0x01, 0x00, 0x02, 0x82, 0x02, + 0x01, 0x00, 0xF5, 0xD0, 0x31, 0xE4, 0x71, 0x59, 0x58, 0xB3, + 0x07, 0x50, 0xDD, 0x16, 0x79, 0xFC, 0xC6, 0x95, 0x50, 0xFC, + 0x46, 0x0E, 0x57, 0x12, 0x86, 0x71, 0x8D, 0xE3, 0x9B, 0x4A, + 0x33, 0xEA, 0x4F, 0xD9, 0x17, 0x13, 0x6D, 0x48, 0x69, 0xDF, + 0x59, 0x11, 0x08, 0x02, 0x9D, 0xAF, 0x2B, 0xC7, 0x30, 0xBE, + 0x0C, 0xDC, 0x87, 0xD4, 0x5A, 0x12, 0x09, 0x23, 0x5D, 0xE1, + 0x76, 0x5A, 0x62, 0x37, 0x46, 0x74, 0xEF, 0x03, 0x05, 0xBB, + 0x1E, 0x6D, 0x29, 0x75, 0x6C, 0x2E, 0x9D, 0x87, 0x0D, 0x8F, + 0x87, 0xCB, 0x14, 0x95, 0x9B, 0xBE, 0x17, 0x6B, 0x51, 0xD1, + 0x4C, 0xDA, 0xD7, 0x91, 0x66, 0xC5, 0x36, 0xEB, 0xE0, 0x07, + 0x1A, 0x76, 0x4D, 0xB0, 0xFB, 0xC1, 0xF5, 0x5E, 0x05, 0xDB, + 0xBA, 0xCB, 0x25, 0xD9, 0x99, 0x13, 0x1C, 0xC0, 0x35, 0xDC, + 0x40, 0xE9, 0x36, 0xCD, 0xC4, 0xD5, 0x7A, 0x41, 0x70, 0x0F, + 0x36, 0xEB, 0xA5, 0x4E, 0x17, 0x05, 0xD5, 0x75, 0x1B, 0x64, + 0x62, 0x7A, 0x3F, 0x0D, 0x28, 0x48, 0x6A, 0xE3, 0xAC, 0x9C, + 0xA8, 0x8F, 0xE9, 0xED, 0xF7, 0xCD, 0x24, 0xA0, 0xB1, 0xA0, + 0x03, 0xAC, 0xE3, 0x03, 0xF5, 0x3F, 0xD1, 0x96, 0xFF, 0x2A, + 0x7E, 0x08, 0xB1, 0xD3, 0xE0, 0x18, 0x14, 0xEC, 0x65, 0x37, + 0x50, 0x43, 0xC2, 0x6A, 0x8C, 0xF4, 0x5B, 0xFE, 0xC4, 0xCB, + 0x8D, 0x3F, 0x81, 0x02, 0xF7, 0xC2, 0xDD, 0xE4, 0xC1, 0x8E, + 0x80, 0x0C, 0x04, 0x25, 0x2D, 0x80, 0x5A, 0x2E, 0x0F, 0x22, + 0x35, 0x4A, 0xF4, 0x85, 0xED, 0x51, 0xD8, 0xAB, 0x6D, 0x8F, + 0xA2, 0x3B, 0x24, 0x00, 0x6E, 0x81, 0xE2, 0x1E, 0x76, 0xD6, + 0xAC, 0x31, 0x12, 0xDB, 0xF3, 0x8E, 0x07, 0xA1, 0xDE, 0x89, + 0x4A, 0x39, 0x60, 0x77, 0xC5, 0xAA, 0xF1, 0x51, 0xE6, 0x06, + 0xF1, 0x95, 0x56, 0x2A, 0xE1, 0x8E, 0x92, 0x30, 0x9F, 0xFE, + 0x58, 0x44, 0xAC, 0x46, 0xF2, 0xFD, 0x9A, 0xFC, 0xA8, 0x1D, + 0xA1, 0xD3, 0x55, 0x37, 0x4A, 0x8B, 0xFC, 0x9C, 0x33, 0xF8, + 0xA7, 0x61, 0x48, 0x41, 0x7C, 0x9C, 0x77, 0x3F, 0xF5, 0x80, + 0x23, 0x7D, 0x43, 0xB4, 0xD5, 0x88, 0x0A, 0xC9, 0x75, 0xD7, + 0x44, 0x19, 0x4D, 0x77, 0x6C, 0x0B, 0x0A, 0x49, 0xAA, 0x1C, + 0x2F, 0xD6, 0x5A, 0x44, 0xA6, 0x47, 0x4D, 0xE5, 0x36, 0x96, + 0x40, 0x99, 0x2C, 0x56, 0x26, 0xB1, 0xF2, 0x92, 0x31, 0x59, + 0xD7, 0x2C, 0xD4, 0xB4, 0x21, 0xD6, 0x65, 0x13, 0x0B, 0x3E, + 0xFB, 0xFF, 0x04, 0xEB, 0xB9, 0x85, 0xB9, 0xD8, 0xD8, 0x28, + 0x4F, 0x5C, 0x17, 0x96, 0xA3, 0x51, 0xBE, 0xFE, 0x7D, 0x0B, + 0x1B, 0x48, 0x40, 0x25, 0x76, 0x94, 0xDC, 0x41, 0xFB, 0xBF, + 0x73, 0x76, 0xDA, 0xEB, 0xB3, 0x62, 0xE7, 0xC1, 0xC8, 0x54, + 0x6A, 0x93, 0xE1, 0x8D, 0x31, 0xE8, 0x3E, 0x3E, 0xDF, 0xBC, + 0x87, 0x02, 0x30, 0x22, 0x57, 0xC4, 0xE0, 0x18, 0x7A, 0xD3, + 0xAE, 0xE4, 0x02, 0x9B, 0xAA, 0xBD, 0x4E, 0x49, 0x47, 0x72, + 0xE9, 0x8D, 0x13, 0x2D, 0x54, 0x9B, 0x00, 0xA7, 0x91, 0x61, + 0x71, 0xC9, 0xCC, 0x48, 0x4F, 0xEE, 0xDF, 0x5E, 0x1B, 0x1A, + 0xDF, 0x67, 0xD3, 0x20, 0xE6, 0x44, 0x45, 0x98, 0x7E, 0xE7, + 0x0E, 0x63, 0x16, 0x83, 0xC9, 0x26, 0x5D, 0x90, 0xC1, 0xE5, + 0x2A, 0x5C, 0x45, 0x54, 0x13, 0xB2, 0x81, 0x18, 0x06, 0x20, + 0x2E, 0x2E, 0x66, 0x5A, 0xB5, 0x7B, 0x6E, 0xD6, 0x0C, 0x4E, + 0x89, 0x01, 0x56, 0x70, 0xBB, 0xAE, 0xDE, 0xE9, 0x99, 0x5E, + 0xD1, 0xB9, 0x3A, 0xB7, 0x6C, 0x17, 0xB6, 0x03, 0xA9, 0x08, + 0xDD, 0x9C, 0xF4, 0x14, 0xC9, 0xC9, 0x59, 0x39, 0x72, 0xD4, + 0x7E, 0x02, 0x37, 0x31, 0xCD, 0x0E, 0xA7, 0x3D, 0xF8, 0xF2, + 0xCF, 0x6B, 0x15, 0xAB, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, + 0x82, 0x02, 0x01, 0x00, 0xC5, 0x76, 0x57, 0x7D, 0xF1, 0x68, + 0x1A, 0x8E, 0xC6, 0x63, 0xB9, 0x16, 0xA3, 0x2B, 0xE1, 0xC2, + 0x74, 0xEA, 0x12, 0xC4, 0xD6, 0x41, 0x75, 0x6A, 0xA6, 0xD6, + 0x9E, 0x1A, 0x7F, 0x95, 0xCC, 0x4A, 0xD1, 0xF4, 0xB3, 0x27, + 0x26, 0x95, 0x5A, 0x91, 0x09, 0xE4, 0x40, 0x13, 0x45, 0x91, + 0x9F, 0xA0, 0x2B, 0xE8, 0xC3, 0xDC, 0x5B, 0xF6, 0x7D, 0x0C, + 0xC2, 0x0F, 0xA9, 0xE9, 0x75, 0x58, 0x7D, 0xEA, 0xD5, 0x4D, + 0x92, 0x3E, 0xFC, 0x74, 0x28, 0x87, 0xC1, 0x3D, 0xB9, 0x21, + 0x92, 0x4D, 0x28, 0x82, 0x84, 0xA8, 0xA2, 0x11, 0x93, 0xF2, + 0x8C, 0x29, 0x1C, 0x19, 0xF8, 0x6D, 0x3F, 0x27, 0x51, 0xB5, + 0x2D, 0xA3, 0xC7, 0x28, 0x1D, 0xC4, 0xFC, 0x98, 0x94, 0xA8, + 0xD0, 0xFF, 0xF0, 0x0F, 0xDC, 0xF9, 0xED, 0xB3, 0xA2, 0xB6, + 0xED, 0x0D, 0x5F, 0xBF, 0x78, 0x5C, 0xD7, 0xAF, 0xBD, 0xA3, + 0xEF, 0x86, 0xE9, 0x51, 0x66, 0xDB, 0x52, 0x37, 0x47, 0x7F, + 0xE9, 0x5F, 0x3C, 0x94, 0x83, 0x2D, 0xE8, 0x9C, 0x33, 0xF1, + 0x6C, 0xE9, 0xF3, 0xA6, 0x97, 0xFE, 0xA7, 0xBF, 0x4D, 0x9B, + 0x20, 0xD5, 0x2F, 0xDE, 0xA4, 0x06, 0xBB, 0xEE, 0x66, 0x49, + 0x6B, 0xF5, 0x10, 0x85, 0x9F, 0x84, 0x5A, 0x52, 0x3E, 0x0C, + 0xA0, 0x4A, 0x4C, 0xDA, 0x01, 0xC5, 0x62, 0x31, 0xB1, 0xEC, + 0xF8, 0xDD, 0xA3, 0x3B, 0xCE, 0x41, 0x3A, 0x12, 0x79, 0xF9, + 0x97, 0x5B, 0x07, 0x95, 0x9F, 0x86, 0xD6, 0x04, 0x73, 0x6C, + 0xE8, 0x8F, 0x4C, 0x4C, 0x48, 0x1D, 0x85, 0xC4, 0xE7, 0xCE, + 0xDE, 0x16, 0x31, 0xF6, 0x5C, 0x37, 0x54, 0x8E, 0x55, 0xBC, + 0xAF, 0x2E, 0x47, 0xE8, 0xAC, 0x03, 0xB0, 0xA4, 0xF9, 0x90, + 0x98, 0x99, 0xA4, 0xDC, 0x6E, 0x98, 0x08, 0x5C, 0x07, 0xBB, + 0x08, 0x93, 0xAF, 0x61, 0x8D, 0x74, 0xA8, 0xF8, 0xC4, 0x89, + 0x64, 0x10, 0xE1, 0xE6, 0xC0, 0xCD, 0x1D, 0x39, 0x20, 0xD6, + 0x5A, 0x89, 0x83, 0xFC, 0x37, 0xE2, 0x12, 0x66, 0xA8, 0x12, + 0xCC, 0x72, 0xBB, 0x1E, 0xFB, 0x6A, 0xE3, 0x7C, 0x71, 0x7E, + 0xB9, 0x2E, 0x8E, 0x84, 0x66, 0xE1, 0xB9, 0xD0, 0x25, 0x9A, + 0x6F, 0x9D, 0x19, 0xE6, 0x7E, 0xE8, 0xD8, 0xF0, 0xC5, 0x23, + 0x16, 0x9A, 0x68, 0x2C, 0x1D, 0x55, 0xAE, 0x8E, 0x90, 0xEE, + 0x8E, 0xEC, 0x5E, 0x46, 0x9D, 0x60, 0x52, 0x32, 0x17, 0x28, + 0x59, 0xC4, 0x49, 0x2A, 0x20, 0x3E, 0x95, 0xC5, 0xDF, 0xF6, + 0x3D, 0xF7, 0xC5, 0xCF, 0xB1, 0xC2, 0xC9, 0x76, 0xF8, 0x3D, + 0xBE, 0xF4, 0x63, 0xFC, 0x2A, 0x00, 0x6F, 0x99, 0xA6, 0xB6, + 0xAD, 0x35, 0xEE, 0xDE, 0xC5, 0xE0, 0x97, 0xC6, 0x73, 0xEE, + 0x33, 0xA0, 0xA8, 0xFC, 0x4C, 0x8F, 0xF2, 0x8C, 0x61, 0xFB, + 0x03, 0x19, 0xA1, 0xE8, 0x17, 0x4E, 0xE3, 0x21, 0x58, 0xCE, + 0xFE, 0xF2, 0x5F, 0xBB, 0xDD, 0x4F, 0xF7, 0x18, 0xCB, 0x35, + 0x57, 0xDD, 0xE5, 0x50, 0x2A, 0x7B, 0x1A, 0xE9, 0x12, 0xF2, + 0x7A, 0x11, 0xB1, 0x43, 0xB9, 0x70, 0x07, 0x0C, 0x8F, 0x69, + 0xB9, 0xE5, 0xA5, 0xC9, 0xE2, 0x1B, 0x96, 0x74, 0x11, 0xF5, + 0x95, 0xB9, 0x58, 0xC0, 0xBD, 0x37, 0xFB, 0x28, 0x2A, 0xBD, + 0x84, 0xB1, 0x2B, 0x67, 0x42, 0x82, 0xC3, 0x95, 0x55, 0x45, + 0xD5, 0xEA, 0xC3, 0x8A, 0x42, 0x3A, 0x43, 0x17, 0x5E, 0xCD, + 0xD2, 0xEA, 0xFC, 0xDF, 0x67, 0xEC, 0xE1, 0x6C, 0xA8, 0x03, + 0x19, 0xB2, 0x1D, 0x4A, 0x5F, 0x4F, 0xE7, 0xD3, 0xE0, 0x86, + 0xC5, 0x1A, 0x10, 0xC3, 0x08, 0xD2, 0xED, 0x85, 0x93, 0x08, + 0x51, 0x05, 0xA6, 0x37, 0x15, 0x32, 0xBD, 0x6C, 0x73, 0x63, + 0x01, 0x5D, 0x5B, 0x4F, 0x6A, 0xDC, 0x6D, 0x1D, 0x55, 0x91, + 0x21, 0xE4, 0x8E, 0xB7, 0xF0, 0x81, 0x02, 0x82, 0x01, 0x01, + 0x00, 0xFD, 0x27, 0xC8, 0xFE, 0x76, 0x5C, 0x89, 0x32, 0xCB, + 0x8A, 0x22, 0x87, 0x61, 0x48, 0x91, 0x4A, 0x05, 0xAD, 0xA4, + 0x5C, 0x8A, 0xCA, 0x5C, 0x02, 0x88, 0x7E, 0x51, 0xC5, 0x66, + 0x90, 0x2C, 0xA3, 0xED, 0xA7, 0x43, 0x19, 0x0B, 0xA2, 0x42, + 0xB4, 0xE0, 0xE0, 0x45, 0xBF, 0xFE, 0xA0, 0xF2, 0x75, 0x0B, + 0x8E, 0x7D, 0x9D, 0x73, 0x67, 0xD3, 0x10, 0x09, 0xC5, 0xD9, + 0x8C, 0xAD, 0x3A, 0x64, 0x72, 0xAD, 0x96, 0x35, 0x91, 0x0F, + 0x4B, 0xC9, 0xBD, 0x4F, 0x65, 0x47, 0xA6, 0x2D, 0xEB, 0x3F, + 0xE2, 0x99, 0x72, 0x66, 0x12, 0xED, 0xEB, 0xD2, 0x7C, 0xFF, + 0x3A, 0x20, 0x37, 0x2A, 0xD3, 0x65, 0x51, 0x9B, 0xC3, 0xAA, + 0x18, 0xB1, 0x1F, 0x6E, 0x9D, 0x40, 0x47, 0xA4, 0x1F, 0x82, + 0x9B, 0xDB, 0x50, 0x6B, 0x86, 0x2F, 0xFB, 0x3F, 0x31, 0xB9, + 0x81, 0x11, 0x04, 0x14, 0x63, 0x86, 0x4F, 0x40, 0x2A, 0xF5, + 0xF9, 0x7C, 0xA1, 0x78, 0x19, 0x13, 0xD0, 0x51, 0x51, 0x0F, + 0x79, 0x88, 0x8D, 0x14, 0xA3, 0xDE, 0xB6, 0x33, 0x29, 0x42, + 0xB9, 0xE8, 0x59, 0x76, 0xF7, 0x43, 0x1A, 0xB6, 0xA6, 0xDF, + 0x0A, 0xC1, 0x42, 0xC7, 0x3F, 0x1C, 0x7E, 0x5C, 0x2C, 0x91, + 0x4B, 0x1E, 0xF8, 0x46, 0x91, 0x1F, 0xEE, 0x56, 0xB3, 0x0E, + 0xC8, 0xD0, 0x31, 0xD3, 0x3D, 0xED, 0x3D, 0xD9, 0xC5, 0x30, + 0x0C, 0x58, 0xD8, 0xB7, 0xB5, 0xEC, 0x14, 0xAC, 0x41, 0x64, + 0x6D, 0xE4, 0xC6, 0x59, 0xFD, 0x14, 0x05, 0x60, 0x65, 0xD8, + 0xC4, 0x84, 0x44, 0x7E, 0x1B, 0xB4, 0xA4, 0x16, 0x75, 0xC1, + 0x27, 0x96, 0xB2, 0x19, 0xD6, 0x39, 0x54, 0xC0, 0x93, 0xF3, + 0xD7, 0x1F, 0xCD, 0x1B, 0xDF, 0xF8, 0x12, 0x88, 0x14, 0x9F, + 0x98, 0x05, 0x47, 0x46, 0x71, 0x81, 0x6C, 0xDF, 0x91, 0xEF, + 0x53, 0xE3, 0xC5, 0xB1, 0x89, 0x2F, 0xE1, 0x02, 0x82, 0x01, + 0x01, 0x00, 0xF8, 0x93, 0x4A, 0x28, 0x77, 0x94, 0xEF, 0xE9, + 0xC4, 0x0A, 0xC3, 0xE8, 0x52, 0x59, 0xB6, 0x1D, 0x8D, 0xCE, + 0x14, 0xE7, 0x43, 0xC6, 0xED, 0x09, 0x27, 0x5D, 0xF3, 0x8E, + 0x08, 0x6A, 0x19, 0x6B, 0x2C, 0x97, 0x9B, 0x88, 0x53, 0x2B, + 0xDA, 0xFE, 0x4B, 0x94, 0x66, 0x84, 0xD5, 0xA9, 0xCE, 0xA5, + 0x43, 0x70, 0xFB, 0x01, 0x5A, 0x6F, 0xCD, 0xF7, 0xD1, 0x9D, + 0x51, 0xEE, 0xA0, 0xDC, 0x46, 0xF5, 0x7D, 0xA7, 0xEE, 0xA0, + 0x86, 0xB7, 0x83, 0xFF, 0x21, 0x8B, 0x76, 0x05, 0x7D, 0xDE, + 0xC4, 0x26, 0x36, 0xBC, 0xB4, 0x8A, 0x48, 0xC3, 0x06, 0x90, + 0x97, 0xE5, 0xA6, 0x38, 0xC3, 0xE6, 0x7C, 0xD0, 0xF8, 0x23, + 0xD2, 0x33, 0x1F, 0x81, 0xC3, 0xE3, 0x7D, 0x85, 0x5A, 0x38, + 0x10, 0x03, 0xE6, 0x88, 0xDB, 0xC8, 0x4C, 0xD0, 0xF7, 0xB2, + 0x4D, 0x27, 0x33, 0x85, 0xCD, 0x3A, 0x74, 0x83, 0x6B, 0x82, + 0x58, 0xD9, 0xDF, 0xEE, 0xF5, 0xD3, 0xE9, 0xFE, 0x1C, 0xEF, + 0x06, 0x12, 0x16, 0xD1, 0x4C, 0xAE, 0x54, 0x4B, 0x0D, 0x1A, + 0xBD, 0xE2, 0xCF, 0x56, 0xB3, 0x74, 0xBE, 0x44, 0x4F, 0xA4, + 0x73, 0x0A, 0x98, 0x8D, 0x61, 0x84, 0x38, 0x46, 0xDC, 0x95, + 0xCF, 0x3F, 0x6B, 0xE7, 0x65, 0x87, 0x02, 0xBF, 0x4B, 0x57, + 0xE2, 0x3D, 0xC4, 0x2B, 0x1C, 0x82, 0x1D, 0xCC, 0x13, 0x7F, + 0xC0, 0x06, 0x12, 0x8C, 0x6F, 0x97, 0x50, 0x7B, 0x8C, 0x81, + 0xC3, 0x23, 0x15, 0xEB, 0x70, 0x07, 0x8E, 0xA1, 0x07, 0x1E, + 0x59, 0xFA, 0x10, 0xCA, 0x7E, 0x0F, 0xE2, 0xBB, 0xEE, 0x86, + 0x26, 0x1E, 0x55, 0xB9, 0x98, 0x66, 0x85, 0xEC, 0x27, 0xC5, + 0xD9, 0x63, 0x8D, 0x51, 0x77, 0xAA, 0xA0, 0x36, 0x55, 0x33, + 0x10, 0x21, 0x5E, 0xEC, 0x47, 0x67, 0x71, 0xD1, 0xAF, 0xFC, + 0x3E, 0x50, 0xF5, 0xBE, 0xD6, 0x92, 0xE7, 0x0B, 0x02, 0x82, + 0x01, 0x00, 0x21, 0x7C, 0x8A, 0xC4, 0xC6, 0x29, 0x55, 0x68, + 0xA7, 0xAD, 0xDD, 0x05, 0x65, 0x63, 0xF0, 0xFC, 0x06, 0xA6, + 0x42, 0x70, 0x8F, 0x57, 0x57, 0x36, 0x6A, 0x91, 0xB3, 0x05, + 0x56, 0x9C, 0xC9, 0x9A, 0xE1, 0x8B, 0xD7, 0x7F, 0x4F, 0x9F, + 0xA6, 0x0D, 0x41, 0x15, 0xC9, 0x84, 0x2D, 0x0D, 0x63, 0x25, + 0x02, 0x63, 0x55, 0xD0, 0x66, 0xFC, 0x9B, 0xD9, 0xAA, 0x41, + 0x46, 0x96, 0xAA, 0x2F, 0x68, 0x2C, 0x17, 0x34, 0x20, 0x5F, + 0xD0, 0xD3, 0x28, 0x9B, 0x67, 0x0E, 0x31, 0x9D, 0x14, 0xC3, + 0xE2, 0x8E, 0x79, 0xD7, 0xBD, 0x12, 0xD1, 0xEF, 0xF8, 0xC6, + 0xDA, 0x07, 0xF9, 0x4C, 0xF2, 0xD8, 0x45, 0xB5, 0xB6, 0xD1, + 0xFA, 0x05, 0x0C, 0x20, 0xE9, 0x43, 0xD9, 0xC5, 0xE0, 0x3A, + 0xDE, 0xCE, 0xF9, 0x02, 0xB9, 0x46, 0x65, 0xC0, 0x69, 0x4A, + 0x8D, 0x8C, 0x3A, 0x10, 0xFD, 0x15, 0x71, 0x25, 0xB8, 0x8A, + 0x36, 0x41, 0x4B, 0x30, 0x1C, 0xAF, 0xCC, 0x84, 0x28, 0xCD, + 0x7D, 0x2B, 0x89, 0x59, 0x88, 0x1A, 0x69, 0x12, 0x56, 0xD0, + 0x25, 0x68, 0x6C, 0x08, 0xB1, 0x88, 0xE1, 0x92, 0x7E, 0x08, + 0xB2, 0xC6, 0x3C, 0x6C, 0x35, 0xE8, 0xEE, 0x3E, 0xF4, 0xB8, + 0x5C, 0x7B, 0xC0, 0x5B, 0xFD, 0x11, 0xA3, 0x54, 0xA6, 0x99, + 0x46, 0xE2, 0x5F, 0x4F, 0xC7, 0xEE, 0x90, 0x1C, 0x37, 0x5B, + 0x33, 0x10, 0xDF, 0x0B, 0xC3, 0xB9, 0x47, 0xC2, 0x30, 0x4A, + 0xF2, 0x1A, 0xEB, 0x41, 0x25, 0x94, 0x29, 0x7A, 0xD0, 0x96, + 0x88, 0x46, 0xEE, 0x6C, 0x14, 0xF6, 0x5B, 0x3D, 0xBD, 0x4E, + 0xD4, 0x3F, 0x05, 0x5B, 0x07, 0xB9, 0xE3, 0x99, 0x87, 0x63, + 0xCA, 0xC4, 0x71, 0x0B, 0x73, 0x9D, 0x7B, 0xB6, 0x0F, 0xD4, + 0x12, 0x8C, 0x4C, 0x5E, 0x72, 0x3D, 0xFF, 0x6D, 0xC4, 0x61, + 0x0C, 0x74, 0x5F, 0x53, 0xBE, 0x39, 0x34, 0x61, 0x02, 0x82, + 0x01, 0x00, 0x5F, 0xF2, 0xF2, 0xB0, 0x16, 0x20, 0x8E, 0x4E, + 0xCC, 0x96, 0x5F, 0x32, 0x80, 0xFF, 0x11, 0xF5, 0xEC, 0x73, + 0xBC, 0xCB, 0xDB, 0xF4, 0xA0, 0x30, 0x65, 0x5A, 0xB5, 0x95, + 0x80, 0x97, 0xFB, 0xC1, 0xCB, 0xCF, 0xA5, 0x80, 0x84, 0xA2, + 0x2C, 0x00, 0xF6, 0x89, 0x8C, 0xDC, 0xFF, 0x60, 0x71, 0x5C, + 0x87, 0x60, 0xC7, 0xF2, 0xA8, 0xC6, 0xF9, 0x59, 0x0C, 0x37, + 0x4E, 0x95, 0xEE, 0xCF, 0xB8, 0x30, 0x30, 0x55, 0xAF, 0x1D, + 0x95, 0x82, 0xA6, 0xD7, 0xC7, 0x49, 0xFE, 0xBF, 0x75, 0xEB, + 0x94, 0x09, 0x30, 0x1D, 0xBD, 0x0E, 0x97, 0xB1, 0x78, 0x0A, + 0x3E, 0x27, 0xAD, 0xF6, 0xC1, 0x5F, 0x69, 0x94, 0x7C, 0x03, + 0xCF, 0xB2, 0x5E, 0x1A, 0x07, 0xD3, 0xFA, 0xF2, 0x8B, 0x75, + 0x92, 0x70, 0xFE, 0xFE, 0x9A, 0xDF, 0x81, 0x0F, 0x34, 0x5D, + 0x45, 0xBC, 0xB8, 0xFD, 0x8F, 0xCF, 0x5D, 0x84, 0x10, 0xEE, + 0x9A, 0x7F, 0x57, 0x19, 0xF5, 0x17, 0xDC, 0x7D, 0x73, 0x0B, + 0xAC, 0x6B, 0x35, 0x15, 0x8B, 0x24, 0xCB, 0x72, 0xC0, 0xD7, + 0x2E, 0xAE, 0xAA, 0xDB, 0xCB, 0x9F, 0x67, 0x86, 0x14, 0xBB, + 0xE4, 0x90, 0x15, 0x7C, 0x95, 0x44, 0xA5, 0x38, 0x6D, 0x13, + 0x02, 0x91, 0x77, 0x84, 0x35, 0x43, 0x5D, 0x03, 0x1C, 0x01, + 0x0B, 0x5A, 0x4E, 0x2B, 0x59, 0xF0, 0xBB, 0xB1, 0xB7, 0x61, + 0x1B, 0x6C, 0xFC, 0xA1, 0xEA, 0xBD, 0x1C, 0x9A, 0xE4, 0x0C, + 0x7E, 0x97, 0x3F, 0x71, 0xC6, 0xA7, 0x94, 0x1D, 0x82, 0x12, + 0xEC, 0x26, 0x43, 0x6E, 0xF6, 0x24, 0x09, 0xA0, 0x03, 0x1D, + 0x12, 0xFF, 0xA8, 0x95, 0x60, 0x47, 0x4A, 0xB0, 0x72, 0x55, + 0xC3, 0x68, 0xD2, 0xF6, 0xBC, 0x5B, 0x47, 0x46, 0x51, 0xB2, + 0xC9, 0x2A, 0x28, 0x6A, 0xC9, 0xD1, 0x1B, 0x35, 0x16, 0x5A, + 0x26, 0x6F, 0xB7, 0xBB, 0xF7, 0x35, 0x73, 0x2B, 0x02, 0x82, + 0x01, 0x00, 0x56, 0xBA, 0xD8, 0x02, 0xD7, 0x4B, 0x30, 0x5E, + 0x1B, 0x1E, 0x2F, 0xF3, 0x0D, 0xBC, 0xF1, 0x05, 0x6A, 0x68, + 0x4A, 0xE1, 0xEA, 0xB3, 0xDE, 0x61, 0x8C, 0x89, 0x44, 0xBA, + 0x63, 0x5E, 0xDF, 0x05, 0x24, 0x32, 0x71, 0x65, 0x1A, 0x36, + 0x2F, 0xBC, 0x07, 0x75, 0xA3, 0xCE, 0x9E, 0x52, 0x92, 0x95, + 0x4D, 0x3F, 0xC9, 0x06, 0xBC, 0xA1, 0x14, 0x33, 0x37, 0x95, + 0xAB, 0x9A, 0xEB, 0x04, 0xF6, 0x15, 0xC3, 0x9B, 0x10, 0x56, + 0x53, 0xA2, 0x28, 0xF2, 0x68, 0xDA, 0x7D, 0x97, 0x52, 0x63, + 0xAC, 0x9B, 0x56, 0xA9, 0xAB, 0x2E, 0x1E, 0x9E, 0x01, 0x70, + 0xFF, 0x2B, 0x6D, 0x0C, 0x4B, 0xA6, 0xC3, 0x3A, 0xB3, 0xD1, + 0xA7, 0x4B, 0x5E, 0x49, 0x2E, 0x95, 0xD6, 0x6A, 0xAE, 0x58, + 0x13, 0x66, 0x8F, 0x2F, 0x93, 0xE4, 0x6E, 0x8B, 0xFA, 0x94, + 0x30, 0x3E, 0xEC, 0x96, 0xAB, 0x46, 0x20, 0x3E, 0xC5, 0x30, + 0xB4, 0xEB, 0x41, 0x00, 0x39, 0x60, 0x1D, 0xE1, 0x20, 0xCE, + 0x31, 0x70, 0x17, 0x39, 0xCB, 0x76, 0x56, 0x6C, 0x55, 0x7B, + 0x90, 0x20, 0xBC, 0x39, 0xB2, 0x5B, 0xD1, 0x28, 0x6F, 0x0C, + 0x4F, 0x45, 0x6B, 0x82, 0xC4, 0x57, 0x23, 0x0C, 0x3F, 0x3F, + 0x2D, 0x83, 0xB3, 0x3D, 0x8E, 0xF9, 0x1A, 0xDA, 0x77, 0x54, + 0x2E, 0xFE, 0x16, 0x2E, 0xBA, 0x99, 0xDD, 0xCA, 0xB3, 0xD1, + 0xD8, 0xBB, 0x87, 0xE1, 0xD0, 0xA9, 0xD4, 0xE6, 0x8F, 0xE8, + 0x00, 0x3E, 0x49, 0x8A, 0xDD, 0xA6, 0x32, 0x91, 0x00, 0x31, + 0x31, 0x21, 0x98, 0x18, 0x94, 0xC9, 0x2D, 0x27, 0x05, 0xB7, + 0x9B, 0x09, 0x2E, 0xBB, 0x5D, 0xBF, 0x67, 0xE8, 0x0E, 0xD1, + 0x44, 0x75, 0x80, 0x1D, 0x0A, 0x21, 0x8F, 0x95, 0x76, 0xB0, + 0xFC, 0x19, 0x3C, 0xFF, 0x92, 0xEA, 0x01, 0x45, 0x89, 0xD1, + 0x4E, 0xFE, 0x4D, 0x2B, 0x4B, 0x18, 0xE6, 0xCE +}; +static const int sizeof_client_key_der_4096 = sizeof(client_key_der_4096); + +/* ./certs/4096/client-keyPub.der, 4096-bit */ +static const unsigned char client_keypub_der_4096[] = +{ + 0x30, 0x82, 0x02, 0x22, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, + 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, + 0x82, 0x02, 0x0F, 0x00, 0x30, 0x82, 0x02, 0x0A, 0x02, 0x82, + 0x02, 0x01, 0x00, 0xF5, 0xD0, 0x31, 0xE4, 0x71, 0x59, 0x58, + 0xB3, 0x07, 0x50, 0xDD, 0x16, 0x79, 0xFC, 0xC6, 0x95, 0x50, + 0xFC, 0x46, 0x0E, 0x57, 0x12, 0x86, 0x71, 0x8D, 0xE3, 0x9B, + 0x4A, 0x33, 0xEA, 0x4F, 0xD9, 0x17, 0x13, 0x6D, 0x48, 0x69, + 0xDF, 0x59, 0x11, 0x08, 0x02, 0x9D, 0xAF, 0x2B, 0xC7, 0x30, + 0xBE, 0x0C, 0xDC, 0x87, 0xD4, 0x5A, 0x12, 0x09, 0x23, 0x5D, + 0xE1, 0x76, 0x5A, 0x62, 0x37, 0x46, 0x74, 0xEF, 0x03, 0x05, + 0xBB, 0x1E, 0x6D, 0x29, 0x75, 0x6C, 0x2E, 0x9D, 0x87, 0x0D, + 0x8F, 0x87, 0xCB, 0x14, 0x95, 0x9B, 0xBE, 0x17, 0x6B, 0x51, + 0xD1, 0x4C, 0xDA, 0xD7, 0x91, 0x66, 0xC5, 0x36, 0xEB, 0xE0, + 0x07, 0x1A, 0x76, 0x4D, 0xB0, 0xFB, 0xC1, 0xF5, 0x5E, 0x05, + 0xDB, 0xBA, 0xCB, 0x25, 0xD9, 0x99, 0x13, 0x1C, 0xC0, 0x35, + 0xDC, 0x40, 0xE9, 0x36, 0xCD, 0xC4, 0xD5, 0x7A, 0x41, 0x70, + 0x0F, 0x36, 0xEB, 0xA5, 0x4E, 0x17, 0x05, 0xD5, 0x75, 0x1B, + 0x64, 0x62, 0x7A, 0x3F, 0x0D, 0x28, 0x48, 0x6A, 0xE3, 0xAC, + 0x9C, 0xA8, 0x8F, 0xE9, 0xED, 0xF7, 0xCD, 0x24, 0xA0, 0xB1, + 0xA0, 0x03, 0xAC, 0xE3, 0x03, 0xF5, 0x3F, 0xD1, 0x96, 0xFF, + 0x2A, 0x7E, 0x08, 0xB1, 0xD3, 0xE0, 0x18, 0x14, 0xEC, 0x65, + 0x37, 0x50, 0x43, 0xC2, 0x6A, 0x8C, 0xF4, 0x5B, 0xFE, 0xC4, + 0xCB, 0x8D, 0x3F, 0x81, 0x02, 0xF7, 0xC2, 0xDD, 0xE4, 0xC1, + 0x8E, 0x80, 0x0C, 0x04, 0x25, 0x2D, 0x80, 0x5A, 0x2E, 0x0F, + 0x22, 0x35, 0x4A, 0xF4, 0x85, 0xED, 0x51, 0xD8, 0xAB, 0x6D, + 0x8F, 0xA2, 0x3B, 0x24, 0x00, 0x6E, 0x81, 0xE2, 0x1E, 0x76, + 0xD6, 0xAC, 0x31, 0x12, 0xDB, 0xF3, 0x8E, 0x07, 0xA1, 0xDE, + 0x89, 0x4A, 0x39, 0x60, 0x77, 0xC5, 0xAA, 0xF1, 0x51, 0xE6, + 0x06, 0xF1, 0x95, 0x56, 0x2A, 0xE1, 0x8E, 0x92, 0x30, 0x9F, + 0xFE, 0x58, 0x44, 0xAC, 0x46, 0xF2, 0xFD, 0x9A, 0xFC, 0xA8, + 0x1D, 0xA1, 0xD3, 0x55, 0x37, 0x4A, 0x8B, 0xFC, 0x9C, 0x33, + 0xF8, 0xA7, 0x61, 0x48, 0x41, 0x7C, 0x9C, 0x77, 0x3F, 0xF5, + 0x80, 0x23, 0x7D, 0x43, 0xB4, 0xD5, 0x88, 0x0A, 0xC9, 0x75, + 0xD7, 0x44, 0x19, 0x4D, 0x77, 0x6C, 0x0B, 0x0A, 0x49, 0xAA, + 0x1C, 0x2F, 0xD6, 0x5A, 0x44, 0xA6, 0x47, 0x4D, 0xE5, 0x36, + 0x96, 0x40, 0x99, 0x2C, 0x56, 0x26, 0xB1, 0xF2, 0x92, 0x31, + 0x59, 0xD7, 0x2C, 0xD4, 0xB4, 0x21, 0xD6, 0x65, 0x13, 0x0B, + 0x3E, 0xFB, 0xFF, 0x04, 0xEB, 0xB9, 0x85, 0xB9, 0xD8, 0xD8, + 0x28, 0x4F, 0x5C, 0x17, 0x96, 0xA3, 0x51, 0xBE, 0xFE, 0x7D, + 0x0B, 0x1B, 0x48, 0x40, 0x25, 0x76, 0x94, 0xDC, 0x41, 0xFB, + 0xBF, 0x73, 0x76, 0xDA, 0xEB, 0xB3, 0x62, 0xE7, 0xC1, 0xC8, + 0x54, 0x6A, 0x93, 0xE1, 0x8D, 0x31, 0xE8, 0x3E, 0x3E, 0xDF, + 0xBC, 0x87, 0x02, 0x30, 0x22, 0x57, 0xC4, 0xE0, 0x18, 0x7A, + 0xD3, 0xAE, 0xE4, 0x02, 0x9B, 0xAA, 0xBD, 0x4E, 0x49, 0x47, + 0x72, 0xE9, 0x8D, 0x13, 0x2D, 0x54, 0x9B, 0x00, 0xA7, 0x91, + 0x61, 0x71, 0xC9, 0xCC, 0x48, 0x4F, 0xEE, 0xDF, 0x5E, 0x1B, + 0x1A, 0xDF, 0x67, 0xD3, 0x20, 0xE6, 0x44, 0x45, 0x98, 0x7E, + 0xE7, 0x0E, 0x63, 0x16, 0x83, 0xC9, 0x26, 0x5D, 0x90, 0xC1, + 0xE5, 0x2A, 0x5C, 0x45, 0x54, 0x13, 0xB2, 0x81, 0x18, 0x06, + 0x20, 0x2E, 0x2E, 0x66, 0x5A, 0xB5, 0x7B, 0x6E, 0xD6, 0x0C, + 0x4E, 0x89, 0x01, 0x56, 0x70, 0xBB, 0xAE, 0xDE, 0xE9, 0x99, + 0x5E, 0xD1, 0xB9, 0x3A, 0xB7, 0x6C, 0x17, 0xB6, 0x03, 0xA9, + 0x08, 0xDD, 0x9C, 0xF4, 0x14, 0xC9, 0xC9, 0x59, 0x39, 0x72, + 0xD4, 0x7E, 0x02, 0x37, 0x31, 0xCD, 0x0E, 0xA7, 0x3D, 0xF8, + 0xF2, 0xCF, 0x6B, 0x15, 0xAB, 0x02, 0x03, 0x01, 0x00, 0x01 + +}; +static const int sizeof_client_keypub_der_4096 = sizeof(client_keypub_der_4096); + +/* ./certs/4096/client-cert.der, 4096-bit */ +static const unsigned char client_cert_der_4096[] = +{ + 0x30, 0x82, 0x06, 0xE0, 0x30, 0x82, 0x04, 0xC8, 0xA0, 0x03, + 0x02, 0x01, 0x02, 0x02, 0x14, 0x2F, 0x0F, 0xAB, 0x23, 0xBC, + 0xA3, 0x14, 0x07, 0x91, 0x06, 0x55, 0x35, 0x01, 0x63, 0x7F, + 0x42, 0xBD, 0xFB, 0xF2, 0x43, 0x30, 0x0D, 0x06, 0x09, 0x2A, + 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, + 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, 0x34, 0x30, 0x39, 0x36, 0x31, 0x19, 0x30, 0x17, 0x06, + 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x10, 0x50, 0x72, 0x6F, 0x67, + 0x72, 0x61, 0x6D, 0x6D, 0x69, 0x6E, 0x67, 0x2D, 0x34, 0x30, + 0x39, 0x36, 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, 0x31, 0x39, 0x30, 0x37, 0x30, + 0x39, 0x30, 0x33, 0x30, 0x36, 0x30, 0x32, 0x5A, 0x17, 0x0D, + 0x32, 0x32, 0x30, 0x34, 0x30, 0x34, 0x30, 0x33, 0x30, 0x36, + 0x30, 0x32, 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, 0x34, 0x30, 0x39, 0x36, 0x31, 0x19, + 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, 0x10, 0x50, + 0x72, 0x6F, 0x67, 0x72, 0x61, 0x6D, 0x6D, 0x69, 0x6E, 0x67, + 0x2D, 0x34, 0x30, 0x39, 0x36, 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, 0x02, 0x22, 0x30, 0x0D, + 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, + 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0F, 0x00, 0x30, 0x82, + 0x02, 0x0A, 0x02, 0x82, 0x02, 0x01, 0x00, 0xF5, 0xD0, 0x31, + 0xE4, 0x71, 0x59, 0x58, 0xB3, 0x07, 0x50, 0xDD, 0x16, 0x79, + 0xFC, 0xC6, 0x95, 0x50, 0xFC, 0x46, 0x0E, 0x57, 0x12, 0x86, + 0x71, 0x8D, 0xE3, 0x9B, 0x4A, 0x33, 0xEA, 0x4F, 0xD9, 0x17, + 0x13, 0x6D, 0x48, 0x69, 0xDF, 0x59, 0x11, 0x08, 0x02, 0x9D, + 0xAF, 0x2B, 0xC7, 0x30, 0xBE, 0x0C, 0xDC, 0x87, 0xD4, 0x5A, + 0x12, 0x09, 0x23, 0x5D, 0xE1, 0x76, 0x5A, 0x62, 0x37, 0x46, + 0x74, 0xEF, 0x03, 0x05, 0xBB, 0x1E, 0x6D, 0x29, 0x75, 0x6C, + 0x2E, 0x9D, 0x87, 0x0D, 0x8F, 0x87, 0xCB, 0x14, 0x95, 0x9B, + 0xBE, 0x17, 0x6B, 0x51, 0xD1, 0x4C, 0xDA, 0xD7, 0x91, 0x66, + 0xC5, 0x36, 0xEB, 0xE0, 0x07, 0x1A, 0x76, 0x4D, 0xB0, 0xFB, + 0xC1, 0xF5, 0x5E, 0x05, 0xDB, 0xBA, 0xCB, 0x25, 0xD9, 0x99, + 0x13, 0x1C, 0xC0, 0x35, 0xDC, 0x40, 0xE9, 0x36, 0xCD, 0xC4, + 0xD5, 0x7A, 0x41, 0x70, 0x0F, 0x36, 0xEB, 0xA5, 0x4E, 0x17, + 0x05, 0xD5, 0x75, 0x1B, 0x64, 0x62, 0x7A, 0x3F, 0x0D, 0x28, + 0x48, 0x6A, 0xE3, 0xAC, 0x9C, 0xA8, 0x8F, 0xE9, 0xED, 0xF7, + 0xCD, 0x24, 0xA0, 0xB1, 0xA0, 0x03, 0xAC, 0xE3, 0x03, 0xF5, + 0x3F, 0xD1, 0x96, 0xFF, 0x2A, 0x7E, 0x08, 0xB1, 0xD3, 0xE0, + 0x18, 0x14, 0xEC, 0x65, 0x37, 0x50, 0x43, 0xC2, 0x6A, 0x8C, + 0xF4, 0x5B, 0xFE, 0xC4, 0xCB, 0x8D, 0x3F, 0x81, 0x02, 0xF7, + 0xC2, 0xDD, 0xE4, 0xC1, 0x8E, 0x80, 0x0C, 0x04, 0x25, 0x2D, + 0x80, 0x5A, 0x2E, 0x0F, 0x22, 0x35, 0x4A, 0xF4, 0x85, 0xED, + 0x51, 0xD8, 0xAB, 0x6D, 0x8F, 0xA2, 0x3B, 0x24, 0x00, 0x6E, + 0x81, 0xE2, 0x1E, 0x76, 0xD6, 0xAC, 0x31, 0x12, 0xDB, 0xF3, + 0x8E, 0x07, 0xA1, 0xDE, 0x89, 0x4A, 0x39, 0x60, 0x77, 0xC5, + 0xAA, 0xF1, 0x51, 0xE6, 0x06, 0xF1, 0x95, 0x56, 0x2A, 0xE1, + 0x8E, 0x92, 0x30, 0x9F, 0xFE, 0x58, 0x44, 0xAC, 0x46, 0xF2, + 0xFD, 0x9A, 0xFC, 0xA8, 0x1D, 0xA1, 0xD3, 0x55, 0x37, 0x4A, + 0x8B, 0xFC, 0x9C, 0x33, 0xF8, 0xA7, 0x61, 0x48, 0x41, 0x7C, + 0x9C, 0x77, 0x3F, 0xF5, 0x80, 0x23, 0x7D, 0x43, 0xB4, 0xD5, + 0x88, 0x0A, 0xC9, 0x75, 0xD7, 0x44, 0x19, 0x4D, 0x77, 0x6C, + 0x0B, 0x0A, 0x49, 0xAA, 0x1C, 0x2F, 0xD6, 0x5A, 0x44, 0xA6, + 0x47, 0x4D, 0xE5, 0x36, 0x96, 0x40, 0x99, 0x2C, 0x56, 0x26, + 0xB1, 0xF2, 0x92, 0x31, 0x59, 0xD7, 0x2C, 0xD4, 0xB4, 0x21, + 0xD6, 0x65, 0x13, 0x0B, 0x3E, 0xFB, 0xFF, 0x04, 0xEB, 0xB9, + 0x85, 0xB9, 0xD8, 0xD8, 0x28, 0x4F, 0x5C, 0x17, 0x96, 0xA3, + 0x51, 0xBE, 0xFE, 0x7D, 0x0B, 0x1B, 0x48, 0x40, 0x25, 0x76, + 0x94, 0xDC, 0x41, 0xFB, 0xBF, 0x73, 0x76, 0xDA, 0xEB, 0xB3, + 0x62, 0xE7, 0xC1, 0xC8, 0x54, 0x6A, 0x93, 0xE1, 0x8D, 0x31, + 0xE8, 0x3E, 0x3E, 0xDF, 0xBC, 0x87, 0x02, 0x30, 0x22, 0x57, + 0xC4, 0xE0, 0x18, 0x7A, 0xD3, 0xAE, 0xE4, 0x02, 0x9B, 0xAA, + 0xBD, 0x4E, 0x49, 0x47, 0x72, 0xE9, 0x8D, 0x13, 0x2D, 0x54, + 0x9B, 0x00, 0xA7, 0x91, 0x61, 0x71, 0xC9, 0xCC, 0x48, 0x4F, + 0xEE, 0xDF, 0x5E, 0x1B, 0x1A, 0xDF, 0x67, 0xD3, 0x20, 0xE6, + 0x44, 0x45, 0x98, 0x7E, 0xE7, 0x0E, 0x63, 0x16, 0x83, 0xC9, + 0x26, 0x5D, 0x90, 0xC1, 0xE5, 0x2A, 0x5C, 0x45, 0x54, 0x13, + 0xB2, 0x81, 0x18, 0x06, 0x20, 0x2E, 0x2E, 0x66, 0x5A, 0xB5, + 0x7B, 0x6E, 0xD6, 0x0C, 0x4E, 0x89, 0x01, 0x56, 0x70, 0xBB, + 0xAE, 0xDE, 0xE9, 0x99, 0x5E, 0xD1, 0xB9, 0x3A, 0xB7, 0x6C, + 0x17, 0xB6, 0x03, 0xA9, 0x08, 0xDD, 0x9C, 0xF4, 0x14, 0xC9, + 0xC9, 0x59, 0x39, 0x72, 0xD4, 0x7E, 0x02, 0x37, 0x31, 0xCD, + 0x0E, 0xA7, 0x3D, 0xF8, 0xF2, 0xCF, 0x6B, 0x15, 0xAB, 0x02, + 0x03, 0x01, 0x00, 0x01, 0xA3, 0x82, 0x01, 0x12, 0x30, 0x82, + 0x01, 0x0E, 0x30, 0x1D, 0x06, 0x03, 0x55, 0x1D, 0x0E, 0x04, + 0x16, 0x04, 0x14, 0xFA, 0x54, 0x89, 0x67, 0xE5, 0x5F, 0xB7, + 0x31, 0x40, 0xEA, 0xFD, 0xE7, 0xF6, 0xA3, 0xC6, 0x5A, 0x56, + 0x16, 0xA5, 0x6E, 0x30, 0x81, 0xDE, 0x06, 0x03, 0x55, 0x1D, + 0x23, 0x04, 0x81, 0xD6, 0x30, 0x81, 0xD3, 0x80, 0x14, 0xFA, + 0x54, 0x89, 0x67, 0xE5, 0x5F, 0xB7, 0x31, 0x40, 0xEA, 0xFD, + 0xE7, 0xF6, 0xA3, 0xC6, 0x5A, 0x56, 0x16, 0xA5, 0x6E, 0xA1, + 0x81, 0xA4, 0xA4, 0x81, 0xA1, 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, 0x34, 0x30, 0x39, 0x36, + 0x31, 0x19, 0x30, 0x17, 0x06, 0x03, 0x55, 0x04, 0x0B, 0x0C, + 0x10, 0x50, 0x72, 0x6F, 0x67, 0x72, 0x61, 0x6D, 0x6D, 0x69, + 0x6E, 0x67, 0x2D, 0x34, 0x30, 0x39, 0x36, 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, 0x82, 0x14, 0x2F, 0x0F, + 0xAB, 0x23, 0xBC, 0xA3, 0x14, 0x07, 0x91, 0x06, 0x55, 0x35, + 0x01, 0x63, 0x7F, 0x42, 0xBD, 0xFB, 0xF2, 0x43, 0x30, 0x0C, + 0x06, 0x03, 0x55, 0x1D, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, + 0x01, 0xFF, 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, + 0xF7, 0x0D, 0x01, 0x01, 0x0B, 0x05, 0x00, 0x03, 0x82, 0x02, + 0x01, 0x00, 0x57, 0x0D, 0x97, 0x98, 0x78, 0xBF, 0x2A, 0x31, + 0x9A, 0x39, 0x41, 0x38, 0x33, 0x46, 0xD5, 0x50, 0x47, 0xE8, + 0x19, 0x62, 0xA8, 0x36, 0x1E, 0xB7, 0xFD, 0xD1, 0xBC, 0x50, + 0x5C, 0x3A, 0xEB, 0x96, 0x1A, 0x9B, 0x43, 0xB0, 0x67, 0x5D, + 0xF4, 0x51, 0x77, 0x87, 0x33, 0x0B, 0x90, 0x6F, 0xE8, 0xD3, + 0x82, 0x4D, 0x1A, 0xAA, 0x93, 0x5F, 0x7D, 0x78, 0xB1, 0xE0, + 0x7B, 0xEE, 0x88, 0x01, 0xE7, 0xB3, 0xFA, 0x7E, 0x0B, 0x76, + 0x9C, 0x9E, 0x81, 0x36, 0xE4, 0xA3, 0xC1, 0x41, 0x62, 0xA4, + 0x0A, 0x7E, 0x24, 0xD0, 0xAB, 0x9F, 0xBA, 0xD8, 0x1E, 0x38, + 0xAD, 0xF1, 0x12, 0x52, 0x0D, 0xF2, 0x96, 0x8A, 0x0B, 0x25, + 0xA2, 0x49, 0x3F, 0x88, 0x5B, 0xEA, 0x23, 0x87, 0x26, 0x22, + 0x7A, 0xB9, 0x60, 0x6B, 0xD6, 0x7A, 0x88, 0x37, 0xAC, 0x64, + 0x9B, 0x18, 0x51, 0x07, 0xEA, 0xDF, 0x00, 0x96, 0x70, 0x95, + 0x88, 0x9D, 0x8F, 0xAF, 0xBE, 0x3C, 0x4E, 0xC7, 0x5E, 0x55, + 0x15, 0x3D, 0x1F, 0xE4, 0x2D, 0xDC, 0xC9, 0xA3, 0xAE, 0xAF, + 0xFA, 0x44, 0xA8, 0xE2, 0xF4, 0xDF, 0x8E, 0xCD, 0xF9, 0x10, + 0x7F, 0x8B, 0x86, 0xCC, 0x6D, 0x45, 0x91, 0x91, 0x4F, 0xE3, + 0xD0, 0xA7, 0xD2, 0xD9, 0x8E, 0x09, 0xC6, 0xF8, 0xEB, 0xE7, + 0xBD, 0x17, 0x19, 0xD6, 0xE7, 0x1A, 0xB8, 0xCA, 0x4D, 0xEC, + 0x34, 0x07, 0x7D, 0x2D, 0xE8, 0x23, 0x9D, 0x82, 0xE9, 0xF7, + 0x47, 0x03, 0xAB, 0x5F, 0x7C, 0xF5, 0x41, 0x6F, 0x70, 0x11, + 0xCB, 0x24, 0xD8, 0x23, 0xC2, 0x65, 0x31, 0xB7, 0x0B, 0x8F, + 0x0A, 0x26, 0x5B, 0x0F, 0xF6, 0x9B, 0x11, 0x7F, 0x9A, 0x8D, + 0x94, 0x6D, 0x5A, 0x9C, 0x5E, 0x73, 0x35, 0x15, 0x7B, 0xE3, + 0x09, 0xE8, 0x08, 0xD0, 0x3F, 0xB4, 0xE5, 0x29, 0x2C, 0xF6, + 0x3E, 0x71, 0x6E, 0xF4, 0x1B, 0x20, 0x55, 0x34, 0x40, 0x2F, + 0xB0, 0x9B, 0xDD, 0xF1, 0xDC, 0xBF, 0x17, 0x1D, 0xA7, 0x2D, + 0x85, 0x01, 0xD6, 0xD2, 0xB2, 0x56, 0x56, 0x98, 0x33, 0x85, + 0xED, 0xF6, 0xA3, 0xF6, 0x3E, 0x7B, 0xF4, 0x03, 0xA4, 0x58, + 0x8E, 0xC5, 0x5B, 0xAB, 0x66, 0xE8, 0x0F, 0x34, 0x17, 0x2D, + 0x33, 0x36, 0x71, 0x0C, 0xB8, 0xD9, 0x78, 0xE7, 0x06, 0xFC, + 0xDA, 0x4F, 0xA1, 0xFA, 0xDB, 0x74, 0xCE, 0xEA, 0x85, 0x27, + 0xF9, 0x75, 0xA9, 0xAD, 0x50, 0x86, 0x6E, 0xEA, 0x01, 0x01, + 0x19, 0x0D, 0x28, 0x4A, 0xED, 0x06, 0xBE, 0x65, 0x70, 0xB2, + 0x06, 0x46, 0x2E, 0x16, 0x57, 0xDF, 0x55, 0xC7, 0x8E, 0xCD, + 0x5B, 0xAD, 0x66, 0x28, 0xB8, 0x74, 0x87, 0xBF, 0xC4, 0xC7, + 0x08, 0x3F, 0x37, 0xA3, 0x23, 0x84, 0x9F, 0x4E, 0xE8, 0x48, + 0x6C, 0x8D, 0x54, 0x9F, 0xFB, 0xE0, 0xFB, 0x53, 0xA3, 0x41, + 0xE1, 0x68, 0x8A, 0x94, 0xC9, 0xF5, 0xEE, 0x3E, 0x15, 0x46, + 0xD2, 0x62, 0x33, 0x86, 0x86, 0x06, 0x34, 0xB4, 0xE4, 0x2F, + 0xDA, 0x28, 0x2E, 0x2F, 0xC0, 0xBD, 0x75, 0xE8, 0x2C, 0x3F, + 0xE2, 0xA5, 0x43, 0x7D, 0x02, 0xEB, 0x25, 0xB9, 0xEF, 0x87, + 0x8A, 0xD7, 0x57, 0x61, 0x16, 0xE8, 0x9E, 0x83, 0x65, 0xF9, + 0x10, 0xF4, 0x5E, 0x5F, 0x1C, 0x7A, 0x25, 0xD6, 0x47, 0xBD, + 0x29, 0xC5, 0x4F, 0x8B, 0xB9, 0x6A, 0x48, 0x7A, 0x9B, 0x1E, + 0x6D, 0x77, 0x8E, 0x72, 0x6C, 0x0C, 0x07, 0xFE, 0x4C, 0xC5, + 0xCF, 0x55, 0x0E, 0xCB, 0x4B, 0xAD, 0x16, 0xE1, 0xE2, 0x54, + 0xB8, 0x9D, 0x34, 0x03, 0xD1, 0x8D, 0xB7, 0x37, 0x9B, 0xE3, + 0x5A, 0x32, 0x60, 0x03, 0x7F, 0x61, 0x0F, 0x50, 0x0B, 0x72, + 0x54, 0x8B, 0x0D, 0xC7, 0x97, 0x7E, 0xBB, 0x9B, 0xB2, 0xF7, + 0x73, 0x47, 0x71, 0x7B, 0x78, 0x65, 0x36, 0xDF, 0x57, 0x72, + 0x9E, 0x42, 0x9C, 0x8A +}; +static const int sizeof_client_cert_der_4096 = sizeof(client_cert_der_4096); + +#endif /* USE_CERT_BUFFERS_4096 */ + #if defined(HAVE_ECC) && defined(USE_CERT_BUFFERS_256) /* ./certs/ecc-client-key.der, ECC */ From ef2c1ae738fac63827e05b3afe97490f9c6b5c18 Mon Sep 17 00:00:00 2001 From: David Garske Date: Sun, 23 Feb 2020 19:01:46 -0800 Subject: [PATCH 158/649] Fix for `examples/benchmark/tls_bench.c:114:20: error: unused variable 'kShutdown'` with `WOLFCRYPT_ONLY`. --- examples/benchmark/tls_bench.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/benchmark/tls_bench.c b/examples/benchmark/tls_bench.c index 382776c1a..dcfb07948 100644 --- a/examples/benchmark/tls_bench.c +++ b/examples/benchmark/tls_bench.c @@ -110,12 +110,12 @@ bench_tls(args); #define MEM_BUFFER_SZ (TEST_PACKET_SIZE + 38 + WC_MAX_DIGEST_SIZE) #define SHOW_VERBOSE 0 /* Default output is tab delimited format */ -/* shutdown message - nice signal to server, we are done */ -static const char* kShutdown = "shutdown"; - #if (!defined(NO_WOLFSSL_CLIENT) || !defined(NO_WOLFSSL_SERVER)) && \ !defined(WOLFCRYPT_ONLY) +/* shutdown message - nice signal to server, we are done */ +static const char* kShutdown = "shutdown"; + #ifndef NO_WOLFSSL_CLIENT static const char* kTestStr = "Biodiesel cupidatat marfa, cliche aute put a bird on it incididunt elit\n" From 4b83b88a299fb2048b475fab168499a12997518d Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 24 Feb 2020 18:52:50 -0800 Subject: [PATCH 159/649] Fix for CRL bit-mask enum value issue. ZD 9948. --- wolfssl/ssl.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 2937e5608..6563ae19f 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1568,13 +1568,14 @@ WOLFSSL_API long wolfSSL_get_verify_result(const WOLFSSL *ssl); #define WOLFSSL_DEFAULT_CIPHER_LIST "" /* default all */ +/* These are bit-masks */ enum { WOLFSSL_OCSP_URL_OVERRIDE = 1, WOLFSSL_OCSP_NO_NONCE = 2, WOLFSSL_OCSP_CHECKALL = 4, WOLFSSL_CRL_CHECKALL = 1, - WOLFSSL_CRL_CHECK = 27, + WOLFSSL_CRL_CHECK = 2, }; #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) || \ From 2a5d7a2ac357a10b535773519c06d00e28194857 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Wed, 26 Feb 2020 10:53:35 +1000 Subject: [PATCH 160/649] Fix for SP x64 div Check the top half of number being divided to see if it is greater than or equal. If it is then the first div_word may crash as the result is more than 64-bits. So subtract modulus from the top to keep value small. --- wolfcrypt/src/sp_x86_64.c | 70 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/wolfcrypt/src/sp_x86_64.c b/wolfcrypt/src/sp_x86_64.c index c1ec7a3a0..1b778bd12 100644 --- a/wolfcrypt/src/sp_x86_64.c +++ b/wolfcrypt/src/sp_x86_64.c @@ -413,6 +413,13 @@ static WC_INLINE int sp_2048_div_16(const sp_digit* a, const sp_digit* d, sp_dig div = d[15]; XMEMCPY(t1, a, sizeof(*t1) * 2 * 16); + r1 = sp_2048_cmp_16(&t1[16], d) >= 0; +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_2048_cond_sub_avx2_16(&t1[16], &t1[16], d, (sp_digit)0 - r1); + else +#endif + sp_2048_cond_sub_16(&t1[16], &t1[16], d, (sp_digit)0 - r1); for (i=15; i>=0; i--) { r1 = div_2048_word_16(t1[16 + i], t1[16 + i - 1], div); @@ -906,6 +913,13 @@ static WC_INLINE int sp_2048_div_32(const sp_digit* a, const sp_digit* d, sp_dig div = d[31]; XMEMCPY(t1, a, sizeof(*t1) * 2 * 32); + r1 = sp_2048_cmp_32(&t1[32], d) >= 0; +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_2048_cond_sub_avx2_32(&t1[32], &t1[32], d, (sp_digit)0 - r1); + else +#endif + sp_2048_cond_sub_32(&t1[32], &t1[32], d, (sp_digit)0 - r1); for (i=31; i>=0; i--) { r1 = div_2048_word_32(t1[32 + i], t1[32 + i - 1], div); @@ -971,6 +985,13 @@ static WC_INLINE int sp_2048_div_32_cond(const sp_digit* a, const sp_digit* d, s div = d[31]; XMEMCPY(t1, a, sizeof(*t1) * 2 * 32); + for (i = 31; i > 0; i--) { + if (t1[i + 32] != d[i]) + break; + } + if (t1[i + 32] >= d[i]) { + sp_2048_sub_in_place_32(&t1[32], d); + } for (i=31; i>=0; i--) { r1 = div_2048_word_32(t1[32 + i], t1[32 + i - 1], div); @@ -2476,6 +2497,13 @@ static WC_INLINE int sp_3072_div_24(const sp_digit* a, const sp_digit* d, sp_dig div = d[23]; XMEMCPY(t1, a, sizeof(*t1) * 2 * 24); + r1 = sp_3072_cmp_24(&t1[24], d) >= 0; +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_3072_cond_sub_avx2_24(&t1[24], &t1[24], d, (sp_digit)0 - r1); + else +#endif + sp_3072_cond_sub_24(&t1[24], &t1[24], d, (sp_digit)0 - r1); for (i=23; i>=0; i--) { r1 = div_3072_word_24(t1[24 + i], t1[24 + i - 1], div); @@ -2969,6 +2997,13 @@ static WC_INLINE int sp_3072_div_48(const sp_digit* a, const sp_digit* d, sp_dig div = d[47]; XMEMCPY(t1, a, sizeof(*t1) * 2 * 48); + r1 = sp_3072_cmp_48(&t1[48], d) >= 0; +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_3072_cond_sub_avx2_48(&t1[48], &t1[48], d, (sp_digit)0 - r1); + else +#endif + sp_3072_cond_sub_48(&t1[48], &t1[48], d, (sp_digit)0 - r1); for (i=47; i>=0; i--) { r1 = div_3072_word_48(t1[48 + i], t1[48 + i - 1], div); @@ -3034,6 +3069,13 @@ static WC_INLINE int sp_3072_div_48_cond(const sp_digit* a, const sp_digit* d, s div = d[47]; XMEMCPY(t1, a, sizeof(*t1) * 2 * 48); + for (i = 47; i > 0; i--) { + if (t1[i + 48] != d[i]) + break; + } + if (t1[i + 48] >= d[i]) { + sp_3072_sub_in_place_48(&t1[48], d); + } for (i=47; i>=0; i--) { r1 = div_3072_word_48(t1[48 + i], t1[48 + i - 1], div); @@ -4531,6 +4573,13 @@ static WC_INLINE int sp_4096_div_64(const sp_digit* a, const sp_digit* d, sp_dig div = d[63]; XMEMCPY(t1, a, sizeof(*t1) * 2 * 64); + r1 = sp_4096_cmp_64(&t1[64], d) >= 0; +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_4096_cond_sub_avx2_64(&t1[64], &t1[64], d, (sp_digit)0 - r1); + else +#endif + sp_4096_cond_sub_64(&t1[64], &t1[64], d, (sp_digit)0 - r1); for (i=63; i>=0; i--) { r1 = div_4096_word_64(t1[64 + i], t1[64 + i - 1], div); @@ -4596,6 +4645,13 @@ static WC_INLINE int sp_4096_div_64_cond(const sp_digit* a, const sp_digit* d, s div = d[63]; XMEMCPY(t1, a, sizeof(*t1) * 2 * 64); + for (i = 63; i > 0; i--) { + if (t1[i + 64] != d[i]) + break; + } + if (t1[i + 64] >= d[i]) { + sp_4096_sub_in_place_64(&t1[64], d); + } for (i=63; i>=0; i--) { r1 = div_4096_word_64(t1[64 + i], t1[64 + i - 1], div); @@ -22156,6 +22212,13 @@ static WC_INLINE int sp_256_div_4(const sp_digit* a, const sp_digit* d, sp_digit div = d[3]; XMEMCPY(t1, a, sizeof(*t1) * 2 * 4); + r1 = sp_256_cmp_4(&t1[4], d) >= 0; +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_256_cond_sub_avx2_4(&t1[4], &t1[4], d, (sp_digit)0 - r1); + else +#endif + sp_256_cond_sub_4(&t1[4], &t1[4], d, (sp_digit)0 - r1); for (i=3; i>=0; i--) { r1 = div_256_word_4(t1[4 + i], t1[4 + i - 1], div); @@ -28015,6 +28078,13 @@ static WC_INLINE int sp_384_div_6(const sp_digit* a, const sp_digit* d, sp_digit div = d[5]; XMEMCPY(t1, a, sizeof(*t1) * 2 * 6); + r1 = sp_384_cmp_6(&t1[6], d) >= 0; +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_384_cond_sub_avx2_6(&t1[6], &t1[6], d, (sp_digit)0 - r1); + else +#endif + sp_384_cond_sub_6(&t1[6], &t1[6], d, (sp_digit)0 - r1); for (i=5; i>=0; i--) { r1 = div_384_word_6(t1[6 + i], t1[6 + i - 1], div); From 3b822ad3d58faf140440717afd4b028a6d2efbae Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Wed, 26 Feb 2020 22:11:36 +0100 Subject: [PATCH 161/649] Fix AES-GCM IV length in wolfSSL_EVP_CIPHER_iv_length --- src/ssl.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 797715ce3..1ea8fd26f 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -32152,15 +32152,15 @@ int wolfSSL_EVP_CIPHER_iv_length(const WOLFSSL_EVP_CIPHER* cipher) #ifdef HAVE_AESGCM #ifdef WOLFSSL_AES_128 if (XSTRNCMP(name, EVP_AES_128_GCM, XSTRLEN(EVP_AES_128_GCM)) == 0) - return AES_BLOCK_SIZE; + return GCM_NONCE_MID_SZ; #endif #ifdef WOLFSSL_AES_192 if (XSTRNCMP(name, EVP_AES_192_GCM, XSTRLEN(EVP_AES_192_GCM)) == 0) - return AES_BLOCK_SIZE; + return GCM_NONCE_MID_SZ; #endif #ifdef WOLFSSL_AES_256 if (XSTRNCMP(name, EVP_AES_256_GCM, XSTRLEN(EVP_AES_256_GCM)) == 0) - return AES_BLOCK_SIZE; + return GCM_NONCE_MID_SZ; #endif #endif /* HAVE_AESGCM */ #ifdef WOLFSSL_AES_COUNTER From 2d530499e30a4d75687e981b6c875b3b0e1c2a85 Mon Sep 17 00:00:00 2001 From: Hideki Miyazaki Date: Thu, 27 Feb 2020 21:56:25 +0900 Subject: [PATCH 162/649] fix dtl server example when freeing stuff --- wrapper/CSharp/wolfSSL-DTLS-Server/wolfSSL-DTLS-Server.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wrapper/CSharp/wolfSSL-DTLS-Server/wolfSSL-DTLS-Server.cs b/wrapper/CSharp/wolfSSL-DTLS-Server/wolfSSL-DTLS-Server.cs index 39f3aad15..c7cdd43a7 100644 --- a/wrapper/CSharp/wolfSSL-DTLS-Server/wolfSSL-DTLS-Server.cs +++ b/wrapper/CSharp/wolfSSL-DTLS-Server/wolfSSL-DTLS-Server.cs @@ -174,8 +174,8 @@ public class wolfSSL_DTLS_Server } Console.WriteLine("At the end freeing stuff"); - udp.Close(); wolfssl.shutdown(ssl); + udp.Close(); clean(ssl, ctx); } } From d9e221806b9cb182d9aaacd9efe34b0b013855ca Mon Sep 17 00:00:00 2001 From: kaleb-himes Date: Thu, 27 Feb 2020 09:39:22 -0700 Subject: [PATCH 163/649] Fix infinite loop with small sha1 inputs. Thanks to Peter W. on ZD9976 for the report --- wolfcrypt/src/port/pic32/pic32mz-crypt.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/wolfcrypt/src/port/pic32/pic32mz-crypt.c b/wolfcrypt/src/port/pic32/pic32mz-crypt.c index 319e6ca3a..1e618c194 100644 --- a/wolfcrypt/src/port/pic32/pic32mz-crypt.c +++ b/wolfcrypt/src/port/pic32/pic32mz-crypt.c @@ -427,6 +427,9 @@ static void start_engine(pic32mz_desc *desc) bufferLen = desc->dbPtr; if (bufferLen % 4) bufferLen = (bufferLen + 4) - (bufferLen % 4); + /* initialize the MSGLEN on engine startup to avoid infinite loop when + * length is less than 257 (size of PIC32_BLOCK_SIZE) */ + uc_desc->bd[desc->currBd].MSGLEN = desc->msgSize; uc_desc->bd[desc->currBd].BD_CTRL.BUFLEN = bufferLen; uc_desc->bd[desc->currBd].BD_CTRL.LAST_BD = 1; uc_desc->bd[desc->currBd].BD_CTRL.LIFM = 1; From d21e370822c7fb53fb484903587c06d55640fe53 Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Thu, 27 Feb 2020 14:42:57 -0700 Subject: [PATCH 164/649] add support for PKCS7/CMS EnvelopedData with fragmented encrypted content --- tests/api.c | 2 +- wolfcrypt/src/pkcs7.c | 130 +++++++++++++++++++++++++++++--------- wolfssl/wolfcrypt/pkcs7.h | 4 ++ 3 files changed, 105 insertions(+), 31 deletions(-) diff --git a/tests/api.c b/tests/api.c index 39fccc391..97c2cb4fc 100644 --- a/tests/api.c +++ b/tests/api.c @@ -18416,7 +18416,7 @@ static void test_wc_PKCS7_BER(void) XFILE f; byte der[4096]; #ifndef NO_DES3 - byte decoded[1024]; + byte decoded[2048]; #endif word32 derSz; int ret; diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 3231ce661..12494d970 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -1172,6 +1172,11 @@ void wc_PKCS7_Free(PKCS7* pkcs7) pkcs7->pkcs7Digest = NULL; pkcs7->pkcs7DigestSz = 0; } + if (pkcs7->cachedEncryptedContent != NULL) { + XFREE(pkcs7->cachedEncryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + pkcs7->cachedEncryptedContent = NULL; + pkcs7->cachedEncryptedContentSz = 0; + } if (pkcs7->isDynamic) { pkcs7->isDynamic = 0; @@ -9987,6 +9992,41 @@ WOLFSSL_API int wc_PKCS7_SetKey(PKCS7* pkcs7, byte* key, word32 keySz) } +/* append data to encrypted content cache in PKCS7 structure + * return 0 on success, negative on error */ +static int PKCS7_CacheEncryptedContent(PKCS7* pkcs7, byte* in, word32 inSz) +{ + byte* oldCache; + word32 oldCacheSz; + + if (pkcs7 == NULL || in == NULL) + return BAD_FUNC_ARG; + + /* save pointer to old cache */ + oldCache = pkcs7->cachedEncryptedContent; + oldCacheSz = pkcs7->cachedEncryptedContentSz; + + /* re-allocate new buffer to fit appended data */ + pkcs7->cachedEncryptedContent = (byte*)XMALLOC(oldCacheSz + inSz, + pkcs7->heap, DYNAMIC_TYPE_PKCS7); + if (pkcs7->cachedEncryptedContent == NULL) { + pkcs7->cachedEncryptedContentSz = 0; + XFREE(oldCache, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + return MEMORY_E; + } + + if (oldCache != NULL) { + XMEMCPY(pkcs7->cachedEncryptedContent, oldCache, oldCacheSz); + } + XMEMCPY(pkcs7->cachedEncryptedContent + oldCacheSz, in, inSz); + pkcs7->cachedEncryptedContentSz += inSz; + + XFREE(oldCache, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + + return 0; +} + + /* unwrap and decrypt PKCS#7 envelopedData object, return decoded size */ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* in, word32 inSz, byte* output, @@ -10009,6 +10049,7 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* in, byte* pkiMsg = in; word32 pkiMsgSz = inSz; byte* decryptedKey = NULL; + int encryptedContentTotalSz = 0; int encryptedContentSz = 0; byte padLen; byte* encryptedContent = NULL; @@ -10223,27 +10264,51 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* in, } idx++; - if (ret == 0 && GetLength(pkiMsg, &idx, &encryptedContentSz, + if (ret == 0 && GetLength(pkiMsg, &idx, &encryptedContentTotalSz, pkiMsgSz) <= 0) { ret = ASN_PARSE_E; } if (ret == 0 && explicitOctet) { - if (GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0) { - ret = ASN_PARSE_E; - break; - } + /* encrypted content may be fragmented into multiple + * consecutive OCTET STRINGs, if so loop through + * collecting and caching encrypted content bytes */ + localIdx = idx; + while (idx < (localIdx + encryptedContentTotalSz)) { - if (tag != ASN_OCTET_STRING) { - ret = ASN_PARSE_E; - break; - } + if (GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0) { + ret = ASN_PARSE_E; + break; + } - if (ret == 0 && GetLength(pkiMsg, &idx, &encryptedContentSz, - pkiMsgSz) <= 0) { - ret = ASN_PARSE_E; + if (tag != ASN_OCTET_STRING) { + ret = ASN_PARSE_E; + break; + } + + if (ret == 0 && GetLength(pkiMsg, &idx, + &encryptedContentSz, pkiMsgSz) <= 0) { + ret = ASN_PARSE_E; + break; + } + + ret = PKCS7_CacheEncryptedContent(pkcs7, &pkiMsg[idx], + encryptedContentSz); + if (ret != 0) { + break; + } + + /* advance idx past encrypted content */ + idx += encryptedContentSz; + } + } else { + /* cache encrypted content, no OCTET STRING */ + ret = PKCS7_CacheEncryptedContent(pkcs7, &pkiMsg[idx], + encryptedContentTotalSz); + if (ret != 0) { break; } + idx += encryptedContentTotalSz; } if (ret != 0) @@ -10253,10 +10318,9 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* in, if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) { break; } - pkcs7->stream->expected = encryptedContentSz; + pkcs7->stream->expected = 0; wc_PKCS7_StreamGetVar(pkcs7, &encOID, &expBlockSz, 0); - wc_PKCS7_StreamStoreVar(pkcs7, encOID, expBlockSz, - encryptedContentSz); + wc_PKCS7_StreamStoreVar(pkcs7, encOID, expBlockSz, 0); #endif wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_ENV_5); FALL_THROUGH; @@ -10269,8 +10333,7 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* in, return ret; } - wc_PKCS7_StreamGetVar(pkcs7, &encOID, &expBlockSz, - &encryptedContentSz); + wc_PKCS7_StreamGetVar(pkcs7, &encOID, &expBlockSz, NULL); tmpIv = pkcs7->stream->tmpIv; /* restore decrypted key */ @@ -10280,23 +10343,16 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* in, #else ret = 0; #endif - encryptedContent = (byte*)XMALLOC(encryptedContentSz, pkcs7->heap, - DYNAMIC_TYPE_PKCS7); - if (encryptedContent == NULL) { - ret = MEMORY_E; - break; - } - if (ret == 0) { - XMEMCPY(encryptedContent, &pkiMsg[idx], encryptedContentSz); - } + /* use cached content */ + encryptedContent = pkcs7->cachedEncryptedContent; + encryptedContentSz = pkcs7->cachedEncryptedContentSz; /* decrypt encryptedContent */ ret = wc_PKCS7_DecryptContent(pkcs7, encOID, decryptedKey, blockKeySz, tmpIv, expBlockSz, NULL, 0, NULL, 0, encryptedContent, encryptedContentSz, encryptedContent); if (ret != 0) { - XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7); break; } @@ -10305,7 +10361,6 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* in, /* copy plaintext to output */ if (padLen > encryptedContentSz || (word32)(encryptedContentSz - padLen) > outputSz) { - XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7); ret = BUFFER_E; break; } @@ -10313,9 +10368,13 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* in, /* free memory, zero out keys */ ForceZero(decryptedKey, MAX_ENCRYPTED_KEY_SZ); - ForceZero(encryptedContent, encryptedContentSz); - XFREE(encryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7); XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + if (pkcs7->cachedEncryptedContent != NULL) { + XFREE(pkcs7->cachedEncryptedContent, pkcs7->heap, + DYNAMIC_TYPE_PKCS7); + pkcs7->cachedEncryptedContent = NULL; + pkcs7->cachedEncryptedContentSz = 0; + } ret = encryptedContentSz - padLen; #ifndef NO_PKCS7_STREAM @@ -10335,12 +10394,23 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* in, if (ret < 0 && ret != WC_PKCS7_WANT_READ_E) { wc_PKCS7_ResetStream(pkcs7); wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_START); + if (pkcs7->cachedEncryptedContent != NULL) { + XFREE(pkcs7->cachedEncryptedContent, pkcs7->heap, + DYNAMIC_TYPE_PKCS7); + pkcs7->cachedEncryptedContent = NULL; + pkcs7->cachedEncryptedContentSz = 0; + } } #else if (decryptedKey != NULL && ret < 0) { ForceZero(decryptedKey, MAX_ENCRYPTED_KEY_SZ); XFREE(decryptedKey, pkcs7->heap, DYNAMIC_TYPE_PKCS7); } + if (pkcs7->cachedEncryptedContent != NULL && ret < 0) { + XFREE(pkcs7->cachedEncryptedContent, pkcs7->heap, DYNAMIC_TYPE_PKCS7); + pkcs7->cachedEncryptedContent = NULL; + pkcs7->cachedEncryptedContentSz = 0; + } #endif return ret; } diff --git a/wolfssl/wolfcrypt/pkcs7.h b/wolfssl/wolfcrypt/pkcs7.h index 840d94281..0292d1d07 100644 --- a/wolfssl/wolfcrypt/pkcs7.h +++ b/wolfssl/wolfcrypt/pkcs7.h @@ -330,6 +330,10 @@ struct PKCS7 { #if defined(HAVE_PKCS7_RSA_RAW_SIGN_CALLBACK) && !defined(NO_RSA) CallbackRsaSignRawDigest rsaSignRawDigestCb; #endif + + /* used by DecodeEnvelopedData with multiple encrypted contents */ + byte* cachedEncryptedContent; + word32 cachedEncryptedContentSz; /* !! NEW DATA MEMBERS MUST BE ADDED AT END !! */ }; From 2c6eb7cb39143cefa10b7a2c371bea8615bbc4ce Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Wed, 19 Feb 2020 18:07:45 +1000 Subject: [PATCH 165/649] Add Curve448, X448, Ed448 implementations --- certs/ed448/ca-ed448-key.der | Bin 0 -> 69 bytes certs/ed448/ca-ed448-key.pem | 4 + certs/ed448/ca-ed448-priv.der | Bin 0 -> 73 bytes certs/ed448/ca-ed448-priv.pem | 4 + certs/ed448/ca-ed448.der | Bin 0 -> 659 bytes certs/ed448/ca-ed448.pem | 52 + certs/ed448/client-ed448-key.der | Bin 0 -> 69 bytes certs/ed448/client-ed448-key.pem | 4 + certs/ed448/client-ed448-priv.der | Bin 0 -> 73 bytes certs/ed448/client-ed448-priv.pem | 4 + certs/ed448/client-ed448.der | Bin 0 -> 882 bytes certs/ed448/client-ed448.pem | 60 + certs/ed448/gen-ed448-certs.sh | 105 + certs/ed448/gen-ed448-keys.sh | 16 + certs/ed448/include.am | 30 + certs/ed448/root-ed448-key.der | Bin 0 -> 69 bytes certs/ed448/root-ed448-key.pem | 4 + certs/ed448/root-ed448-priv.der | Bin 0 -> 73 bytes certs/ed448/root-ed448-priv.pem | 4 + certs/ed448/root-ed448.der | Bin 0 -> 680 bytes certs/ed448/root-ed448.pem | 54 + certs/ed448/server-ed448-cert.pem | 57 + certs/ed448/server-ed448-key.der | Bin 0 -> 69 bytes certs/ed448/server-ed448-key.pem | 4 + certs/ed448/server-ed448-priv.der | Bin 0 -> 73 bytes certs/ed448/server-ed448-priv.pem | 4 + certs/ed448/server-ed448.der | Bin 0 -> 700 bytes certs/ed448/server-ed448.pem | 109 + certs/include.am | 1 + certs/renewcerts.sh | 11 + configure.ac | 96 +- cyassl/openssl/ec448.h | 3 + cyassl/openssl/ed448.h | 3 + cyassl/openssl/include.am | 2 + examples/client/client.c | 83 +- examples/echoclient/echoclient.c | 6 +- examples/echoserver/echoserver.c | 15 +- examples/server/server.c | 45 +- src/include.am | 19 + src/internal.c | 1586 +++- src/keys.c | 9 +- src/ssl.c | 604 +- src/tls.c | 271 +- src/tls13.c | 107 +- tests/api.c | 1021 ++- tests/include.am | 1 + tests/suites.c | 11 + tests/test-ed448.conf | 59 + tests/test-fails.conf | 4 +- tests/test-tls13-ecc.conf | 13 + tests/test.conf | 12 + wolfcrypt/benchmark/benchmark.c | 205 +- wolfcrypt/benchmark/benchmark.h | 4 + wolfcrypt/src/asn.c | 630 +- wolfcrypt/src/curve448.c | 635 ++ wolfcrypt/src/ed448.c | 917 +++ wolfcrypt/src/fe_448.c | 2394 ++++++ wolfcrypt/src/ge_448.c | 10780 ++++++++++++++++++++++++++++ wolfcrypt/src/hash.c | 39 + wolfcrypt/src/sha3.c | 75 +- wolfcrypt/test/test.c | 5365 +++++++++----- wolfssl/internal.h | 143 +- wolfssl/openssl/ec448.h | 44 + wolfssl/openssl/ed448.h | 47 + wolfssl/openssl/include.am | 2 + wolfssl/ssl.h | 45 +- wolfssl/test.h | 296 +- wolfssl/wolfcrypt/asn.h | 13 +- wolfssl/wolfcrypt/asn_public.h | 28 +- wolfssl/wolfcrypt/curve448.h | 139 + wolfssl/wolfcrypt/ecc.h | 2 +- wolfssl/wolfcrypt/ed448.h | 160 + wolfssl/wolfcrypt/fe_448.h | 116 + wolfssl/wolfcrypt/ge_448.h | 86 + wolfssl/wolfcrypt/hash.h | 3 + wolfssl/wolfcrypt/include.am | 4 + wolfssl/wolfcrypt/settings.h | 54 +- wolfssl/wolfcrypt/sha3.h | 8 + wolfssl/wolfcrypt/types.h | 2 + 79 files changed, 24343 insertions(+), 2390 deletions(-) create mode 100644 certs/ed448/ca-ed448-key.der create mode 100644 certs/ed448/ca-ed448-key.pem create mode 100644 certs/ed448/ca-ed448-priv.der create mode 100644 certs/ed448/ca-ed448-priv.pem create mode 100644 certs/ed448/ca-ed448.der create mode 100644 certs/ed448/ca-ed448.pem create mode 100644 certs/ed448/client-ed448-key.der create mode 100644 certs/ed448/client-ed448-key.pem create mode 100644 certs/ed448/client-ed448-priv.der create mode 100644 certs/ed448/client-ed448-priv.pem create mode 100644 certs/ed448/client-ed448.der create mode 100644 certs/ed448/client-ed448.pem create mode 100755 certs/ed448/gen-ed448-certs.sh create mode 100755 certs/ed448/gen-ed448-keys.sh create mode 100644 certs/ed448/include.am create mode 100644 certs/ed448/root-ed448-key.der create mode 100644 certs/ed448/root-ed448-key.pem create mode 100644 certs/ed448/root-ed448-priv.der create mode 100644 certs/ed448/root-ed448-priv.pem create mode 100644 certs/ed448/root-ed448.der create mode 100644 certs/ed448/root-ed448.pem create mode 100644 certs/ed448/server-ed448-cert.pem create mode 100644 certs/ed448/server-ed448-key.der create mode 100644 certs/ed448/server-ed448-key.pem create mode 100644 certs/ed448/server-ed448-priv.der create mode 100644 certs/ed448/server-ed448-priv.pem create mode 100644 certs/ed448/server-ed448.der create mode 100644 certs/ed448/server-ed448.pem create mode 100644 cyassl/openssl/ec448.h create mode 100644 cyassl/openssl/ed448.h create mode 100644 tests/test-ed448.conf create mode 100644 wolfcrypt/src/curve448.c create mode 100644 wolfcrypt/src/ed448.c create mode 100644 wolfcrypt/src/fe_448.c create mode 100644 wolfcrypt/src/ge_448.c create mode 100644 wolfssl/openssl/ec448.h create mode 100644 wolfssl/openssl/ed448.h create mode 100644 wolfssl/wolfcrypt/curve448.h create mode 100644 wolfssl/wolfcrypt/ed448.h create mode 100644 wolfssl/wolfcrypt/fe_448.h create mode 100644 wolfssl/wolfcrypt/ge_448.h diff --git a/certs/ed448/ca-ed448-key.der b/certs/ed448/ca-ed448-key.der new file mode 100644 index 0000000000000000000000000000000000000000..a3daad5ba5920725bf20fc51ba2f4016a13482e1 GIT binary patch literal 69 zcmXqTHeh9A)=n*CwqoFWw59Cnr89@Tt2b!woAmqe`pl(Mb`_|+Sp5D(@~ped)<-y7 cu&8_xn7D5_sC%EqjnT4>NX(~#SMlZ`o)g-w_#G}utUfDgps;9>X8 z&nrpHON5EA^RPSRSEc4A<{63^h=9~^@$i=C=cEM(`^3AZn3z}?3L6N5#JPF6g7WiA zbRmKg24WyVW*+|X@^U?phT`HJz2y8{LwN&PHcqWJkGAi;jGT;O0-1Sf`3^`54CKUl zjSLKo42=y8jZIBVqQrTPj0_D8ETLS3#_7~>dn(xNf(HB`XL9p!I6LY>geY*iGcC7ST>J6IvCjCCVK6B}mT?HyH7Qa7{JnQbV^%2e%EGi!aChl9#I5Fh& z`OH?Iozr`kn6F}3oNSP2Aj`%aD$BH6ZXi_X^CrK;Ds&scsaIxr>KKprHm z%pzeR)*x~#bH+(EuhQRV*mg~$IZ|H literal 0 HcmV?d00001 diff --git a/certs/ed448/ca-ed448.pem b/certs/ed448/ca-ed448.pem new file mode 100644 index 000000000..2e8926ffd --- /dev/null +++ b/certs/ed448/ca-ed448.pem @@ -0,0 +1,52 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: ED448 + Issuer: C = US, ST = Montana, L = Bozeman, O = wolfSSL_Ed448, OU = Root-Ed448, CN = www.wolfssl.com, emailAddress = info@wolfssl.com + Validity + Not Before: Feb 13 01:35:44 2020 GMT + Not After : Nov 9 01:35:44 2022 GMT + Subject: C = US, ST = Montana, L = Bozeman, O = wolfSSL_ed448, OU = CA-ed448, CN = www.wolfssl.com, emailAddress = info@wolfssl.com + Subject Public Key Info: + Public Key Algorithm: ED448 + ED448 Public-Key: + pub: + 0e:e2:b4:76:e5:d2:cc:c2:4b:7b:b0:29:be:92:fb: + c3:af:69:a5:94:ba:70:24:e8:a3:ef:c8:63:9a:dd: + a6:af:58:43:38:04:24:f0:10:91:be:a7:01:91:54: + f3:cf:69:85:4c:b9:97:8c:a4:37:aa:00 + X509v3 extensions: + X509v3 Subject Key Identifier: + 38:59:45:E8:DD:44:2C:B5:7D:A5:25:D6:0B:CC:39:F0:72:C0:94:63 + X509v3 Authority Key Identifier: + keyid:DA:69:98:C9:26:4A:75:FB:59:5E:53:9A:63:4B:0C:B8:88:0B:0F:1E + + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Digital Signature, Certificate Sign, CRL Sign + Signature Algorithm: ED448 + a0:94:c1:de:f0:7f:40:b2:88:77:f7:f7:7b:da:42:b3:3f:f6: + 32:57:a9:e9:41:7f:51:53:1c:f3:5e:d5:77:d7:fa:55:f9:0e: + 54:eb:d8:6b:4e:bc:e9:0d:38:ea:da:c4:81:23:2c:84:bd:8b: + 65:e3:80:ad:26:ce:a9:e5:21:65:59:5c:e7:44:75:a3:d5:c5: + 2d:70:30:48:55:76:64:58:dd:a5:6a:77:3c:e5:46:aa:54:49: + a9:cd:48:f7:7b:ac:36:01:4a:61:aa:f3:3b:0b:fe:9f:56:5a: + ba:51:e4:33:2e:00 +-----BEGIN CERTIFICATE----- +MIICjzCCAg+gAwIBAgIBATAFBgMrZXEwgZkxCzAJBgNVBAYTAlVTMRAwDgYDVQQI +DAdNb250YW5hMRAwDgYDVQQHDAdCb3plbWFuMRYwFAYDVQQKDA13b2xmU1NMX0Vk +NDQ4MRMwEQYDVQQLDApSb290LUVkNDQ4MRgwFgYDVQQDDA93d3cud29sZnNzbC5j +b20xHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20wHhcNMjAwMjEzMDEz +NTQ0WhcNMjIxMTA5MDEzNTQ0WjCBlzELMAkGA1UEBhMCVVMxEDAOBgNVBAgMB01v +bnRhbmExEDAOBgNVBAcMB0JvemVtYW4xFjAUBgNVBAoMDXdvbGZTU0xfZWQ0NDgx +ETAPBgNVBAsMCENBLWVkNDQ4MRgwFgYDVQQDDA93d3cud29sZnNzbC5jb20xHzAd +BgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb20wQzAFBgMrZXEDOgAO4rR25dLM +wkt7sCm+kvvDr2mllLpwJOij78hjmt2mr1hDOAQk8BCRvqcBkVTzz2mFTLmXjKQ3 +qgCjYzBhMB0GA1UdDgQWBBQ4WUXo3UQstX2lJdYLzDnwcsCUYzAfBgNVHSMEGDAW +gBTaaZjJJkp1+1leU5pjSwy4iAsPHjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB +/wQEAwIBhjAFBgMrZXEDcwCglMHe8H9Asoh39/d72kKzP/YyV6npQX9RUxzzXtV3 +1/pV+Q5U69hrTrzpDTjq2sSBIyyEvYtl44CtJs6p5SFlWVznRHWj1cUtcDBIVXZk +WN2lanc85UaqVEmpzUj3e6w2AUphqvM7C/6fVlq6UeQzLgA= +-----END CERTIFICATE----- diff --git a/certs/ed448/client-ed448-key.der b/certs/ed448/client-ed448-key.der new file mode 100644 index 0000000000000000000000000000000000000000..7151dce842c64291f76172ed22fdb110f1a43466 GIT binary patch literal 69 zcmXqTHeh9A)=n*Cwqg)C(4^nX^(Iv)$iZ?|RYFFep_1p?*$4j=KDDa|H$73dd9y)( ad&M)gDD@jW7W1lYg!RuX(adRh-v9tiv>Sf_ literal 0 HcmV?d00001 diff --git a/certs/ed448/client-ed448-key.pem b/certs/ed448/client-ed448-key.pem new file mode 100644 index 000000000..606313935 --- /dev/null +++ b/certs/ed448/client-ed448-key.pem @@ -0,0 +1,4 @@ +-----BEGIN PUBLIC KEY----- +MEMwBQYDK2VxAzoAEMCCL40K7GUSUkA5qnpgaI4xIkmtm8H8ceU+eFc1yHazszCP +h3jmJlon2Aw4nns8Ey/MpClsgO+A +-----END PUBLIC KEY----- diff --git a/certs/ed448/client-ed448-priv.der b/certs/ed448/client-ed448-priv.der new file mode 100644 index 0000000000000000000000000000000000000000..2bc7530dafafdc745d8f795326472f85a87e32d4 GIT binary patch literal 73 zcmXqTXJTY9U}a<0PAz1yX0d#<@KxZ>%}Ts)6Q3$Re!l5CU*kig--=IsHnQKgnqzYD gmDYCdYQuxOH;eC^kiqt;QDEm;M1& literal 0 HcmV?d00001 diff --git a/certs/ed448/client-ed448-priv.pem b/certs/ed448/client-ed448-priv.pem new file mode 100644 index 000000000..ac2c00c6e --- /dev/null +++ b/certs/ed448/client-ed448-priv.pem @@ -0,0 +1,4 @@ +-----BEGIN PRIVATE KEY----- +MEcCAQAwBQYDK2VxBDsEOeKh6lG5syIN7WHlIePnstcOgeEy+yHkTLEH2zqcNNHq +KrcLezHBu7MXvpBoBvKBELmtS4gZhOX7nQ== +-----END PRIVATE KEY----- diff --git a/certs/ed448/client-ed448.der b/certs/ed448/client-ed448.der new file mode 100644 index 0000000000000000000000000000000000000000..667cabab0f8858bfd49747b7bef2e2d866ec44c9 GIT binary patch literal 882 zcmXqLV$L&YVtTiLnTe5!Nkpn_+v>C7_wI%l&Z}B~Ax}Z#-us^htZdBMsf7lOvkkco zIN6v(S=fY`LW2zj4ER7C4jy*j{JfIHyhNA?I}f{4epPC2VxFOxfe1(q7Y}cFeok6& zuuptyiiwGZp{Ri{NSvF8$2li6HLpY$A}nDb1`=lG;V&;Q*8^!OF3!_Z5T2 z+aP&mmd48ljTaiQs#(~$a7p95!5wBz*b^%c$aBIhtOm@CjQ_#ONmh`B-+;G?JGCM) zw;(4Kl$>CpUChwkIm^L(sa4m5RhO3E)0*3|ug_`y_1|LE)lZl_**6*H&R%MMI<`B0 z>%!c(Q)8F2MISZ%_IX9Bq!xpYTkYPOuqMWSYgLO2)Ayx*$T<4Pb+c9&>mGfBWgh1H fxi(+7IQ60BhW3~4FeCMqKOSY>nx%HyU6%m>-$V{A literal 0 HcmV?d00001 diff --git a/certs/ed448/client-ed448.pem b/certs/ed448/client-ed448.pem new file mode 100644 index 000000000..7cd3d70d1 --- /dev/null +++ b/certs/ed448/client-ed448.pem @@ -0,0 +1,60 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 1a:76:b6:ab:cd:57:de:dd:57:71:9e:7a:af:d0:6e:20:18:de:ef:f9 + Signature Algorithm: ED448 + Issuer: C = US, ST = Montana, L = Bozeman, O = wolfSSL_ed448, OU = Client-ed448, CN = www.wolfssl.com, emailAddress = info@wolfssl.com + Validity + Not Before: Feb 13 01:35:44 2020 GMT + Not After : Nov 9 01:35:44 2022 GMT + Subject: C = US, ST = Montana, L = Bozeman, O = wolfSSL_ed448, OU = Client-ed448, CN = www.wolfssl.com, emailAddress = info@wolfssl.com + Subject Public Key Info: + Public Key Algorithm: ED448 + ED448 Public-Key: + pub: + 10:c0:82:2f:8d:0a:ec:65:12:52:40:39:aa:7a:60: + 68:8e:31:22:49:ad:9b:c1:fc:71:e5:3e:78:57:35: + c8:76:b3:b3:30:8f:87:78:e6:26:5a:27:d8:0c:38: + 9e:7b:3c:13:2f:cc:a4:29:6c:80:ef:80 + X509v3 extensions: + X509v3 Subject Key Identifier: + F3:C7:66:93:0D:CB:0E:1B:80:08:00:CF:E3:4E:11:4D:58:2B:4B:D4 + X509v3 Authority Key Identifier: + keyid:F3:C7:66:93:0D:CB:0E:1B:80:08:00:CF:E3:4E:11:4D:58:2B:4B:D4 + DirName:/C=US/ST=Montana/L=Bozeman/O=wolfSSL_ed448/OU=Client-ed448/CN=www.wolfssl.com/emailAddress=info@wolfssl.com + serial:1A:76:B6:AB:CD:57:DE:DD:57:71:9E:7A:AF:D0:6E:20:18:DE:EF:F9 + + X509v3 Basic Constraints: + CA:TRUE + X509v3 Subject Alternative Name: + DNS:example.com + Signature Algorithm: ED448 + 8b:89:9a:40:37:a5:3a:8a:e0:aa:d2:a7:de:2a:9d:84:be:8e: + 42:af:d7:fb:16:7b:7b:e4:02:49:07:b2:31:6d:9b:a5:37:cb: + 5d:8b:5f:b5:a1:6d:ed:95:5d:a7:06:5b:c5:31:f6:f3:a8:65: + 19:2a:00:2c:46:7d:bd:7c:56:82:01:8f:3b:25:38:d0:97:be: + 65:f0:68:c5:fc:45:b3:2a:56:05:bc:2f:30:a6:48:37:bf:0a: + b3:d7:38:ca:f0:84:d8:2b:f4:8b:56:32:27:a9:f8:e2:6a:da: + 9a:26:cb:47:2d:00 +-----BEGIN CERTIFICATE----- +MIIDbjCCAu6gAwIBAgIUGna2q81X3t1XcZ56r9BuIBje7/kwBQYDK2VxMIGbMQsw +CQYDVQQGEwJVUzEQMA4GA1UECAwHTW9udGFuYTEQMA4GA1UEBwwHQm96ZW1hbjEW +MBQGA1UECgwNd29sZlNTTF9lZDQ0ODEVMBMGA1UECwwMQ2xpZW50LWVkNDQ4MRgw +FgYDVQQDDA93d3cud29sZnNzbC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29s +ZnNzbC5jb20wHhcNMjAwMjEzMDEzNTQ0WhcNMjIxMTA5MDEzNTQ0WjCBmzELMAkG +A1UEBhMCVVMxEDAOBgNVBAgMB01vbnRhbmExEDAOBgNVBAcMB0JvemVtYW4xFjAU +BgNVBAoMDXdvbGZTU0xfZWQ0NDgxFTATBgNVBAsMDENsaWVudC1lZDQ0ODEYMBYG +A1UEAwwPd3d3LndvbGZzc2wuY29tMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZz +c2wuY29tMEMwBQYDK2VxAzoAEMCCL40K7GUSUkA5qnpgaI4xIkmtm8H8ceU+eFc1 +yHazszCPh3jmJlon2Aw4nns8Ey/MpClsgO+Ao4IBJzCCASMwHQYDVR0OBBYEFPPH +ZpMNyw4bgAgAz+NOEU1YK0vUMIHbBgNVHSMEgdMwgdCAFPPHZpMNyw4bgAgAz+NO +EU1YK0vUoYGhpIGeMIGbMQswCQYDVQQGEwJVUzEQMA4GA1UECAwHTW9udGFuYTEQ +MA4GA1UEBwwHQm96ZW1hbjEWMBQGA1UECgwNd29sZlNTTF9lZDQ0ODEVMBMGA1UE +CwwMQ2xpZW50LWVkNDQ4MRgwFgYDVQQDDA93d3cud29sZnNzbC5jb20xHzAdBgkq +hkiG9w0BCQEWEGluZm9Ad29sZnNzbC5jb22CFBp2tqvNV97dV3Geeq/QbiAY3u/5 +MAwGA1UdEwQFMAMBAf8wFgYDVR0RBA8wDYILZXhhbXBsZS5jb20wBQYDK2VxA3MA +i4maQDelOorgqtKn3iqdhL6OQq/X+xZ7e+QCSQeyMW2bpTfLXYtftaFt7ZVdpwZb +xTH286hlGSoALEZ9vXxWggGPOyU40Je+ZfBoxfxFsypWBbwvMKZIN78Ks9c4yvCE +2Cv0i1YyJ6n44mramibLRy0A +-----END CERTIFICATE----- diff --git a/certs/ed448/gen-ed448-certs.sh b/certs/ed448/gen-ed448-certs.sh new file mode 100755 index 000000000..af51bd232 --- /dev/null +++ b/certs/ed448/gen-ed448-certs.sh @@ -0,0 +1,105 @@ +#!/bin/bash + +check_result(){ + if [ $1 -ne 0 ]; then + echo "Failed at \"$2\", Abort" + exit 1 + else + echo "Step Succeeded!" + fi +} + +openssl pkey -in root-ed448-priv.pem -noout >/dev/null 2>&1 +if [ $? -ne 0 ]; then + echo "OpenSSL does not support Ed448" + echo "Skipping Ed448 certificate renewal" + exit 0 +fi + +############################################################ +###### update the self-signed root-ed448.pem ############### +############################################################ +echo "Updating root-ed448.pem" +echo "" +#pipe the following arguments to openssl req... +echo -e "US\\nMontana\\nBozeman\\nwolfSSL_Ed448\\nRoot-Ed448\\nwww.wolfssl.com\\ninfo@wolfssl.com\\n.\\n.\\n" | \ +openssl req -new -key root-ed448-priv.pem -config ../renewcerts/wolfssl.cnf -nodes -out root-ed448.csr +check_result $? "Generate request" + +openssl x509 -req -in root-ed448.csr -days 1000 -extfile ../renewcerts/wolfssl.cnf -extensions ca_ecc_cert -signkey root-ed448-priv.pem -out root-ed448.pem +check_result $? "Generate certificate" +rm root-ed448.csr + +openssl x509 -in root-ed448.pem -outform DER > root-ed448.der +check_result $? "Convert to DER" +openssl x509 -in root-ed448.pem -text > tmp.pem +check_result $? "Add text" +mv tmp.pem root-ed448.pem +echo "End of section" +echo "---------------------------------------------------------------------" + +############################################################ +###### update ca-ed448.pem signed by root ################## +############################################################ +echo "Updating ca-ed448.pem" +echo "" +#pipe the following arguments to openssl req... +echo -e "US\\nMontana\\nBozeman\\nwolfSSL_ed448\\nCA-ed448\\nwww.wolfssl.com\\ninfo@wolfssl.com\\n\\n\\n\\n" | openssl req -new -key ca-ed448-priv.pem -config ../renewcerts/wolfssl.cnf -nodes -out ca-ed448.csr +check_result $? "Generate request" + +openssl x509 -req -in ca-ed448.csr -days 1000 -extfile ../renewcerts/wolfssl.cnf -extensions ca_ecc_cert -CA root-ed448.pem -CAkey root-ed448-priv.pem -set_serial 01 -out ca-ed448.pem +check_result $? "Generate certificate" +rm ca-ed448.csr + +openssl x509 -in ca-ed448.pem -outform DER > ca-ed448.der +check_result $? "Convert to DER" +openssl x509 -in ca-ed448.pem -text > tmp.pem +check_result $? "Add text" +mv tmp.pem ca-ed448.pem +echo "End of section" +echo "---------------------------------------------------------------------" + +############################################################ +###### update server-ed448.pem signed by ca ################ +############################################################ +echo "Updating server-ed448.pem" +echo "" +#pipe the following arguments to openssl req... +echo -e "US\\nMontana\\nBozeman\\nwolfSSL_ed448\\nServer-ed448\\nwww.wolfssl.com\\ninfo@wolfssl.com\\n\\n\\n\\n" | openssl req -new -key server-ed448-priv.pem -config ../renewcerts/wolfssl.cnf -nodes -out server-ed448.csr +check_result $? "Generate request" + +openssl x509 -req -in server-ed448.csr -days 1000 -extfile ../renewcerts/wolfssl.cnf -extensions server_ecc -CA ca-ed448.pem -CAkey ca-ed448-priv.pem -set_serial 01 -out server-ed448-cert.pem +check_result $? "Generate certificate" +rm server-ed448.csr + +openssl x509 -in server-ed448-cert.pem -outform DER > server-ed448.der +check_result $? "Convert to DER" +openssl x509 -in server-ed448-cert.pem -text > tmp.pem +check_result $? "Add text" +mv tmp.pem server-ed448-cert.pem +cat server-ed448-cert.pem ca-ed448.pem > server-ed448.pem +check_result $? "Add CA into server cert" +echo "End of section" +echo "---------------------------------------------------------------------" + +############################################################ +###### update the self-signed client-ed448.pem ############# +############################################################ +echo "Updating client-ed448.pem" +echo "" +#pipe the following arguments to openssl req... +echo -e "US\\nMontana\\nBozeman\\nwolfSSL_ed448\\nClient-ed448\\nwww.wolfssl.com\\ninfo@wolfssl.com\\n\\n\\n\\n" | openssl req -new -key client-ed448-priv.pem -config ../renewcerts/wolfssl.cnf -nodes -out client-ed448.csr +check_result $? "Generate request" + +openssl x509 -req -in client-ed448.csr -days 1000 -extfile ../renewcerts/wolfssl.cnf -extensions wolfssl_opts -signkey client-ed448-priv.pem -out client-ed448.pem +check_result $? "Generate certificate" +rm client-ed448.csr + +openssl x509 -in client-ed448.pem -outform DER > client-ed448.der +check_result $? "Convert to DER" +openssl x509 -in client-ed448.pem -text > tmp.pem +check_result $? "Add text" +mv tmp.pem client-ed448.pem +echo "End of section" +echo "---------------------------------------------------------------------" + diff --git a/certs/ed448/gen-ed448-keys.sh b/certs/ed448/gen-ed448-keys.sh new file mode 100755 index 000000000..fc6cb1d49 --- /dev/null +++ b/certs/ed448/gen-ed448-keys.sh @@ -0,0 +1,16 @@ +#!/bin/sh + +for key in root ca server client +do + + openssl genpkey -algorithm ED448 > ${key}-ed448-priv.pem + + openssl pkey -in ${key}-ed448-priv.pem -outform DER -out ${key}-ed448-priv.der + + openssl pkey -in ${key}-ed448-priv.pem -outform PEM -pubout -out ${key}-ed448-key.pem + + openssl pkey -in ${key}-ed448-priv.pem -outform DER -pubout -out ${key}-ed448-key.der + +done + + diff --git a/certs/ed448/include.am b/certs/ed448/include.am new file mode 100644 index 000000000..7ad7aefb8 --- /dev/null +++ b/certs/ed448/include.am @@ -0,0 +1,30 @@ +# vim:ft=automake +# All paths should be given relative to the root +# + +EXTRA_DIST += \ + certs/ed448/ca-ed448.der \ + certs/ed448/ca-ed448.pem \ + certs/ed448/ca-ed448-key.der \ + certs/ed448/ca-ed448-key.pem \ + certs/ed448/ca-ed448-priv.der \ + certs/ed448/ca-ed448-priv.pem \ + certs/ed448/client-ed448.der \ + certs/ed448/client-ed448.pem \ + certs/ed448/client-ed448-key.der \ + certs/ed448/client-ed448-key.pem \ + certs/ed448/client-ed448-priv.der \ + certs/ed448/client-ed448-priv.pem \ + certs/ed448/root-ed448.der \ + certs/ed448/root-ed448.pem \ + certs/ed448/root-ed448-key.der \ + certs/ed448/root-ed448-key.pem \ + certs/ed448/root-ed448-priv.der \ + certs/ed448/root-ed448-priv.pem \ + certs/ed448/server-ed448.der \ + certs/ed448/server-ed448.pem \ + certs/ed448/server-ed448-cert.pem \ + certs/ed448/server-ed448-key.der \ + certs/ed448/server-ed448-key.pem \ + certs/ed448/server-ed448-priv.der \ + certs/ed448/server-ed448-priv.pem diff --git a/certs/ed448/root-ed448-key.der b/certs/ed448/root-ed448-key.der new file mode 100644 index 0000000000000000000000000000000000000000..84319039090e939f3bdafc532cfeb50cde4b7786 GIT binary patch literal 69 zcmXqTHeh9A)=n*CwqoE;QPViT)ou1W`&ZUq)2fWF{Hy)Z5FZhqbG`Ci+9KPK{$7st ar*}9{35b0foRoQ@v}swK%PH?@ZUz9ti5=nq literal 0 HcmV?d00001 diff --git a/certs/ed448/root-ed448-key.pem b/certs/ed448/root-ed448-key.pem new file mode 100644 index 000000000..95630424c --- /dev/null +++ b/certs/ed448/root-ed448-key.pem @@ -0,0 +1,4 @@ +-----BEGIN PUBLIC KEY----- +MEMwBQYDK2VxAzoAC2QmKM+1RpvuP+o79WZ6MtT+ffiAX1hXbNd57maiPVSPjQiv +y7hDlFBd5VNiach1gqZeRMpLWwsA +-----END PUBLIC KEY----- diff --git a/certs/ed448/root-ed448-priv.der b/certs/ed448/root-ed448-priv.der new file mode 100644 index 0000000000000000000000000000000000000000..41480571fc6e9011ca5af4b57bd0c47ce8fce139 GIT binary patch literal 73 zcmXqTXJTY9U}a<0PAz1yX0hanPkq}sk;VP(F@H<_*47-M1)`g)H1e*mTlCQ_VpFNv euD?CHieWY%cK4gtJESx(n&9DjRLW>2%P9bXh8#`+ literal 0 HcmV?d00001 diff --git a/certs/ed448/root-ed448-priv.pem b/certs/ed448/root-ed448-priv.pem new file mode 100644 index 000000000..0b28472a5 --- /dev/null +++ b/certs/ed448/root-ed448-priv.pem @@ -0,0 +1,4 @@ +-----BEGIN PRIVATE KEY----- +MEcCAQAwBQYDK2VxBDsEOQxfZe2BkQRH7cZPOS+FhWwSoBWzeihu166i8UZYsnU2 +uv2MLSFWPPC7jzd/QGSDopBIRcUaMqkEyg== +-----END PRIVATE KEY----- diff --git a/certs/ed448/root-ed448.der b/certs/ed448/root-ed448.der new file mode 100644 index 0000000000000000000000000000000000000000..181a58397f85b15c5504a59cffad1ebd73c9e4ec GIT binary patch literal 680 zcmXqLVp?L*#H6x-nTe5!NyO*v{InOxz8uPp-E&Li`^&^hzk6>Ou(C00rxqGC&NSpU z;ACSCWnmL$3Jo?CFyI4mIC$87^Ycm)^Aceq>^$sF`Bka8iFt-%1|lFeTs*wx`8jF9 z!9MY>DJCWshQbDdAaQOUuAuz<5?zR(gn<}HkeP?Syu4fwq@lPtM=v=)*HGR-mW@-Z z&7f3f=1x;vi9T#lSs3n7QGkV!+au^6D;5 z@#n5AU$Q^WnxRdmZ@HJhw@R|iA3rwB^(?h5^=T`gynMcEd;1IZ8mX(Hwsm_a7%%_; D=_b;l literal 0 HcmV?d00001 diff --git a/certs/ed448/root-ed448.pem b/certs/ed448/root-ed448.pem new file mode 100644 index 000000000..8cfaf623f --- /dev/null +++ b/certs/ed448/root-ed448.pem @@ -0,0 +1,54 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + 4c:ed:9f:66:e8:c6:f4:c2:6d:5d:bc:da:14:f7:e9:61:92:fb:8d:d8 + Signature Algorithm: ED448 + Issuer: C = US, ST = Montana, L = Bozeman, O = wolfSSL_Ed448, OU = Root-Ed448, CN = www.wolfssl.com, emailAddress = info@wolfssl.com + Validity + Not Before: Feb 13 01:35:44 2020 GMT + Not After : Nov 9 01:35:44 2022 GMT + Subject: C = US, ST = Montana, L = Bozeman, O = wolfSSL_Ed448, OU = Root-Ed448, CN = www.wolfssl.com, emailAddress = info@wolfssl.com + Subject Public Key Info: + Public Key Algorithm: ED448 + ED448 Public-Key: + pub: + 0b:64:26:28:cf:b5:46:9b:ee:3f:ea:3b:f5:66:7a: + 32:d4:fe:7d:f8:80:5f:58:57:6c:d7:79:ee:66:a2: + 3d:54:8f:8d:08:af:cb:b8:43:94:50:5d:e5:53:62: + 69:c8:75:82:a6:5e:44:ca:4b:5b:0b:00 + X509v3 extensions: + X509v3 Subject Key Identifier: + DA:69:98:C9:26:4A:75:FB:59:5E:53:9A:63:4B:0C:B8:88:0B:0F:1E + X509v3 Authority Key Identifier: + keyid:DA:69:98:C9:26:4A:75:FB:59:5E:53:9A:63:4B:0C:B8:88:0B:0F:1E + + X509v3 Basic Constraints: critical + CA:TRUE + X509v3 Key Usage: critical + Digital Signature, Certificate Sign, CRL Sign + Signature Algorithm: ED448 + 32:f2:95:d6:56:9f:c4:5c:2a:36:da:51:b7:96:cb:97:f7:c5: + 02:f2:20:f4:20:fa:a8:25:6f:dc:f9:c4:b7:ac:be:39:68:3b: + 9e:58:4a:42:c3:74:e2:55:bd:44:54:40:18:7c:d4:30:47:6f: + 53:03:80:c9:21:50:a5:e9:1f:27:44:42:5f:ce:d4:a7:a4:bf: + 5e:3b:00:86:1c:8e:a7:4a:4f:4b:24:63:1c:fc:4e:06:39:af: + 04:7d:84:7f:66:a9:e4:e9:e7:ba:b7:87:e8:27:7c:1a:d5:55: + 3d:7e:bd:90:30:00 +-----BEGIN CERTIFICATE----- +MIICpDCCAiSgAwIBAgIUTO2fZujG9MJtXbzaFPfpYZL7jdgwBQYDK2VxMIGZMQsw +CQYDVQQGEwJVUzEQMA4GA1UECAwHTW9udGFuYTEQMA4GA1UEBwwHQm96ZW1hbjEW +MBQGA1UECgwNd29sZlNTTF9FZDQ0ODETMBEGA1UECwwKUm9vdC1FZDQ0ODEYMBYG +A1UEAwwPd3d3LndvbGZzc2wuY29tMR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZz +c2wuY29tMB4XDTIwMDIxMzAxMzU0NFoXDTIyMTEwOTAxMzU0NFowgZkxCzAJBgNV +BAYTAlVTMRAwDgYDVQQIDAdNb250YW5hMRAwDgYDVQQHDAdCb3plbWFuMRYwFAYD +VQQKDA13b2xmU1NMX0VkNDQ4MRMwEQYDVQQLDApSb290LUVkNDQ4MRgwFgYDVQQD +DA93d3cud29sZnNzbC5jb20xHzAdBgkqhkiG9w0BCQEWEGluZm9Ad29sZnNzbC5j +b20wQzAFBgMrZXEDOgALZCYoz7VGm+4/6jv1Znoy1P59+IBfWFds13nuZqI9VI+N +CK/LuEOUUF3lU2JpyHWCpl5EyktbCwCjYzBhMB0GA1UdDgQWBBTaaZjJJkp1+1le +U5pjSwy4iAsPHjAfBgNVHSMEGDAWgBTaaZjJJkp1+1leU5pjSwy4iAsPHjAPBgNV +HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAFBgMrZXEDcwAy8pXWVp/EXCo2 +2lG3lsuX98UC8iD0IPqoJW/c+cS3rL45aDueWEpCw3TiVb1EVEAYfNQwR29TA4DJ +IVCl6R8nREJfztSnpL9eOwCGHI6nSk9LJGMc/E4GOa8EfYR/Zqnk6ee6t4foJ3wa +1VU9fr2QMAA= +-----END CERTIFICATE----- diff --git a/certs/ed448/server-ed448-cert.pem b/certs/ed448/server-ed448-cert.pem new file mode 100644 index 000000000..c239c13db --- /dev/null +++ b/certs/ed448/server-ed448-cert.pem @@ -0,0 +1,57 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 1 (0x1) + Signature Algorithm: ED448 + Issuer: C = US, ST = Montana, L = Bozeman, O = wolfSSL_ed448, OU = CA-ed448, CN = www.wolfssl.com, emailAddress = info@wolfssl.com + Validity + Not Before: Feb 13 01:35:44 2020 GMT + Not After : Nov 9 01:35:44 2022 GMT + Subject: C = US, ST = Montana, L = Bozeman, O = wolfSSL_ed448, OU = Server-ed448, CN = www.wolfssl.com, emailAddress = info@wolfssl.com + Subject Public Key Info: + Public Key Algorithm: ED448 + ED448 Public-Key: + pub: + 54:81:39:01:eb:37:d9:a9:07:cd:01:bc:9d:70:16: + c2:2c:2b:75:5b:63:db:ee:3a:2d:44:92:46:b4:7b: + 07:03:4f:a2:ae:86:86:dc:8b:4b:2c:7f:e8:6b:14: + 8d:58:dd:6d:e7:6f:3a:05:95:a8:ef:00 + X509v3 extensions: + X509v3 Subject Key Identifier: + 7C:AB:5C:12:A9:68:D8:18:10:28:7D:92:C5:4A:B8:4C:4C:76:0E:DB + X509v3 Authority Key Identifier: + keyid:38:59:45:E8:DD:44:2C:B5:7D:A5:25:D6:0B:CC:39:F0:72:C0:94:63 + + X509v3 Basic Constraints: critical + CA:FALSE + X509v3 Key Usage: critical + Digital Signature, Key Encipherment, Key Agreement + X509v3 Extended Key Usage: + TLS Web Server Authentication + Netscape Cert Type: + SSL Server + Signature Algorithm: ED448 + 91:15:fc:8e:a6:00:50:bf:8e:44:4e:14:39:a3:91:29:12:25: + a5:8b:42:5b:85:a0:c3:d7:b3:6a:1b:4c:d9:4f:20:5a:92:5b: + 58:2a:f4:86:21:35:0b:d6:a5:b1:ca:98:6a:cb:09:c7:98:a5: + 22:b6:00:a2:ef:81:19:4f:4d:28:4e:80:47:6a:3c:82:88:84: + 8b:03:99:48:5b:cc:c4:75:98:b2:70:b1:93:6c:24:a7:8e:01: + 6a:2f:15:53:25:c2:45:5c:b6:25:db:17:93:fb:9c:1d:0f:c6: + a6:88:70:44:2e:00 +-----BEGIN CERTIFICATE----- +MIICuDCCAjigAwIBAgIBATAFBgMrZXEwgZcxCzAJBgNVBAYTAlVTMRAwDgYDVQQI +DAdNb250YW5hMRAwDgYDVQQHDAdCb3plbWFuMRYwFAYDVQQKDA13b2xmU1NMX2Vk +NDQ4MREwDwYDVQQLDAhDQS1lZDQ0ODEYMBYGA1UEAwwPd3d3LndvbGZzc2wuY29t +MR8wHQYJKoZIhvcNAQkBFhBpbmZvQHdvbGZzc2wuY29tMB4XDTIwMDIxMzAxMzU0 +NFoXDTIyMTEwOTAxMzU0NFowgZsxCzAJBgNVBAYTAlVTMRAwDgYDVQQIDAdNb250 +YW5hMRAwDgYDVQQHDAdCb3plbWFuMRYwFAYDVQQKDA13b2xmU1NMX2VkNDQ4MRUw +EwYDVQQLDAxTZXJ2ZXItZWQ0NDgxGDAWBgNVBAMMD3d3dy53b2xmc3NsLmNvbTEf +MB0GCSqGSIb3DQEJARYQaW5mb0B3b2xmc3NsLmNvbTBDMAUGAytlcQM6AFSBOQHr +N9mpB80BvJ1wFsIsK3VbY9vuOi1Ekka0ewcDT6Kuhobci0ssf+hrFI1Y3W3nbzoF +lajvAKOBiTCBhjAdBgNVHQ4EFgQUfKtcEqlo2BgQKH2SxUq4TEx2DtswHwYDVR0j +BBgwFoAUOFlF6N1ELLV9pSXWC8w58HLAlGMwDAYDVR0TAQH/BAIwADAOBgNVHQ8B +Af8EBAMCA6gwEwYDVR0lBAwwCgYIKwYBBQUHAwEwEQYJYIZIAYb4QgEBBAQDAgZA +MAUGAytlcQNzAJEV/I6mAFC/jkROFDmjkSkSJaWLQluFoMPXs2obTNlPIFqSW1gq +9IYhNQvWpbHKmGrLCceYpSK2AKLvgRlPTShOgEdqPIKIhIsDmUhbzMR1mLJwsZNs +JKeOAWovFVMlwkVctiXbF5P7nB0PxqaIcEQuAA== +-----END CERTIFICATE----- diff --git a/certs/ed448/server-ed448-key.der b/certs/ed448/server-ed448-key.der new file mode 100644 index 0000000000000000000000000000000000000000..4804c53be3e4e31726f53d83466aca90b53bd484 GIT binary patch literal 69 zcmXqTHeh9A)=n*Cwqgirv}Am3esd-JS;jqc3&alTXqQGO-+pJM>oUo0OEo*Q|Dttm aZFjo8b?RSai}Xg^&3&G4#X5Dxdj{*iA!s(UNcVB@=$=NEWvR=}R`cd+CQML_AZTFsXm* f13w|v&xtz1`}SX+D;9J5vQXWYZ>xSOPTdaxfWsZ3 literal 0 HcmV?d00001 diff --git a/certs/ed448/server-ed448-priv.pem b/certs/ed448/server-ed448-priv.pem new file mode 100644 index 000000000..9be220d0e --- /dev/null +++ b/certs/ed448/server-ed448-priv.pem @@ -0,0 +1,4 @@ +-----BEGIN PRIVATE KEY----- +MEcCAQAwBQYDK2VxBDsEOZjjRigtoqT2f3SQ+CwZc4ZSLxmBR0ovViBY5iOQko+1 +4E4SJfNhLBO+v9OdFlzL0xJ+tPaq+iGVvw== +-----END PRIVATE KEY----- diff --git a/certs/ed448/server-ed448.der b/certs/ed448/server-ed448.der new file mode 100644 index 0000000000000000000000000000000000000000..c9971b413037bc0add36d48b3549da9f876c3d11 GIT binary patch literal 700 zcmXqLV%lNQ#ALC6nTe5!iILHOm5o_Dwa}n(x*@j#CmVAp3!5-gXt1Gx0UwCN!NcyG zpI4HYmk1MK=V5osuS(5L%rg`-5CN&-;^8gN&q)go_K8nTF)^_)6g1!miF5OCI6LY> zgd_~aKtjws{N?54dLZS+#W{M(`MHMj2C{6NT5TR}-+3818N~!L^V0GikQ5lmiSrs6 z7#JBE8yFg!nwUh1^BNf$8X8zaxdx51spoQ017VOexp{bkQ;W({izs)!Gch{F>KLJw88;*ZG-@Xu_1fX%Q^t4OKprHm%pzeR z)*xaL>H6ZXi_X^CrK;Ds&scsaIxr>KfCr>Nn33^63zGo@IC^FIK|B^_Cgv4jkISmE z@ECBhacHwKva+%>Ga3l8aVE5RFt+`0Vq|1tVP;};fO)5wVWQ}tzGVyn`} diff --git a/cyassl/openssl/ed448.h b/cyassl/openssl/ed448.h new file mode 100644 index 000000000..ebb9c6194 --- /dev/null +++ b/cyassl/openssl/ed448.h @@ -0,0 +1,3 @@ +/* ed448.h */ + +#include diff --git a/cyassl/openssl/include.am b/cyassl/openssl/include.am index c0a6d125f..a1b25c6b6 100644 --- a/cyassl/openssl/include.am +++ b/cyassl/openssl/include.am @@ -15,6 +15,8 @@ nobase_include_HEADERS+= \ cyassl/openssl/ec.h \ cyassl/openssl/ec25519.h \ cyassl/openssl/ed25519.h \ + cyassl/openssl/ec448.h \ + cyassl/openssl/ed448.h \ cyassl/openssl/engine.h \ cyassl/openssl/err.h \ cyassl/openssl/evp.h \ diff --git a/examples/client/client.c b/examples/client/client.c index de839b3e7..82cf47452 100644 --- a/examples/client/client.c +++ b/examples/client/client.c @@ -229,12 +229,14 @@ static void ShowVersions(void) } #ifdef WOLFSSL_TLS13 -static void SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519) +static void SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519, + int useX448) { int groups[3] = {0}; int count = 0; (void)useX25519; + (void)useX448; WOLFSSL_START(WC_FUNC_CLIENT_KEY_EXCHANGE_SEND); if (onlyKeyShare == 0 || onlyKeyShare == 2) { @@ -245,6 +247,14 @@ static void SetKeyShare(WOLFSSL* ssl, int onlyKeyShare, int useX25519) err_sys("unable to use curve x25519"); } else + #endif + #ifdef HAVE_CURVE448 + if (useX448) { + groups[count++] = WOLFSSL_ECC_X448; + if (wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_X448) != WOLFSSL_SUCCESS) + err_sys("unable to use curve x448"); + } + else #endif { #ifdef HAVE_ECC @@ -342,7 +352,7 @@ static const char* client_bench_conmsg[][5] = { static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port, int dtlsUDP, int dtlsSCTP, int benchmark, int resumeSession, int useX25519, - int helloRetry, int onlyKeyShare, int version, int earlyData) + int useX448, int helloRetry, int onlyKeyShare, int version, int earlyData) { /* time passed in number of connects give average */ int times = benchmark, skip = times * 0.1; @@ -362,6 +372,7 @@ static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port, (void)resumeSession; (void)useX25519; + (void)useX448; (void)helloRetry; (void)onlyKeyShare; (void)version; @@ -391,7 +402,7 @@ static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port, #ifdef WOLFSSL_TLS13 else if (version >= 4) { if (!helloRetry) - SetKeyShare(ssl, onlyKeyShare, useX25519); + SetKeyShare(ssl, onlyKeyShare, useX25519, useX448); else wolfSSL_NoKeyShares(ssl); } @@ -470,7 +481,8 @@ static int ClientBenchmarkConnections(WOLFSSL_CTX* ctx, char* host, word16 port, /* Measures throughput in kbps. Throughput = number of bytes */ static int ClientBenchmarkThroughput(WOLFSSL_CTX* ctx, char* host, word16 port, - int dtlsUDP, int dtlsSCTP, int block, size_t throughput, int useX25519) + int dtlsUDP, int dtlsSCTP, int block, size_t throughput, int useX25519, + int useX448) { double start, conn_time = 0, tx_time = 0, rx_time = 0; SOCKET_T sockfd; @@ -488,6 +500,7 @@ static int ClientBenchmarkThroughput(WOLFSSL_CTX* ctx, char* host, word16 port, } (void)useX25519; + (void)useX448; #ifdef WOLFSSL_TLS13 #ifdef HAVE_CURVE25519 if (useX25519) { @@ -497,6 +510,14 @@ static int ClientBenchmarkThroughput(WOLFSSL_CTX* ctx, char* host, word16 port, } } #endif + #ifdef HAVE_CURVE448 + if (useX448) { + if (wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_X448) + != WOLFSSL_SUCCESS) { + err_sys("unable to use curve x448"); + } + } + #endif #endif do { @@ -1000,6 +1021,9 @@ static const char* client_usage_msg[][59] = { #endif #ifdef HAVE_TRUSTED_CA "-5 Use Trusted CA Key Indication\n", /* 62 */ +#endif +#ifdef HAVE_CURVE448 + "-8 Use X448 for key exchange\n", /* 65 */ #endif NULL, }, @@ -1162,6 +1186,9 @@ static const char* client_usage_msg[][59] = { #endif #ifdef HAVE_TRUSTED_CA "-5 信頼できる認証局の鍵表示を使用する\n", /* 62 */ +#endif +#ifdef HAVE_CURVE448 + "-8 Use X448 for key exchange\n", /* 65 */ #endif NULL, }, @@ -1319,6 +1346,9 @@ static void Usage(void) #ifdef HAVE_TRUSTED_CA printf("%s", msg[++msgid]); /* -5 */ #endif +#ifdef HAVE_CURVE448 + printf("%s", msg[++msgid]); /* -8 */ +#endif } THREAD_RETURN WOLFSSL_THREAD client_test(void* args) @@ -1446,6 +1476,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) char* ocspUrl = NULL; #endif int useX25519 = 0; + int useX448 = 0; int exitWithRet = 0; int loadCertKeyIntoSSLObj = 0; @@ -1493,6 +1524,10 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) verifyCert = caEdCertFile; ourCert = cliEdCertFile; ourKey = cliEdKeyFile; + #elif defined(HAVE_ED448) + verifyCert = caEd448CertFile; + ourCert = cliEd448CertFile; + ourKey = cliEd448KeyFile; #else verifyCert = NULL; ourCert = NULL; @@ -1521,6 +1556,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) (void)updateKeysIVs; (void)earlyData; (void)useX25519; + (void)useX448; (void)helloRetry; (void)onlyKeyShare; (void)useSupCurve; @@ -1533,7 +1569,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) while ((ch = mygetopt(argc, argv, "?:" "ab:c:defgh:ijk:l:mnop:q:rstuv:wxyz" "A:B:CDE:F:GH:IJKL:M:NO:PQRS:TUVW:XYZ:" - "01:23:45")) != -1) { + "01:23:458")) != -1) { switch (ch) { case '?' : if(myoptarg!=NULL) { @@ -1971,6 +2007,18 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) #endif /* HAVE_TRUSTED_CA */ break; + case '8' : + #ifdef HAVE_CURVE448 + useX448 = 1; + #ifdef HAVE_ECC + useSupCurve = 1; + #ifdef WOLFSSL_TLS13 + onlyKeyShare = 2; + #endif + #endif + #endif + break; + default: Usage(); XEXIT_T(MY_EX_USAGE); @@ -2216,7 +2264,8 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) } #endif -#if defined(NO_RSA) && !defined(HAVE_ECC) && !defined(HAVE_ED25519) +#if defined(NO_RSA) && !defined(HAVE_ECC) && !defined(HAVE_ED25519) && \ + !defined(HAVE_ED448) if (!usePsk) { usePsk = 1; } @@ -2465,6 +2514,14 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) } } #endif /* HAVE_CURVE25519 */ + #if defined(HAVE_CURVE448) + if (useX448) { + if (wolfSSL_CTX_UseSupportedCurve(ctx, WOLFSSL_ECC_X448) + != WOLFSSL_SUCCESS) { + err_sys("unable to support X448"); + } + } + #endif /* HAVE_CURVE448 */ #ifdef HAVE_ECC if (useSupCurve) { #if !defined(NO_ECC_SECP) && \ @@ -2506,8 +2563,8 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) ((func_args*)args)->return_code = ClientBenchmarkConnections(ctx, host, port, dtlsUDP, dtlsSCTP, benchmark, resumeSession, useX25519, - helloRetry, onlyKeyShare, version, - earlyData); + useX448, helloRetry, onlyKeyShare, + version, earlyData); wolfSSL_CTX_free(ctx); ctx = NULL; XEXIT_T(EXIT_SUCCESS); } @@ -2515,7 +2572,7 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) if (throughput) { ((func_args*)args)->return_code = ClientBenchmarkThroughput(ctx, host, port, dtlsUDP, dtlsSCTP, - block, throughput, useX25519); + block, throughput, useX25519, useX448); wolfSSL_CTX_free(ctx); ctx = NULL; XEXIT_T(EXIT_SUCCESS); } @@ -2621,6 +2678,14 @@ THREAD_RETURN WOLFSSL_THREAD client_test(void* args) } } #endif + #ifdef HAVE_CURVE448 + if (useX448) { + if (wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_X448) + != WOLFSSL_SUCCESS) { + err_sys("unable to use curve x448"); + } + } + #endif #ifdef HAVE_ECC #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES) if (wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_SECP256R1) diff --git a/examples/echoclient/echoclient.c b/examples/echoclient/echoclient.c index 13a0a381f..c447ad88b 100644 --- a/examples/echoclient/echoclient.c +++ b/examples/echoclient/echoclient.c @@ -107,7 +107,8 @@ void echoclient_test(void* args) doPSK = 1; #endif -#if defined(NO_RSA) && !defined(HAVE_ECC) && !defined(HAVE_ED25519) +#if defined(NO_RSA) && !defined(HAVE_ECC) && !defined(HAVE_ED25519) && \ + !defined(HAVE_ED448) doPSK = 1; #endif @@ -137,6 +138,9 @@ void echoclient_test(void* args) #elif defined(HAVE_ED25519) if (SSL_CTX_load_verify_locations(ctx, caEdCertFile, 0) != WOLFSSL_SUCCESS) err_sys("can't load ca file, Please run from wolfSSL home dir"); + #elif defined(HAVE_ED448) + if (SSL_CTX_load_verify_locations(ctx, caEd448CertFile, 0) != WOLFSSL_SUCCESS) + err_sys("can't load ca file, Please run from wolfSSL home dir"); #endif #elif !defined(NO_CERTS) if (!doPSK) diff --git a/examples/echoserver/echoserver.c b/examples/echoserver/echoserver.c index a0cefb450..d268ab479 100644 --- a/examples/echoserver/echoserver.c +++ b/examples/echoserver/echoserver.c @@ -108,8 +108,8 @@ THREAD_RETURN CYASSL_THREAD echoserver_test(void* args) doDTLS = 1; #endif -#if (defined(NO_RSA) && !defined(HAVE_ECC) && !defined(HAVE_ED25519)) || \ - defined(CYASSL_LEANPSK) +#if (defined(NO_RSA) && !defined(HAVE_ECC) && !defined(HAVE_ED25519) && \ + !defined(HAVE_ED448)) || defined(CYASSL_LEANPSK) doPSK = 1; #else doPSK = 0; @@ -193,6 +193,17 @@ THREAD_RETURN CYASSL_THREAD echoserver_test(void* args) != WOLFSSL_SUCCESS) err_sys("can't load server key file, " "Please run from wolfSSL home dir"); + #elif defined(HAVE_ED448) && !defined(CYASSL_SNIFFER) + /* ed448 */ + if (CyaSSL_CTX_use_certificate_chain_file(ctx, ed448CertFile) + != WOLFSSL_SUCCESS) + err_sys("can't load server cert file, " + "Please run from wolfSSL home dir"); + + if (CyaSSL_CTX_use_PrivateKey_file(ctx, ed448KeyFile, + WOLFSSL_FILETYPE_PEM) != WOLFSSL_SUCCESS) + err_sys("can't load server key file, " + "Please run from wolfSSL home dir"); #elif defined(NO_CERTS) /* do nothing, just don't load cert files */ #else diff --git a/examples/server/server.c b/examples/server/server.c index 7440d64df..b9350292a 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -631,6 +631,9 @@ static const char* server_usage_msg[][49] = { "\n 0: English, 1: Japanese\n", /* 49 */ #ifdef HAVE_TRUSTED_CA "-5 Use Trusted CA Key Indication\n", /* 52 */ +#endif +#ifdef HAVE_CURVE448 + "-8 Pre-generate Key share using Curve448 only\n", /* 55 */ #endif NULL, }, @@ -750,6 +753,9 @@ static const char* server_usage_msg[][49] = { "\n 0: 英語、 1: 日本語\n", /* 49 */ #ifdef HAVE_TRUSTED_CA "-5 信頼できる認証局の鍵表示を使用する\n", /* 52 */ +#endif +#ifdef HAVE_CURVE448 + "-8 Pre-generate Key share using Curve448 only\n", /* 55 */ #endif NULL, }, @@ -870,6 +876,9 @@ static void Usage(void) #ifdef HAVE_TRUSTED_CA printf("%s", msg[++msgId]); /* -5 */ #endif /* HAVE_TRUSTED_CA */ +#ifdef HAVE_CURVE448 + printf("%s", msg[++msgId]); /* -8 */ +#endif } THREAD_RETURN WOLFSSL_THREAD server_test(void* args) @@ -1013,6 +1022,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) int noTicket = 0; #endif int useX25519 = 0; + int useX448 = 0; int exitWithRet = 0; int loadCertKeyIntoSSLObj = 0; @@ -1035,6 +1045,10 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) verifyCert = cliEdCertFile; ourCert = edCertFile; ourKey = edKeyFile; + #elif defined(HAVE_ED448) + verifyCert = cliEd448CertFile; + ourCert = ed448CertFile; + ourKey = ed448KeyFile; #else verifyCert = NULL; ourCert = NULL; @@ -1074,7 +1088,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) while ((ch = mygetopt(argc, argv, "?:" "abc:defgijk:l:mnop:q:rstuv:wxy" "A:B:C:D:E:GH:IJKL:MNO:PQR:S:TUVYZ:" - "01:23:4:5")) != -1) { + "01:23:4:58")) != -1) { switch (ch) { case '?' : if(myoptarg!=NULL) { @@ -1455,6 +1469,15 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) #endif /* HAVE_TRUSTED_CA */ break; + case '8' : + #ifdef HAVE_CURVE448 + useX448 = 1; + #if defined(WOLFSSL_TLS13) && defined(HAVE_ECC) + onlyKeyShare = 2; + #endif + #endif + break; + default: Usage(); XEXIT_T(MY_EX_USAGE); @@ -1611,7 +1634,8 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) } #endif -#if defined(NO_RSA) && !defined(HAVE_ECC) && !defined(HAVE_ED25519) +#if defined(NO_RSA) && !defined(HAVE_ECC) && !defined(HAVE_ED25519) && \ + !defined(HAVE_ED448) if (!usePsk) { usePsk = 1; } @@ -2028,8 +2052,20 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) } #endif } - else - { + else if (useX448 == 1) { + #ifdef HAVE_CURVE448 + int groups[1] = { WOLFSSL_ECC_X448 }; + + if (wolfSSL_UseKeyShare(ssl, WOLFSSL_ECC_X448) + != WOLFSSL_SUCCESS) { + err_sys("unable to use curve x448"); + } + if (wolfSSL_set_groups(ssl, groups, 1) != WOLFSSL_SUCCESS) { + err_sys("unable to set groups: x448"); + } + #endif + } + else { #ifdef HAVE_ECC #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES) int groups[1] = { WOLFSSL_ECC_SECP256R1 }; @@ -2458,6 +2494,7 @@ exit: (void) ourDhParam; (void) ourCert; (void) useX25519; + (void) useX448; #ifdef HAVE_SECURE_RENEGOTIATION (void) forceScr; #endif diff --git a/src/include.am b/src/include.am index 3c18e190a..a7f20deac 100644 --- a/src/include.am +++ b/src/include.am @@ -462,6 +462,25 @@ endif endif endif +if BUILD_CURVE448 +src_libwolfssl_la_SOURCES += wolfcrypt/src/curve448.c +endif + +if BUILD_ED448 +src_libwolfssl_la_SOURCES += wolfcrypt/src/ed448.c +endif + +if BUILD_FE448 +src_libwolfssl_la_SOURCES += wolfcrypt/src/fe_448.c +endif + +if BUILD_GE448 +src_libwolfssl_la_SOURCES += wolfcrypt/src/ge_448.c +if !BUILD_FE448 +src_libwolfssl_la_SOURCES += wolfcrypt/src/fe_448.c +endif +endif + if BUILD_LIBZ src_libwolfssl_la_SOURCES += wolfcrypt/src/compress.c endif diff --git a/src/internal.c b/src/internal.c index 0d6fa1630..d73a881c7 100644 --- a/src/internal.c +++ b/src/internal.c @@ -111,8 +111,8 @@ WOLFSSL_CALLBACKS needs LARGE_STATIC_BUFFERS, please add LARGE_STATIC_BUFFERS #ifndef NO_WOLFSSL_SERVER static int DoClientKeyExchange(WOLFSSL* ssl, byte* input, word32*, word32); - #if (!defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519)) && \ - !defined(WOLFSSL_NO_CLIENT_AUTH) + #if (!defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519) || \ + defined(HAVE_ED448)) && !defined(WOLFSSL_NO_CLIENT_AUTH) static int DoCertificateVerify(WOLFSSL* ssl, byte*, word32*, word32); #endif #ifdef WOLFSSL_DTLS @@ -1599,7 +1599,7 @@ int InitSSL_Side(WOLFSSL* ssl, word16 side) ssl->options.haveECC = 1; /* server turns on with ECC key cert */ ssl->options.haveStaticECC = 1; /* server can turn on by loading key */ } -#elif defined(HAVE_ED25519) +#elif defined(HAVE_ED25519) || defined(HAVE_ED448) if (ssl->options.side == WOLFSSL_CLIENT_END) { ssl->options.haveECDSAsig = 1; /* always on client side */ ssl->options.haveECC = 1; /* server turns on with ECC key cert */ @@ -1731,7 +1731,7 @@ int InitSSL_Ctx(WOLFSSL_CTX* ctx, WOLFSSL_METHOD* method, void* heap) ctx->haveECC = 1; /* server turns on with ECC key cert */ ctx->haveStaticECC = 1; /* server can turn on by loading key */ } -#elif defined(HAVE_ED25519) +#elif defined(HAVE_ED25519) || defined(HAVE_ED448) if (method->side == WOLFSSL_CLIENT_END) { ctx->haveECDSAsig = 1; /* always on client side */ ctx->haveECC = 1; /* server turns on with ECC key cert */ @@ -2147,7 +2147,7 @@ void InitSuitesHashSigAlgo(Suites* suites, int haveECDSAsig, int haveRSAsig, (void)tls1_2; (void)keySz; -#if defined(HAVE_ECC) || defined(HAVE_ED25519) +#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) if (haveECDSAsig) { #ifdef HAVE_ECC #ifdef WOLFSSL_SHA512 @@ -2165,22 +2165,30 @@ void InitSuitesHashSigAlgo(Suites* suites, int haveECDSAsig, int haveRSAsig, #endif #endif #ifdef HAVE_ED25519 - AddSuiteHashSigAlgo(suites, ED25519_SA_MAJOR, ED25519_SA_MINOR, keySz, &idx); + AddSuiteHashSigAlgo(suites, ED25519_SA_MAJOR, ED25519_SA_MINOR, keySz, + &idx); + #endif + #ifdef HAVE_ED448 + AddSuiteHashSigAlgo(suites, ED448_SA_MAJOR, ED448_SA_MINOR, keySz, + &idx); #endif } -#endif /* HAVE_ECC || HAVE_ED25519 */ +#endif /* HAVE_ECC || HAVE_ED25519 || defined(HAVE_ED448 */ if (haveRSAsig) { #ifdef WC_RSA_PSS if (tls1_2) { #ifdef WOLFSSL_SHA512 - AddSuiteHashSigAlgo(suites, sha512_mac, rsa_pss_sa_algo, keySz, &idx); + AddSuiteHashSigAlgo(suites, sha512_mac, rsa_pss_sa_algo, keySz, + &idx); #endif #ifdef WOLFSSL_SHA384 - AddSuiteHashSigAlgo(suites, sha384_mac, rsa_pss_sa_algo, keySz, &idx); + AddSuiteHashSigAlgo(suites, sha384_mac, rsa_pss_sa_algo, keySz, + &idx); #endif #ifndef NO_SHA256 - AddSuiteHashSigAlgo(suites, sha256_mac, rsa_pss_sa_algo, keySz, &idx); + AddSuiteHashSigAlgo(suites, sha256_mac, rsa_pss_sa_algo, keySz, + &idx); #endif } #endif @@ -3240,6 +3248,15 @@ static WC_INLINE void DecodeSigAlg(const byte* input, byte* hashAlgo, byte* hsTy } else #endif + #ifdef HAVE_ED448 + /* ED448: 0x0808 */ + if (input[1] == ED448_SA_MINOR) { + *hsType = ed448_sa_algo; + /* Hash performed as part of sign/verify operation. */ + *hashAlgo = sha512_mac; + } + else + #endif #ifdef WC_RSA_PSS /* PSS PSS signatures: 0x080[9-b] */ if (input[1] >= pss_sha256 && input[1] <= pss_sha512) { @@ -3248,7 +3265,6 @@ static WC_INLINE void DecodeSigAlg(const byte* input, byte* hashAlgo, byte* hsTy } else #endif - /* ED448: 0x0808 */ { *hsType = input[0]; *hashAlgo = input[1]; @@ -3265,7 +3281,7 @@ static WC_INLINE void DecodeSigAlg(const byte* input, byte* hashAlgo, byte* hsTy #ifndef WOLFSSL_NO_TLS12 #if !defined(NO_WOLFSSL_SERVER) || !defined(NO_WOLFSSL_CLIENT) #if !defined(NO_DH) || defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ - (!defined(NO_RSA) && defined(WC_RSA_PSS)) + defined(HAVE_CURVE448) || (!defined(NO_RSA) && defined(WC_RSA_PSS)) static enum wc_HashType HashAlgoToType(int hashAlgo) { @@ -3463,6 +3479,13 @@ static WC_INLINE void EncodeSigAlg(byte hashAlgo, byte hsType, byte* output) (void)hashAlgo; break; #endif +#ifdef HAVE_ED448 + case ed448_sa_algo: + output[0] = ED448_SA_MAJOR; + output[1] = ED448_SA_MINOR; + (void)hashAlgo; + break; +#endif #ifndef NO_RSA case rsa_sa_algo: output[0] = hashAlgo; @@ -3476,7 +3499,6 @@ static WC_INLINE void EncodeSigAlg(byte hashAlgo, byte hsType, byte* output) break; #endif #endif - /* ED448: 0x0808 */ } (void)hashAlgo; (void)output; @@ -4593,6 +4615,305 @@ static int X25519MakeKey(WOLFSSL* ssl, curve25519_key* key, } #endif /* HAVE_CURVE25519 */ +#ifdef HAVE_ED448 +/* Check whether the key contains a public key. + * If not then pull it out of the leaf certificate. + * + * ssl SSL/TLS object. + * returns MEMORY_E when unable to allocate memory, a parsing error, otherwise + * 0 on success. + */ +int Ed448CheckPubKey(WOLFSSL* ssl) +{ + ed448_key* key = (ed448_key*)ssl->hsKey; + int ret = 0; + + /* Public key required for signing. */ + if (!key->pubKeySet) { + DerBuffer* leaf = ssl->buffers.certificate; + DecodedCert* cert = (DecodedCert*)XMALLOC(sizeof(*cert), ssl->heap, + DYNAMIC_TYPE_DCERT); + if (cert == NULL) + ret = MEMORY_E; + + if (ret == 0) { + InitDecodedCert(cert, leaf->buffer, leaf->length, ssl->heap); + ret = DecodeToKey(cert, 0); + } + if (ret == 0) { + ret = wc_ed448_import_public(cert->publicKey, cert->pubKeySize, + key); + } + if (cert != NULL) { + FreeDecodedCert(cert); + XFREE(cert, ssl->heap, DYNAMIC_TYPE_DCERT); + } + } + + return ret; +} + +/* Sign the data using EdDSA and key using Ed448. + * + * ssl SSL object. + * in Data or message to sign. + * inSz Length of the data. + * out Buffer to hold signature. + * outSz On entry, size of the buffer. On exit, the size of the signature. + * key The private Ed448 key data. + * keySz The length of the private key data in bytes. + * ctx The callback context. + * returns 0 on success, otherwise the value is an error. + */ +int Ed448Sign(WOLFSSL* ssl, const byte* in, word32 inSz, byte* out, + word32* outSz, ed448_key* key, DerBuffer* keyBufInfo) +{ + int ret; +#ifdef HAVE_PK_CALLBACKS + const byte* keyBuf = NULL; + word32 keySz = 0; + + if (keyBufInfo) { + keyBuf = keyBufInfo->buffer; + keySz = keyBufInfo->length; + } +#endif + + (void)ssl; + (void)keyBufInfo; + + WOLFSSL_ENTER("Ed448Sign"); + +#ifdef WOLFSSL_ASYNC_CRYPT + /* initialize event */ + ret = wolfSSL_AsyncInit(ssl, &key->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN); + if (ret != 0) + return ret; +#endif + +#if defined(HAVE_PK_CALLBACKS) + if (ssl->ctx->Ed448SignCb) { + void* ctx = wolfSSL_GetEd448SignCtx(ssl); + ret = ssl->ctx->Ed448SignCb(ssl, in, inSz, out, outSz, keyBuf, keySz, + ctx); + } + else +#endif /* HAVE_PK_CALLBACKS */ + { + ret = wc_ed448_sign_msg(in, inSz, out, outSz, key, NULL, 0); + } + + /* Handle async pending response */ +#ifdef WOLFSSL_ASYNC_CRYPT + if (ret == WC_PENDING_E) { + ret = wolfSSL_AsyncPush(ssl, &key->asyncDev); + } +#endif /* WOLFSSL_ASYNC_CRYPT */ + + WOLFSSL_LEAVE("Ed448Sign", ret); + + return ret; +} + +/* Verify the data using EdDSA and key using Ed448. + * + * ssl SSL object. + * in Signature data. + * inSz Length of the signature data in bytes. + * msg Message to verify. + * outSz Length of message in bytes. + * key The public Ed448 key data. + * keySz The length of the private key data in bytes. + * ctx The callback context. + * returns 0 on success, otherwise the value is an error. + */ +int Ed448Verify(WOLFSSL* ssl, const byte* in, word32 inSz, const byte* msg, + word32 msgSz, ed448_key* key, buffer* keyBufInfo) +{ + int ret; +#ifdef HAVE_PK_CALLBACKS + const byte* keyBuf = NULL; + word32 keySz = 0; + + if (keyBufInfo) { + keyBuf = keyBufInfo->buffer; + keySz = keyBufInfo->length; + } +#endif + + (void)ssl; + (void)keyBufInfo; + + WOLFSSL_ENTER("Ed448Verify"); + +#ifdef WOLFSSL_ASYNC_CRYPT + /* initialize event */ + ret = wolfSSL_AsyncInit(ssl, &key->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN); + if (ret != 0) + return ret; +#endif + +#ifdef HAVE_PK_CALLBACKS + if (ssl->ctx->Ed448VerifyCb) { + void* ctx = wolfSSL_GetEd448VerifyCtx(ssl); + ret = ssl->ctx->Ed448VerifyCb(ssl, in, inSz, msg, msgSz, keyBuf, keySz, + &ssl->eccVerifyRes, ctx); + } + else +#endif /* HAVE_PK_CALLBACKS */ + { + ret = wc_ed448_verify_msg(in, inSz, msg, msgSz, &ssl->eccVerifyRes, key, + NULL, 0); + } + + /* Handle async pending response */ +#ifdef WOLFSSL_ASYNC_CRYPT + if (ret == WC_PENDING_E) { + ret = wolfSSL_AsyncPush(ssl, &key->asyncDev); + } + else +#endif /* WOLFSSL_ASYNC_CRYPT */ + { + ret = (ret != 0 || ssl->eccVerifyRes == 0) ? VERIFY_SIGN_ERROR : 0; + } + + WOLFSSL_LEAVE("Ed448Verify", ret); + + return ret; +} +#endif /* HAVE_ED448 */ + +#ifdef HAVE_CURVE448 +#ifdef HAVE_PK_CALLBACKS + /* Gets X448 key for shared secret callback testing + * Client side: returns peer key + * Server side: returns private key + */ + static int X448GetKey(WOLFSSL* ssl, curve448_key** otherKey) + { + int ret = NO_PEER_KEY; + struct curve448_key* tmpKey = NULL; + + if (ssl == NULL || otherKey == NULL) { + return BAD_FUNC_ARG; + } + + if (ssl->options.side == WOLFSSL_CLIENT_END) { + if (!ssl->peerX448Key || !ssl->peerX448KeyPresent) { + return NO_PEER_KEY; + } + tmpKey = (struct curve448_key*)ssl->peerX448Key; + } + else if (ssl->options.side == WOLFSSL_SERVER_END) { + if (!ssl->eccTempKeyPresent) { + return NO_PRIVATE_KEY; + } + tmpKey = (struct curve448_key*)ssl->eccTempKey; + } + + if (tmpKey) { + *otherKey = (curve448_key *)tmpKey; + ret = 0; + } + + return ret; + } +#endif /* HAVE_PK_CALLBACKS */ + +static int X448SharedSecret(WOLFSSL* ssl, curve448_key* priv_key, + curve448_key* pub_key, byte* pubKeyDer, + word32* pubKeySz, byte* out, word32* outlen, + int side) +{ + int ret; + + (void)ssl; + (void)pubKeyDer; + (void)pubKeySz; + (void)side; + + WOLFSSL_ENTER("X448SharedSecret"); + +#ifdef WOLFSSL_ASYNC_CRYPT + /* initialize event */ + ret = wolfSSL_AsyncInit(ssl, &priv_key->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN); + if (ret != 0) + return ret; +#endif + +#ifdef HAVE_PK_CALLBACKS + if (ssl->ctx->X448SharedSecretCb) { + curve448_key* otherKey = NULL; + + ret = X448GetKey(ssl, &otherKey); + if (ret == 0) { + void* ctx = wolfSSL_GetX448SharedSecretCtx(ssl); + ret = ssl->ctx->X448SharedSecretCb(ssl, otherKey, pubKeyDer, + pubKeySz, out, outlen, side, ctx); + } + } + else +#endif + { + ret = wc_curve448_shared_secret_ex(priv_key, pub_key, out, outlen, + EC448_LITTLE_ENDIAN); + } + + /* Handle async pending response */ +#ifdef WOLFSSL_ASYNC_CRYPT + if (ret == WC_PENDING_E) { + ret = wolfSSL_AsyncPush(ssl, &priv_key->asyncDev); + } +#endif /* WOLFSSL_ASYNC_CRYPT */ + + WOLFSSL_LEAVE("X448SharedSecret", ret); + + return ret; +} + +static int X448MakeKey(WOLFSSL* ssl, curve448_key* key, curve448_key* peer) +{ + int ret = 0; + + (void)peer; + + WOLFSSL_ENTER("X448MakeKey"); + +#ifdef WOLFSSL_ASYNC_CRYPT + /* initialize event */ + ret = wolfSSL_AsyncInit(ssl, &key->asyncDev, WC_ASYNC_FLAG_NONE); + if (ret != 0) + return ret; +#endif + +#ifdef HAVE_PK_CALLBACKS + if (ssl->ctx->X448KeyGenCb) { + void* ctx = wolfSSL_GetX448KeyGenCtx(ssl); + ret = ssl->ctx->X448KeyGenCb(ssl, key, CURVE448_KEY_SIZE, ctx); + } + else +#endif + { + ret = wc_curve448_make_key(ssl->rng, CURVE448_KEY_SIZE, key); + } + + if (ret == 0) { + ssl->ecdhCurveOID = ECC_X448_OID; + } + + /* Handle async pending response */ +#ifdef WOLFSSL_ASYNC_CRYPT + if (ret == WC_PENDING_E) { + ret = wolfSSL_AsyncPush(ssl, &key->asyncDev); + } +#endif /* WOLFSSL_ASYNC_CRYPT */ + + WOLFSSL_LEAVE("X448MakeKey", ret); + + return ret; +} +#endif /* HAVE_CURVE448 */ + #if !defined(NO_CERTS) || !defined(NO_PSK) #if !defined(NO_DH) @@ -4693,7 +5014,8 @@ int wolfSSL_IsPrivatePkSet(WOLFSSL* ssl) int pkcbset = 0; (void)ssl; -#if defined(HAVE_ECC) || defined(HAVE_ED25519) || !defined(NO_RSA) +#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) || \ + !defined(NO_RSA) if (0 #ifdef HAVE_ECC || (ssl->ctx->EccSignCb != NULL && @@ -4703,6 +5025,10 @@ int wolfSSL_IsPrivatePkSet(WOLFSSL* ssl) || (ssl->ctx->Ed25519SignCb != NULL && ssl->buffers.keyType == ed25519_sa_algo) #endif + #ifdef HAVE_ED448 + || (ssl->ctx->Ed448SignCb != NULL && + ssl->buffers.keyType == ed448_sa_algo) + #endif #ifndef NO_RSA || (ssl->ctx->RsaSignCb != NULL && ssl->buffers.keyType == rsa_sa_algo) || (ssl->ctx->RsaDecCb != NULL && ssl->buffers.keyType == rsa_kea) @@ -4722,7 +5048,8 @@ int wolfSSL_CTX_IsPrivatePkSet(WOLFSSL_CTX* ctx) { int pkcbset = 0; (void)ctx; -#if defined(HAVE_ECC) || defined(HAVE_ED25519) || !defined(NO_RSA) +#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) || \ + !defined(NO_RSA) if (0 #ifdef HAVE_ECC || ctx->EccSignCb != NULL @@ -4730,6 +5057,9 @@ int wolfSSL_CTX_IsPrivatePkSet(WOLFSSL_CTX* ctx) #ifdef HAVE_ED25519 || ctx->Ed25519SignCb != NULL #endif + #ifdef HAVE_ED448 + || ctx->Ed448SignCb != NULL + #endif #ifndef NO_RSA || ctx->RsaSignCb != NULL || ctx->RsaDecCb != NULL @@ -4777,10 +5107,12 @@ int InitSSL_Suites(WOLFSSL* ssl) if (ssl->options.side == WOLFSSL_SERVER_END) ssl->options.maxEarlyDataSz = ssl->ctx->maxEarlyDataSz; #endif -#if !defined(WOLFSSL_NO_CLIENT_AUTH) && defined(HAVE_ED25519) && \ - !defined(NO_ED25519_CLIENT_AUTH) +#if !defined(WOLFSSL_NO_CLIENT_AUTH) && \ + ((defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \ + (defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH))) ssl->options.cacheMessages = ssl->options.side == WOLFSSL_SERVER_END || - ssl->buffers.keyType == ed25519_sa_algo; + ssl->buffers.keyType == ed25519_sa_algo || + ssl->buffers.keyType == ed448_sa_algo; #endif #ifndef NO_CERTS @@ -4907,7 +5239,7 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) ssl->eccTempKeySz = ctx->eccTempKeySz; ssl->ecdhCurveOID = ctx->ecdhCurveOID; #endif -#if defined(HAVE_ECC) || defined(HAVE_ED25519) +#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) ssl->pkCurveOID = ctx->pkCurveOID; #endif @@ -4996,10 +5328,12 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) ssl->buffers.keySz = ctx->privateKeySz; ssl->buffers.keyDevId = ctx->privateKeyDevId; #endif -#if !defined(WOLFSSL_NO_CLIENT_AUTH) && defined(HAVE_ED25519) && \ - !defined(NO_ED25519_CLIENT_AUTH) +#if !defined(WOLFSSL_NO_CLIENT_AUTH) && \ + ((defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \ + (defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH))) ssl->options.cacheMessages = ssl->options.side == WOLFSSL_SERVER_END || - ssl->buffers.keyType == ed25519_sa_algo; + ssl->buffers.keyType == ed25519_sa_algo || + ssl->buffers.keyType == ed448_sa_algo; #endif @@ -5133,7 +5467,8 @@ void FreeHandshakeHashes(WOLFSSL* ssl) #ifdef WOLFSSL_SHA512 wc_Sha512Free(&ssl->hsHashes->hashSha512); #endif - #if defined(HAVE_ED25519) && !defined(WOLFSSL_NO_CLIENT_AUTH) + #if (defined(HAVE_ED25519) || defined(HAVE_ED448)) && \ + !defined(WOLFSSL_NO_CLIENT_AUTH) if (ssl->hsHashes->messages != NULL) { XFREE(ssl->hsHashes->messages, ssl->heap, DYNAMIC_TYPE_HASHES); ssl->hsHashes->messages = NULL; @@ -5590,12 +5925,22 @@ void FreeKey(WOLFSSL* ssl, int type, void** pKey) case DYNAMIC_TYPE_ED25519: wc_ed25519_free((ed25519_key*)*pKey); break; - #endif /* HAVE_CURVE25519 */ + #endif /* HAVE_ED25519 */ #ifdef HAVE_CURVE25519 case DYNAMIC_TYPE_CURVE25519: wc_curve25519_free((curve25519_key*)*pKey); break; #endif /* HAVE_CURVE25519 */ + #ifdef HAVE_ED448 + case DYNAMIC_TYPE_ED448: + wc_ed448_free((ed448_key*)*pKey); + break; + #endif /* HAVE_ED448 */ + #ifdef HAVE_CURVE448 + case DYNAMIC_TYPE_CURVE448: + wc_curve448_free((curve448_key*)*pKey); + break; + #endif /* HAVE_CURVE448 */ #ifndef NO_DH case DYNAMIC_TYPE_DH: wc_FreeDhKey((DhKey*)*pKey); @@ -5648,6 +5993,16 @@ int AllocKey(WOLFSSL* ssl, int type, void** pKey) sz = sizeof(curve25519_key); break; #endif /* HAVE_CURVE25519 */ + #ifdef HAVE_ED448 + case DYNAMIC_TYPE_ED448: + sz = sizeof(ed448_key); + break; + #endif /* HAVE_ED448 */ + #ifdef HAVE_CURVE448 + case DYNAMIC_TYPE_CURVE448: + sz = sizeof(curve448_key); + break; + #endif /* HAVE_CURVE448 */ #ifndef NO_DH case DYNAMIC_TYPE_DH: sz = sizeof(DhKey); @@ -5691,6 +6046,18 @@ int AllocKey(WOLFSSL* ssl, int type, void** pKey) ret = 0; break; #endif /* HAVE_CURVE25519 */ + #ifdef HAVE_ED448 + case DYNAMIC_TYPE_ED448: + wc_ed448_init((ed448_key*)*pKey); + ret = 0; + break; + #endif /* HAVE_CURVE448 */ + #ifdef HAVE_CURVE448 + case DYNAMIC_TYPE_CURVE448: + wc_curve448_init((curve448_key*)*pKey); + ret = 0; + break; + #endif /* HAVE_CURVE448 */ #ifndef NO_DH case DYNAMIC_TYPE_DH: ret = wc_InitDhKey_ex((DhKey*)*pKey, ssl->heap, ssl->devId); @@ -5709,7 +6076,7 @@ int AllocKey(WOLFSSL* ssl, int type, void** pKey) } #if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519) || \ - defined(HAVE_CURVE25519) + defined(HAVE_CURVE25519) || defined(HHAVE_ED448) || defined(HAVE_CURVE448) static int ReuseKey(WOLFSSL* ssl, int type, void* pKey) { int ret = 0; @@ -5741,6 +6108,18 @@ static int ReuseKey(WOLFSSL* ssl, int type, void* pKey) ret = wc_curve25519_init((curve25519_key*)pKey); break; #endif /* HAVE_CURVE25519 */ + #ifdef HAVE_ED448 + case DYNAMIC_TYPE_ED448: + wc_ed448_free((ed448_key*)pKey); + ret = wc_ed448_init((ed448_key*)pKey); + break; + #endif /* HAVE_CURVE448 */ + #ifdef HAVE_CURVE448 + case DYNAMIC_TYPE_CURVE448: + wc_curve448_free((curve448_key*)pKey); + ret = wc_curve448_init((curve448_key*)pKey); + break; + #endif /* HAVE_CURVE448 */ #ifndef NO_DH case DYNAMIC_TYPE_DH: wc_FreeDhKey((DhKey*)pKey); @@ -5895,7 +6274,7 @@ void SSL_ResourceFree(WOLFSSL* ssl) FreeKey(ssl, DYNAMIC_TYPE_ECC, (void**)&ssl->peerEccDsaKey); ssl->peerEccDsaKeyPresent = 0; #endif -#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) +#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) ||defined(HAVE_CURVE448) { int dtype; #ifdef HAVE_ECC @@ -5910,10 +6289,19 @@ void SSL_ResourceFree(WOLFSSL* ssl) dtype = DYNAMIC_TYPE_CURVE25519; } #endif /* HAVE_CURVE25519 */ + #ifdef HAVE_CURVE448 + #ifdef HAVE_ECC + if (ssl->peerX448KeyPresent || + ssl->eccTempKeyPresent == DYNAMIC_TYPE_CURVE448) + #endif /* HAVE_ECC */ + { + dtype = DYNAMIC_TYPE_CURVE448; + } + #endif /* HAVE_CURVE448 */ FreeKey(ssl, dtype, (void**)&ssl->eccTempKey); ssl->eccTempKeyPresent = 0; } -#endif /* HAVE_ECC || HAVE_CURVE25519 */ +#endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */ #ifdef HAVE_CURVE25519 FreeKey(ssl, DYNAMIC_TYPE_CURVE25519, (void**)&ssl->peerX25519Key); ssl->peerX25519KeyPresent = 0; @@ -5929,6 +6317,21 @@ void SSL_ResourceFree(WOLFSSL* ssl) } #endif #endif +#ifdef HAVE_CURVE448 + FreeKey(ssl, DYNAMIC_TYPE_CURVE448, (void**)&ssl->peerX448Key); + ssl->peerX448KeyPresent = 0; +#endif +#ifdef HAVE_ED448 + FreeKey(ssl, DYNAMIC_TYPE_ED448, (void**)&ssl->peerEd448Key); + ssl->peerEd448KeyPresent = 0; + #ifdef HAVE_PK_CALLBACKS + if (ssl->buffers.peerEd448Key.buffer != NULL) { + XFREE(ssl->buffers.peerEd448Key.buffer, ssl->heap, + DYNAMIC_TYPE_ED448); + ssl->buffers.peerEd448Key.buffer = NULL; + } + #endif +#endif #ifdef HAVE_PK_CALLBACKS #ifdef HAVE_ECC XFREE(ssl->buffers.peerEccDsaKey.buffer, ssl->heap, DYNAMIC_TYPE_ECC); @@ -6116,13 +6519,17 @@ void FreeHandshakeResources(WOLFSSL* ssl) FreeKey(ssl, DYNAMIC_TYPE_ED25519, (void**)&ssl->peerEd25519Key); ssl->peerEd25519KeyPresent = 0; #endif /* HAVE_ED25519 */ +#ifdef HAVE_ED448 + FreeKey(ssl, DYNAMIC_TYPE_ED448, (void**)&ssl->peerEd448Key); + ssl->peerEd448KeyPresent = 0; +#endif /* HAVE_ED448 */ } #ifdef HAVE_ECC FreeKey(ssl, DYNAMIC_TYPE_ECC, (void**)&ssl->peerEccKey); ssl->peerEccKeyPresent = 0; #endif -#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) +#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) { int dtype; #ifdef HAVE_ECC @@ -6137,14 +6544,27 @@ void FreeHandshakeResources(WOLFSSL* ssl) dtype = DYNAMIC_TYPE_CURVE25519; } #endif /* HAVE_CURVE25519 */ + #ifdef HAVE_CURVE448 + #ifdef HAVE_ECC + if (ssl->peerX448KeyPresent || + ssl->eccTempKeyPresent == DYNAMIC_TYPE_CURVE448) + #endif /* HAVE_ECC */ + { + dtype = DYNAMIC_TYPE_CURVE448; + } + #endif /* HAVE_CURVE448 */ FreeKey(ssl, dtype, (void**)&ssl->eccTempKey); ssl->eccTempKeyPresent = 0; } -#endif /* HAVE_ECC || HAVE_CURVE25519 */ +#endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */ #ifdef HAVE_CURVE25519 FreeKey(ssl, DYNAMIC_TYPE_CURVE25519, (void**)&ssl->peerX25519Key); ssl->peerX25519KeyPresent = 0; #endif +#ifdef HAVE_CURVE448 + FreeKey(ssl, DYNAMIC_TYPE_CURVE448, (void**)&ssl->peerX448Key); + ssl->peerX448KeyPresent = 0; +#endif #ifndef NO_DH if (ssl->buffers.serverDH_Priv.buffer) { @@ -6185,6 +6605,10 @@ void FreeHandshakeResources(WOLFSSL* ssl) DYNAMIC_TYPE_ED25519); ssl->buffers.peerEd25519Key.buffer = NULL; #endif + #ifdef HAVE_ED448 + XFREE(ssl->buffers.peerEd448Key.buffer, ssl->heap, DYNAMIC_TYPE_ED448); + ssl->buffers.peerEd448Key.buffer = NULL; + #endif } #endif /* HAVE_PK_CALLBACKS */ @@ -7101,16 +7525,17 @@ ProtocolVersion MakeDTLSv1_2(void) return (word32)XTIME(0); } #endif -#if !defined(WOLFSSL_NO_CLIENT_AUTH) && defined(HAVE_ED25519) && \ - !defined(NO_ED25519_CLIENT_AUTH) -/* Store the message for use with CertificateVerify using Ed25519. +#if !defined(WOLFSSL_NO_CLIENT_AUTH) && \ + ((defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \ + (defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH))) +/* Store the message for use with CertificateVerify using EdDSA. * * ssl SSL/TLS object. * data Message to store. * sz Size of message to store. * returns MEMORY_E if not able to reallocate, otherwise 0. */ -static int Ed25519Update(WOLFSSL* ssl, const byte* data, int sz) +static int EdDSA_Update(WOLFSSL* ssl, const byte* data, int sz) { int ret = 0; byte* msgs; @@ -7131,7 +7556,7 @@ static int Ed25519Update(WOLFSSL* ssl, const byte* data, int sz) return ret; } -#endif /* HAVE_ED25519 && !WOLFSSL_NO_CLIENT_AUTH */ +#endif /* (HAVE_ED25519 || HAVE_ED448) && !WOLFSSL_NO_CLIENT_AUTH */ #ifndef NO_CERTS int HashOutputRaw(WOLFSSL* ssl, const byte* output, int sz) @@ -7173,9 +7598,10 @@ int HashOutputRaw(WOLFSSL* ssl, const byte* output, int sz) if (ret != 0) return ret; #endif - #if !defined(WOLFSSL_NO_CLIENT_AUTH) && defined(HAVE_ED25519) && \ - !defined(NO_ED25519_CLIENT_AUTH) - ret = Ed25519Update(ssl, output, sz); + #if !defined(WOLFSSL_NO_CLIENT_AUTH) && \ + ((defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \ + (defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH))) + ret = EdDSA_Update(ssl, output, sz); if (ret != 0) return ret; #endif @@ -7233,9 +7659,10 @@ int HashOutput(WOLFSSL* ssl, const byte* output, int sz, int ivSz) if (ret != 0) return ret; #endif - #if !defined(WOLFSSL_NO_CLIENT_AUTH) && defined(HAVE_ED25519) && \ - !defined(NO_ED25519_CLIENT_AUTH) - ret = Ed25519Update(ssl, adj, sz); + #if !defined(WOLFSSL_NO_CLIENT_AUTH) && \ + ((defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \ + (defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH))) + ret = EdDSA_Update(ssl, adj, sz); if (ret != 0) return ret; #endif @@ -7292,9 +7719,10 @@ int HashInput(WOLFSSL* ssl, const byte* input, int sz) if (ret != 0) return ret; #endif - #if !defined(WOLFSSL_NO_CLIENT_AUTH) && defined(HAVE_ED25519) && \ - !defined(NO_ED25519_CLIENT_AUTH) - ret = Ed25519Update(ssl, adj, sz); + #if !defined(WOLFSSL_NO_CLIENT_AUTH) && \ + ((defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \ + (defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH))) + ret = EdDSA_Update(ssl, adj, sz); if (ret != 0) return ret; #endif @@ -8212,7 +8640,7 @@ static int BuildFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender) if (first == ECC_BYTE) { switch (second) { -#ifdef HAVE_ECC +#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) #ifndef NO_RSA case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA : if (requirement == REQUIRES_RSA) @@ -8338,10 +8766,10 @@ static int BuildFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender) if (requirement == REQUIRES_AEAD) return 1; break; -#endif /* HAVE_ECC */ +#endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */ #ifndef NO_RSA - #ifdef HAVE_ECC + #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 : if (requirement == REQUIRES_RSA) return 1; @@ -8373,7 +8801,7 @@ static int BuildFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender) if (requirement == REQUIRES_AEAD) return 1; break; - #endif /* HAVE_ECC */ + #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */ #ifdef HAVE_AESCCM case TLS_RSA_WITH_AES_128_CCM_8 : case TLS_RSA_WITH_AES_256_CCM_8 : @@ -8385,7 +8813,7 @@ static int BuildFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender) return 1; break; #endif /* HAVE_AESCCM */ - #ifdef HAVE_ECC + #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 : @@ -8400,10 +8828,10 @@ static int BuildFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender) if (requirement == REQUIRES_ECC_STATIC) return 1; break; - #endif /* HAVE_ECC */ + #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */ #endif /* !NO_RSA */ -#ifdef HAVE_ECC +#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) case TLS_ECDHE_ECDSA_WITH_AES_128_CCM : case TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 : case TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 : @@ -8426,7 +8854,7 @@ static int BuildFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender) if (requirement == REQUIRES_ECC_STATIC) return 1; break; -#endif /* HAVE_ECC */ +#endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */ #ifndef NO_PSK case TLS_PSK_WITH_AES_128_CCM: @@ -8449,7 +8877,7 @@ static int BuildFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender) return 1; break; #endif /* !NO_PSK */ -#ifdef HAVE_ECC +#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) case TLS_ECDHE_ECDSA_WITH_NULL_SHA : if (requirement == REQUIRES_ECC) return 1; @@ -8464,7 +8892,7 @@ static int BuildFinished(WOLFSSL* ssl, Hashes* hashes, const byte* sender) if (requirement == REQUIRES_PSK) return 1; break; -#endif /* HAVE_ECC */ +#endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */ #if defined(WOLFSSL_TLS13) && defined(HAVE_NULL_CIPHER) case TLS_SHA256_SHA256: @@ -9232,9 +9660,9 @@ int CopyDecodedToX509(WOLFSSL_X509* x509, DecodedCert* dCert) } #endif /* WOLFSSL_CERT_EXT */ #endif /* OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL */ -#if defined(HAVE_ECC) || defined(HAVE_ED25519) +#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) x509->pkCurveOID = dCert->pkCurveOID; -#endif /* HAVE_ECC */ +#endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */ return ret; } @@ -9900,14 +10328,23 @@ static int ProcessPeerCertCheckKey(WOLFSSL* ssl, ProcPeerCertArgs* args) #ifdef HAVE_ED25519 case ED25519k: if (ssl->options.minEccKeySz < 0 || - ED25519_KEY_SIZE < - (word16)ssl->options.minEccKeySz) { + ED25519_KEY_SIZE < (word16)ssl->options.minEccKeySz) { WOLFSSL_MSG( "ECC key size in cert chain error"); ret = ECC_KEY_SIZE_E; } break; #endif /* HAVE_ED25519 */ + #ifdef HAVE_ED448 + case ED448k: + if (ssl->options.minEccKeySz < 0 || + ED448_KEY_SIZE < (word16)ssl->options.minEccKeySz) { + WOLFSSL_MSG( + "ECC key size in cert chain error"); + ret = ECC_KEY_SIZE_E; + } + break; + #endif /* HAVE_ED448 */ default: WOLFSSL_MSG("Key size not checked"); /* key not being checked for size if not in @@ -10240,7 +10677,7 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, #endif /* WOLFSSL_TRUST_PEER_CERT */ ) { int skipAddCA = 0; - + /* select last certificate */ args->certIdx = args->count - 1; @@ -10927,6 +11364,55 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, break; } #endif /* HAVE_ED25519 */ + #ifdef HAVE_ED448 + case ED448k: + { + int keyRet = 0; + if (ssl->peerEd448Key == NULL) { + /* alloc/init on demand */ + keyRet = AllocKey(ssl, DYNAMIC_TYPE_ED448, + (void**)&ssl->peerEd448Key); + } else if (ssl->peerEd448KeyPresent) { + keyRet = ReuseKey(ssl, DYNAMIC_TYPE_ED448, + ssl->peerEd448Key); + ssl->peerEd448KeyPresent = 0; + } + + if (keyRet != 0 || + wc_ed448_import_public(args->dCert->publicKey, + args->dCert->pubKeySize, + ssl->peerEd448Key) != 0) { + ret = PEER_KEY_ERROR; + } + else { + ssl->peerEd448KeyPresent = 1; + #ifdef HAVE_PK_CALLBACKS + ssl->buffers.peerEd448Key.buffer = + (byte*)XMALLOC(args->dCert->pubKeySize, + ssl->heap, DYNAMIC_TYPE_ED448); + if (ssl->buffers.peerEd448Key.buffer == NULL) { + ERROR_OUT(MEMORY_ERROR, exit_ppc); + } + else { + XMEMCPY(ssl->buffers.peerEd448Key.buffer, + args->dCert->publicKey, + args->dCert->pubKeySize); + ssl->buffers.peerEd448Key.length = + args->dCert->pubKeySize; + } + #endif /*HAVE_PK_CALLBACKS */ + } + + /* check size of peer ECC key */ + if (ret == 0 && ssl->peerEd448KeyPresent && + !ssl->options.verifyNone && + ED448_KEY_SIZE < ssl->options.minEccKeySz) { + ret = ECC_KEY_SIZE_E; + WOLFSSL_MSG("Peer ECC key is too small"); + } + break; + } + #endif /* HAVE_ED448 */ default: break; } @@ -11847,8 +12333,9 @@ static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx, case server_hello: WOLFSSL_MSG("processing server hello"); ret = DoServerHello(ssl, input, inOutIdx, size); - #if !defined(WOLFSSL_NO_CLIENT_AUTH) && defined(HAVE_ED25519) && \ - !defined(NO_ED25519_CLIENT_AUTH) + #if !defined(WOLFSSL_NO_CLIENT_AUTH) && \ + ((defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \ + (defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH))) if (ssl->options.resuming || !IsAtLeastTLSv1_2(ssl) || IsAtLeastTLSv1_3(ssl->version)) { @@ -11931,8 +12418,9 @@ static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx, case client_hello: WOLFSSL_MSG("processing client hello"); ret = DoClientHello(ssl, input, inOutIdx, size); - #if !defined(WOLFSSL_NO_CLIENT_AUTH) && defined(HAVE_ED25519) && \ - !defined(NO_ED25519_CLIENT_AUTH) + #if !defined(WOLFSSL_NO_CLIENT_AUTH) && \ + ((defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \ + (defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH))) if (ssl->options.resuming || !ssl->options.verifyPeer || \ !IsAtLeastTLSv1_2(ssl) || IsAtLeastTLSv1_3(ssl->version)) { #if defined(WOLFSSL_ASYNC_CRYPT) || defined(WOLFSSL_NONBLOCK_OCSP) @@ -11973,13 +12461,13 @@ static int DoHandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx, ret = DoClientKeyExchange(ssl, input, inOutIdx, size); break; -#if (!defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519)) && \ - !defined(WOLFSSL_NO_CLIENT_AUTH) +#if (!defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519) || \ + defined(HAVE_ED448)) && !defined(WOLFSSL_NO_CLIENT_AUTH) case certificate_verify: WOLFSSL_MSG("processing certificate verify"); ret = DoCertificateVerify(ssl, input, inOutIdx, size); break; -#endif /* (!NO_RSA || HAVE_ECC || HAVE_ED25519) && !WOLFSSL_NO_CLIENT_AUTH */ +#endif /* (!NO_RSA || ECC || ED25519 || ED448) && !WOLFSSL_NO_CLIENT_AUTH */ #endif /* !NO_WOLFSSL_SERVER */ @@ -18285,13 +18773,15 @@ int SetCipherList(WOLFSSL_CTX* ctx, Suites* suites, const char* list) #ifndef NO_RSA haveRSAsig = 1; #endif - #if defined(HAVE_ECC) || defined(HAVE_ED25519) + #if defined(HAVE_ECC) || defined(HAVE_ED25519) || \ + defined(HAVE_ED448) haveECDSAsig = 1; #endif } else #endif - #if defined(HAVE_ECC) || defined(HAVE_ED25519) + #if defined(HAVE_ECC) || defined(HAVE_ED25519) || \ + defined(HAVE_ED448) if ((haveECDSAsig == 0) && XSTRSTR(name, "ECDSA")) haveECDSAsig = 1; else @@ -18370,15 +18860,32 @@ int PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, word32 hashSigAlgoSz) DecodeSigAlg(&hashSigAlgo[i], &hashAlgo, &sigAlgo); #ifdef HAVE_ED25519 - if (ssl->pkCurveOID == ECC_ED25519_OID && sigAlgo != ed25519_sa_algo) - continue; - - if (sigAlgo == ed25519_sa_algo && + if (ssl->pkCurveOID == ECC_ED25519_OID) { + if (sigAlgo != ed25519_sa_algo) + continue; + if (sigAlgo == ed25519_sa_algo && ssl->suites->sigAlgo == ecc_dsa_sa_algo) { - ssl->suites->sigAlgo = sigAlgo; - ssl->suites->hashAlgo = sha512_mac; - ret = 0; - break; + ssl->suites->sigAlgo = sigAlgo; + ssl->suites->hashAlgo = sha512_mac; + ssl->namedGroup = 0; + ret = 0; + break; + } + } + #endif + #ifdef HAVE_ED448 + if (ssl->pkCurveOID == ECC_ED448_OID) { + if (sigAlgo != ed448_sa_algo) + continue; + + if (sigAlgo == ed448_sa_algo && + ssl->suites->sigAlgo == ecc_dsa_sa_algo) { + ssl->suites->sigAlgo = sigAlgo; + ssl->suites->hashAlgo = sha512_mac; + ssl->namedGroup = 0; + ret = 0; + break; + } } #endif /* For ECDSA the `USE_ECDSA_KEYSZ_HASH_ALGO` build option will choose a hash @@ -18397,6 +18904,7 @@ int PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, word32 hashSigAlgoSz) if (digestSz == ssl->eccTempKeySz) { ssl->suites->hashAlgo = hashAlgo; ssl->suites->sigAlgo = sigAlgo; + ssl->namedGroup = 0; ret = 0; break; /* done selected sig/hash algorithms */ } @@ -18663,7 +19171,7 @@ int PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, word32 hashSigAlgoSz) #if !defined(NO_CERTS) -/* Decode the private key - RSA, ECC, or Ed25519 - and creates a key object. +/* Decode the private key - RSA/ECC/Ed25519/Ed448 - and creates a key object. * The signature type is set as well. * The maximum length of a signature is returned. * @@ -18863,6 +19371,50 @@ int DecodePrivateKey(WOLFSSL *ssl, word16* length) } } #endif /* HAVE_ED25519 */ +#ifdef HAVE_ED448 + #if !defined(NO_RSA) || defined(HAVE_ECC) + FreeKey(ssl, ssl->hsType, (void**)&ssl->hsKey); + #endif + + if (ssl->buffers.keyType == ed448_sa_algo || ssl->buffers.keyType == 0) { + ssl->hsType = DYNAMIC_TYPE_ED448; + ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey); + if (ret != 0) { + goto exit_dpk; + } + + #ifdef HAVE_ED25519 + WOLFSSL_MSG("Trying ED448 private key, ED25519 didn't work"); + #elif defined(HAVE_ECC) + WOLFSSL_MSG("Trying ED448 private key, ECC didn't work"); + #elif !defined(NO_RSA) + WOLFSSL_MSG("Trying ED448 private key, RSA didn't work"); + #else + WOLFSSL_MSG("Trying ED447 private key"); + #endif + + /* Set start of data to beginning of buffer. */ + idx = 0; + /* Decode the key assuming it is an ED448 private key. */ + ret = wc_Ed448PrivateKeyDecode(ssl->buffers.key->buffer, &idx, + (ed448_key*)ssl->hsKey, + ssl->buffers.key->length); + if (ret == 0) { + WOLFSSL_MSG("Using ED448 private key"); + + /* Check it meets the minimum ECC key size requirements. */ + if (ED448_KEY_SIZE < ssl->options.minEccKeySz) { + WOLFSSL_MSG("ED448 key size too small"); + ERROR_OUT(ECC_KEY_SIZE_E, exit_dpk); + } + + /* Return the maximum signature length. */ + *length = ED448_SIG_SIZE; + + goto exit_dpk; + } + } +#endif /* HAVE_ED448 */ (void)idx; (void)keySz; @@ -19814,7 +20366,7 @@ exit_dpk: #endif /* !NO_CERTS */ -#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) +#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) static int CheckCurveId(int tlsCurveId) { @@ -19848,10 +20400,10 @@ exit_dpk: case WOLFSSL_ECC_SECP224K1: return ECC_SECP224K1_OID; #endif /* HAVE_ECC_KOBLITZ */ #endif - #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES) #ifdef HAVE_CURVE25519 case WOLFSSL_ECC_X25519: return ECC_X25519_OID; #endif + #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES) #ifndef NO_ECC_SECP case WOLFSSL_ECC_SECP256R1: return ECC_SECP256R1_OID; #endif /* !NO_ECC_SECP */ @@ -19862,6 +20414,9 @@ exit_dpk: case WOLFSSL_ECC_BRAINPOOLP256R1: return ECC_BRAINPOOLP256R1_OID; #endif /* HAVE_ECC_BRAINPOOL */ #endif + #ifdef HAVE_CURVE448 + case WOLFSSL_ECC_X448: return ECC_X448_OID; + #endif #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES) #ifndef NO_ECC_SECP case WOLFSSL_ECC_SECP384R1: return ECC_SECP384R1_OID; @@ -19890,12 +20445,14 @@ exit_dpk: /* Persistable DoServerKeyExchange arguments */ typedef struct DskeArgs { byte* output; /* not allocated */ -#if !defined(NO_DH) || defined(HAVE_ECC) || defined(HAVE_ED25519) +#if !defined(NO_DH) || defined(HAVE_ECC) || defined(HAVE_ED25519) || \ + defined(HAVE_ED448) byte* verifySig; #endif word32 idx; word32 begin; -#if !defined(NO_DH) || defined(HAVE_ECC) || defined(HAVE_ED25519) +#if !defined(NO_DH) || defined(HAVE_ECC) || defined(HAVE_ED25519) || \ + defined(HAVE_ED448) word16 verifySigSz; #endif word16 sigSz; @@ -19913,7 +20470,8 @@ static void FreeDskeArgs(WOLFSSL* ssl, void* pArgs) (void)ssl; (void)args; -#if !defined(NO_DH) || defined(HAVE_ECC) || defined(HAVE_ED25519) +#if !defined(NO_DH) || defined(HAVE_ECC) || defined(HAVE_ED25519) || \ + defined(HAVE_ED448) if (args->verifySig) { XFREE(args->verifySig, ssl->heap, DYNAMIC_TYPE_SIGNATURE); args->verifySig = NULL; @@ -20177,7 +20735,8 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, break; } #endif /* !NO_DH */ - #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) + #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ + defined(HAVE_CURVE448) case ecc_diffie_hellman_kea: { byte b; @@ -20252,6 +20811,49 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, break; } #endif + #ifdef HAVE_CURVE448 + if (ssl->ecdhCurveOID == ECC_X448_OID) { + if (ssl->peerX448Key == NULL) { + ret = AllocKey(ssl, DYNAMIC_TYPE_CURVE448, + (void**)&ssl->peerX448Key); + if (ret != 0) { + goto exit_dske; + } + } else if (ssl->peerX448KeyPresent) { + ret = ReuseKey(ssl, DYNAMIC_TYPE_CURVE448, + ssl->peerX448Key); + ssl->peerX448KeyPresent = 0; + if (ret != 0) { + goto exit_dske; + } + } + + if ((ret = wc_curve448_check_public( + input + args->idx, length, + EC448_LITTLE_ENDIAN)) != 0) { + #ifdef WOLFSSL_EXTRA_ALERTS + if (ret == BUFFER_E) + SendAlert(ssl, alert_fatal, decode_error); + else if (ret == ECC_OUT_OF_RANGE_E) + SendAlert(ssl, alert_fatal, bad_record_mac); + else { + SendAlert(ssl, alert_fatal, illegal_parameter); + } + #endif + ERROR_OUT(ECC_PEERKEY_ERROR, exit_dske); + } + + if (wc_curve448_import_public_ex(input + args->idx, + length, ssl->peerX448Key, + EC448_LITTLE_ENDIAN) != 0) { + ERROR_OUT(ECC_PEERKEY_ERROR, exit_dske); + } + + args->idx += length; + ssl->peerX448KeyPresent = 1; + break; + } + #endif #ifdef HAVE_ECC if (ssl->peerEccKey == NULL) { ret = AllocKey(ssl, DYNAMIC_TYPE_ECC, @@ -20281,7 +20883,7 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, #endif break; } - #endif /* HAVE_ECC || HAVE_CURVE25519 */ + #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */ #if !defined(NO_DH) && !defined(NO_PSK) case dhe_psk_kea: { @@ -20312,8 +20914,8 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, break; } #endif /* !NO_DH && !NO_PSK */ - #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519)) && \ - !defined(NO_PSK) + #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ + defined(HAVE_CURVE448)) && !defined(NO_PSK) case ecdhe_psk_kea: { byte b; @@ -20405,6 +21007,49 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, break; } #endif + #ifdef HAVE_CURVE448 + if (ssl->ecdhCurveOID == ECC_X448_OID) { + if (ssl->peerX448Key == NULL) { + ret = AllocKey(ssl, DYNAMIC_TYPE_CURVE448, + (void**)&ssl->peerX448Key); + if (ret != 0) { + goto exit_dske; + } + } else if (ssl->peerEccKeyPresent) { + ret = ReuseKey(ssl, DYNAMIC_TYPE_CURVE448, + ssl->peerX448Key); + ssl->peerX448KeyPresent = 0; + if (ret != 0) { + goto exit_dske; + } + } + + if ((ret = wc_curve448_check_public( + input + args->idx, length, + EC448_LITTLE_ENDIAN)) != 0) { + #ifdef WOLFSSL_EXTRA_ALERTS + if (ret == BUFFER_E) + SendAlert(ssl, alert_fatal, decode_error); + else if (ret == ECC_OUT_OF_RANGE_E) + SendAlert(ssl, alert_fatal, bad_record_mac); + else { + SendAlert(ssl, alert_fatal, illegal_parameter); + } + #endif + ERROR_OUT(ECC_PEERKEY_ERROR, exit_dske); + } + + if (wc_curve448_import_public_ex(input + args->idx, + length, ssl->peerX448Key, + EC448_LITTLE_ENDIAN) != 0) { + ERROR_OUT(ECC_PEERKEY_ERROR, exit_dske); + } + + args->idx += length; + ssl->peerX448KeyPresent = 1; + break; + } + #endif if (ssl->peerEccKey == NULL) { ret = AllocKey(ssl, DYNAMIC_TYPE_ECC, @@ -20430,7 +21075,7 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, ssl->peerEccKeyPresent = 1; break; } - #endif /* (HAVE_ECC || HAVE_CURVE25519) && !NO_PSK */ + #endif /* (HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448) && !NO_PSK */ default: ret = BAD_KEA_TYPE_E; } /* switch(ssl->specs.kea) */ @@ -20460,7 +21105,8 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, case diffie_hellman_kea: case ecc_diffie_hellman_kea: { - #if defined(NO_DH) && !defined(HAVE_ECC) && !defined(HAVE_ED25519) + #if defined(NO_DH) && !defined(HAVE_ECC) && !defined(HAVE_ED25519) \ + && !defined(HAVE_ED448) ERROR_OUT(NOT_COMPILED_IN, exit_dske); #else enum wc_HashType hashType; @@ -20586,12 +21232,21 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, break; } #endif /* HAVE_ED25519 */ + #if defined(HAVE_ED448) + case ed448_sa_algo: + { + if (!ssl->peerEd448KeyPresent) { + ERROR_OUT(NO_PEER_KEY, exit_dske); + } + break; + } + #endif /* HAVE_ED448 */ default: ret = ALGO_ID_E; } /* switch (args->sigAlgo) */ - #endif /* NO_DH && !HAVE_ECC && !HAVE_ED25519 */ + #endif /* NO_DH && !HAVE_ECC && !HAVE_ED25519 && !HAVE_ED448 */ break; } default: @@ -20623,7 +21278,8 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, case diffie_hellman_kea: case ecc_diffie_hellman_kea: { - #if defined(NO_DH) && !defined(HAVE_ECC) && !defined(HAVE_ED25519) + #if defined(NO_DH) && !defined(HAVE_ECC) && !defined(HAVE_ED25519) \ + && !defined(HAVE_ED448) ERROR_OUT(NOT_COMPILED_IN, exit_dske); #else if (ssl->options.usingAnon_cipher) { @@ -20733,11 +21389,38 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, break; } #endif /* HAVE_ED25519 */ + #if defined(HAVE_ED448) + case ed448_sa_algo: + { + ret = Ed448Verify(ssl, + args->verifySig, args->verifySigSz, + ssl->buffers.sig.buffer, + ssl->buffers.sig.length, + ssl->peerEd448Key, + #ifdef HAVE_PK_CALLBACKS + &ssl->buffers.peerEd448Key + #else + NULL + #endif + ); + + #ifdef WOLFSSL_ASYNC_CRYPT + if (ret != WC_PENDING_E) + #endif + { + /* peerEccDsaKey */ + FreeKey(ssl, DYNAMIC_TYPE_ED448, + (void**)&ssl->peerEd448Key); + ssl->peerEd448KeyPresent = 0; + } + break; + } + #endif /* HAVE_ED448 */ default: ret = ALGO_ID_E; } /* switch (sigAlgo) */ - #endif /* NO_DH && !HAVE_ECC && !HAVE_ED25519 */ + #endif /* NO_DH && !HAVE_ECC && !HAVE_ED25519 && !HAVE_ED448 */ break; } default: @@ -20769,7 +21452,8 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, case diffie_hellman_kea: case ecc_diffie_hellman_kea: { - #if defined(NO_DH) && !defined(HAVE_ECC) && !defined(HAVE_ED25519) + #if defined(NO_DH) && !defined(HAVE_ECC) && !defined(HAVE_ED25519) \ + && !defined(HAVE_ED448) ERROR_OUT(NOT_COMPILED_IN, exit_dske); #else if (ssl->options.usingAnon_cipher) { @@ -20856,10 +21540,15 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, /* Nothing to do in this algo */ break; #endif /* HAVE_ED25519 */ + #if defined(HAVE_ED448) + case ed448_sa_algo: + /* Nothing to do in this algo */ + break; + #endif /* HAVE_ED448 */ default: ret = ALGO_ID_E; } /* switch (sigAlgo) */ - #endif /* NO_DH && !HAVE_ECC && !HAVE_ED25519 */ + #endif /* NO_DH && !HAVE_ECC && !HAVE_ED25519 && !HAVE_ED448 */ break; } default: @@ -21449,8 +22138,8 @@ int SendClientKeyExchange(WOLFSSL* ssl) } break; #endif /* !NO_DH && !NO_PSK */ - #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519)) && \ - !defined(NO_PSK) + #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ + defined(HAVE_CURVE448)) && !defined(NO_PSK) case ecdhe_psk_kea: /* sanity check that PSK client callback has been set */ if (ssl->options.client_psk_cb == NULL) { @@ -21483,6 +22172,32 @@ int SendClientKeyExchange(WOLFSSL* ssl) ssl->peerX25519Key); break; } + #endif + #ifdef HAVE_CURVE448 + if (ssl->peerX448KeyPresent) { + /* Check client ECC public key */ + if (!ssl->peerX448Key) { + ERROR_OUT(NO_PEER_KEY, exit_scke); + } + + #ifdef HAVE_PK_CALLBACKS + /* if callback then use it for shared secret */ + if (ssl->ctx->X448SharedSecretCb != NULL) { + break; + } + #endif + + /* create private key */ + ssl->hsType = DYNAMIC_TYPE_CURVE448; + ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey); + if (ret != 0) { + goto exit_scke; + } + + ret = X448MakeKey(ssl, (curve448_key*)ssl->hsKey, + ssl->peerX448Key); + break; + } #endif /* Check client ECC public key */ if (!ssl->peerEccKey || !ssl->peerEccKeyPresent || @@ -21507,7 +22222,7 @@ int SendClientKeyExchange(WOLFSSL* ssl) ret = EccMakeKey(ssl, (ecc_key*)ssl->hsKey, ssl->peerEccKey); break; - #endif /* (HAVE_ECC || HAVE_CURVE25519) && !NO_PSK */ + #endif /* (HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448) && !NO_PSK */ #ifdef HAVE_NTRU case ntru_kea: if (ssl->peerNtruKeyPresent == 0) { @@ -21515,7 +22230,8 @@ int SendClientKeyExchange(WOLFSSL* ssl) } break; #endif /* HAVE_NTRU */ - #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) + #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ + defined(HAVE_CURVE448) case ecc_diffie_hellman_kea: { #ifdef HAVE_ECC @@ -21530,6 +22246,13 @@ int SendClientKeyExchange(WOLFSSL* ssl) break; } else + #endif + #ifdef HAVE_CURVE448 + if (ssl->ecdhCurveOID == ECC_X448_OID) { + if (ssl->ctx->X448SharedSecretCb != NULL) + break; + } + else #endif if (ssl->ctx->EccSharedSecretCb != NULL) { break; @@ -21554,18 +22277,34 @@ int SendClientKeyExchange(WOLFSSL* ssl) break; } #endif + #ifdef HAVE_CURVE448 + if (ssl->peerX448KeyPresent) { + if (!ssl->peerX448Key) { + ERROR_OUT(NO_PEER_KEY, exit_scke); + } + + /* create private key */ + ssl->hsType = DYNAMIC_TYPE_CURVE448; + ret = AllocKey(ssl, ssl->hsType, &ssl->hsKey); + if (ret != 0) { + goto exit_scke; + } + + ret = X448MakeKey(ssl, (curve448_key*)ssl->hsKey, + ssl->peerX448Key); + break; + } + #endif #ifdef HAVE_ECC if (ssl->specs.static_ecdh) { /* Note: EccDsa is really fixed Ecc key here */ - if (!ssl->peerEccDsaKey || !ssl->peerEccDsaKeyPresent || - !ssl->peerEccDsaKey->dp) { + if (!ssl->peerEccDsaKey || !ssl->peerEccDsaKeyPresent) { ERROR_OUT(NO_PEER_KEY, exit_scke); } peerKey = ssl->peerEccDsaKey; } else { - if (!ssl->peerEccKey || !ssl->peerEccKeyPresent || - !ssl->peerEccKey->dp) { + if (!ssl->peerEccKey || !ssl->peerEccKeyPresent) { ERROR_OUT(NO_PEER_KEY, exit_scke); } peerKey = ssl->peerEccKey; @@ -21586,7 +22325,7 @@ int SendClientKeyExchange(WOLFSSL* ssl) break; } - #endif /* HAVE_ECC || HAVE_CURVE25519 */ + #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */ default: ret = BAD_KEA_TYPE_E; @@ -21820,8 +22559,8 @@ int SendClientKeyExchange(WOLFSSL* ssl) break; } #endif /* !NO_DH && !NO_PSK */ - #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519)) && \ - !defined(NO_PSK) + #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ + defined(HAVE_CURVE448)) && !defined(NO_PSK) case ecdhe_psk_kea: { word32 esSz = 0; @@ -21875,6 +22614,26 @@ int SendClientKeyExchange(WOLFSSL* ssl) break; } #endif + #ifdef HAVE_CURVE448 + if (ssl->ecdhCurveOID == ECC_X448_OID) { + #ifdef HAVE_PK_CALLBACKS + /* if callback then use it for shared secret */ + if (ssl->ctx->X448SharedSecretCb != NULL) { + break; + } + #endif + + ret = wc_curve448_export_public_ex( + (curve448_key*)ssl->hsKey, + args->output + OPAQUE8_LEN, &args->length, + EC448_LITTLE_ENDIAN); + if (ret != 0) { + ERROR_OUT(ECC_EXPORT_ERROR, exit_scke); + } + + break; + } + #endif #ifdef HAVE_PK_CALLBACKS /* if callback then use it for shared secret */ if (ssl->ctx->EccSharedSecretCb != NULL) { @@ -21891,7 +22650,7 @@ int SendClientKeyExchange(WOLFSSL* ssl) break; } - #endif /* (HAVE_ECC || HAVE_CURVE25519) && !NO_PSK */ + #endif /* (HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448) && !NO_PSK */ #ifdef HAVE_NTRU case ntru_kea: { @@ -21906,7 +22665,8 @@ int SendClientKeyExchange(WOLFSSL* ssl) break; } #endif /* HAVE_NTRU */ - #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) + #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ + defined(HAVE_CURVE448) case ecc_diffie_hellman_kea: { ssl->arrays->preMasterSz = ENCRYPT_LEN; @@ -21931,6 +22691,26 @@ int SendClientKeyExchange(WOLFSSL* ssl) break; } #endif + #ifdef HAVE_CURVE448 + if (ssl->hsType == DYNAMIC_TYPE_CURVE448) { + #ifdef HAVE_PK_CALLBACKS + /* if callback then use it for shared secret */ + if (ssl->ctx->X448SharedSecretCb != NULL) { + break; + } + #endif + + ret = wc_curve448_export_public_ex( + (curve448_key*)ssl->hsKey, + args->encSecret + OPAQUE8_LEN, &args->encSz, + EC448_LITTLE_ENDIAN); + if (ret != 0) { + ERROR_OUT(ECC_EXPORT_ERROR, exit_scke); + } + + break; + } + #endif #if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) #ifdef HAVE_PK_CALLBACKS /* if callback then use it for shared secret */ @@ -21948,7 +22728,7 @@ int SendClientKeyExchange(WOLFSSL* ssl) #endif /* HAVE_ECC */ break; } - #endif /* HAVE_ECC || HAVE_CURVE25519 */ + #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */ default: ret = BAD_KEA_TYPE_E; @@ -22025,8 +22805,8 @@ int SendClientKeyExchange(WOLFSSL* ssl) break; } #endif /* !NO_DH && !NO_PSK */ - #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519)) && \ - !defined(NO_PSK) + #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ + defined(HAVE_CURVE448)) && !defined(NO_PSK) case ecdhe_psk_kea: { #ifdef HAVE_CURVE25519 @@ -22049,6 +22829,27 @@ int SendClientKeyExchange(WOLFSSL* ssl) } break; } + #endif + #ifdef HAVE_CURVE448 + if (ssl->peerX448KeyPresent) { + ret = X448SharedSecret(ssl, + (curve448_key*)ssl->hsKey, ssl->peerX448Key, + args->output + OPAQUE8_LEN, &args->length, + ssl->arrays->preMasterSecret + OPAQUE16_LEN, + &ssl->arrays->preMasterSz, + WOLFSSL_CLIENT_END + ); + if (!ssl->specs.static_ecdh + #ifdef WOLFSSL_ASYNC_CRYPT + && ret != WC_PENDING_E + #endif + ) { + FreeKey(ssl, DYNAMIC_TYPE_CURVE448, + (void**)&ssl->peerX448Key); + ssl->peerX448KeyPresent = 0; + } + break; + } #endif ret = EccSharedSecret(ssl, (ecc_key*)ssl->hsKey, ssl->peerEccKey, @@ -22067,7 +22868,7 @@ int SendClientKeyExchange(WOLFSSL* ssl) } break; } - #endif /* (HAVE_ECC || HAVE_CURVE25519) && !NO_PSK */ + #endif /* (HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448) && !NO_PSK */ #ifdef HAVE_NTRU case ntru_kea: { @@ -22094,7 +22895,8 @@ int SendClientKeyExchange(WOLFSSL* ssl) break; } #endif /* HAVE_NTRU */ - #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) + #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ + defined(HAVE_CURVE448) case ecc_diffie_hellman_kea: { #ifdef HAVE_ECC @@ -22122,6 +22924,27 @@ int SendClientKeyExchange(WOLFSSL* ssl) break; } #endif + #ifdef HAVE_CURVE448 + if (ssl->peerX448KeyPresent) { + ret = X448SharedSecret(ssl, + (curve448_key*)ssl->hsKey, ssl->peerX448Key, + args->encSecret + OPAQUE8_LEN, &args->encSz, + ssl->arrays->preMasterSecret, + &ssl->arrays->preMasterSz, + WOLFSSL_CLIENT_END + ); + if (!ssl->specs.static_ecdh + #ifdef WOLFSSL_ASYNC_CRYPT + && ret != WC_PENDING_E + #endif + ) { + FreeKey(ssl, DYNAMIC_TYPE_CURVE448, + (void**)&ssl->peerX448Key); + ssl->peerX448KeyPresent = 0; + } + break; + } + #endif #ifdef HAVE_ECC peerKey = (ssl->specs.static_ecdh) ? ssl->peerEccDsaKey : ssl->peerEccKey; @@ -22146,7 +22969,7 @@ int SendClientKeyExchange(WOLFSSL* ssl) break; } - #endif /* HAVE_ECC || HAVE_CURVE25519 */ + #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */ default: ret = BAD_KEA_TYPE_E; @@ -22212,8 +23035,8 @@ int SendClientKeyExchange(WOLFSSL* ssl) break; } #endif /* !NO_DH && !NO_PSK */ - #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519)) && \ - !defined(NO_PSK) + #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ + defined(HAVE_CURVE448)) && !defined(NO_PSK) case ecdhe_psk_kea: { byte* pms = ssl->arrays->preMasterSecret; @@ -22243,14 +23066,15 @@ int SendClientKeyExchange(WOLFSSL* ssl) ssl->arrays->psk_keySz = 0; /* No further need */ break; } - #endif /* (HAVE_ECC || HAVE_CURVE25519) && !NO_PSK */ + #endif /* (HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448) && !NO_PSK */ #ifdef HAVE_NTRU case ntru_kea: { break; } #endif /* HAVE_NTRU */ - #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) + #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ + defined(HAVE_CURVE448) case ecc_diffie_hellman_kea: { /* place size of public key in buffer */ @@ -22258,7 +23082,7 @@ int SendClientKeyExchange(WOLFSSL* ssl) args->encSz += OPAQUE8_LEN; break; } - #endif /* HAVE_ECC || HAVE_CURVE25519 */ + #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */ default: ret = BAD_KEA_TYPE_E; @@ -22494,6 +23318,12 @@ exit_scke: sigSz = ED25519_SIG_SIZE; /* fixed known value */ ssl->hsType = DYNAMIC_TYPE_ED25519; break; + #endif + #ifdef HAVE_ED448 + case ed448_sa_algo: + sigSz = ED448_SIG_SIZE; /* fixed known value */ + ssl->hsType = DYNAMIC_TYPE_ED448; + break; #endif default: break; @@ -22673,6 +23503,8 @@ int SendCertificateVerify(WOLFSSL* ssl) args->sigAlgo = ecc_dsa_sa_algo; else if (ssl->hsType == DYNAMIC_TYPE_ED25519) args->sigAlgo = ed25519_sa_algo; + else if (ssl->hsType == DYNAMIC_TYPE_ED448) + args->sigAlgo = ed448_sa_algo; if (IsAtLeastTLSv1_2(ssl)) { EncodeSigAlg(ssl->suites->hashAlgo, args->sigAlgo, @@ -22722,6 +23554,13 @@ int SendCertificateVerify(WOLFSSL* ssl) goto exit_scv; } #endif /* HAVE_ED25519 && !NO_ED25519_CLIENT_AUTH */ + #if defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH) + if (args->sigAlgo == ed448_sa_algo) { + ret = Ed448CheckPubKey(ssl); + if (ret != 0) + goto exit_scv; + } + #endif /* HAVE_ED448 && !NO_ED448_CLIENT_AUTH */ /* Advance state and proceed */ ssl->options.asyncState = TLS_ASYNC_DO; @@ -22762,6 +23601,22 @@ int SendCertificateVerify(WOLFSSL* ssl) ); } #endif /* HAVE_ED25519 && !NO_ED25519_CLIENT_AUTH */ + #if defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH) + if (ssl->hsType == DYNAMIC_TYPE_ED448) { + ed448_key* key = (ed448_key*)ssl->hsKey; + + ret = Ed448Sign(ssl, + ssl->hsHashes->messages, ssl->hsHashes->length, + ssl->buffers.sig.buffer, (word32*)&ssl->buffers.sig.length, + key, + #ifdef HAVE_PK_CALLBACKS + ssl->buffers.key + #else + NULL + #endif + ); + } + #endif /* HAVE_ED448 && !NO_ED448_CLIENT_AUTH */ #ifndef NO_RSA if (ssl->hsType == DYNAMIC_TYPE_RSA) { RsaKey* key = (RsaKey*)ssl->hsKey; @@ -22793,47 +23648,52 @@ int SendCertificateVerify(WOLFSSL* ssl) /* restore verify pointer */ args->verify = &args->output[args->idx]; - #ifdef HAVE_ECC - if (ssl->hsType == DYNAMIC_TYPE_ECC) { - args->length = (word16)ssl->buffers.sig.length; - /* prepend hdr */ - c16toa(args->length, args->verify + args->extraSz); - XMEMCPY(args->verify + args->extraSz + VERIFY_HEADER, - ssl->buffers.sig.buffer, ssl->buffers.sig.length); - } - #endif /* HAVE_ECC */ - #ifdef HAVE_ED25519 - if (ssl->hsType == DYNAMIC_TYPE_ED25519) { - args->length = (word16)ssl->buffers.sig.length; - /* prepend hdr */ - c16toa(args->length, args->verify + args->extraSz); - XMEMCPY(args->verify + args->extraSz + VERIFY_HEADER, - ssl->buffers.sig.buffer, ssl->buffers.sig.length); - } - #endif /* HAVE_ED25519 */ - #ifndef NO_RSA - if (ssl->hsType == DYNAMIC_TYPE_RSA) { - RsaKey* key = (RsaKey*)ssl->hsKey; + switch (ssl->hsType) { + #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) + #ifdef HAVE_ECC + case DYNAMIC_TYPE_ECC: + #endif + #ifdef HAVE_ED25519 + case DYNAMIC_TYPE_ED25519: + #endif + #ifdef HAVE_ED448 + case DYNAMIC_TYPE_ED448: + #endif + args->length = (word16)ssl->buffers.sig.length; + /* prepend hdr */ + c16toa(args->length, args->verify + args->extraSz); + XMEMCPY(args->verify + args->extraSz + VERIFY_HEADER, + ssl->buffers.sig.buffer, ssl->buffers.sig.length); + break; + #endif + #ifndef NO_RSA + case DYNAMIC_TYPE_RSA: + { + RsaKey* key = (RsaKey*)ssl->hsKey; - if (args->verifySig == NULL) { - args->verifySig = (byte*)XMALLOC(args->sigSz, ssl->heap, - DYNAMIC_TYPE_SIGNATURE); if (args->verifySig == NULL) { - ERROR_OUT(MEMORY_E, exit_scv); - } - XMEMCPY(args->verifySig, args->verify + args->extraSz + + args->verifySig = (byte*)XMALLOC(args->sigSz, ssl->heap, + DYNAMIC_TYPE_SIGNATURE); + if (args->verifySig == NULL) { + ERROR_OUT(MEMORY_E, exit_scv); + } + XMEMCPY(args->verifySig, args->verify + args->extraSz + VERIFY_HEADER, args->sigSz); - } + } - /* check for signature faults */ - ret = VerifyRsaSign(ssl, - args->verifySig, args->sigSz, - ssl->buffers.sig.buffer, ssl->buffers.sig.length, - args->sigAlgo, ssl->suites->hashAlgo, key, - ssl->buffers.key - ); + /* check for signature faults */ + ret = VerifyRsaSign(ssl, + args->verifySig, args->sigSz, + ssl->buffers.sig.buffer, ssl->buffers.sig.length, + args->sigAlgo, ssl->suites->hashAlgo, key, + ssl->buffers.key + ); + break; + } + #endif /* !NO_RSA */ + default: + break; } - #endif /* !NO_RSA */ /* Check for error */ if (ret != 0) { @@ -23400,15 +24260,15 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, return (byte)GetCurveByOID(key->dp->oidSum); } -#endif /* HAVE_ECC || HAVE_CURVE25519 */ +#endif /* HAVE_ECC */ typedef struct SskeArgs { byte* output; /* not allocated */ - #if defined(HAVE_ECC) || defined(HAVE_ED25519) || \ + #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) || \ (!defined(NO_DH) && !defined(NO_RSA)) byte* sigDataBuf; #endif - #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) + #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) byte* exportBuf; #endif #ifndef NO_RSA @@ -23419,11 +24279,11 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, word32 tmpSigSz; word32 length; word32 sigSz; - #if defined(HAVE_ECC) || defined(HAVE_ED25519) || \ + #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) || \ (!defined(NO_DH) && !defined(NO_RSA)) word32 sigDataSz; #endif - #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) + #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) word32 exportSz; #endif #ifdef HAVE_QSH @@ -23439,13 +24299,13 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, (void)ssl; - #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) + #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) if (args->exportBuf) { XFREE(args->exportBuf, ssl->heap, DYNAMIC_TYPE_DER); args->exportBuf = NULL; } #endif - #if defined(HAVE_ECC) || defined(HAVE_ED25519) || \ + #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) || \ (!defined(NO_DH) && !defined(NO_RSA)) if (args->sigDataBuf) { XFREE(args->sigDataBuf, ssl->heap, DYNAMIC_TYPE_SIGNATURE); @@ -23508,19 +24368,20 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, /* Do some checks / debug msgs */ switch(ssl->specs.kea) { - #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519)) && \ - !defined(NO_PSK) + #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ + defined(HAVE_CURVE448)) && !defined(NO_PSK) case ecdhe_psk_kea: { WOLFSSL_MSG("Using ephemeral ECDH PSK"); break; } - #endif /* (HAVE_ECC || CURVE25519) && !NO_PSK */ + #endif /* (HAVE_ECC || CURVE25519 || CURVE448) && !NO_PSK */ #if defined(HAVE_ECC) case ecc_diffie_hellman_kea: { if (ssl->specs.static_ecdh) { - WOLFSSL_MSG("Using Static ECDH, not sending ServerKeyExchange"); + WOLFSSL_MSG("Using Static ECDH, not sending " + "ServerKeyExchange"); ERROR_OUT(0, exit_sske); } @@ -23622,12 +24483,13 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, break; } #endif /* !NO_DH && (!NO_PSK || !NO_RSA) */ - #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519)) && \ - !defined(NO_PSK) + #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ + defined(HAVE_CURVE448)) && !defined(NO_PSK) case ecdhe_psk_kea: /* Fall through to create temp ECC key */ - #endif /* (HAVE_ECC || CURVE25519) && !NO_PSK */ - #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) + #endif /* (HAVE_ECC || CURVE25519 || CURVE448) && !NO_PSK */ + #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ + defined(HAVE_CURVE448) case ecc_diffie_hellman_kea: { #ifdef HAVE_CURVE25519 @@ -23653,6 +24515,29 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, break; } #endif + #ifdef HAVE_CURVE448 + if (ssl->ecdhCurveOID == ECC_X448_OID) { + /* need ephemeral key now, create it if missing */ + if (ssl->eccTempKey == NULL) { + /* alloc/init on demand */ + ret = AllocKey(ssl, DYNAMIC_TYPE_CURVE448, + (void**)&ssl->eccTempKey); + if (ret != 0) { + goto exit_sske; + } + } + + if (ssl->eccTempKeyPresent == 0) { + ret = X448MakeKey(ssl, + (curve448_key*)ssl->eccTempKey, NULL); + if (ret == 0 || ret == WC_PENDING_E) { + ssl->eccTempKeyPresent = + DYNAMIC_TYPE_CURVE448; + } + } + break; + } + #endif #ifdef HAVE_ECC /* need ephemeral key now, create it if missing */ if (ssl->eccTempKey == NULL) { @@ -23673,7 +24558,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #endif break; } - #endif /* HAVE_ECC || HAVE_CURVE25519 */ + #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */ default: /* Skip ServerKeyExchange */ goto exit_sske; @@ -23692,7 +24577,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, case TLS_ASYNC_BUILD: { #if (!defined(NO_DH) && !defined(NO_RSA)) || (defined(HAVE_ECC) || \ - defined(HAVE_CURVE25519)) + defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)) word32 preSigSz, preSigIdx; #endif @@ -23845,8 +24730,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, break; } #endif /* !defined(NO_DH) && !defined(NO_PSK) */ - #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519)) && \ - !defined(NO_PSK) + #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ + defined(HAVE_CURVE448)) && !defined(NO_PSK) case ecdhe_psk_kea: { word32 hintLen; @@ -23871,6 +24756,17 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } } else + #endif + #ifdef HAVE_CURVE448 + if (ssl->ecdhCurveOID == ECC_X448_OID) { + if (wc_curve448_export_public_ex( + (curve448_key*)ssl->eccTempKey, + args->exportBuf, &args->exportSz, + EC448_LITTLE_ENDIAN) != 0) { + ERROR_OUT(ECC_EXPORT_ERROR, exit_sske); + } + } + else #endif { if (wc_ecc_export_x963(ssl->eccTempKey, @@ -23926,6 +24822,11 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if (ssl->ecdhCurveOID == ECC_X25519_OID) args->output[args->idx++] = WOLFSSL_ECC_X25519; else + #endif + #ifdef HAVE_CURVE448 + if (ssl->ecdhCurveOID == ECC_X448_OID) + args->output[args->idx++] = WOLFSSL_ECC_X448; + else #endif { #ifdef HAVE_ECC @@ -23938,8 +24839,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, args->exportSz); break; } - #endif /* (HAVE_ECC || HAVE_CURVE25519) && !NO_PSK */ - #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) + #endif /* (HAVE_ECC || CURVE25519 || CURVE448) && !NO_PSK */ + #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ + defined(HAVE_CURVE448) case ecc_diffie_hellman_kea: { enum wc_HashType hashType; @@ -23965,6 +24867,17 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } } else + #endif + #ifdef HAVE_CURVE448 + if (ssl->ecdhCurveOID == ECC_X448_OID) { + if (wc_curve448_export_public_ex( + (curve448_key*)ssl->eccTempKey, + args->exportBuf, &args->exportSz, + EC448_LITTLE_ENDIAN) != 0) { + ERROR_OUT(ECC_EXPORT_ERROR, exit_sske); + } + } + else #endif { #if defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT) @@ -24042,6 +24955,22 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, break; } #endif /* HAVE_ED25519 */ + #ifdef HAVE_ED448 + case ed448_sa_algo: + { + word16 keySz; + + ssl->buffers.keyType = ed448_sa_algo; + ret = DecodePrivateKey(ssl, &keySz); + if (ret != 0) { + goto exit_sske; + } + + /* worst case estimate */ + args->tmpSigSz = ED448_SIG_SIZE; + break; + } + #endif /* HAVE_ED448 */ default: ERROR_OUT(ALGO_ID_E, exit_sske); /* unsupported type */ } /* switch(ssl->specs.sig_algo) */ @@ -24091,6 +25020,11 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, if (ssl->ecdhCurveOID == ECC_X25519_OID) args->output[args->idx++] = WOLFSSL_ECC_X25519; else + #endif + #ifdef HAVE_CURVE448 + if (ssl->ecdhCurveOID == ECC_X448_OID) + args->output[args->idx++] = WOLFSSL_ECC_X448; + else #endif { #ifdef HAVE_ECC @@ -24149,7 +25083,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, XMEMCPY(args->sigDataBuf+RAN_LEN+RAN_LEN, args->output + preSigIdx, preSigSz); - if (ssl->suites->sigAlgo != ed25519_sa_algo) { + if (ssl->suites->sigAlgo != ed25519_sa_algo && + ssl->suites->sigAlgo != ed448_sa_algo) { ssl->buffers.sig.length = wc_HashGetDigestSize(hashType); if ((int)ssl->buffers.sig.length < 0) { @@ -24227,10 +25162,17 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, goto exit_sske; break; #endif /* HAVE_ED25519 */ + #ifdef HAVE_ED448 + case ed448_sa_algo: + ret = Ed448CheckPubKey(ssl); + if (ret != 0) + goto exit_sske; + break; + #endif /* HAVE_ED448 */ } /* switch(ssl->specs.sig_algo) */ break; } - #endif /* HAVE_ECC || HAVE_CURVE25519 */ + #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */ #if !defined(NO_DH) && !defined(NO_RSA) case diffie_hellman_kea: { @@ -24391,7 +25333,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, XMEMCPY(args->sigDataBuf+RAN_LEN+RAN_LEN, args->output + preSigIdx, preSigSz); - if (ssl->suites->sigAlgo != ed25519_sa_algo) { + if (ssl->suites->sigAlgo != ed25519_sa_algo && + ssl->suites->sigAlgo != ed448_sa_algo) { ssl->buffers.sig.length = wc_HashGetDigestSize(hashType); ssl->buffers.sig.buffer = (byte*)XMALLOC( @@ -24474,14 +25417,15 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, break; } #endif /* !defined(NO_DH) && !defined(NO_PSK) */ - #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519)) && \ - !defined(NO_PSK) + #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ + defined(HAVE_CURVE448)) && !defined(NO_PSK) case ecdhe_psk_kea: { break; } - #endif /* (HAVE_ECC || HAVE_CURVE25519) && !NO_PSK */ - #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) + #endif /* (HAVE_ECC || CURVE25519 || CURVE448) && !NO_PSK */ + #if defined(HAVE_ECC) || defined(HAVE_ED25519) || \ + defined(HAVE_ED448) case ecc_diffie_hellman_kea: { /* Sign hash to create signature */ @@ -24546,10 +25490,29 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, break; } #endif + #ifdef HAVE_ED448 + case ed448_sa_algo: + { + ed448_key* key = (ed448_key*)ssl->hsKey; + + ret = Ed448Sign(ssl, + args->sigDataBuf, args->sigDataSz, + args->output + LENGTH_SZ + args->idx, + &args->sigSz, + key, + #ifdef HAVE_PK_CALLBACKS + ssl->buffers.key + #else + NULL + #endif + ); + break; + } + #endif } /* switch(ssl->specs.sig_algo) */ break; } - #endif /* HAVE_ECC || HAVE_CURVE25519 */ + #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */ #if !defined(NO_DH) && !defined(NO_RSA) case diffie_hellman_kea: { @@ -24615,15 +25578,16 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, break; } #endif /* !defined(NO_DH) && !defined(NO_PSK) */ - #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519)) && \ - !defined(NO_PSK) + #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ + defined(HAVE_CURVE448)) && !defined(NO_PSK) case ecdhe_psk_kea: { /* Nothing to do in this sub-state */ break; } - #endif /* (HAVE_ECC || HAVE_CURVE25519) && !NO_PSK */ - #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) + #endif /* (HAVE_ECC || CURVE25519 || CURVE448) && !NO_PSK */ + #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ + defined(HAVE_CURVE448) case ecc_diffie_hellman_kea: { switch(ssl->suites->sigAlgo) @@ -24664,6 +25628,9 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, case ecc_dsa_sa_algo: #ifdef HAVE_ED25519 case ed25519_sa_algo: + #endif + #ifdef HAVE_ED448 + case ed448_sa_algo: #endif { /* Now that we know the real sig size, write it. */ @@ -24680,7 +25647,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } /* switch(ssl->specs.sig_algo) */ break; } - #endif /* HAVE_ECC || HAVE_CURVE25519 */ + #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */ #if !defined(NO_DH) && !defined(NO_RSA) case diffie_hellman_kea: { @@ -24764,7 +25731,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } #endif - #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) + #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ + defined(HAVE_CURVE448) if (ssl->specs.kea == ecdhe_psk_kea || ssl->specs.kea == ecc_diffie_hellman_kea) { /* Check output to make sure it was set */ @@ -24776,7 +25744,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, ERROR_OUT(BUFFER_ERROR, exit_sske); } } - #endif /* HAVE_ECC || HAVE_CURVE25519 */ + #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */ if (IsEncryptionOn(ssl, 1)) { args->inputSz = args->length + HANDSHAKE_HEADER_SZ; @@ -24993,8 +25961,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } #endif -#if (defined(HAVE_ECC) || defined(HAVE_CURVE25519)) && \ - defined(HAVE_SUPPORTED_CURVES) +#if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ + defined(HAVE_CURVE448)) && defined(HAVE_SUPPORTED_CURVES) if (!TLSX_ValidateSupportedCurves(ssl, first, second)) { WOLFSSL_MSG("Don't have matching curves"); return 0; @@ -25962,8 +26930,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } -#if (!defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519)) && \ - !defined(WOLFSSL_NO_CLIENT_AUTH) +#if (!defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519) || \ + defined(HAVE_ED448)) && !defined(WOLFSSL_NO_CLIENT_AUTH) typedef struct DcvArgs { byte* output; /* not allocated */ @@ -26062,6 +27030,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, else if (ssl->peerEd25519KeyPresent) args->sigAlgo = ed25519_sa_algo; #endif /* HAVE_ED25519 && !NO_ED25519_CLIENT_AUTH */ + #if defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH) + else if (ssl->peerEd448KeyPresent) + args->sigAlgo = ed448_sa_algo; + #endif /* HAVE_ED448 && !NO_ED448_CLIENT_AUTH */ if ((args->idx - args->begin) + OPAQUE16_LEN > size) { ERROR_OUT(BUFFER_ERROR, exit_dcv); @@ -26112,6 +27084,16 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } } #endif /* HAVE_ED25519 && !NO_ED25519_CLIENT_AUTH */ + #if defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH) + if (ssl->peerEd448KeyPresent) { + WOLFSSL_MSG("Doing ED448 peer cert verify"); + if (IsAtLeastTLSv1_2(ssl) && + args->sigAlgo != ed448_sa_algo) { + WOLFSSL_MSG( + "Oops, peer sent ED448 key but not in verify"); + } + } + #endif /* HAVE_ED448 && !NO_ED448_CLIENT_AUTH */ /* Advance state and proceed */ ssl->options.asyncState = TLS_ASYNC_DO; @@ -26179,6 +27161,22 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, ); } #endif /* HAVE_ED25519 && !NO_ED25519_CLIENT_AUTH */ + #if defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH) + if (ssl->peerEd448KeyPresent) { + WOLFSSL_MSG("Doing Ed448 peer cert verify"); + + ret = Ed448Verify(ssl, + input + args->idx, args->sz, + ssl->hsHashes->messages, ssl->hsHashes->prevLen, + ssl->peerEd448Key, + #ifdef HAVE_PK_CALLBACKS + &ssl->buffers.peerEd448Key + #else + NULL + #endif + ); + } + #endif /* HAVE_ED448 && !NO_ED448_CLIENT_AUTH */ #ifdef WOLFSSL_ASYNC_CRYPT /* handle async pending */ @@ -26341,7 +27339,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, return ret; } -#endif /* (!NO_RSA || HAVE_ECC || HAVE_ED25519) && !WOLFSSL_NO_CLIENT_AUTH */ +#endif /* (!NO_RSA || ECC || ED25519 || ED448) && !WOLFSSL_NO_CLIENT_AUTH */ /* handle generation of server_hello_done (14) */ int SendServerHelloDone(WOLFSSL* ssl) @@ -27010,12 +28008,13 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, break; } #endif /* HAVE_NTRU */ - #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) + #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ + defined(HAVE_CURVE448) case ecc_diffie_hellman_kea: { break; } - #endif /* HAVE_ECC || HAVE_CURVE25519 */ + #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */ #ifndef NO_DH case diffie_hellman_kea: { @@ -27033,8 +28032,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, break; } #endif /* !NO_DH && !NO_PSK */ - #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519)) && \ - !defined(NO_PSK) + #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ + defined(HAVE_CURVE448)) && !defined(NO_PSK) case ecdhe_psk_kea: { /* sanity check that PSK server callback has been set */ @@ -27044,7 +28043,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } break; } - #endif /* (HAVE_ECC || HAVE_CURVE25519) && !NO_PSK */ + #endif /* (HAVE_ECC || CURVE25519 || CURVE448) && !NO_PSK */ default: WOLFSSL_MSG("Bad kea type"); ret = BAD_KEA_TYPE_E; @@ -27202,7 +28201,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, break; } #endif /* HAVE_NTRU */ - #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) + #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ + defined(HAVE_CURVE448) case ecc_diffie_hellman_kea: { #ifdef HAVE_ECC @@ -27210,7 +28210,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, /* handle static private key */ if (ssl->specs.static_ecdh && - ssl->ecdhCurveOID != ECC_X25519_OID) { + ssl->ecdhCurveOID != ECC_X25519_OID && + ssl->ecdhCurveOID != ECC_X448_OID) { word16 keySz; ssl->buffers.keyType = ecc_dsa_sa_algo; @@ -27293,6 +28294,63 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, ssl->peerX25519KeyPresent = 1; + break; + } + #endif + #ifdef HAVE_CURVE448 + if (ssl->ecdhCurveOID == ECC_X448_OID) { + #ifdef HAVE_PK_CALLBACKS + /* if callback then use it for shared secret */ + if (ssl->ctx->X448SharedSecretCb != NULL) { + break; + } + #endif + if (ssl->peerX448Key == NULL) { + /* alloc/init on demand */ + ret = AllocKey(ssl, DYNAMIC_TYPE_CURVE448, + (void**)&ssl->peerX448Key); + if (ret != 0) { + goto exit_dcke; + } + } else if (ssl->peerX448KeyPresent) { + ret = ReuseKey(ssl, DYNAMIC_TYPE_CURVE448, + ssl->peerX448Key); + ssl->peerX448KeyPresent = 0; + if (ret != 0) { + goto exit_dcke; + } + } + + if ((ret = wc_curve448_check_public( + input + args->idx, args->length, + EC448_LITTLE_ENDIAN)) != 0) { + #ifdef WOLFSSL_EXTRA_ALERTS + if (ret == BUFFER_E) + SendAlert(ssl, alert_fatal, decode_error); + else if (ret == ECC_OUT_OF_RANGE_E) + SendAlert(ssl, alert_fatal, bad_record_mac); + else { + SendAlert(ssl, alert_fatal, + illegal_parameter); + } + #endif + ERROR_OUT(ECC_PEERKEY_ERROR, exit_dcke); + } + + if (wc_curve448_import_public_ex( + input + args->idx, args->length, + ssl->peerX448Key, + EC448_LITTLE_ENDIAN)) { + #ifdef WOLFSSL_EXTRA_ALERTS + SendAlert(ssl, alert_fatal, illegal_parameter); + #endif + ERROR_OUT(ECC_PEERKEY_ERROR, exit_dcke); + } + + ssl->arrays->preMasterSz = CURVE448_KEY_SIZE; + + ssl->peerX448KeyPresent = 1; + break; } #endif @@ -27342,7 +28400,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, break; } - #endif /* HAVE_ECC || HAVE_CURVE25519 */ + #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */ #ifndef NO_DH case diffie_hellman_kea: { @@ -27435,8 +28493,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, break; } #endif /* !NO_DH && !NO_PSK */ - #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519)) && \ - !defined(NO_PSK) + #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ + defined(HAVE_CURVE448)) && !defined(NO_PSK) case ecdhe_psk_kea: { word16 clientSz; @@ -27532,6 +28590,65 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, break; } #endif + #ifdef HAVE_CURVE448 + if (ssl->ecdhCurveOID == ECC_X448_OID) { + #ifdef HAVE_PK_CALLBACKS + /* if callback then use it for shared secret */ + if (ssl->ctx->X448SharedSecretCb != NULL) { + break; + } + #endif + + if (ssl->eccTempKeyPresent == 0) { + WOLFSSL_MSG( + "X448 ephemeral key not made correctly"); + ERROR_OUT(ECC_MAKEKEY_ERROR, exit_dcke); + } + + if (ssl->peerX448Key == NULL) { + /* alloc/init on demand */ + ret = AllocKey(ssl, DYNAMIC_TYPE_CURVE448, + (void**)&ssl->peerX448Key); + if (ret != 0) { + goto exit_dcke; + } + } else if (ssl->peerX448KeyPresent) { + ret = ReuseKey(ssl, DYNAMIC_TYPE_CURVE448, + ssl->peerX448Key); + ssl->peerX448KeyPresent = 0; + if (ret != 0) { + goto exit_dcke; + } + } + + if ((ret = wc_curve448_check_public( + input + args->idx, args->length, + EC448_LITTLE_ENDIAN)) != 0) { + #ifdef WOLFSSL_EXTRA_ALERTS + if (ret == BUFFER_E) + SendAlert(ssl, alert_fatal, decode_error); + else if (ret == ECC_OUT_OF_RANGE_E) + SendAlert(ssl, alert_fatal, bad_record_mac); + else { + SendAlert(ssl, alert_fatal, + illegal_parameter); + } + #endif + ERROR_OUT(ECC_PEERKEY_ERROR, exit_dcke); + } + + if (wc_curve448_import_public_ex( + input + args->idx, args->length, + ssl->peerX448Key, + EC448_LITTLE_ENDIAN)) { + ERROR_OUT(ECC_PEERKEY_ERROR, exit_dcke); + } + + ssl->peerX448KeyPresent = 1; + + break; + } + #endif #ifdef HAVE_PK_CALLBACKS /* if callback then use it for shared secret */ if (ssl->ctx->EccSharedSecretCb != NULL) { @@ -27560,15 +28677,16 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, goto exit_dcke; } } - if (wc_ecc_import_x963_ex(input + args->idx, args->length, - ssl->peerEccKey, ssl->eccTempKey->dp->id)) { + if (wc_ecc_import_x963_ex(input + args->idx, + args->length, ssl->peerEccKey, + ssl->eccTempKey->dp->id)) { ERROR_OUT(ECC_PEERKEY_ERROR, exit_dcke); } ssl->peerEccKeyPresent = 1; break; } - #endif /* (HAVE_ECC || HAVE_CURVE25519) && !NO_PSK */ + #endif /* (HAVE_ECC || CURVE25519 || CURVE448) && !NO_PSK */ default: ret = BAD_KEA_TYPE_E; } /* switch (ssl->specs.kea) */ @@ -27632,7 +28750,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, break; } #endif /* HAVE_NTRU */ - #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) + #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ + defined(HAVE_CURVE448) case ecc_diffie_hellman_kea: { void* private_key = ssl->eccTempKey; @@ -27651,6 +28770,19 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, break; } #endif + #ifdef HAVE_CURVE448 + if (ssl->ecdhCurveOID == ECC_X448_OID) { + ret = X448SharedSecret(ssl, + (curve448_key*)private_key, + ssl->peerX448Key, + input + args->idx, &args->length, + ssl->arrays->preMasterSecret, + &ssl->arrays->preMasterSz, + WOLFSSL_SERVER_END + ); + break; + } + #endif #ifdef HAVE_ECC if (ssl->specs.static_ecdh) { private_key = ssl->hsKey; @@ -27675,7 +28807,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, #endif break; } - #endif /* HAVE_ECC || HAVE_CURVE25519 */ + #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */ #ifndef NO_DH case diffie_hellman_kea: { @@ -27702,8 +28834,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, break; } #endif /* !NO_DH && !NO_PSK */ - #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519)) && \ - !defined(NO_PSK) + #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ + defined(HAVE_CURVE448)) && !defined(NO_PSK) case ecdhe_psk_kea: { #ifdef HAVE_CURVE25519 @@ -27726,6 +28858,27 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } break; } + #endif + #ifdef HAVE_CURVE448 + if (ssl->ecdhCurveOID == ECC_X448_OID) { + ret = X448SharedSecret(ssl, + (curve448_key*)ssl->eccTempKey, + ssl->peerX448Key, + input + args->idx, &args->length, + ssl->arrays->preMasterSecret + OPAQUE16_LEN, + &args->sigSz, + WOLFSSL_SERVER_END + ); + #ifdef WOLFSSL_ASYNC_CRYPT + if (ret != WC_PENDING_E) + #endif + { + FreeKey(ssl, DYNAMIC_TYPE_CURVE448, + (void**)&ssl->peerX448Key); + ssl->peerX448KeyPresent = 0; + } + break; + } #endif /* Generate shared secret */ ret = EccSharedSecret(ssl, @@ -27746,7 +28899,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, } break; } - #endif /* (HAVE_ECC || HAVE_CURVE25519) && !NO_PSK */ + #endif /* (HAVE_ECC || CURVE25519 || CURVE448) && !NO_PSK */ default: ret = BAD_KEA_TYPE_E; } /* switch (ssl->specs.kea) */ @@ -27827,14 +28980,15 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, break; } #endif /* HAVE_NTRU */ - #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) + #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ + defined(HAVE_CURVE448) case ecc_diffie_hellman_kea: { /* skip past the imported peer key */ args->idx += args->length; break; } - #endif /* HAVE_ECC || HAVE_CURVE25519 */ + #endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */ #ifndef NO_DH case diffie_hellman_kea: { @@ -27874,8 +29028,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, break; } #endif /* !NO_DH && !NO_PSK */ - #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519)) && \ - !defined(NO_PSK) + #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ + defined(HAVE_CURVE448)) && !defined(NO_PSK) case ecdhe_psk_kea: { byte* pms = ssl->arrays->preMasterSecret; @@ -27908,7 +29062,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx, ssl->arrays->psk_keySz + OPAQUE16_LEN; break; } - #endif /* (HAVE_ECC || HAVE_CURVE25519) && !NO_PSK */ + #endif /* (HAVE_ECC || CURVE25519 || CURVE448) && !NO_PSK */ default: ret = BAD_KEA_TYPE_E; } /* switch (ssl->specs.kea) */ diff --git a/src/keys.c b/src/keys.c index 917a40914..e7aa36173 100644 --- a/src/keys.c +++ b/src/keys.c @@ -241,7 +241,7 @@ int SetCipherSpecs(WOLFSSL* ssl) switch (ssl->options.cipherSuite) { -#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) +#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) #ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 : @@ -417,9 +417,10 @@ int SetCipherSpecs(WOLFSSL* ssl) break; #endif -#endif /* HAVE_ECC || HAVE_CURVE25519 */ +#endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */ -#if defined(HAVE_ECC) || (defined(HAVE_CURVE25519) && defined(HAVE_ED25519)) +#if defined(HAVE_ECC) || (defined(HAVE_CURVE25519) && defined(HAVE_ED25519)) \ + || (defined(HAVE_CURVE448) && defined(HAVE_ED448)) #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 : @@ -630,7 +631,7 @@ int SetCipherSpecs(WOLFSSL* ssl) break; #endif -#endif /* HAVE_ECC || (HAVE_CURVE25519 && HAVE_ED25519) */ +#endif /* HAVE_ECC || (CURVE25519 && ED25519) || (CURVE448 && ED448) */ #if defined(HAVE_ECC) diff --git a/src/ssl.c b/src/ssl.c index dea5a1d3c..96b99596c 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -52,7 +52,7 @@ #if !defined(WOLFSSL_ALLOW_NO_SUITES) && !defined(WOLFCRYPT_ONLY) #if defined(NO_DH) && !defined(HAVE_ECC) && !defined(WOLFSSL_STATIC_RSA) \ && !defined(WOLFSSL_STATIC_DH) && !defined(WOLFSSL_STATIC_PSK) \ - && !defined(HAVE_ED25519) + && !defined(HAVE_ED25519) && !defined(HAVE_ED448) #error "No cipher suites defined because DH disabled, ECC disabled, and no static suites defined. Please see top of README" #endif #ifdef WOLFSSL_CERT_GEN @@ -87,6 +87,8 @@ #include #include #include + #include + #include #include #include #include @@ -105,6 +107,7 @@ #include #include #include + #include #if defined(OPENSSL_ALL) || defined(HAVE_STUNNEL) #include #endif /* WITH_STUNNEL */ @@ -2344,6 +2347,7 @@ int wolfSSL_UseSupportedCurve(WOLFSSL* ssl, word16 name) case WOLFSSL_ECC_BRAINPOOLP384R1: case WOLFSSL_ECC_BRAINPOOLP512R1: case WOLFSSL_ECC_X25519: + case WOLFSSL_ECC_X448: case WOLFSSL_FFDHE_2048: case WOLFSSL_FFDHE_3072: @@ -2383,6 +2387,7 @@ int wolfSSL_CTX_UseSupportedCurve(WOLFSSL_CTX* ctx, word16 name) case WOLFSSL_ECC_BRAINPOOLP384R1: case WOLFSSL_ECC_BRAINPOOLP512R1: case WOLFSSL_ECC_X25519: + case WOLFSSL_ECC_X448: case WOLFSSL_FFDHE_2048: case WOLFSSL_FFDHE_3072: case WOLFSSL_FFDHE_4096: @@ -5069,6 +5074,15 @@ int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify) } break; #endif /* HAVE_ED25519 */ + #ifdef HAVE_ED448 + case ED448k: + if (cm->minEccKeySz < 0 || + ED448_KEY_SIZE < (word16)cm->minEccKeySz) { + ret = ECC_KEY_SIZE_E; + WOLFSSL_MSG("\tCA ECC key size error"); + } + break; + #endif /* HAVE_ED448 */ default: WOLFSSL_MSG("\tNo key size check done on CA"); @@ -5510,8 +5524,10 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der *idx = 0; if (wc_RsaPrivateKeyDecode(der->buffer, idx, key, der->length) != 0) { - #if !defined(HAVE_ECC) && !defined(HAVE_ED25519) - WOLFSSL_MSG("RSA decode failed and ECC/ED25519 not enabled to try"); + #if !defined(HAVE_ECC) && !defined(HAVE_ED25519) && \ + !defined(HAVE_ED448) + WOLFSSL_MSG("RSA decode failed and ECC/ED25519/ED448 not " + "enabled to try"); ret = WOLFSSL_BAD_FILE; #endif } @@ -5623,11 +5639,7 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der if (ret == 0) { *idx = 0; if (wc_Ed25519PrivateKeyDecode(der->buffer, idx, key, - der->length) != 0) { - ret = WOLFSSL_BAD_FILE; - } - - if (ret == 0) { + der->length) == 0) { /* check for minimum key size and then free */ int minKeySz = ssl ? ssl->options.minEccKeySz : ctx->minEccKeySz; @@ -5636,20 +5648,20 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der WOLFSSL_MSG("ED25519 private key too small"); ret = ECC_KEY_SIZE_E; } - } - if (ret == 0) { - if (ssl) { - ssl->buffers.keyType = ed25519_sa_algo; - ssl->buffers.keySz = *keySz; - } - else if (ctx) { - ctx->privateKeyType = ed25519_sa_algo; - ctx->privateKeySz = *keySz; - } + if (ret == 0) { + if (ssl) { + ssl->buffers.keyType = ed25519_sa_algo; + ssl->buffers.keySz = *keySz; + } + else if (ctx) { + ctx->privateKeyType = ed25519_sa_algo; + ctx->privateKeySz = *keySz; + } - *keyFormat = ED25519k; - if (ssl && ssl->options.side == WOLFSSL_SERVER_END) { - *resetSuites = 1; + *keyFormat = ED25519k; + if (ssl && ssl->options.side == WOLFSSL_SERVER_END) { + *resetSuites = 1; + } } } @@ -5661,6 +5673,63 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der #endif } #endif /* HAVE_ED25519 */ +#ifdef HAVE_ED448 + if (ret == 0 && (*keyFormat == 0 || *keyFormat == ED448k)) { + /* make sure Ed448 key can be used */ + #ifdef WOLFSSL_SMALL_STACK + ed448_key* key = NULL; + #else + ed448_key key[1]; + #endif + + #ifdef WOLFSSL_SMALL_STACK + key = (ed448_key*)XMALLOC(sizeof(ed448_key), heap, DYNAMIC_TYPE_ED448); + if (key == NULL) + return MEMORY_E; + #endif + + ret = wc_ed448_init(key); + if (ret == 0) { + *idx = 0; + if (wc_Ed448PrivateKeyDecode(der->buffer, idx, key, + der->length) != 0) { + ret = WOLFSSL_BAD_FILE; + } + + if (ret == 0) { + /* check for minimum key size and then free */ + int minKeySz = ssl ? ssl->options.minEccKeySz : + ctx->minEccKeySz; + *keySz = ED448_KEY_SIZE; + if (*keySz < minKeySz) { + WOLFSSL_MSG("ED448 private key too small"); + ret = ECC_KEY_SIZE_E; + } + } + if (ret == 0) { + if (ssl) { + ssl->buffers.keyType = ed448_sa_algo; + ssl->buffers.keySz = *keySz; + } + else if (ctx) { + ctx->privateKeyType = ed448_sa_algo; + ctx->privateKeySz = *keySz; + } + + *keyFormat = ED448k; + if (ssl && ssl->options.side == WOLFSSL_SERVER_END) { + *resetSuites = 1; + } + } + + wc_ed448_free(key); + } + + #ifdef WOLFSSL_SMALL_STACK + XFREE(key, heap, DYNAMIC_TYPE_ED448); + #endif + } +#endif /* HAVE_ED448 */ return ret; } @@ -5997,12 +6066,19 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, else if (ctx) ctx->haveECDSAsig = 1; break; + case CTC_ED448: + WOLFSSL_MSG("ED448 cert signature"); + if (ssl) + ssl->options.haveECDSAsig = 1; + else if (ctx) + ctx->haveECDSAsig = 1; + break; default: WOLFSSL_MSG("Not ECDSA cert signature"); break; } - #if defined(HAVE_ECC) || defined(HAVE_ED25519) + #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) if (ssl) { ssl->pkCurveOID = cert->pkCurveOID; #ifndef WC_STRICT_SIG @@ -6014,6 +6090,11 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, ssl->options.haveECC = 1; } #endif + #ifdef HAVE_ED448 + else if (cert->keyOID == ED448k) { + ssl->options.haveECC = 1; + } + #endif #else ssl->options.haveECC = ssl->options.haveECDSAsig; #endif @@ -6029,6 +6110,11 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, ctx->haveECC = 1; } #endif + #ifdef HAVE_ED448 + else if (cert->keyOID == ED448k) { + ctx->haveECC = 1; + } + #endif #else ctx->haveECC = ctx->haveECDSAsig; #endif @@ -6137,6 +6223,37 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff, } break; #endif /* HAVE_ED25519 */ + #ifdef HAVE_ED448 + case ED448k: + #ifdef HAVE_PK_CALLBACKS + keyType = ed448_sa_algo; + #endif + #ifdef HAVE_PKCS11 + if (ctx) { + ctx->privateKeyType = ed448_sa_algo; + } + else { + ssl->buffers.keyType = ed448_sa_algo; + } + #endif + /* ED448 is fixed key size */ + keySz = ED448_KEY_SIZE; + if (ssl && !ssl->options.verifyNone) { + if (ssl->options.minEccKeySz < 0 || + keySz < (int)ssl->options.minEccKeySz) { + ret = ECC_KEY_SIZE_E; + WOLFSSL_MSG("Certificate Ed key size error"); + } + } + else if (ctx && !ctx->verifyNone) { + if (ctx->minEccKeySz < 0 || + keySz < (int)ctx->minEccKeySz) { + ret = ECC_KEY_SIZE_E; + WOLFSSL_MSG("Certificate ECC key size error"); + } + } + break; + #endif /* HAVE_ED448 */ default: WOLFSSL_MSG("No key size check done on certificate"); @@ -22427,7 +22544,8 @@ void wolfSSL_sk_CIPHER_free(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk) } #endif -#if defined(HAVE_ECC) || !defined(NO_DH) +#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) || \ + !defined(NO_DH) #ifdef HAVE_FFDHE static const char* wolfssl_ffdhe_name(word16 group) { @@ -22476,6 +22594,12 @@ const char* wolfSSL_get_curve_name(WOLFSSL* ssl) } #endif +#ifdef HAVE_CURVE448 + if (ssl->ecdhCurveOID == ECC_X448_OID && cName == NULL) { + cName = "X448"; + } +#endif + #ifdef HAVE_ECC if (ssl->ecdhCurveOID != 0 && cName == NULL) { cName = wc_ecc_get_name(wc_ecc_get_oid(ssl->ecdhCurveOID, NULL, @@ -33444,22 +33568,22 @@ int wolfSSL_EVP_PKEY_assign(WOLFSSL_EVP_PKEY *pkey, int type, void *key) switch(type) { #ifndef NO_RSA case EVP_PKEY_RSA: - ret = wolfSSL_EVP_PKEY_assign_RSA(pkey,key); + ret = wolfSSL_EVP_PKEY_assign_RSA(pkey, (WOLFSSL_RSA*)key); break; #endif #ifndef NO_DSA case EVP_PKEY_DSA: - ret = wolfSSL_EVP_PKEY_assign_DSA(pkey, key); + ret = wolfSSL_EVP_PKEY_assign_DSA(pkey, (WOLFSSL_DSA*)key); break; #endif #ifdef HAVE_ECC case EVP_PKEY_EC: - ret = wolfSSL_EVP_PKEY_assign_EC_KEY(pkey,key); + ret = wolfSSL_EVP_PKEY_assign_EC_KEY(pkey, (WOLFSSL_EC_KEY*)key); break; #endif #ifdef NO_DH case EVP_PKEY_DH: - ret = wolfSSL_EVP_PKEY_assign_DH(pkey,key); + ret = wolfSSL_EVP_PKEY_assign_DH(pkey, (WOLFSSL_DH*)key); break; #endif default: @@ -38720,6 +38844,84 @@ void* wolfSSL_GetX25519SharedSecretCtx(WOLFSSL* ssl) } #endif /* HAVE_CURVE25519 */ +#ifdef HAVE_ED448 +void wolfSSL_CTX_SetEd448SignCb(WOLFSSL_CTX* ctx, CallbackEd448Sign cb) +{ + if (ctx) + ctx->Ed448SignCb = cb; +} +void wolfSSL_SetEd448SignCtx(WOLFSSL* ssl, void *ctx) +{ + if (ssl) + ssl->Ed448SignCtx = ctx; +} +void* wolfSSL_GetEd448SignCtx(WOLFSSL* ssl) +{ + if (ssl) + return ssl->Ed448SignCtx; + + return NULL; +} + +void wolfSSL_CTX_SetEd448VerifyCb(WOLFSSL_CTX* ctx, CallbackEd448Verify cb) +{ + if (ctx) + ctx->Ed448VerifyCb = cb; +} +void wolfSSL_SetEd448VerifyCtx(WOLFSSL* ssl, void *ctx) +{ + if (ssl) + ssl->Ed448VerifyCtx = ctx; +} +void* wolfSSL_GetEd448VerifyCtx(WOLFSSL* ssl) +{ + if (ssl) + return ssl->Ed448VerifyCtx; + + return NULL; +} +#endif /* HAVE_ED448 */ + +#ifdef HAVE_CURVE448 +void wolfSSL_CTX_SetX448KeyGenCb(WOLFSSL_CTX* ctx, + CallbackX448KeyGen cb) +{ + if (ctx) + ctx->X448KeyGenCb = cb; +} +void wolfSSL_SetX448KeyGenCtx(WOLFSSL* ssl, void *ctx) +{ + if (ssl) + ssl->X448KeyGenCtx = ctx; +} +void* wolfSSL_GetX448KeyGenCtx(WOLFSSL* ssl) +{ + if (ssl) + return ssl->X448KeyGenCtx; + + return NULL; +} + +void wolfSSL_CTX_SetX448SharedSecretCb(WOLFSSL_CTX* ctx, + CallbackX448SharedSecret cb) +{ + if (ctx) + ctx->X448SharedSecretCb = cb; +} +void wolfSSL_SetX448SharedSecretCtx(WOLFSSL* ssl, void *ctx) +{ + if (ssl) + ssl->X448SharedSecretCtx = ctx; +} +void* wolfSSL_GetX448SharedSecretCtx(WOLFSSL* ssl) +{ + if (ssl) + return ssl->X448SharedSecretCtx; + + return NULL; +} +#endif /* HAVE_CURVE448 */ + #ifndef NO_RSA void wolfSSL_CTX_SetRsaSignCb(WOLFSSL_CTX* ctx, CallbackRsaSign cb) { @@ -41581,12 +41783,15 @@ err: break; #ifdef HAVE_ED25519 case ED25519k: + #endif + #ifdef HAVE_ED448 + case ED448k: #endif case ECDSAk: ctx->haveECC = 1; - #if defined(HAVE_ECC) || defined(HAVE_ED25519) + #if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) ctx->pkCurveOID = x->pkCurveOID; - #endif + #endif break; } @@ -43437,7 +43642,7 @@ long wolfSSL_CTX_ctrl(WOLFSSL_CTX* ctx, int cmd, long opt, void* pt) ret = WOLFSSL_FAILURE; break; } - return wolfSSL_CTX_add_extra_chain_cert(ctx,pt); + return wolfSSL_CTX_add_extra_chain_cert(ctx, (WOLFSSL_X509*)pt); #ifndef NO_DH case SSL_CTRL_SET_TMP_DH: @@ -43447,7 +43652,7 @@ long wolfSSL_CTX_ctrl(WOLFSSL_CTX* ctx, int cmd, long opt, void* pt) ret = WOLFSSL_FAILURE; break; } - return wolfSSL_CTX_set_tmp_dh(ctx, pt); + return wolfSSL_CTX_set_tmp_dh(ctx, (WOLFSSL_DH*)pt); #endif #ifdef HAVE_ECC @@ -43458,7 +43663,7 @@ long wolfSSL_CTX_ctrl(WOLFSSL_CTX* ctx, int cmd, long opt, void* pt) ret = WOLFSSL_FAILURE; break; } - return wolfSSL_SSL_CTX_set_tmp_ecdh(ctx,pt); + return wolfSSL_SSL_CTX_set_tmp_ecdh(ctx, (WOLFSSL_EC_KEY*)pt); #endif case SSL_CTRL_MODE: wolfSSL_CTX_set_mode(ctx,opt); @@ -45456,6 +45661,338 @@ int wolfSSL_ED25519_verify(const unsigned char *msg, unsigned int msgSz, #endif /* OPENSSL_EXTRA && HAVE_ED25519 */ +#if defined(OPENSSL_EXTRA) && defined(HAVE_CURVE448) +/* return 1 if success, 0 if error + * output keys are little endian format + */ +int wolfSSL_EC448_generate_key(unsigned char *priv, unsigned int *privSz, + unsigned char *pub, unsigned int *pubSz) +{ +#ifndef WOLFSSL_KEY_GEN + WOLFSSL_MSG("No Key Gen built in"); + (void) priv; + (void) privSz; + (void) pub; + (void) pubSz; + return WOLFSSL_FAILURE; +#else /* WOLFSSL_KEY_GEN */ + int ret = WOLFSSL_FAILURE; + int initTmpRng = 0; + WC_RNG *rng = NULL; +#ifdef WOLFSSL_SMALL_STACK + WC_RNG *tmpRNG = NULL; +#else + WC_RNG tmpRNG[1]; +#endif + + WOLFSSL_ENTER("wolfSSL_EC448_generate_key"); + + if (priv == NULL || privSz == NULL || *privSz < CURVE448_KEY_SIZE || + pub == NULL || pubSz == NULL || *pubSz < CURVE448_KEY_SIZE) { + WOLFSSL_MSG("Bad arguments"); + return WOLFSSL_FAILURE; + } + +#ifdef WOLFSSL_SMALL_STACK + tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG); + if (tmpRNG == NULL) + return WOLFSSL_FAILURE; +#endif + if (wc_InitRng(tmpRNG) == 0) { + rng = tmpRNG; + initTmpRng = 1; + } + else { + WOLFSSL_MSG("Bad RNG Init, trying global"); + if (initGlobalRNG == 0) + WOLFSSL_MSG("Global RNG no Init"); + else + rng = &globalRNG; + } + + if (rng) { + curve448_key key; + + if (wc_curve448_init(&key) != MP_OKAY) + WOLFSSL_MSG("wc_curve448_init failed"); + else if (wc_curve448_make_key(rng, CURVE448_KEY_SIZE, &key)!=MP_OKAY) + WOLFSSL_MSG("wc_curve448_make_key failed"); + /* export key pair */ + else if (wc_curve448_export_key_raw_ex(&key, priv, privSz, pub, pubSz, + EC448_LITTLE_ENDIAN) + != MP_OKAY) + WOLFSSL_MSG("wc_curve448_export_key_raw_ex failed"); + else + ret = WOLFSSL_SUCCESS; + + wc_curve448_free(&key); + } + + if (initTmpRng) + wc_FreeRng(tmpRNG); + +#ifdef WOLFSSL_SMALL_STACK + XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG); +#endif + + return ret; +#endif /* WOLFSSL_KEY_GEN */ +} + +/* return 1 if success, 0 if error + * input and output keys are little endian format + */ +int wolfSSL_EC448_shared_key(unsigned char *shared, unsigned int *sharedSz, + const unsigned char *priv, unsigned int privSz, + const unsigned char *pub, unsigned int pubSz) +{ +#ifndef WOLFSSL_KEY_GEN + WOLFSSL_MSG("No Key Gen built in"); + (void) shared; + (void) sharedSz; + (void) priv; + (void) privSz; + (void) pub; + (void) pubSz; + return WOLFSSL_FAILURE; +#else /* WOLFSSL_KEY_GEN */ + int ret = WOLFSSL_FAILURE; + curve448_key privkey, pubkey; + + WOLFSSL_ENTER("wolfSSL_EC448_shared_key"); + + if (shared == NULL || sharedSz == NULL || *sharedSz < CURVE448_KEY_SIZE || + priv == NULL || privSz < CURVE448_KEY_SIZE || + pub == NULL || pubSz < CURVE448_KEY_SIZE) { + WOLFSSL_MSG("Bad arguments"); + return WOLFSSL_FAILURE; + } + + /* import private key */ + if (wc_curve448_init(&privkey) != MP_OKAY) { + WOLFSSL_MSG("wc_curve448_init privkey failed"); + return ret; + } + if (wc_curve448_import_private_ex(priv, privSz, &privkey, + EC448_LITTLE_ENDIAN) != MP_OKAY) { + WOLFSSL_MSG("wc_curve448_import_private_ex failed"); + wc_curve448_free(&privkey); + return ret; + } + + /* import public key */ + if (wc_curve448_init(&pubkey) != MP_OKAY) { + WOLFSSL_MSG("wc_curve448_init pubkey failed"); + wc_curve448_free(&privkey); + return ret; + } + if (wc_curve448_import_public_ex(pub, pubSz, &pubkey, + EC448_LITTLE_ENDIAN) != MP_OKAY) { + WOLFSSL_MSG("wc_curve448_import_public_ex failed"); + wc_curve448_free(&privkey); + wc_curve448_free(&pubkey); + return ret; + } + + if (wc_curve448_shared_secret_ex(&privkey, &pubkey, shared, sharedSz, + EC448_LITTLE_ENDIAN) != MP_OKAY) + WOLFSSL_MSG("wc_curve448_shared_secret_ex failed"); + else + ret = WOLFSSL_SUCCESS; + + wc_curve448_free(&privkey); + wc_curve448_free(&pubkey); + + return ret; +#endif /* WOLFSSL_KEY_GEN */ +} +#endif /* OPENSSL_EXTRA && HAVE_CURVE448 */ + +#if defined(OPENSSL_EXTRA) && defined(HAVE_ED448) +/* return 1 if success, 0 if error + * output keys are little endian format + */ +int wolfSSL_ED448_generate_key(unsigned char *priv, unsigned int *privSz, + unsigned char *pub, unsigned int *pubSz) +{ +#ifndef WOLFSSL_KEY_GEN + WOLFSSL_MSG("No Key Gen built in"); + (void) priv; + (void) privSz; + (void) pub; + (void) pubSz; + return WOLFSSL_FAILURE; +#else /* WOLFSSL_KEY_GEN */ + int ret = WOLFSSL_FAILURE; + int initTmpRng = 0; + WC_RNG *rng = NULL; +#ifdef WOLFSSL_SMALL_STACK + WC_RNG *tmpRNG = NULL; +#else + WC_RNG tmpRNG[1]; +#endif + + WOLFSSL_ENTER("wolfSSL_ED448_generate_key"); + + if (priv == NULL || privSz == NULL || *privSz < ED448_PRV_KEY_SIZE || + pub == NULL || pubSz == NULL || *pubSz < ED448_PUB_KEY_SIZE) { + WOLFSSL_MSG("Bad arguments"); + return WOLFSSL_FAILURE; + } + +#ifdef WOLFSSL_SMALL_STACK + tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG); + if (tmpRNG == NULL) + return WOLFSSL_FATAL_ERROR; +#endif + if (wc_InitRng(tmpRNG) == 0) { + rng = tmpRNG; + initTmpRng = 1; + } + else { + WOLFSSL_MSG("Bad RNG Init, trying global"); + if (initGlobalRNG == 0) + WOLFSSL_MSG("Global RNG no Init"); + else + rng = &globalRNG; + } + + if (rng) { + ed448_key key; + + if (wc_ed448_init(&key) != MP_OKAY) + WOLFSSL_MSG("wc_ed448_init failed"); + else if (wc_ed448_make_key(rng, ED448_KEY_SIZE, &key) != MP_OKAY) + WOLFSSL_MSG("wc_ed448_make_key failed"); + /* export private key */ + else if (wc_ed448_export_key(&key, priv, privSz, pub, pubSz) != MP_OKAY) + WOLFSSL_MSG("wc_ed448_export_key failed"); + else + ret = WOLFSSL_SUCCESS; + + wc_ed448_free(&key); + } + + if (initTmpRng) + wc_FreeRng(tmpRNG); + +#ifdef WOLFSSL_SMALL_STACK + XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG); +#endif + + return ret; +#endif /* WOLFSSL_KEY_GEN */ +} + +/* return 1 if success, 0 if error + * input and output keys are little endian format + * priv is a buffer containing private and public part of key + */ +int wolfSSL_ED448_sign(const unsigned char *msg, unsigned int msgSz, + const unsigned char *priv, unsigned int privSz, + unsigned char *sig, unsigned int *sigSz) +{ +#ifndef WOLFSSL_KEY_GEN + WOLFSSL_MSG("No Key Gen built in"); + (void) msg; + (void) msgSz; + (void) priv; + (void) privSz; + (void) sig; + (void) sigSz; + return WOLFSSL_FAILURE; +#else /* WOLFSSL_KEY_GEN */ + ed448_key key; + int ret = WOLFSSL_FAILURE; + + WOLFSSL_ENTER("wolfSSL_ED448_sign"); + + if (priv == NULL || privSz != ED448_PRV_KEY_SIZE || msg == NULL || + sig == NULL || *sigSz < ED448_SIG_SIZE) { + WOLFSSL_MSG("Bad arguments"); + return WOLFSSL_FAILURE; + } + + /* import key */ + if (wc_ed448_init(&key) != MP_OKAY) { + WOLFSSL_MSG("wc_curve448_init failed"); + return ret; + } + if (wc_ed448_import_private_key(priv, privSz/2, priv+(privSz/2), + ED448_PUB_KEY_SIZE, &key) != MP_OKAY){ + WOLFSSL_MSG("wc_ed448_import_private failed"); + wc_ed448_free(&key); + return ret; + } + + if (wc_ed448_sign_msg(msg, msgSz, sig, sigSz, &key) != MP_OKAY) + WOLFSSL_MSG("wc_curve448_shared_secret_ex failed"); + else + ret = WOLFSSL_SUCCESS; + + wc_ed448_free(&key); + + return ret; +#endif /* WOLFSSL_KEY_GEN */ +} + +/* return 1 if success, 0 if error + * input and output keys are little endian format + * pub is a buffer containing public part of key + */ +int wolfSSL_ED448_verify(const unsigned char *msg, unsigned int msgSz, + const unsigned char *pub, unsigned int pubSz, + const unsigned char *sig, unsigned int sigSz) +{ +#ifndef WOLFSSL_KEY_GEN + WOLFSSL_MSG("No Key Gen built in"); + (void) msg; + (void) msgSz; + (void) pub; + (void) pubSz; + (void) sig; + (void) sigSz; + return WOLFSSL_FAILURE; +#else /* WOLFSSL_KEY_GEN */ + ed448_key key; + int ret = WOLFSSL_FAILURE, check = 0; + + WOLFSSL_ENTER("wolfSSL_ED448_verify"); + + if (pub == NULL || pubSz != ED448_PUB_KEY_SIZE || msg == NULL || + sig == NULL || sigSz != ED448_SIG_SIZE) { + WOLFSSL_MSG("Bad arguments"); + return WOLFSSL_FAILURE; + } + + /* import key */ + if (wc_ed448_init(&key) != MP_OKAY) { + WOLFSSL_MSG("wc_curve448_init failed"); + return ret; + } + if (wc_ed448_import_public(pub, pubSz, &key) != MP_OKAY){ + WOLFSSL_MSG("wc_ed448_import_public failed"); + wc_ed448_free(&key); + return ret; + } + + if ((ret = wc_ed448_verify_msg((byte*)sig, sigSz, msg, msgSz, &check, + &key)) != MP_OKAY) { + WOLFSSL_MSG("wc_ed448_verify_msg failed"); + } + else if (!check) + WOLFSSL_MSG("wc_ed448_verify_msg failed (signature invalid)"); + else + ret = WOLFSSL_SUCCESS; + + wc_ed448_free(&key); + + return ret; +#endif /* WOLFSSL_KEY_GEN */ +} + +#endif /* OPENSSL_EXTRA && HAVE_ED448 */ + #ifdef WOLFSSL_JNI int wolfSSL_set_jobject(WOLFSSL* ssl, void* objPtr) @@ -46490,6 +47027,9 @@ int wolfSSL_CTX_set1_curves_list(WOLFSSL_CTX* ctx, const char* names) else if (XSTRNCMP(name, "X25519", len) == 0) { curve = WOLFSSL_ECC_X25519; } + else if (XSTRNCMP(name, "X448", len) == 0) { + curve = WOLFSSL_ECC_X448; + } else { #if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) int ret; diff --git a/src/tls.c b/src/tls.c index 531e0f15b..e5c451469 100644 --- a/src/tls.c +++ b/src/tls.c @@ -43,7 +43,9 @@ #ifdef HAVE_CURVE25519 #include #endif - +#ifdef HAVE_CURVE448 + #include +#endif #ifdef HAVE_NTRU #include "libntruencrypt/ntru_crypto.h" #include @@ -65,10 +67,10 @@ static int TLSX_KeyShare_IsSupported(int namedGroup); #if ((!defined(NO_WOLFSSL_SERVER) && defined(WOLFSSL_TLS13) && \ !defined(WOLFSSL_NO_SERVER_GROUPS_EXT)) || \ - (defined(WOLFSSL_TLS13) && !defined(HAVE_ECC) && \ - !defined(HAVE_CURVE25519) && defined(HAVE_SUPPORTED_CURVES)) || \ - ((defined(HAVE_ECC) || defined(HAVE_CURVE25519)) && \ - defined(HAVE_SUPPORTED_CURVES))) && \ + (defined(WOLFSSL_TLS13) && !defined(HAVE_ECC) && !defined(HAVE_CURVE25519) \ + && !defined(HAVE_CURVE448) && defined(HAVE_SUPPORTED_CURVES)) || \ + ((defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ + defined(HAVE_CURVE448)) && defined(HAVE_SUPPORTED_CURVES))) && \ defined(HAVE_TLS_EXTENSIONS) static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions); #endif @@ -3696,7 +3698,8 @@ int TLSX_UseCertificateStatusRequestV2(TLSX** extensions, byte status_type, #ifdef HAVE_SUPPORTED_CURVES -#if !defined(HAVE_ECC) && !defined(HAVE_CURVE25519) && !defined(HAVE_FFDHE) +#if !defined(HAVE_ECC) && !defined(HAVE_CURVE25519) && !defined(HAVE_CURVE448) \ + && !defined(HAVE_FFDHE) #error Elliptic Curves Extension requires Elliptic Curve Cryptography. \ Use --enable-ecc in the configure script or define HAVE_ECC. \ Alternatively use FFDHE for DH ciperhsuites. @@ -3815,7 +3818,8 @@ static void TLSX_SupportedCurve_ValidateRequest(WOLFSSL* ssl, byte* semaphore) return; if (ssl->suites->suites[i] == ECC_BYTE || ssl->suites->suites[i] == CHACHA_BYTE) { - #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) + #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ + defined(HAVE_CURVE448) return; #endif } @@ -3839,7 +3843,8 @@ static void TLSX_PointFormat_ValidateRequest(WOLFSSL* ssl, byte* semaphore) return; if (ssl->suites->suites[i] == ECC_BYTE || ssl->suites->suites[i] == CHACHA_BYTE) { - #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) + #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ + defined(HAVE_CURVE448) return; #endif } @@ -3860,7 +3865,8 @@ static void TLSX_PointFormat_ValidateRequest(WOLFSSL* ssl, byte* semaphore) static void TLSX_PointFormat_ValidateResponse(WOLFSSL* ssl, byte* semaphore) { -#if defined(HAVE_FFDHE) || defined(HAVE_ECC) || defined(HAVE_CURVE25519) +#if defined(HAVE_FFDHE) || defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ + defined(HAVE_CURVE448) (void)semaphore; #endif @@ -3868,7 +3874,7 @@ static void TLSX_PointFormat_ValidateResponse(WOLFSSL* ssl, byte* semaphore) return; if (ssl->options.cipherSuite0 == ECC_BYTE || ssl->options.cipherSuite0 == CHACHA_BYTE) { -#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) +#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) return; #endif } @@ -3878,7 +3884,8 @@ static void TLSX_PointFormat_ValidateResponse(WOLFSSL* ssl, byte* semaphore) #endif } -#if !defined(HAVE_FFDHE) || (!defined(HAVE_ECC) && !defined(HAVE_CURVE25519)) +#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 @@ -4244,7 +4251,7 @@ static int TLSX_PointFormat_Parse(WOLFSSL* ssl, byte* input, word16 length, return 0; } -#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) +#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) int TLSX_ValidateSupportedCurves(WOLFSSL* ssl, byte first, byte second) { TLSX* extension = NULL; SupportedCurve* curve = NULL; @@ -4273,7 +4280,7 @@ int TLSX_ValidateSupportedCurves(WOLFSSL* ssl, byte first, byte second) { #ifdef OPENSSL_EXTRA /* skip if name is not in supported ECC range */ - if (curve->name > WOLFSSL_ECC_X25519) + if (curve->name > WOLFSSL_ECC_X448) continue; /* skip if curve is disabled by user */ if (ssl->ctx->disabledCurves & (1 << curve->name)) @@ -4366,6 +4373,19 @@ int TLSX_ValidateSupportedCurves(WOLFSSL* ssl, byte first, byte second) { break; #endif /* HAVE_ECC_BRAINPOOL */ #endif +#endif + #ifdef HAVE_CURVE448 + case WOLFSSL_ECC_X448: + oid = ECC_X448_OID; + #ifdef HAVE_ED448 + pkOid = ECC_ED448_OID; + #else + pkOid = ECC_X448_OID; + #endif + octets = 57; + break; + #endif /* HAVE_CURVE448 */ +#ifdef HAVE_ECC #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES) #ifndef NO_ECC_SECP case WOLFSSL_ECC_SECP384R1: @@ -4460,6 +4480,10 @@ int TLSX_ValidateSupportedCurves(WOLFSSL* ssl, byte first, byte second) { defOid = 0; defSz = 80; } + if (oid == ECC_X448_OID && defOid == oid) { + defOid = 0; + defSz = 80; + } sig |= ssl->pkCurveOID == pkOid; key |= ssl->pkCurveOID == oid; break; @@ -4493,6 +4517,10 @@ int TLSX_ValidateSupportedCurves(WOLFSSL* ssl, byte first, byte second) { defOid = 0; defSz = 80; } + if (oid == ECC_X448_OID && defOid == oid) { + defOid = 0; + defSz = 80; + } sig = 1; key |= ssl->pkCurveOID == pkOid; break; @@ -4503,8 +4531,13 @@ int TLSX_ValidateSupportedCurves(WOLFSSL* ssl, byte first, byte second) { defOid = 0; defSz = 80; } - if (oid != ECC_X25519_OID) + if (oid == ECC_X448_OID && defOid == oid) { + defOid = 0; + defSz = 80; + } + if (oid != ECC_X25519_OID && oid != ECC_X448_OID) { sig = 1; + } key = 1; break; } @@ -6667,8 +6700,8 @@ static int TLSX_KeyShare_GenX25519Key(WOLFSSL *ssl, KeyShareEntry* kse) curve25519_key* key; /* Allocate an ECC key to hold private key. */ - key = (curve25519_key*)XMALLOC(sizeof(curve25519_key), - ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY); + key = (curve25519_key*)XMALLOC(sizeof(curve25519_key), ssl->heap, + DYNAMIC_TYPE_PRIVATE_KEY); if (key == NULL) { WOLFSSL_MSG("EccTempKey Memory error"); return MEMORY_E; @@ -6725,6 +6758,80 @@ end: return ret; } +/* Create a key share entry using X448 parameters group. + * Generates a key pair. + * + * ssl The SSL/TLS object. + * kse The key share entry object. + * returns 0 on success, otherwise failure. + */ +static int TLSX_KeyShare_GenX448Key(WOLFSSL *ssl, KeyShareEntry* kse) +{ + int ret; +#ifdef HAVE_CURVE448 + byte* keyData = NULL; + word32 dataSize = CURVE448_KEY_SIZE; + curve448_key* key; + + /* Allocate an ECC key to hold private key. */ + key = (curve448_key*)XMALLOC(sizeof(curve448_key), ssl->heap, + DYNAMIC_TYPE_PRIVATE_KEY); + if (key == NULL) { + WOLFSSL_MSG("EccTempKey Memory error"); + return MEMORY_E; + } + + /* Make an ECC key. */ + ret = wc_curve448_init(key); + if (ret != 0) + goto end; + ret = wc_curve448_make_key(ssl->rng, CURVE448_KEY_SIZE, key); + if (ret != 0) + goto end; + + /* Allocate space for the public key. */ + keyData = (byte*)XMALLOC(CURVE448_KEY_SIZE, ssl->heap, + DYNAMIC_TYPE_PUBLIC_KEY); + if (keyData == NULL) { + WOLFSSL_MSG("Key data Memory error"); + ret = MEMORY_E; + goto end; + } + + /* Export public key. */ + if (wc_curve448_export_public_ex(key, keyData, &dataSize, + EC448_LITTLE_ENDIAN) != 0) { + ret = ECC_EXPORT_ERROR; + goto end; + } + + kse->pubKey = keyData; + kse->pubKeyLen = CURVE448_KEY_SIZE; + kse->key = key; + +#ifdef WOLFSSL_DEBUG_TLS + WOLFSSL_MSG("Public Curve448 Key"); + WOLFSSL_BUFFER(keyData, dataSize); +#endif + +end: + if (ret != 0) { + /* Data owned by key share entry otherwise. */ + if (keyData != NULL) + XFREE(keyData, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY); + wc_curve448_free(key); + XFREE(key, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY); + } +#else + (void)ssl; + (void)kse; + + ret = NOT_COMPILED_IN; +#endif /* HAVE_CURVE448 */ + + return ret; +} + /* Create a key share entry using named elliptic curve parameters group. * Generates a key pair. * @@ -6859,6 +6966,8 @@ static int TLSX_KeyShare_GenKey(WOLFSSL *ssl, KeyShareEntry *kse) return TLSX_KeyShare_GenDhKey(ssl, kse); if (kse->group == WOLFSSL_ECC_X25519) return TLSX_KeyShare_GenX25519Key(ssl, kse); + if (kse->group == WOLFSSL_ECC_X448) + return TLSX_KeyShare_GenX448Key(ssl, kse); return TLSX_KeyShare_GenEccKey(ssl, kse); } @@ -6877,6 +6986,11 @@ static void TLSX_KeyShare_FreeAll(KeyShareEntry* list, void* heap) if (current->group == WOLFSSL_ECC_X25519) { #ifdef HAVE_CURVE25519 wc_curve25519_free((curve25519_key*)current->key); +#endif + } + else if (current->group == WOLFSSL_ECC_X448) { +#ifdef HAVE_CURVE448 + wc_curve448_free((curve448_key*)current->key); #endif } else { @@ -7179,6 +7293,82 @@ static int TLSX_KeyShare_ProcessX25519(WOLFSSL* ssl, return ret; } +/* Process the X448 key share extension on the client side. + * + * ssl The SSL/TLS object. + * keyShareEntry The key share entry object to use to calculate shared secret. + * returns 0 on success and other values indicate failure. + */ +static int TLSX_KeyShare_ProcessX448(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) +{ + int ret; + +#ifdef HAVE_CURVE448 + curve448_key* key = (curve448_key*)keyShareEntry->key; + curve448_key* peerX448Key; + +#ifdef HAVE_ECC + if (ssl->peerEccKey != NULL) { + wc_ecc_free(ssl->peerEccKey); + ssl->peerEccKey = NULL; + } +#endif + + peerX448Key = (curve448_key*)XMALLOC(sizeof(curve448_key), ssl->heap, + DYNAMIC_TYPE_TLSX); + if (peerX448Key == NULL) { + WOLFSSL_MSG("PeerEccKey Memory error"); + return MEMORY_ERROR; + } + ret = wc_curve448_init(peerX448Key); + if (ret != 0) { + XFREE(peerX448Key, ssl->heap, DYNAMIC_TYPE_TLSX); + return ret; + } +#ifdef WOLFSSL_DEBUG_TLS + WOLFSSL_MSG("Peer Curve448 Key"); + WOLFSSL_BUFFER(keyShareEntry->ke, keyShareEntry->keLen); +#endif + + if (wc_curve448_check_public(keyShareEntry->ke, keyShareEntry->keLen, + EC448_LITTLE_ENDIAN) != 0) { + ret = ECC_PEERKEY_ERROR; + } + + if (ret == 0) { + if (wc_curve448_import_public_ex(keyShareEntry->ke, + keyShareEntry->keLen, peerX448Key, + EC448_LITTLE_ENDIAN) != 0) { + ret = ECC_PEERKEY_ERROR; + } + } + + if (ret == 0) { + ssl->ecdhCurveOID = ECC_X448_OID; + + ret = wc_curve448_shared_secret_ex(key, peerX448Key, + ssl->arrays->preMasterSecret, + &ssl->arrays->preMasterSz, + EC448_LITTLE_ENDIAN); + } + + wc_curve448_free(peerX448Key); + XFREE(peerX448Key, ssl->heap, DYNAMIC_TYPE_TLSX); + wc_curve448_free((curve448_key*)keyShareEntry->key); + if (keyShareEntry->key != NULL) { + XFREE(keyShareEntry->key, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY); + keyShareEntry->key = NULL; + } +#else + (void)ssl; + (void)keyShareEntry; + + ret = PEER_KEY_ERROR; +#endif /* HAVE_CURVE448 */ + + return ret; +} + /* Process the ECC key share extension on the client side. * * ssl The SSL/TLS object. @@ -7306,6 +7496,8 @@ static int TLSX_KeyShare_Process(WOLFSSL* ssl, KeyShareEntry* keyShareEntry) ret = TLSX_KeyShare_ProcessDh(ssl, keyShareEntry); else if (keyShareEntry->group == WOLFSSL_ECC_X25519) ret = TLSX_KeyShare_ProcessX25519(ssl, keyShareEntry); + else if (keyShareEntry->group == WOLFSSL_ECC_X448) + ret = TLSX_KeyShare_ProcessX448(ssl, keyShareEntry); else ret = TLSX_KeyShare_ProcessEcc(ssl, keyShareEntry); @@ -7703,6 +7895,10 @@ static int TLSX_KeyShare_IsSupported(int namedGroup) case WOLFSSL_ECC_X25519: break; #endif + #ifdef HAVE_CURVE448 + case WOLFSSL_ECC_X448: + break; + #endif #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES) #ifndef NO_ECC_SECP case WOLFSSL_ECC_SECP384R1: @@ -7714,10 +7910,6 @@ static int TLSX_KeyShare_IsSupported(int namedGroup) case WOLFSSL_ECC_SECP521R1: break; #endif /* !NO_ECC_SECP */ - #endif - #ifdef HAVE_X448 - case WOLFSSL_ECC_X448: - break; #endif default: return 0; @@ -7751,6 +7943,11 @@ static int TLSX_KeyShare_GroupRank(WOLFSSL* ssl, int group) ssl->group[ssl->numGroups++] = WOLFSSL_ECC_X25519; #endif #endif + #ifndef HAVE_FIPS + #if defined(HAVE_CURVE448) + ssl->group[ssl->numGroups++] = WOLFSSL_ECC_X448; + #endif + #endif #if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES) #if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES) #ifndef NO_ECC_SECP @@ -9526,10 +9723,10 @@ static byte* TLSX_QSHKeyFind_Pub(QSHKey* qsh, word16* pubLen, word16 name) #if (!defined(NO_WOLFSSL_SERVER) && defined(WOLFSSL_TLS13) && \ !defined(WOLFSSL_NO_SERVER_GROUPS_EXT)) || \ - (defined(WOLFSSL_TLS13) && !defined(HAVE_ECC) && \ - !defined(HAVE_CURVE25519) && defined(HAVE_SUPPORTED_CURVES)) || \ - ((defined(HAVE_ECC) || defined(HAVE_CURVE25519)) && \ - defined(HAVE_SUPPORTED_CURVES)) + (defined(WOLFSSL_TLS13) && !defined(HAVE_ECC) && !defined(HAVE_CURVE25519) \ + && !defined(HAVE_CURVE448) && defined(HAVE_SUPPORTED_CURVES)) || \ + ((defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ + defined(HAVE_CURVE448)) && defined(HAVE_SUPPORTED_CURVES)) /* Populates the default supported groups / curves */ static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions) @@ -9583,6 +9780,17 @@ static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions) if (ret != WOLFSSL_SUCCESS) return ret; #endif #endif +#endif /* HAVE_ECC && HAVE_SUPPORTED_CURVES */ + + #ifndef HAVE_FIPS + #if defined(HAVE_CURVE448) + ret = TLSX_UseSupportedCurve(extensions, + WOLFSSL_ECC_X448, ssl->heap); + if (ret != WOLFSSL_SUCCESS) return ret; + #endif + #endif /* HAVE_FIPS */ + +#if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES) #if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES) #ifndef NO_ECC_SECP ret = TLSX_UseSupportedCurve(extensions, @@ -9811,8 +10019,8 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer) } #endif -#if (defined(HAVE_ECC) || defined(HAVE_CURVE25519)) && \ - defined(HAVE_SUPPORTED_CURVES) +#if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ + defined(HAVE_CURVE448)) && defined(HAVE_SUPPORTED_CURVES) if (!ssl->options.userCurves && !ssl->ctx->userCurves) { if (TLSX_Find(ssl->ctx->extensions, TLSX_SUPPORTED_GROUPS) == NULL) { @@ -9829,7 +10037,7 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer) if (ret != WOLFSSL_SUCCESS) return ret; } -#endif /* (HAVE_ECC || HAVE_CURVE25519) && HAVE_SUPPORTED_CURVES */ +#endif /* (HAVE_ECC || CURVE25519 || CURVE448) && HAVE_SUPPORTED_CURVES */ } /* is not server */ #if !defined(WOLFSSL_NO_SIGALG) @@ -9851,7 +10059,7 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer) } #if !defined(HAVE_ECC) && !defined(HAVE_CURVE25519) && \ - defined(HAVE_SUPPORTED_CURVES) + !defined(HAVE_CURVE448) && defined(HAVE_SUPPORTED_CURVES) if (TLSX_Find(ssl->ctx->extensions, TLSX_SUPPORTED_GROUPS) == NULL) { /* Put in DH groups for TLS 1.3 only. */ ret = TLSX_PopulateSupportedGroups(ssl, &ssl->extensions); @@ -9859,7 +10067,7 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer) return ret; ret = 0; } - #endif /* !HAVE_ECC && !HAVE_CURVE25519 && HAVE_SUPPORTED_CURVES */ + #endif /* (HAVE_ECC || CURVE25519 || CURVE448) && HAVE_SUPPORTED_CURVES */ #if !defined(WOLFSSL_TLS13_DRAFT_18) && !defined(WOLFSSL_TLS13_DRAFT_22) if (ssl->certHashSigAlgoSz > 0) { @@ -9885,6 +10093,8 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer) namedGroup = WOLFSSL_ECC_SECP256R1; #elif defined(HAVE_CURVE25519) namedGroup = WOLFSSL_ECC_X25519; + #elif defined(HAVE_CURVE448) + namedGroup = WOLFSSL_ECC_X448; #elif defined(HAVE_ECC) && (!defined(NO_ECC384) || \ defined(HAVE_ALL_CURVES)) && !defined(NO_ECC_SECP) namedGroup = WOLFSSL_ECC_SECP384R1; @@ -9996,7 +10206,8 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer) /* Pre-shared key modes: mandatory extension for resumption. */ modes = 1 << PSK_KE; - #if !defined(NO_DH) || defined(HAVE_ECC) || defined(HAVE_CURVE25519) + #if !defined(NO_DH) || defined(HAVE_ECC) || \ + defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) if (!ssl->options.noPskDheKe) modes |= 1 << PSK_DHE_KE; #endif diff --git a/src/tls13.c b/src/tls13.c index 097c74c50..e5fd49d8b 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -4861,7 +4861,8 @@ static int SendTls13CertificateRequest(WOLFSSL* ssl, byte* reqCtx, #endif /* NO_WOLFSSL_SERVER */ #ifndef NO_CERTS -#if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519) +#if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519) || \ + defined(HAVE_ED448) /* Encode the signature algorithm into buffer. * * hashalgo The hash algorithm. @@ -4885,6 +4886,14 @@ static WC_INLINE void EncodeSigAlg(byte hashAlgo, byte hsType, byte* output) (void)hashAlgo; break; #endif +#ifdef HAVE_ED448 + /* ED448: 0x0808 */ + case ed448_sa_algo: + output[0] = ED448_SA_MAJOR; + output[1] = ED448_SA_MINOR; + (void)hashAlgo; + break; +#endif #ifndef NO_RSA /* PSS signatures: 0x080[4-6] */ case rsa_pss_sa_algo: @@ -4892,7 +4901,6 @@ static WC_INLINE void EncodeSigAlg(byte hashAlgo, byte hsType, byte* output) output[1] = hashAlgo; break; #endif - /* ED448: 0x0808 */ } } @@ -4900,7 +4908,7 @@ static WC_INLINE void EncodeSigAlg(byte hashAlgo, byte hsType, byte* output) * * input The encoded signature algorithm. * hashalgo The hash algorithm. - * hsType The signature type. + * hsType The signature type. * returns INVALID_PARAMETER if not recognized and 0 otherwise. */ static WC_INLINE int DecodeTls13SigAlg(byte* input, byte* hashAlgo, @@ -4922,10 +4930,17 @@ static WC_INLINE int DecodeTls13SigAlg(byte* input, byte* hashAlgo, /* Hash performed as part of sign/verify operation. */ *hashAlgo = sha512_mac; } + #endif + #ifdef HAVE_ED448 + /* ED448: 0x0808 */ + else if (input[1] == ED448_SA_MINOR) { + *hsType = ed448_sa_algo; + /* Hash performed as part of sign/verify operation. */ + *hashAlgo = sha512_mac; + } #endif else ret = INVALID_PARAMETER; - /* ED448: 0x0808 */ break; default: *hashAlgo = input[0]; @@ -5637,6 +5652,10 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl) #ifdef HAVE_ED25519 else if (ssl->hsType == DYNAMIC_TYPE_ED25519) args->sigAlgo = ed25519_sa_algo; + #endif + #ifdef HAVE_ED448 + else if (ssl->hsType == DYNAMIC_TYPE_ED448) + args->sigAlgo = ed448_sa_algo; #endif EncodeSigAlg(ssl->suites->hashAlgo, args->sigAlgo, args->verify); @@ -5701,7 +5720,16 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl) } sig->length = ED25519_SIG_SIZE; } - #endif /* HAVE_ECC */ + #endif /* HAVE_ED25519 */ + #ifdef HAVE_ED448 + if (ssl->hsType == DYNAMIC_TYPE_ED448) { + ret = Ed448CheckPubKey(ssl); + if (ret < 0) { + ERROR_OUT(ret, exit_scv); + } + sig->length = ED448_SIG_SIZE; + } + #endif /* HAVE_ED448 */ /* Advance state and proceed */ ssl->options.asyncState = TLS_ASYNC_DO; @@ -5739,6 +5767,20 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl) args->length = (word16)sig->length; } #endif + #ifdef HAVE_ED448 + if (ssl->hsType == DYNAMIC_TYPE_ED448) { + ret = Ed448Sign(ssl, args->sigData, args->sigDataSz, + args->verify + HASH_SIG_SIZE + VERIFY_HEADER, + (word32*)&sig->length, (ed448_key*)ssl->hsKey, + #ifdef HAVE_PK_CALLBACKS + ssl->buffers.key + #else + NULL + #endif + ); + args->length = (word16)sig->length; + } + #endif #ifndef NO_RSA if (ssl->hsType == DYNAMIC_TYPE_RSA) { ret = RsaSign(ssl, sig->buffer, (word32)sig->length, @@ -5903,7 +5945,8 @@ static int DoTls13Certificate(WOLFSSL* ssl, byte* input, word32* inOutIdx, return ret; } -#if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519) +#if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519) || \ + defined(HAVE_ED448) typedef struct Dcv13Args { byte* output; /* not allocated */ @@ -6028,6 +6071,11 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, WOLFSSL_MSG("Oops, peer sent ED25519 key but not in verify"); } #endif + #ifdef HAVE_ED448 + if (args->sigAlgo == ed448_sa_algo && !ssl->peerEd448KeyPresent) { + WOLFSSL_MSG("Oops, peer sent ED448 key but not in verify"); + } + #endif #ifdef HAVE_ECC if (args->sigAlgo == ecc_dsa_sa_algo && !ssl->peerEccDsaKeyPresent) { @@ -6058,7 +6106,7 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, WOLFSSL_MSG("Doing ECC peer cert verify"); args->sigData = (byte*)XMALLOC(MAX_SIG_DATA_SZ, ssl->heap, - DYNAMIC_TYPE_SIGNATURE); + DYNAMIC_TYPE_SIGNATURE); if (args->sigData == NULL) { ERROR_OUT(MEMORY_E, exit_dcv); } @@ -6079,7 +6127,7 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, WOLFSSL_MSG("Doing ED25519 peer cert verify"); args->sigData = (byte*)XMALLOC(MAX_SIG_DATA_SZ, ssl->heap, - DYNAMIC_TYPE_SIGNATURE); + DYNAMIC_TYPE_SIGNATURE); if (args->sigData == NULL) { ERROR_OUT(MEMORY_E, exit_dcv); } @@ -6088,6 +6136,20 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, ret = 0; } #endif + #ifdef HAVE_ED448 + if (ssl->peerEd448KeyPresent) { + WOLFSSL_MSG("Doing ED448 peer cert verify"); + + args->sigData = (byte*)XMALLOC(MAX_SIG_DATA_SZ, ssl->heap, + DYNAMIC_TYPE_SIGNATURE); + if (args->sigData == NULL) { + ERROR_OUT(MEMORY_E, exit_dcv); + } + + CreateSigData(ssl, args->sigData, &args->sigDataSz, 1); + ret = 0; + } + #endif /* Advance state and proceed */ ssl->options.asyncState = TLS_ASYNC_DO; @@ -6155,6 +6217,27 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input, } } #endif + #ifdef HAVE_ED448 + if (ssl->peerEd448KeyPresent) { + WOLFSSL_MSG("Doing ED448 peer cert verify"); + + ret = Ed448Verify(ssl, input + args->idx, args->sz, + args->sigData, args->sigDataSz, + ssl->peerEd448Key, + #ifdef HAVE_PK_CALLBACKS + &ssl->buffers.peerEd448Key + #else + NULL + #endif + ); + + if (ret >= 0) { + FreeKey(ssl, DYNAMIC_TYPE_ED448, + (void**)&ssl->peerEd448Key); + ssl->peerEd448KeyPresent = 0; + } + } + #endif /* Check for error */ if (ret != 0) { @@ -7473,8 +7556,9 @@ int DoTls13HandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx, case server_hello: WOLFSSL_MSG("processing server hello"); ret = DoTls13ServerHello(ssl, input, inOutIdx, size, &type); - #if !defined(WOLFSSL_NO_CLIENT_AUTH) && defined(HAVE_ED25519) && \ - !defined(NO_ED25519_CLIENT_AUTH) + #if !defined(WOLFSSL_NO_CLIENT_AUTH) && \ + ((defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \ + (defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH))) if (ssl->options.resuming || !IsAtLeastTLSv1_2(ssl) || IsAtLeastTLSv1_3(ssl->version)) { ssl->options.cacheMessages = 0; @@ -7527,7 +7611,8 @@ int DoTls13HandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx, break; #endif -#if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519) +#if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519) || \ + defined(HAVE_ED448) case certificate_verify: WOLFSSL_MSG("processing certificate verify"); ret = DoTls13CertificateVerify(ssl, input, inOutIdx, size); diff --git a/tests/api.c b/tests/api.c index 39fccc391..8bbfbeb6c 100644 --- a/tests/api.c +++ b/tests/api.c @@ -282,10 +282,16 @@ #ifdef HAVE_ED25519 #include #endif - #ifdef HAVE_CURVE25519 #include #endif +#ifdef HAVE_ED448 + #include +#endif +#ifdef HAVE_CURVE448 + #include +#endif + #ifdef HAVE_PKCS12 #include #endif @@ -1603,19 +1609,24 @@ static void test_wolfSSL_SetTmpDH_file(void) AssertNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method())); #ifndef NO_RSA AssertTrue(wolfSSL_CTX_use_certificate_file(ctx, svrCertFile, - WOLFSSL_FILETYPE_PEM)); + WOLFSSL_FILETYPE_PEM)); AssertTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, svrKeyFile, - WOLFSSL_FILETYPE_PEM)); + WOLFSSL_FILETYPE_PEM)); #elif defined(HAVE_ECC) AssertTrue(wolfSSL_CTX_use_certificate_file(ctx, eccCertFile, - WOLFSSL_FILETYPE_PEM)); + WOLFSSL_FILETYPE_PEM)); AssertTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, eccKeyFile, - WOLFSSL_FILETYPE_PEM)); + WOLFSSL_FILETYPE_PEM)); #elif defined(HAVE_ED25519) AssertTrue(wolfSSL_CTX_use_certificate_file(ctx, edCertFile, - WOLFSSL_FILETYPE_PEM)); + WOLFSSL_FILETYPE_PEM)); AssertTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, edKeyFile, - WOLFSSL_FILETYPE_PEM)); + WOLFSSL_FILETYPE_PEM)); +#elif defined(HAVE_ED448) + AssertTrue(wolfSSL_CTX_use_certificate_file(ctx, ed448CertFile, + WOLFSSL_FILETYPE_PEM)); + AssertTrue(wolfSSL_CTX_use_PrivateKey_file(ctx, ed448KeyFile, + WOLFSSL_FILETYPE_PEM)); #endif AssertNotNull(ssl = wolfSSL_new(ctx)); @@ -5082,6 +5093,37 @@ static void test_wolfSSL_PKCS8_ED25519(void) #endif } +static void test_wolfSSL_PKCS8_ED448(void) +{ +#if !defined(NO_ASN) && defined(HAVE_PKCS8) && \ + defined(WOLFSSL_ENCRYPTED_KEYS) && defined(HAVE_ED448) + const byte encPrivKey[] = \ + "-----BEGIN ENCRYPTED PRIVATE KEY-----\n" + "MIGrMFcGCSqGSIb3DQEFDTBKMCkGCSqGSIb3DQEFDDAcBAjSbZKnG4EPggICCAAw\n" + "DAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEFvCFWBBHBlJBsYleBJlJWcEUNC7\n" + "Tf5pZviT5Btar4D/MNg6BsQHSDf5KW4ix871EsgDY2Zz+euaoWspiMntz7gU+PQu\n" + "T/JJcbD2Ly8BbE3l5WHMifAQqNLxJBfXrHkfYtAo\n" + "-----END ENCRYPTED PRIVATE KEY-----\n"; + const char password[] = "abcdefghijklmnopqrstuvwxyz"; + byte der[FOURK_BUF]; + WOLFSSL_CTX* ctx; + int bytes; + + XMEMSET(der, 0, sizeof(der)); + AssertIntGT((bytes = wc_KeyPemToDer(encPrivKey, sizeof(encPrivKey), der, + (word32)sizeof(der), password)), 0); +#ifndef NO_WOLFSSL_SERVER + AssertNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_server_method())); +#else + AssertNotNull(ctx = wolfSSL_CTX_new(wolfSSLv23_client_method())); +#endif + AssertIntEQ(wolfSSL_CTX_use_PrivateKey_buffer(ctx, der, bytes, + WOLFSSL_FILETYPE_ASN1), WOLFSSL_SUCCESS); + + wolfSSL_CTX_free(ctx); +#endif +} + /* Testing functions dealing with PKCS5 */ static void test_wolfSSL_PKCS5(void) { @@ -7879,6 +7921,150 @@ static int test_wc_Sha3_512_Copy (void) +static int test_wc_InitShake256 (void) +{ + int ret = 0; +#if defined(WOLFSSL_SHAKE256) && !defined(WOLFSSL_NO_SHAKE256) + wc_Shake shake; + + printf(testingFmt, "wc_InitShake256()"); + + ret = wc_InitShake256(&shake, HEAP_HINT, devId); + /* Test bad args. */ + if (ret == 0) { + ret = wc_InitShake256(NULL, HEAP_HINT, devId); + if (ret == BAD_FUNC_ARG) { + ret = 0; + } else if (ret == 0) { + ret = WOLFSSL_FATAL_ERROR; + } + } + wc_Shake256_Free(&shake); + printf(resultFmt, ret == 0 ? passed : failed); +#endif + return ret; + +} /* END test_wc_InitSha3 */ + + +static int testing_wc_Shake256_Update (void) +{ + int ret = 0; + +#if defined(WOLFSSL_SHAKE256) && !defined(WOLFSSL_NO_SHAKE256) + wc_Shake shake; + byte msg[] = "Everybody's working for the weekend."; + byte msg2[] = "Everybody gets Friday off."; + byte msgCmp[] = "\x45\x76\x65\x72\x79\x62\x6f\x64\x79\x27\x73\x20" + "\x77\x6f\x72\x6b\x69\x6e\x67\x20\x66\x6f\x72\x20\x74" + "\x68\x65\x20\x77\x65\x65\x6b\x65\x6e\x64\x2e\x45\x76" + "\x65\x72\x79\x62\x6f\x64\x79\x20\x67\x65\x74\x73\x20" + "\x46\x72\x69\x64\x61\x79\x20\x6f\x66\x66\x2e"; + word32 msglen = sizeof(msg) - 1; + word32 msg2len = sizeof(msg2); + word32 msgCmplen = sizeof(msgCmp); + + printf(testingFmt, "wc_Shake256_Update()"); + + ret = wc_InitShake256(&shake, HEAP_HINT, devId); + if (ret != 0) { + return ret; + } + ret = wc_Shake256_Update(&shake, msg, msglen); + if (XMEMCMP(msg, shake.t, msglen) || shake.i != msglen) { + ret = WOLFSSL_FATAL_ERROR; + } + if (ret == 0) { + ret = wc_Shake256_Update(&shake, msg2, msg2len); + if (XMEMCMP(shake.t, msgCmp, msgCmplen) != 0) { + ret = WOLFSSL_FATAL_ERROR; + } + } + /* Pass bad args. */ + if (ret == 0) { + ret = wc_Shake256_Update(NULL, msg2, msg2len); + if (ret == BAD_FUNC_ARG) { + ret = wc_Shake256_Update(&shake, NULL, 5); + } + if (ret == BAD_FUNC_ARG) { + wc_Shake256_Free(&shake); + if (wc_InitShake256(&shake, HEAP_HINT, devId)) { + return ret; + } + ret = wc_Shake256_Update(&shake, NULL, 0); + if (ret == 0) { + ret = wc_Shake256_Update(&shake, msg2, msg2len); + } + if (ret == 0 && XMEMCMP(msg2, shake.t, msg2len) != 0) { + ret = WOLFSSL_FATAL_ERROR; + } + } + } + wc_Shake256_Free(&shake); + + printf(resultFmt, ret == 0 ? passed : failed); +#endif /* WOLFSSL_SHAKE256 && !WOLFSSL_NO_SHAKE256 */ + + return ret; + +} + +static int test_wc_Shake256_Final (void) +{ + int ret = 0; + +#if defined(WOLFSSL_SHAKE256) && !defined(WOLFSSL_NO_SHAKE256) + wc_Shake shake; + const char* msg = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnom" + "nopnopq"; + const char* expOut = "\x4d\x8c\x2d\xd2\x43\x5a\x01\x28\xee\xfb\xb8\xc3\x6f" + "\x6f\x87\x13\x3a\x79\x11\xe1\x8d\x97\x9e\xe1\xae\x6b" + "\xe5\xd4\xfd\x2e\x33\x29\x40\xd8\x68\x8a\x4e\x6a\x59" + "\xaa\x80\x60\xf1\xf9\xbc\x99\x6c\x05\xac\xa3\xc6\x96" + "\xa8\xb6\x62\x79\xdc\x67\x2c\x74\x0b\xb2\x24\xec\x37" + "\xa9\x2b\x65\xdb\x05\x39\xc0\x20\x34\x55\xf5\x1d\x97" + "\xcc\xe4\xcf\xc4\x91\x27\xd7\x26\x0a\xfc\x67\x3a\xf2" + "\x08\xba\xf1\x9b\xe2\x12\x33\xf3\xde\xbe\x78\xd0\x67" + "\x60\xcf\xa5\x51\xee\x1e\x07\x91\x41\xd4"; + byte hash[114]; + + /* Init stack variables. */ + XMEMSET(hash, 0, sizeof(hash)); + + printf(testingFmt, "wc_Shake256_Final()"); + + ret = wc_InitShake256(&shake, HEAP_HINT, devId); + if (ret != 0) { + return ret; + } + + ret= wc_Shake256_Update(&shake, (byte*)msg, (word32)XSTRLEN(msg)); + if (ret == 0) { + ret = wc_Shake256_Final(&shake, hash, (word32)sizeof(hash)); + if (ret == 0 && XMEMCMP(expOut, hash, (word32)sizeof(hash)) != 0) { + ret = WOLFSSL_FATAL_ERROR; + } + } + /* Test bad args. */ + if (ret == 0) { + ret = wc_Shake256_Final(NULL, hash, (word32)sizeof(hash)); + if (ret == 0) { + ret = wc_Shake256_Final(&shake, NULL, (word32)sizeof(hash)); + } + if (ret == BAD_FUNC_ARG) { + ret = 0; + } else if (ret == 0) { + ret = WOLFSSL_FATAL_ERROR; + } + } + wc_Shake256_Free(&shake); + printf(resultFmt, ret == 0 ? passed : failed); +#endif + return ret; +} + + + /* * unit test for wc_IdeaSetKey() */ @@ -14909,6 +15095,759 @@ static int test_wc_curve25519_size (void) return ret; } /* END test_wc_curve25519_size*/ + +/* + * Testing wc_ed448_make_key(). + */ +static int test_wc_ed448_make_key (void) +{ + int ret = 0; + +#if defined(HAVE_ED448) + ed448_key key; + WC_RNG rng; + + ret = wc_InitRng(&rng); + if (ret == 0) { + ret = wc_ed448_init(&key); + } + printf(testingFmt, "wc_ed448_make_key()"); + if (ret == 0) { + ret = wc_ed448_make_key(&rng, ED448_KEY_SIZE, &key); + } + /* Test bad args. */ + if (ret == 0) { + ret = wc_ed448_make_key(NULL, ED448_KEY_SIZE, &key); + if (ret == BAD_FUNC_ARG) { + ret = wc_ed448_make_key(&rng, ED448_KEY_SIZE, NULL); + } + if (ret == BAD_FUNC_ARG) { + ret = wc_ed448_make_key(&rng, ED448_KEY_SIZE - 1, &key); + } + if (ret == BAD_FUNC_ARG) { + ret = wc_ed448_make_key(&rng, ED448_KEY_SIZE + 1, &key); + } + if (ret == BAD_FUNC_ARG) { + ret = 0; + } else if (ret == 0) { + ret = SSL_FATAL_ERROR; + } + } + + + printf(resultFmt, ret == 0 ? passed : failed); + + if (wc_FreeRng(&rng) && ret == 0) { + ret = SSL_FATAL_ERROR; + } + wc_ed448_free(&key); + +#endif + return ret; + +} /* END test_wc_ed448_make_key */ + + +/* + * Testing wc_ed448_init() + */ +static int test_wc_ed448_init (void) +{ + int ret = 0; + +#if defined(HAVE_ED448) + + ed448_key key; + + printf(testingFmt, "wc_ed448_init()"); + + ret = wc_ed448_init(&key); + + /* Test bad args. */ + if (ret == 0) { + ret = wc_ed448_init(NULL); + if (ret == BAD_FUNC_ARG) { + ret = 0; + } else if (ret == 0) { + ret = SSL_FATAL_ERROR; + } + } + + printf(resultFmt, ret == 0 ? passed : failed); + + wc_ed448_free(&key); + +#endif + return ret; + +} /* END test_wc_ed448_init */ + +/* + * Test wc_ed448_sign_msg() and wc_ed448_verify_msg() + */ +static int test_wc_ed448_sign_msg (void) +{ + int ret = 0; + +#if defined(HAVE_ED448) && defined(HAVE_ED448_SIGN) + WC_RNG rng; + ed448_key key; + byte msg[] = "Everybody gets Friday off.\n"; + byte sig[ED448_SIG_SIZE]; + word32 msglen = sizeof(msg); + word32 siglen = sizeof(sig); + word32 badSigLen = sizeof(sig) - 1; + int verify_ok = 0; /*1 = Verify success.*/ + + /* Initialize stack variables. */ + XMEMSET(sig, 0, siglen); + + /* Initialize key. */ + ret = wc_InitRng(&rng); + if (ret == 0) { + ret = wc_ed448_init(&key); + if (ret == 0) { + ret = wc_ed448_make_key(&rng, ED448_KEY_SIZE, &key); + } + } + + printf(testingFmt, "wc_ed448_sign_msg()"); + + if (ret == 0) { + ret = wc_ed448_sign_msg(msg, msglen, sig, &siglen, &key, NULL, 0); + } + /* Test bad args. */ + if (ret == 0 && siglen == ED448_SIG_SIZE) { + ret = wc_ed448_sign_msg(NULL, msglen, sig, &siglen, &key, NULL, 0); + if (ret == BAD_FUNC_ARG) { + ret = wc_ed448_sign_msg(msg, msglen, NULL, &siglen, &key, NULL, 0); + } + if (ret == BAD_FUNC_ARG) { + ret = wc_ed448_sign_msg(msg, msglen, sig, NULL, &key, NULL, 0); + } + if (ret == BAD_FUNC_ARG) { + ret = wc_ed448_sign_msg(msg, msglen, sig, &siglen, NULL, NULL, 0); + } + if (ret == BAD_FUNC_ARG) { + ret = wc_ed448_sign_msg(msg, msglen, sig, &badSigLen, &key, + NULL, 0); + } + if (ret == BUFFER_E && badSigLen == ED448_SIG_SIZE) { + badSigLen -= 1; + ret = 0; + } else if (ret == 0) { + ret = SSL_FATAL_ERROR; + } + } /* END sign */ + + printf(resultFmt, ret == 0 ? passed : failed); + #ifdef HAVE_ED448_VERIFY + printf(testingFmt, "wc_ed448_verify_msg()"); + + if (ret == 0) { + + ret = wc_ed448_verify_msg(sig, siglen, msg, msglen, &verify_ok, + &key, NULL, 0); + if (ret == 0 && verify_ok == 1) { + ret = 0; + } else if (ret == 0) { + ret = SSL_FATAL_ERROR; + } + + /* Test bad args. */ + if (ret == 0) { + ret = wc_ed448_verify_msg(NULL, siglen, msg, msglen, &verify_ok, + &key, NULL, 0); + if (ret == BAD_FUNC_ARG) { + ret = wc_ed448_verify_msg(sig, siglen, NULL, msglen, + &verify_ok, &key, NULL, 0); + } + if (ret == BAD_FUNC_ARG) { + ret = wc_ed448_verify_msg(sig, siglen, msg, msglen, + NULL, &key, NULL, 0); + } + if (ret == BAD_FUNC_ARG) { + ret = wc_ed448_verify_msg(sig, siglen, msg, msglen, + &verify_ok, NULL, NULL, 0); + } + if (ret == BAD_FUNC_ARG) { + ret = wc_ed448_verify_msg(sig, badSigLen, msg, msglen, + &verify_ok, &key, NULL, 0); + } + if (ret == BAD_FUNC_ARG) { + ret = 0; + } else if (ret == 0) { + ret = SSL_FATAL_ERROR; + } + } + + } /* END verify. */ + + printf(resultFmt, ret == 0 ? passed : failed); + #endif /* Verify. */ + + if (wc_FreeRng(&rng) && ret == 0) { + ret = SSL_FATAL_ERROR; + } + wc_ed448_free(&key); + +#endif + return ret; + +} /* END test_wc_ed448_sign_msg */ + +/* + * Testing wc_ed448_import_public() + */ +static int test_wc_ed448_import_public (void) +{ + int ret = 0; + +#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT) + WC_RNG rng; + ed448_key pubKey; + const byte in[] = + "Ed448PublicKeyUnitTest.................................\n"; + word32 inlen = sizeof(in); + + + ret = wc_InitRng(&rng); + if (ret == 0) { + ret = wc_ed448_init(&pubKey); + if (ret == 0) { + ret = wc_ed448_make_key(&rng, ED448_KEY_SIZE, &pubKey); + } + } + printf(testingFmt, "wc_ed448_import_public()"); + + if (ret == 0) { + ret = wc_ed448_import_public(in, inlen, &pubKey); + + if (ret == 0 && XMEMCMP(in, pubKey.p, inlen) == 0) { + ret = 0; + } else { + ret = SSL_FATAL_ERROR; + } + + /* Test bad args. */ + if (ret == 0) { + ret = wc_ed448_import_public(NULL, inlen, &pubKey); + if (ret == BAD_FUNC_ARG) { + ret = wc_ed448_import_public(in, inlen, NULL); + } + if (ret == BAD_FUNC_ARG) { + ret = wc_ed448_import_public(in, inlen - 1, &pubKey); + } + if (ret == BAD_FUNC_ARG) { + ret = 0; + } else if (ret == 0) { + ret = SSL_FATAL_ERROR; + } + } + } + + printf(resultFmt, ret == 0 ? passed : failed); + + if (wc_FreeRng(&rng) && ret == 0) { + ret = SSL_FATAL_ERROR; + } + wc_ed448_free(&pubKey); + +#endif + return ret; + +} /* END wc_ed448_import_public */ + +/* + * Testing wc_ed448_import_private_key() + */ +static int test_wc_ed448_import_private_key (void) +{ + int ret = 0; + +#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_IMPORT) + WC_RNG rng; + ed448_key key; + const byte privKey[] = + "Ed448PrivateKeyUnitTest................................\n"; + const byte pubKey[] = + "Ed448PublicKeyUnitTest.................................\n"; + word32 privKeySz = sizeof(privKey); + word32 pubKeySz = sizeof(pubKey); + + ret = wc_InitRng(&rng); + if (ret != 0) { + return ret; + } + ret = wc_ed448_init(&key); + if (ret != 0) { + wc_FreeRng(&rng); + return ret; + } + ret = wc_ed448_make_key(&rng, ED448_KEY_SIZE, &key); + + printf(testingFmt, "wc_ed448_import_private_key()"); + + if (ret == 0) { + ret = wc_ed448_import_private_key(privKey, privKeySz, pubKey, pubKeySz, + &key); + if (ret == 0 && (XMEMCMP(pubKey, key.p, privKeySz) != 0 || + XMEMCMP(privKey, key.k, pubKeySz) != 0)) { + ret = SSL_FATAL_ERROR; + } + } + + /* Test bad args. */ + if (ret == 0) { + ret = wc_ed448_import_private_key(NULL, privKeySz, pubKey, pubKeySz, + &key); + if (ret == BAD_FUNC_ARG) { + ret = wc_ed448_import_private_key(privKey, privKeySz, NULL, + pubKeySz, &key); + } + if (ret == BAD_FUNC_ARG) { + ret = wc_ed448_import_private_key(privKey, privKeySz, pubKey, + pubKeySz, NULL); + } + if (ret == BAD_FUNC_ARG) { + ret = wc_ed448_import_private_key(privKey, privKeySz - 1, pubKey, + pubKeySz, &key); + } + if (ret == BAD_FUNC_ARG) { + ret = wc_ed448_import_private_key(privKey, privKeySz, pubKey, + pubKeySz - 1, &key); + } + if (ret == BAD_FUNC_ARG) { + ret = 0; + } else if (ret == 0) { + ret = SSL_FATAL_ERROR; + } + } + + printf(resultFmt, ret == 0 ? passed : failed); + + if (wc_FreeRng(&rng) && ret == 0) { + ret = SSL_FATAL_ERROR; + } + wc_ed448_free(&key); + +#endif + return ret; + +} /* END test_wc_ed448_import_private_key */ + +/* + * Testing wc_ed448_export_public() and wc_ed448_export_private_only() + */ +static int test_wc_ed448_export (void) +{ + int ret = 0; + +#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT) + WC_RNG rng; + ed448_key key; + byte priv[ED448_PRV_KEY_SIZE]; + byte pub[ED448_PUB_KEY_SIZE]; + word32 privSz = sizeof(priv); + word32 pubSz = sizeof(pub); + + ret = wc_InitRng(&rng); + if (ret != 0) { + return ret; + } + + ret = wc_ed448_init(&key); + if (ret != 0) { + wc_FreeRng(&rng); + return ret; + } + + if (ret == 0) { + ret = wc_ed448_make_key(&rng, ED448_KEY_SIZE, &key); + } + + printf(testingFmt, "wc_ed448_export_public()"); + + if (ret == 0) { + ret = wc_ed448_export_public(&key, pub, &pubSz); + if (ret == 0 && (pubSz != ED448_KEY_SIZE || + XMEMCMP(key.p, pub, pubSz) != 0)) { + ret = SSL_FATAL_ERROR; + } + if (ret == 0) { + ret = wc_ed448_export_public(NULL, pub, &pubSz); + if (ret == BAD_FUNC_ARG) { + ret = wc_ed448_export_public(&key, NULL, &pubSz); + } + if (ret == BAD_FUNC_ARG) { + ret = wc_ed448_export_public(&key, pub, NULL); + } + if (ret == BAD_FUNC_ARG) { + ret = 0; + } else if (ret == 0) { + ret = SSL_FATAL_ERROR; + } + } + } + + printf(resultFmt, ret == 0 ? passed : failed); + printf(testingFmt, "wc_ed448_export_private_only()"); + + if (ret == 0) { + ret = wc_ed448_export_private_only(&key, priv, &privSz); + if (ret == 0 && (privSz != ED448_KEY_SIZE || + XMEMCMP(key.k, priv, privSz) != 0)) { + ret = SSL_FATAL_ERROR; + } + if (ret == 0) { + ret = wc_ed448_export_private_only(NULL, priv, &privSz); + if (ret == BAD_FUNC_ARG) { + ret = wc_ed448_export_private_only(&key, NULL, &privSz); + } + if (ret == BAD_FUNC_ARG) { + ret = wc_ed448_export_private_only(&key, priv, NULL); + } + if (ret == BAD_FUNC_ARG) { + ret = 0; + } else if (ret == 0) { + ret = SSL_FATAL_ERROR; + } + } + } + + printf(resultFmt, ret == 0 ? passed : failed); + + if (wc_FreeRng(&rng) && ret == 0) { + ret = SSL_FATAL_ERROR; + } + wc_ed448_free(&key); + +#endif + return ret; + +} /* END test_wc_ed448_export */ + +/* + * Testing wc_ed448_size() + */ +static int test_wc_ed448_size (void) +{ + int ret = 0; +#if defined(HAVE_ED448) + WC_RNG rng; + ed448_key key; + + ret = wc_InitRng(&rng); + if (ret != 0) { + return ret; + } + ret = wc_ed448_init(&key); + if (ret != 0) { + wc_FreeRng(&rng); + return ret; + } + + ret = wc_ed448_make_key(&rng, ED448_KEY_SIZE, &key); + if (ret != 0) { + wc_FreeRng(&rng); + wc_ed448_free(&key); + return ret; + } + + printf(testingFmt, "wc_ed448_size()"); + ret = wc_ed448_size(&key); + /* Test bad args. */ + if (ret == ED448_KEY_SIZE) { + ret = wc_ed448_size(NULL); + if (ret == BAD_FUNC_ARG) { + ret = 0; + } + } + printf(resultFmt, ret == 0 ? passed : failed); + + if (ret == 0) { + printf(testingFmt, "wc_ed448_sig_size()"); + + ret = wc_ed448_sig_size(&key); + if (ret == ED448_SIG_SIZE) { + ret = 0; + } + /* Test bad args. */ + if (ret == 0) { + ret = wc_ed448_sig_size(NULL); + if (ret == BAD_FUNC_ARG) { + ret = 0; + } + } + + printf(resultFmt, ret == 0 ? passed : failed); + } /* END wc_ed448_sig_size() */ + + if (ret == 0) { + printf(testingFmt, "wc_ed448_pub_size"); + ret = wc_ed448_pub_size(&key); + if (ret == ED448_PUB_KEY_SIZE) { + ret = 0; + } + if (ret == 0) { + ret = wc_ed448_pub_size(NULL); + if (ret == BAD_FUNC_ARG) { + ret = 0; + } + } + printf(resultFmt, ret == 0 ? passed : failed); + } /* END wc_ed448_pub_size */ + + if (ret == 0) { + printf(testingFmt, "wc_ed448_priv_size"); + ret = wc_ed448_priv_size(&key); + if (ret == ED448_PRV_KEY_SIZE) { + ret = 0; + } + if (ret == 0) { + ret = wc_ed448_priv_size(NULL); + if (ret == BAD_FUNC_ARG) { + ret = 0; + } + } + printf(resultFmt, ret == 0 ? passed : failed); + } /* END wc_ed448_pub_size */ + + if (wc_FreeRng(&rng) && ret == 0) { + ret = SSL_FATAL_ERROR; + } + wc_ed448_free(&key); + +#endif + return ret; + +} /* END test_wc_ed448_size */ + +/* + * Testing wc_ed448_export_private() and wc_ed448_export_key() + */ +static int test_wc_ed448_exportKey (void) +{ + int ret = 0; +#if defined(HAVE_ED448) && defined(HAVE_ED448_KEY_EXPORT) + WC_RNG rng; + ed448_key key; + byte priv[ED448_PRV_KEY_SIZE]; + byte pub[ED448_PUB_KEY_SIZE]; + byte privOnly[ED448_PRV_KEY_SIZE]; + word32 privSz = sizeof(priv); + word32 pubSz = sizeof(pub); + word32 privOnlySz = sizeof(privOnly); + + ret = wc_InitRng(&rng); + if (ret != 0) { + return ret; + } + ret = wc_ed448_init(&key); + if (ret != 0) { + wc_FreeRng(&rng); + return ret; + } + + ret = wc_ed448_make_key(&rng, ED448_KEY_SIZE, &key); + if (ret != 0) { + wc_FreeRng(&rng); + wc_ed448_free(&key); + return ret; + } + + printf(testingFmt, "wc_ed448_export_private()"); + + ret = wc_ed448_export_private(&key, privOnly, &privOnlySz); + if (ret == 0) { + ret = wc_ed448_export_private(NULL, privOnly, &privOnlySz); + if (ret == BAD_FUNC_ARG) { + ret = wc_ed448_export_private(&key, NULL, &privOnlySz); + } + if (ret == BAD_FUNC_ARG) { + ret = wc_ed448_export_private(&key, privOnly, NULL); + } + if (ret == BAD_FUNC_ARG) { + ret = 0; + } else if (ret == 0) { + ret = SSL_FATAL_ERROR; + } + } + + printf(resultFmt, ret == 0 ? passed : failed); + + if (ret == 0) { + printf(testingFmt, "wc_ed448_export_key()"); + + ret = wc_ed448_export_key(&key, priv, &privSz, pub, &pubSz); + if (ret == 0) { + ret = wc_ed448_export_key(NULL, priv, &privSz, pub, &pubSz); + if (ret == BAD_FUNC_ARG) { + ret = wc_ed448_export_key(&key, NULL, &privSz, pub, &pubSz); + } + if (ret == BAD_FUNC_ARG) { + ret = wc_ed448_export_key(&key, priv, NULL, pub, &pubSz); + } + if (ret == BAD_FUNC_ARG) { + ret = wc_ed448_export_key(&key, priv, &privSz, NULL, &pubSz); + } + if (ret == BAD_FUNC_ARG) { + ret = wc_ed448_export_key(&key, priv, &privSz, pub, NULL); + } + if (ret == BAD_FUNC_ARG) { + ret = 0; + } else if (ret == 0) { + ret = SSL_FATAL_ERROR; + } + } + printf(resultFmt, ret == 0 ? passed : failed); + } /* END wc_ed448_export_key() */ + + /* Cross check output. */ + if (ret == 0 && XMEMCMP(priv, privOnly, privSz) != 0) { + ret = SSL_FATAL_ERROR; + } + + if (wc_FreeRng(&rng) && ret == 0) { + ret = SSL_FATAL_ERROR; + } + wc_ed448_free(&key); + +#endif + return ret; + +} /* END test_wc_ed448_exportKey */ + +/* + * Testing wc_Ed448PublicKeyToDer + */ +static int test_wc_Ed448PublicKeyToDer (void) +{ + int ret = 0; + +#if defined(HAVE_ED448) && (defined(WOLFSSL_CERT_GEN) || \ + defined(WOLFSSL_KEY_GEN)) + int tmp; + ed448_key key; + byte derBuf[1024]; + + printf(testingFmt, "wc_Ed448PublicKeyToDer()"); + + /* Test bad args */ + tmp = wc_Ed448PublicKeyToDer(NULL, NULL, 0, 0); + if (tmp != BAD_FUNC_ARG) { + ret = SSL_FATAL_ERROR; + } + + if (ret == 0) { + wc_ed448_init(&key); + tmp = wc_Ed448PublicKeyToDer(&key, derBuf, 0, 0); + if (tmp != BUFFER_E) { + ret = SSL_FATAL_ERROR; + } + wc_ed448_free(&key); + } + + /* Test good args */ + if (ret == 0) { + WC_RNG rng; + ret = wc_InitRng(&rng); + if (ret != 0) { + return ret; + } + ret = wc_ed448_init(&key); + if (ret != 0) { + wc_FreeRng(&rng); + return ret; + } + + ret = wc_ed448_make_key(&rng, ED448_KEY_SIZE, &key); + if (ret != 0) { + wc_FreeRng(&rng); + wc_ed448_free(&key); + return ret; + } + + tmp = wc_Ed448PublicKeyToDer(&key, derBuf, 1024, 1); + if (tmp <= 0) { + ret = SSL_FATAL_ERROR; + } + + wc_FreeRng(&rng); + wc_ed448_free(&key); + } + printf(resultFmt, ret == 0 ? passed : failed); +#endif + return ret; + +} /* END testing wc_Ed448PublicKeyToDer */ + +/* + * Testing wc_curve448_init and wc_curve448_free. + */ +static int test_wc_curve448_init (void) +{ + int ret = 0; + +#if defined(HAVE_CURVE448) + + curve448_key key; + + printf(testingFmt, "wc_curve448_init()"); + ret = wc_curve448_init(&key); + + /* Test bad args for wc_curve448_init */ + if (ret == 0) { + ret = wc_curve448_init(NULL); + if (ret == BAD_FUNC_ARG) { + ret = 0; + } else if (ret == 0) { + ret = SSL_FATAL_ERROR; + } + } + + printf(resultFmt, ret == 0 ? passed : failed); + /* Test good args for wc_curve_448_free */ + wc_curve448_free(&key); + + wc_curve448_free(NULL); + +#endif + return ret; + +} /* END test_wc_curve448_init and wc_curve_448_free*/ +/* + * Testing test_wc_curve448_size. + */ +static int test_wc_curve448_size (void) +{ + int ret = 0; + +#if defined(HAVE_CURVE448) + + curve448_key key; + + printf(testingFmt, "wc_curve448_size()"); + + ret = wc_curve448_init(&key); + + /* Test good args for wc_curve448_size */ + if (ret == 0) { + ret = wc_curve448_size(&key); + } + + /* Test bad args for wc_curve448_size */ + if (ret != 0) { + ret = wc_curve448_size(NULL); + } + + printf(resultFmt, ret == 0 ? passed : failed); + wc_curve448_free(&key); +#endif + return ret; + +} /* END test_wc_curve448_size*/ + /* * Testing wc_ecc_make_key. */ @@ -19663,6 +20602,33 @@ static void test_wolfSSL_private_keys(void) SSL_free(ssl); SSL_CTX_free(ctx); #endif /* end of Ed25519 private key match tests */ + +#ifdef HAVE_ED448 + #ifndef NO_WOLFSSL_SERVER + AssertNotNull(ctx = SSL_CTX_new(wolfSSLv23_server_method())); + #else + AssertNotNull(ctx = SSL_CTX_new(wolfSSLv23_client_method())); + #endif + AssertTrue(SSL_CTX_use_certificate_file(ctx, ed448CertFile, + WOLFSSL_FILETYPE_PEM)); + AssertTrue(SSL_CTX_use_PrivateKey_file(ctx, ed448KeyFile, + WOLFSSL_FILETYPE_PEM)); + AssertNotNull(ssl = SSL_new(ctx)); + + AssertIntEQ(wolfSSL_check_private_key(ssl), WOLFSSL_SUCCESS); + SSL_free(ssl); + + + AssertTrue(SSL_CTX_use_PrivateKey_file(ctx, cliEd448KeyFile, + WOLFSSL_FILETYPE_PEM)); + AssertNotNull(ssl = SSL_new(ctx)); + + AssertIntNE(wolfSSL_check_private_key(ssl), WOLFSSL_SUCCESS); + + SSL_free(ssl); + SSL_CTX_free(ctx); +#endif /* end of Ed448 private key match tests */ + EVP_cleanup(); /* test existence of no-op macros in wolfssl/openssl/ssl.h */ @@ -24104,7 +25070,7 @@ static void test_wolfSSL_BIO_write(void) BIO_set_flags(bio64, BIO_FLAG_BASE64_NO_NL); #ifdef HAVE_EX_DATA BIO_set_ex_data(bio64, 0, (void*) "data"); - AssertIntEQ(strcmp(BIO_get_ex_data(bio64, 0), "data"), 0); + AssertIntEQ(strcmp((const char*)BIO_get_ex_data(bio64, 0), "data"), 0); #endif AssertIntEQ(BIO_write(bio, msg, sizeof(msg)), sizeof(msg)); BIO_flush(bio); @@ -26015,7 +26981,7 @@ static void test_wolfSSL_ASN1_STRING_to_UTF8(void) WOLFSSL_ASN1_STRING* a; FILE* file; int idx = 0; - char targetOutput[15] = "www.wolfssl.com"; + char targetOutput[16] = "www.wolfssl.com"; unsigned char* actual_output; int len = 0; int result = 0; @@ -26098,7 +27064,7 @@ static void test_wolfSSL_sk_CIPHER_description(void) * the cipher based on the provided offset. */ - if ((cipher = sk_value(supportedCiphers, i))) { + if ((cipher = (const WOLFSSL_CIPHER*)sk_value(supportedCiphers, i))) { SSL_CIPHER_description(cipher, buf, sizeof(buf)); } @@ -26316,7 +27282,7 @@ static void test_wolfSSL_EC_KEY_dup(void) /* Valid cases */ AssertNotNull(dupKey = wolfSSL_EC_KEY_dup(ecKey)); - AssertIntEQ(wc_ecc_check_key(dupKey->internal), 0); + AssertIntEQ(wc_ecc_check_key((ecc_key*)dupKey->internal), 0); /* Compare pubkey */ srcKey = (ecc_key*)ecKey->internal; @@ -28654,8 +29620,8 @@ static int test_tls13_apis(void) #ifdef WOLFSSL_EARLY_DATA int outSz; #endif - int groups[1] = { WOLFSSL_ECC_X25519 }; - int numGroups = 1; + int groups[2] = { WOLFSSL_ECC_X25519, WOLFSSL_ECC_X448 }; + int numGroups = 2; #if defined(OPENSSL_EXTRA) && defined(HAVE_ECC) char groupList[] = "P-521:P-384:P-256"; #endif /* defined(OPENSSL_EXTRA) && defined(HAVE_ECC) */ @@ -28732,6 +29698,20 @@ static int test_tls13_apis(void) AssertIntEQ(wolfSSL_UseKeyShare(clientSsl, WOLFSSL_ECC_X25519), WOLFSSL_SUCCESS); #endif +#elif defined(HAVE_CURVE448) + AssertIntEQ(wolfSSL_UseKeyShare(NULL, WOLFSSL_ECC_X448), BAD_FUNC_ARG); +#ifndef NO_WOLFSSL_SERVER + AssertIntEQ(wolfSSL_UseKeyShare(serverSsl, WOLFSSL_ECC_X448), + WOLFSSL_SUCCESS); +#endif +#ifndef NO_WOLFSSL_CLIENT +#ifndef WOLFSSL_NO_TLS12 + AssertIntEQ(wolfSSL_UseKeyShare(clientTls12Ssl, WOLFSSL_ECC_X448), + WOLFSSL_SUCCESS); +#endif + AssertIntEQ(wolfSSL_UseKeyShare(clientSsl, WOLFSSL_ECC_X448), + WOLFSSL_SUCCESS); +#endif #else AssertIntEQ(wolfSSL_UseKeyShare(NULL, WOLFSSL_ECC_SECP256R1), BAD_FUNC_ARG); #ifndef NO_WOLFSSL_CLIENT @@ -30632,6 +31612,7 @@ void ApiTest(void) test_wolfSSL_no_password_cb(); test_wolfSSL_PKCS8(); test_wolfSSL_PKCS8_ED25519(); + test_wolfSSL_PKCS8_ED448(); test_wolfSSL_PKCS5(); test_wolfSSL_URI(); test_wolfSSL_TBS(); @@ -30916,6 +31897,9 @@ void ApiTest(void) AssertIntEQ(test_wc_Sha3_256_Copy(), 0); AssertIntEQ(test_wc_Sha3_384_Copy(), 0); AssertIntEQ(test_wc_Sha3_512_Copy(), 0); + AssertIntEQ(test_wc_InitShake256(), 0); + AssertIntEQ(testing_wc_Shake256_Update(), 0); + AssertIntEQ(test_wc_Shake256_Final(), 0); AssertFalse(test_wc_Md5HmacSetKey()); AssertFalse(test_wc_Md5HmacUpdate()); @@ -31039,6 +32023,17 @@ void ApiTest(void) AssertIntEQ(test_wc_Ed25519PublicKeyToDer(), 0); AssertIntEQ(test_wc_curve25519_init(), 0); AssertIntEQ(test_wc_curve25519_size (), 0); + AssertIntEQ(test_wc_ed448_make_key(), 0); + AssertIntEQ(test_wc_ed448_init(), 0); + AssertIntEQ(test_wc_ed448_sign_msg(), 0); + AssertIntEQ(test_wc_ed448_import_public(), 0); + AssertIntEQ(test_wc_ed448_import_private_key(), 0); + AssertIntEQ(test_wc_ed448_export(), 0); + AssertIntEQ(test_wc_ed448_size(), 0); + AssertIntEQ(test_wc_ed448_exportKey(), 0); + AssertIntEQ(test_wc_Ed448PublicKeyToDer(), 0); + AssertIntEQ(test_wc_curve448_init(), 0); + AssertIntEQ(test_wc_curve448_size (), 0); AssertIntEQ(test_wc_ecc_make_key(), 0); AssertIntEQ(test_wc_ecc_init(), 0); AssertIntEQ(test_wc_ecc_check_key(), 0); diff --git a/tests/include.am b/tests/include.am index 0e9f7cb1d..ee4952667 100644 --- a/tests/include.am +++ b/tests/include.am @@ -36,6 +36,7 @@ EXTRA_DIST += tests/test.conf \ tests/test-sctp-sha2.conf \ tests/test-sig.conf \ tests/test-ed25519.conf \ + tests/test-ed448.conf \ tests/test-enckeys.conf \ tests/test-maxfrag.conf \ tests/test-maxfrag-dtls.conf \ diff --git a/tests/suites.c b/tests/suites.c index efb8b79b4..43a023550 100644 --- a/tests/suites.c +++ b/tests/suites.c @@ -799,6 +799,17 @@ int SuiteTest(int argc, char** argv) goto exit; } #endif +#if defined(HAVE_CURVE448) && defined(HAVE_ED448) + /* add ED448 certificate cipher suite tests */ + strcpy(argv0[1], "tests/test-ed448.conf"); + printf("starting ED448 extra cipher suite tests\n"); + test_harness(&args); + if (args.return_code != 0) { + printf("error from script %d\n", args.return_code); + args.return_code = EXIT_FAILURE; + goto exit; + } +#endif #ifdef WOLFSSL_DTLS /* add dtls extra suites */ strcpy(argv0[1], "tests/test-dtls.conf"); diff --git a/tests/test-ed448.conf b/tests/test-ed448.conf new file mode 100644 index 000000000..255e189a6 --- /dev/null +++ b/tests/test-ed448.conf @@ -0,0 +1,59 @@ +# server TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256 +-v 3 +-l ECDHE-ECDSA-AES128-GCM-SHA256 +-c ./certs/ed448/server-ed448.pem +-k ./certs/ed448/server-ed448-priv.pem + +# client TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256 +-v 3 +-l ECDHE-ECDSA-AES128-GCM-SHA256 +-A ./certs/ed448/root-ed448.pem +-C + +# server TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256 +-v 3 +-l ECDHE-ECDSA-AES128-GCM-SHA256 +-c ./certs/ed448/server-ed448.pem +-k ./certs/ed448/server-ed448-priv.pem +-A ./certs/ed448/client-ed448.pem +-V +# Remove -V when CRL for ED448 certificates available. + +# client TLSv1.2 ECDHE-ECDSA-AES128-GCM-SHA256 +-v 3 +-l ECDHE-ECDSA-AES128-GCM-SHA256 +-c ./certs/ed448/client-ed448.pem +-k ./certs/ed448/client-ed448-priv.pem +-A ./certs/ed448/root-ed448.pem +-C + +# server TLSv1.3 TLS13-AES128-GCM-SHA256 +-v 4 +-l TLS13-AES128-GCM-SHA256 +-c ./certs/ed448/server-ed448.pem +-k ./certs/ed448/server-ed448-priv.pem + +# client TLSv1.3 TLS13-AES128-GCM-SHA256 +-v 4 +-l TLS13-AES128-GCM-SHA256 +-A ./certs/ed448/root-ed448.pem +-C + +# Enable when CRL for ED448 certificates available. +# server TLSv1.3 TLS13-AES128-GCM-SHA256 +-v 4 +-l TLS13-AES128-GCM-SHA256 +-c ./certs/ed448/server-ed448.pem +-k ./certs/ed448/server-ed448-priv.pem +-A ./certs/ed448/client-ed448.pem +-V +# Remove -V when CRL for ED448 certificates available. + +# client TLSv1.3 TLS13-AES128-GCM-SHA256 +-v 4 +-l TLS13-AES128-GCM-SHA256 +-c ./certs/ed448/client-ed448.pem +-k ./certs/ed448/client-ed448-priv.pem +-A ./certs/ed448/root-ed448.pem +-C + diff --git a/tests/test-fails.conf b/tests/test-fails.conf index d976b307b..86fb3d4e3 100644 --- a/tests/test-fails.conf +++ b/tests/test-fails.conf @@ -69,8 +69,10 @@ -A ./certs/client-cert.pem # server ECC no signer error --v 3 +#-v 3 -l ECDHE-ECDSA-AES128-GCM-SHA256 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem # client ECC no signer error -v 3 diff --git a/tests/test-tls13-ecc.conf b/tests/test-tls13-ecc.conf index 3496eab8c..ee14f5406 100644 --- a/tests/test-tls13-ecc.conf +++ b/tests/test-tls13-ecc.conf @@ -66,6 +66,19 @@ -A ./certs/ca-ecc-cert.pem -t +# server TLSv1.3 TLS13-AES128-GCM-SHA256 +-v 4 +-l TLS13-AES128-GCM-SHA256 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem +-8 + +# client TLSv1.3 TLS13-AES128-GCM-SHA256 +-v 4 +-l TLS13-AES128-GCM-SHA256 +-A ./certs/ca-ecc-cert.pem +-8 + # server TLSv1.3 TLS13-AES128-GCM-SHA256 -v 4 -l TLS13-AES128-GCM-SHA256 diff --git a/tests/test.conf b/tests/test.conf index 2e67d461f..0fe6464a3 100644 --- a/tests/test.conf +++ b/tests/test.conf @@ -1942,6 +1942,18 @@ -A ./certs/ca-ecc-cert.pem -t +# server TLSv1.2 ECDHE-EDCSA-CHACHA20-POLY1305 +-v 3 +-l ECDHE-ECDSA-CHACHA20-POLY1305 +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client TLSv1.2 ECDHE-ECDSA-CHACHA20-POLY1305 +-v 3 +-l ECDHE-ECDSA-CHACHA20-POLY1305 +-A ./certs/ca-ecc-cert.pem +-8 + # server TLSv1.2 private-only key -v 3 -c ./certs/ecc-privOnlyCert.pem diff --git a/wolfcrypt/benchmark/benchmark.c b/wolfcrypt/benchmark/benchmark.c index d1925ecd0..ece26577c 100755 --- a/wolfcrypt/benchmark/benchmark.c +++ b/wolfcrypt/benchmark/benchmark.c @@ -162,6 +162,12 @@ #ifdef HAVE_ED25519 #include #endif +#ifdef HAVE_CURVE448 + #include +#endif +#ifdef HAVE_ED448 + #include +#endif #include #ifdef HAVE_NTRU @@ -271,6 +277,10 @@ #define BENCH_CURVE25519_KA 0x00020000 #define BENCH_ED25519_KEYGEN 0x00040000 #define BENCH_ED25519_SIGN 0x00080000 +#define BENCH_CURVE448_KEYGEN 0x00100000 +#define BENCH_CURVE448_KA 0x00200000 +#define BENCH_ED448_KEYGEN 0x00400000 +#define BENCH_ED448_SIGN 0x00800000 /* Other */ #define BENCH_RNG 0x00000001 #define BENCH_SCRYPT 0x00000002 @@ -470,7 +480,7 @@ static const bench_alg bench_asym_opt[] = { #endif #endif #ifdef HAVE_CURVE25519 - { "-curve25519_kg", BENCH_CURVE25519_KEYGEN }, + { "-curve25519-kg", BENCH_CURVE25519_KEYGEN }, #ifdef HAVE_CURVE25519_SHARED_SECRET { "-x25519", BENCH_CURVE25519_KA }, #endif @@ -478,6 +488,16 @@ static const bench_alg bench_asym_opt[] = { #ifdef HAVE_ED25519 { "-ed25519-kg", BENCH_ED25519_KEYGEN }, { "-ed25519", BENCH_ED25519_SIGN }, +#endif +#ifdef HAVE_CURVE448 + { "-curve448-kg", BENCH_CURVE448_KEYGEN }, + #ifdef HAVE_CURVE448_SHARED_SECRET + { "-x448", BENCH_CURVE448_KA }, + #endif +#endif +#ifdef HAVE_ED448 + { "-ed448-kg", BENCH_ED448_KEYGEN }, + { "-ed448", BENCH_ED448_SIGN }, #endif { NULL, 0} }; @@ -565,7 +585,8 @@ static const char* bench_result_words1[][4] = { #if !defined(NO_RSA) || defined(WOLFSSL_KEY_GEN) || defined(HAVE_NTRU) || \ defined(HAVE_ECC) || !defined(NO_DH) || defined(HAVE_ECC_ENCRYPT) || \ defined(HAVE_CURVE25519) || defined(HAVE_CURVE25519_SHARED_SECRET) || \ - defined(HAVE_ED25519) + defined(HAVE_ED25519) || defined(HAVE_CURVE448) || \ + defined(HAVE_CURVE448_SHARED_SECRET) || defined(HAVE_ED448) #if !defined(WOLFSSL_RSA_PUBLIC_ONLY) || defined(WOLFSSL_PUBLIC_MP) || \ !defined(NO_DH) @@ -694,12 +715,14 @@ static const char* bench_desc_words[][9] = { #if (!defined(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) || !defined(NO_DH) \ || defined(WOLFSSL_KEY_GEN) || defined(HAVE_ECC) \ - || defined(HAVE_CURVE25519) || defined(HAVE_ED25519) + || defined(HAVE_CURVE25519) || defined(HAVE_ED25519) \ + || defined(HAVE_CURVE448) || defined(HAVE_ED448) #define HAVE_LOCAL_RNG static THREAD_LS_T WC_RNG rng; #endif -#if defined(HAVE_ED25519) || defined(HAVE_CURVE25519) || defined(HAVE_ECC) || \ +#if defined(HAVE_ED25519) || defined(HAVE_CURVE25519) || \ + defined(HAVE_CURVE448) || defined(HAVE_ED448) || \ defined(HAVE_ECC) || defined(HAVE_NTRU) || !defined(NO_DH) || \ !defined(NO_RSA) || defined(HAVE_SCRYPT) #define BENCH_ASYM @@ -1826,6 +1849,22 @@ static void* benchmarks_do(void* args) bench_ed25519KeySign(); #endif +#ifdef HAVE_CURVE448 + if (bench_all || (bench_asym_algs & BENCH_CURVE448_KEYGEN)) + bench_curve448KeyGen(); + #ifdef HAVE_CURVE448_SHARED_SECRET + if (bench_all || (bench_asym_algs & BENCH_CURVE448_KA)) + bench_curve448KeyAgree(); + #endif +#endif + +#ifdef HAVE_ED448 + if (bench_all || (bench_asym_algs & BENCH_ED448_KEYGEN)) + bench_ed448KeyGen(); + if (bench_all || (bench_asym_algs & BENCH_ED448_SIGN)) + bench_ed448KeySign(); +#endif + exit: /* free benchmark buffers */ XFREE(bench_plain, HEAP_HINT, DYNAMIC_TYPE_WOLF_BIGINT); @@ -5617,6 +5656,164 @@ exit_ed_verify: } #endif /* HAVE_ED25519 */ +#ifdef HAVE_CURVE448 +void bench_curve448KeyGen(void) +{ + curve448_key genKey; + double start; + int ret = 0, i, count; + const char**desc = bench_desc_words[lng_index]; + + /* Key Gen */ + bench_stats_start(&count, &start); + do { + for (i = 0; i < genTimes; i++) { + ret = wc_curve448_make_key(&rng, 56, &genKey); + wc_curve448_free(&genKey); + if (ret != 0) { + printf("wc_curve448_make_key failed: %d\n", ret); + break; + } + } + count += i; + } while (bench_stats_sym_check(start)); + bench_stats_asym_finish("CURVE", 448, desc[2], 0, count, start, ret); +} + +#ifdef HAVE_CURVE448_SHARED_SECRET +void bench_curve448KeyAgree(void) +{ + curve448_key genKey, genKey2; + double start; + int ret, i, count; + byte shared[56]; + const char**desc = bench_desc_words[lng_index]; + word32 x = 0; + + wc_curve448_init(&genKey); + wc_curve448_init(&genKey2); + + ret = wc_curve448_make_key(&rng, 56, &genKey); + if (ret != 0) { + printf("curve448_make_key failed\n"); + return; + } + ret = wc_curve448_make_key(&rng, 56, &genKey2); + if (ret != 0) { + printf("curve448_make_key failed: %d\n", ret); + wc_curve448_free(&genKey); + return; + } + + /* Shared secret */ + bench_stats_start(&count, &start); + do { + for (i = 0; i < agreeTimes; i++) { + x = sizeof(shared); + ret = wc_curve448_shared_secret(&genKey, &genKey2, shared, &x); + if (ret != 0) { + printf("curve448_shared_secret failed: %d\n", ret); + goto exit; + } + } + count += i; + } while (bench_stats_sym_check(start)); +exit: + bench_stats_asym_finish("CURVE", 448, desc[3], 0, count, start, ret); + + wc_curve448_free(&genKey2); + wc_curve448_free(&genKey); +} +#endif /* HAVE_CURVE448_SHARED_SECRET */ +#endif /* HAVE_CURVE448 */ + +#ifdef HAVE_ED448 +void bench_ed448KeyGen(void) +{ + ed448_key genKey; + double start; + int i, count; + const char**desc = bench_desc_words[lng_index]; + + /* Key Gen */ + bench_stats_start(&count, &start); + do { + for (i = 0; i < genTimes; i++) { + wc_ed448_init(&genKey); + (void)wc_ed448_make_key(&rng, ED448_KEY_SIZE, &genKey); + wc_ed448_free(&genKey); + } + count += i; + } while (bench_stats_sym_check(start)); + bench_stats_asym_finish("ED", 448, desc[2], 0, count, start, 0); +} + + +void bench_ed448KeySign(void) +{ + int ret; + ed448_key genKey; +#ifdef HAVE_ED448_SIGN + double start; + int i, count; + byte sig[ED448_SIG_SIZE]; + byte msg[512]; + word32 x = 0; +#endif + const char**desc = bench_desc_words[lng_index]; + + wc_ed448_init(&genKey); + + ret = wc_ed448_make_key(&rng, ED448_KEY_SIZE, &genKey); + if (ret != 0) { + printf("ed448_make_key failed\n"); + return; + } + +#ifdef HAVE_ED448_SIGN + /* make dummy msg */ + for (i = 0; i < (int)sizeof(msg); i++) + msg[i] = (byte)i; + + bench_stats_start(&count, &start); + do { + for (i = 0; i < agreeTimes; i++) { + x = sizeof(sig); + ret = wc_ed448_sign_msg(msg, sizeof(msg), sig, &x, &genKey, + NULL, 0); + if (ret != 0) { + printf("ed448_sign_msg failed\n"); + goto exit_ed_sign; + } + } + count += i; + } while (bench_stats_sym_check(start)); +exit_ed_sign: + bench_stats_asym_finish("ED", 448, desc[4], 0, count, start, ret); + +#ifdef HAVE_ED448_VERIFY + bench_stats_start(&count, &start); + do { + for (i = 0; i < agreeTimes; i++) { + int verify = 0; + ret = wc_ed448_verify_msg(sig, x, msg, sizeof(msg), &verify, + &genKey, NULL, 0); + if (ret != 0 || verify != 1) { + printf("ed448_verify_msg failed\n"); + goto exit_ed_verify; + } + } + count += i; + } while (bench_stats_sym_check(start)); +exit_ed_verify: + bench_stats_asym_finish("ED", 448, desc[5], 0, count, start, ret); +#endif /* HAVE_ED448_VERIFY */ +#endif /* HAVE_ED448_SIGN */ + + wc_ed448_free(&genKey); +} +#endif /* HAVE_ED448 */ + #ifndef HAVE_STACK_SIZE #if defined(_WIN32) && !defined(INTIME_RTOS) diff --git a/wolfcrypt/benchmark/benchmark.h b/wolfcrypt/benchmark/benchmark.h index 236225854..c2771bb59 100644 --- a/wolfcrypt/benchmark/benchmark.h +++ b/wolfcrypt/benchmark/benchmark.h @@ -88,6 +88,10 @@ void bench_curve25519KeyGen(void); void bench_curve25519KeyAgree(void); void bench_ed25519KeyGen(void); void bench_ed25519KeySign(void); +void bench_curve448KeyGen(void); +void bench_curve448KeyAgree(void); +void bench_ed448KeyGen(void); +void bench_ed448KeySign(void); void bench_ntru(void); void bench_ntruKeyGen(void); void bench_rng(void); diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index f70fe0f02..1f323ec5b 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -102,6 +102,10 @@ ASN Options: #include #endif +#ifdef HAVE_ED448 + #include +#endif + #ifndef NO_RSA #include #if defined(WOLFSSL_XILINX_CRYPT) || defined(WOLFSSL_CRYPTOCELL) @@ -640,8 +644,9 @@ static int SetASNInt(int len, byte firstByte, byte* output) } #endif -#if !defined(NO_DSA) || defined(HAVE_ECC) || defined(WOLFSSL_CERT_GEN) || \ - ((defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA)) && !defined(NO_RSA) && !defined(HAVE_USER_RSA)) +#if !defined(NO_DSA) || defined(HAVE_ECC) || (defined(WOLFSSL_CERT_GEN) && \ + !defined(NO_RSA)) || ((defined(WOLFSSL_KEY_GEN) || \ + defined(OPENSSL_EXTRA)) && !defined(NO_RSA) && !defined(HAVE_USER_RSA)) /* Set the DER/BER encoding of the ASN.1 INTEGER element with an mp_int. * The number is assumed to be positive. * @@ -944,11 +949,12 @@ static int CheckBitString(const byte* input, word32* inOutIdx, int* len, return 0; } -/* RSA (with CertGen or KeyGen) OR ECC OR ED25519 (with CertGen or KeyGen) */ +/* RSA (with CertGen or KeyGen) OR ECC OR ED25519 OR ED448 (with CertGen or + * KeyGen) */ #if (!defined(NO_RSA) && !defined(HAVE_USER_RSA) && \ (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA))) || \ (defined(HAVE_ECC) && defined(HAVE_ECC_KEY_EXPORT)) || \ - (defined(HAVE_ED25519) && \ + ((defined(HAVE_ED25519) || defined(HAVE_ED448)) && \ (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA))) /* Set the DER/BER encoding of the ASN.1 BIT_STRING header. @@ -975,7 +981,7 @@ word32 SetBitString(word32 len, byte unusedBits, byte* output) return idx; } -#endif /* !NO_RSA || HAVE_ECC || HAVE_ED25519 */ +#endif /* !NO_RSA || HAVE_ECC || HAVE_ED25519 || HAVE_ED448 */ #ifdef ASN_BER_TO_DER /* Pull informtation from the ASN.1 BER encoded item header */ @@ -1353,7 +1359,7 @@ end: #if defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN) #if (!defined(NO_RSA) && !defined(HAVE_USER_RSA)) || \ - defined(HAVE_ECC) || defined(HAVE_ED25519) + defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) #ifdef WOLFSSL_CERT_EXT /* Set the DER/BER encoding of the ASN.1 BIT_STRING with a 16-bit value. @@ -1389,7 +1395,7 @@ static word32 SetBitString16Bit(word16 val, byte* output) return idx; } #endif /* WOLFSSL_CERT_EXT */ -#endif /* !NO_RSA || HAVE_ECC || HAVE_ED25519 */ +#endif /* !NO_RSA || HAVE_ECC || HAVE_ED25519 || defined(HAVE_ED448) */ #endif /* WOLFSSL_CERT_GEN || WOLFSSL_KEY_GEN */ @@ -1480,6 +1486,9 @@ static word32 SetBitString16Bit(word16 val, byte* output) #ifdef HAVE_ED25519 static const byte sigEd25519Oid[] = {43, 101, 112}; #endif /* HAVE_ED25519 */ +#ifdef HAVE_ED448 + static const byte sigEd448Oid[] = {43, 101, 113}; +#endif /* HAVE_ED448 */ /* keyType */ #ifndef NO_DSA @@ -1497,6 +1506,9 @@ static word32 SetBitString16Bit(word16 val, byte* output) #ifdef HAVE_ED25519 static const byte keyEd25519Oid[] = {43, 101, 112}; #endif /* HAVE_ED25519 */ +#ifdef HAVE_ED448 + static const byte keyEd448Oid[] = {43, 101, 113}; +#endif /* HAVE_ED448 */ #if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL)) static const byte keyDhOid[] = {42, 134, 72, 134, 247, 13, 1, 3, 1}; #endif /* ! NO_DH ... */ @@ -1796,6 +1808,12 @@ const byte* OidFromId(word32 id, word32 type, word32* oidSz) *oidSz = sizeof(sigEd25519Oid); break; #endif + #ifdef HAVE_ED448 + case CTC_ED448: + oid = sigEd448Oid; + *oidSz = sizeof(sigEd448Oid); + break; + #endif default: break; } @@ -1833,6 +1851,12 @@ const byte* OidFromId(word32 id, word32 type, word32* oidSz) *oidSz = sizeof(keyEd25519Oid); break; #endif /* HAVE_ED25519 */ + #ifdef HAVE_ED448 + case ED448k: + oid = keyEd448Oid; + *oidSz = sizeof(keyEd448Oid); + break; + #endif /* HAVE_ED448 */ #if !defined(NO_DH) && (defined(WOLFSSL_QT) || defined(OPENSSL_ALL)) case DHk: oid = keyDhOid; @@ -2999,6 +3023,49 @@ int wc_CheckPrivateKey(byte* key, word32 keySz, DecodedCert* der) } else #endif /* HAVE_ED25519 && !NO_ASN_CRYPT */ + + #if defined(HAVE_ED448) && !defined(NO_ASN_CRYPT) + if (der->keyOID == ED448k) { + #ifdef WOLFSSL_SMALL_STACK + ed448_key* key_pair = NULL; + #else + ed448_key key_pair[1]; + #endif + word32 keyIdx = 0; + + #ifdef WOLFSSL_SMALL_STACK + key_pair = (ed448_key*)XMALLOC(sizeof(ed448_key), NULL, + DYNAMIC_TYPE_ED448); + if (key_pair == NULL) + return MEMORY_E; + #endif + + if ((ret = wc_ed448_init(key_pair)) < 0) { + #ifdef WOLFSSL_SMALL_STACK + XFREE(key_pair, NULL, DYNAMIC_TYPE_ED448); + #endif + return ret; + } + if ((ret = wc_Ed448PrivateKeyDecode(key, &keyIdx, key_pair, + keySz)) == 0) { + WOLFSSL_MSG("Checking ED448 key pair"); + keyIdx = 0; + if ((ret = wc_ed448_import_public(der->publicKey, der->pubKeySize, + key_pair)) == 0) { + /* public and private extracted successfully no check if is + * a pair and also do sanity checks on key. wc_ecc_check_key + * checks that private * base generator equals pubkey */ + if ((ret = wc_ed448_check_key(key_pair)) == 0) + ret = 1; + } + } + wc_ed448_free(key_pair); + #ifdef WOLFSSL_SMALL_STACK + XFREE(key_pair, NULL, DYNAMIC_TYPE_ED448); + #endif + } + else + #endif /* HAVE_ED448 && !NO_ASN_CRYPT */ { ret = 0; } @@ -3183,6 +3250,25 @@ int wc_GetKeyOID(byte* key, word32 keySz, const byte** curveOID, word32* oidSz, } } #endif /* HAVE_ED25519 && !NO_ASN_CRYPT */ +#if defined(HAVE_ED448) && !defined(NO_ASN_CRYPT) + if (*algoID != RSAk && *algoID != ECDSAk && *algoID != ED25519k) { + ed448_key ed448; + + tmpIdx = 0; + if (wc_ed448_init(&ed448) == 0) { + if (wc_Ed448PrivateKeyDecode(key, &tmpIdx, &ed448, keySz) == 0) { + *algoID = ED448k; + } + else { + WOLFSSL_MSG("Not ED448 DER key"); + } + wc_ed448_free(&ed448); + } + else { + WOLFSSL_MSG("GetKeyOID wc_ed448_init failed"); + } + } +#endif /* HAVE_ED448 && !NO_ASN_CRYPT */ /* if flag is not set then is neither RSA or ECC key that could be * found */ @@ -5331,6 +5417,40 @@ static int GetKey(DecodedCert* cert) return 0; } #endif /* HAVE_ED25519 */ + #ifdef HAVE_ED448 + case ED448k: + { + byte* publicKey; + int ret; + + cert->pkCurveOID = ED448k; + + ret = CheckBitString(cert->source, &cert->srcIdx, &length, + cert->maxIdx, 1, NULL); + if (ret != 0) + return ret; + + #ifdef HAVE_OCSP + ret = CalcHashId(cert->source + cert->srcIdx, length, + cert->subjectKeyHash); + if (ret != 0) + return ret; + #endif + + publicKey = (byte*) XMALLOC(length, cert->heap, + DYNAMIC_TYPE_PUBLIC_KEY); + if (publicKey == NULL) + return MEMORY_E; + XMEMCPY(publicKey, &cert->source[cert->srcIdx], length); + cert->publicKey = publicKey; + cert->pubKeyStored = 1; + cert->pubKeySize = length; + + cert->srcIdx += length; + + return 0; + } + #endif /* HAVE_ED448 */ #if !defined(NO_DSA) && defined(WOLFSSL_QT) case DSAk: { @@ -6816,6 +6936,9 @@ word32 SetAlgoID(int algoOID, byte* output, int type, int curveSz) #endif #ifdef HAVE_ED25519 && algoOID != ED25519k + #endif + #ifdef HAVE_ED448 + && algoOID != ED448k #endif ) || (type == oidKeyType && algoOID == RSAk)) ? 2 : 0; @@ -6934,6 +7057,12 @@ void FreeSignatureCtx(SignatureCtx* sigCtx) XFREE(sigCtx->key.ed25519, sigCtx->heap, DYNAMIC_TYPE_ED25519); break; #endif /* HAVE_ED25519 */ + #ifdef HAVE_ED448 + case ED448k: + wc_ed448_free(sigCtx->key.ed448); + XFREE(sigCtx->key.ed448, sigCtx->heap, DYNAMIC_TYPE_ED448); + break; + #endif /* HAVE_ED448 */ default: break; } /* switch (keyOID) */ @@ -7020,11 +7149,20 @@ static int HashForSignature(const byte* buf, word32 bufSz, word32 sigOID, } break; #endif + #ifdef HAVE_ED25519 case CTC_ED25519: /* Hashes done in signing operation. * Two dependent hashes with prefixes performed. */ break; + #endif + #ifdef HAVE_ED448 + case CTC_ED448: + /* Hashes done in signing operation. + * Two dependent hashes with prefixes performed. + */ + break; + #endif default: ret = HASH_TYPE_E; WOLFSSL_MSG("Hash for Signature has unsupported type"); @@ -7171,6 +7309,30 @@ static int ConfirmSignature(SignatureCtx* sigCtx, #endif break; } + #endif + #ifdef HAVE_ED448 + case ED448k: + { + sigCtx->verify = 0; + sigCtx->key.ed448 = (ed448_key*)XMALLOC( + sizeof(ed448_key), sigCtx->heap, + DYNAMIC_TYPE_ED448); + if (sigCtx->key.ed448 == NULL) { + ERROR_OUT(MEMORY_E, exit_cs); + } + if ((ret = wc_ed448_init(sigCtx->key.ed448)) < 0) { + goto exit_cs; + } + if ((ret = wc_ed448_import_public(key, keySz, + sigCtx->key.ed448)) < 0) { + WOLFSSL_MSG("ASN Key import error ED448"); + goto exit_cs; + } + #ifdef WOLFSSL_ASYNC_CRYPT + sigCtx->asyncDev = &sigCtx->key.ed448->asyncDev; + #endif + break; + } #endif default: WOLFSSL_MSG("Verify Key type unknown"); @@ -7265,6 +7427,15 @@ static int ConfirmSignature(SignatureCtx* sigCtx, &sigCtx->verify, sigCtx->key.ed25519); break; } + #endif + #ifdef HAVE_ED448 + case ED448k: + { + ret = wc_ed448_verify_msg(sig, sigSz, buf, bufSz, + &sigCtx->verify, sigCtx->key.ed448, + NULL, 0); + break; + } #endif default: break; @@ -7352,6 +7523,19 @@ static int ConfirmSignature(SignatureCtx* sigCtx, break; } #endif /* HAVE_ED25519 */ + #ifdef HAVE_ED448 + case ED448k: + { + if (sigCtx->verify == 1) { + ret = 0; + } + else { + WOLFSSL_MSG("ED448 Verify didn't match"); + ret = ASN_SIG_CONFIRM_E; + } + break; + } + #endif /* HAVE_ED448 */ default: break; } /* switch (keyOID) */ @@ -9753,7 +9937,8 @@ const char* const END_ENC_PRIV_KEY = "-----END ENCRYPTED PRIVATE KEY-----"; const char* const BEGIN_EC_PRIV = "-----BEGIN EC PRIVATE KEY-----"; const char* const END_EC_PRIV = "-----END EC PRIVATE KEY-----"; #endif -#if defined(HAVE_ECC) || defined(HAVE_ED25519) || !defined(NO_DSA) +#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) || \ + !defined(NO_DSA) const char* const BEGIN_DSA_PRIV = "-----BEGIN DSA PRIVATE KEY-----"; const char* const END_DSA_PRIV = "-----END DSA PRIVATE KEY-----"; #endif @@ -9764,7 +9949,7 @@ const char* const END_ENC_PRIV_KEY = "-----END ENCRYPTED PRIVATE KEY-----"; #endif const char* const BEGIN_PUB_KEY = "-----BEGIN PUBLIC KEY-----"; const char* const END_PUB_KEY = "-----END PUBLIC KEY-----"; -#ifdef HAVE_ED25519 +#if defined(HAVE_ED25519) || defined(HAVE_ED448) const char* const BEGIN_EDDSA_PRIV = "-----BEGIN EDDSA PRIVATE KEY-----"; const char* const END_EDDSA_PRIV = "-----END EDDSA PRIVATE KEY-----"; #endif @@ -9847,6 +10032,11 @@ int wc_PemGetHeaderFooter(int type, const char** header, const char** footer) break; #ifdef HAVE_ED25519 case ED25519_TYPE: + #endif + #ifdef HAVE_ED448 + case ED448_TYPE: + #endif + #if defined(HAVE_ED25519) || defined(HAVE_ED448) case EDDSA_PRIVATEKEY_TYPE: if (header) *header = BEGIN_EDDSA_PRIV; if (footer) *footer = END_EDDSA_PRIV; @@ -10275,7 +10465,7 @@ int PemToDer(const unsigned char* buff, long longSz, int type, header = BEGIN_DSA_PRIV; footer = END_DSA_PRIV; } else #endif - #ifdef HAVE_ED25519 + #if defined(HAVE_ED25519) || defined(HAVE_ED448) #ifdef HAVE_ECC if (header == BEGIN_DSA_PRIV) #else @@ -11637,6 +11827,110 @@ int wc_Ed25519PublicKeyToDer(ed25519_key* key, byte* output, word32 inLen, return SetEd25519PublicKey(output, key, withAlg); } #endif /* HAVE_ED25519 && (WOLFSSL_CERT_GEN || WOLFSSL_KEY_GEN) */ +#if defined(HAVE_ED448) && (defined(WOLFSSL_CERT_GEN) || \ + defined(WOLFSSL_KEY_GEN)) + +/* Write a public ECC key to output */ +static int SetEd448PublicKey(byte* output, ed448_key* key, int with_header) +{ + byte bitString[1 + MAX_LENGTH_SZ + 1]; + int algoSz; + int bitStringSz; + int idx; + word32 pubSz = ED448_PUB_KEY_SIZE; +#ifdef WOLFSSL_SMALL_STACK + byte* algo = NULL; + byte* pub = NULL; +#else + byte algo[MAX_ALGO_SZ]; + byte pub[ED448_PUB_KEY_SIZE]; +#endif + +#ifdef WOLFSSL_SMALL_STACK + pub = (byte*)XMALLOC(ECC_BUFSIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (pub == NULL) + return MEMORY_E; +#endif + + idx = wc_ed448_export_public(key, pub, &pubSz); + if (idx != 0) { +#ifdef WOLFSSL_SMALL_STACK + XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER); +#endif + return idx; + } + + /* headers */ + if (with_header) { +#ifdef WOLFSSL_SMALL_STACK + algo = (byte*)XMALLOC(MAX_ALGO_SZ, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (algo == NULL) { + XFREE(pub, key->heap, DYNAMIC_TYPE_TMP_BUFFER); + return MEMORY_E; + } +#endif + algoSz = SetAlgoID(ED448k, algo, oidKeyType, 0); + + bitStringSz = SetBitString(pubSz, 0, bitString); + + idx = SetSequence(pubSz + bitStringSz + algoSz, output); + /* algo */ + XMEMCPY(output + idx, algo, algoSz); + idx += algoSz; + /* bit string */ + XMEMCPY(output + idx, bitString, bitStringSz); + idx += bitStringSz; + } + else + idx = 0; + + /* pub */ + XMEMCPY(output + idx, pub, pubSz); + idx += pubSz; + +#ifdef WOLFSSL_SMALL_STACK + if (with_header) { + XFREE(algo, NULL, DYNAMIC_TYPE_TMP_BUFFER); + } + XFREE(pub, NULL, DYNAMIC_TYPE_TMP_BUFFER); +#endif + + return idx; +} + +int wc_Ed448PublicKeyToDer(ed448_key* key, byte* output, word32 inLen, + int withAlg) +{ + word32 infoSz = 0; + word32 keySz = 0; + int ret; + + if (output == NULL || key == NULL) { + return BAD_FUNC_ARG; + } + + if (withAlg) { + /* buffer space for algorithm */ + infoSz += MAX_SEQ_SZ; + infoSz += MAX_ALGO_SZ; + + /* buffer space for public key sequence */ + infoSz += MAX_SEQ_SZ; + infoSz += TRAILING_ZERO; + } + + if ((ret = wc_ed448_export_public(key, output, &keySz)) != BUFFER_E) { + WOLFSSL_MSG("Error in getting ECC public key size"); + return ret; + } + + if (inLen < keySz + infoSz) { + return BUFFER_E; + } + + return SetEd448PublicKey(output, key, withAlg); +} +#endif /* HAVE_ED448 && (WOLFSSL_CERT_GEN || WOLFSSL_KEY_GEN) */ #ifdef WOLFSSL_CERT_GEN @@ -12615,7 +12909,7 @@ int SetName(byte* output, word32 outputSz, CertName* name) /* encode info from cert into DER encoded format */ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng, const byte* ntruKey, word16 ntruSz, - ed25519_key* ed25519Key) + ed25519_key* ed25519Key, ed448_key* ed448Key) { int ret; @@ -12623,8 +12917,10 @@ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey, return BAD_FUNC_ARG; /* make sure at least one key type is provided */ - if (rsaKey == NULL && eccKey == NULL && ed25519Key == NULL && ntruKey == NULL) + if (rsaKey == NULL && eccKey == NULL && ed25519Key == NULL && + ed448Key == NULL && ntruKey == NULL) { return PUBLIC_KEY_E; + } /* init */ XMEMSET(der, 0, sizeof(DerCert)); @@ -12678,6 +12974,14 @@ static int EncodeCert(Cert* cert, DerCert* der, RsaKey* rsaKey, ecc_key* eccKey, } #endif +#ifdef HAVE_ED448 + if (cert->keyType == ED448_KEY) { + if (ed448Key == NULL) + return PUBLIC_KEY_E; + der->publicKeySz = SetEd448PublicKey(der->publicKey, ed448Key, 1); + } +#endif + #ifdef HAVE_NTRU if (cert->keyType == NTRU_KEY) { word32 rc; @@ -13011,7 +13315,8 @@ static int WriteCertBody(DerCert* der, byte* buf) /* Make RSA signature from buffer (sz), write to sig (sigSz) */ static int MakeSignature(CertSignCtx* certSignCtx, const byte* buf, int sz, byte* sig, int sigSz, RsaKey* rsaKey, ecc_key* eccKey, - ed25519_key* ed25519Key, WC_RNG* rng, int sigAlgoType, void* heap) + ed25519_key* ed25519Key, ed448_key* ed448Key, WC_RNG* rng, int sigAlgoType, + void* heap) { int digestSz = 0, typeH = 0, ret = 0; @@ -13024,6 +13329,7 @@ static int MakeSignature(CertSignCtx* certSignCtx, const byte* buf, int sz, (void)rsaKey; (void)eccKey; (void)ed25519Key; + (void)ed448Key; (void)rng; (void)heap; @@ -13095,6 +13401,16 @@ static int MakeSignature(CertSignCtx* certSignCtx, const byte* buf, int sz, ret = outSz; } #endif /* HAVE_ECC */ + + #ifdef HAVE_ED448 + if (!rsaKey && !eccKey && !ed25519Key && ed448Key) { + word32 outSz = sigSz; + + ret = wc_ed448_sign_msg(buf, sz, sig, &outSz, ed448Key, NULL, 0); + if (ret == 0) + ret = outSz; + } + #endif /* HAVE_ECC */ break; } @@ -13154,7 +13470,7 @@ static int AddSignature(byte* buf, int bodySz, const byte* sig, int sigSz, static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng, const byte* ntruKey, word16 ntruSz, - ed25519_key* ed25519Key) + ed25519_key* ed25519Key, ed448_key* ed448Key) { int ret; #ifdef WOLFSSL_SMALL_STACK @@ -13168,7 +13484,7 @@ static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz, } cert->keyType = eccKey ? ECC_KEY : (rsaKey ? RSA_KEY : - (ed25519Key ? ED25519_KEY : NTRU_KEY)); + (ed25519Key ? ED25519_KEY : (ed448Key ? ED448_KEY : NTRU_KEY))); #ifdef WOLFSSL_SMALL_STACK der = (DerCert*)XMALLOC(sizeof(DerCert), cert->heap, DYNAMIC_TYPE_TMP_BUFFER); @@ -13177,7 +13493,7 @@ static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz, #endif ret = EncodeCert(cert, der, rsaKey, eccKey, rng, ntruKey, ntruSz, - ed25519Key); + ed25519Key, ed448Key); if (ret == 0) { if (der->total + MAX_SEQ_SZ * 2 > (int)derSz) ret = BUFFER_E; @@ -13197,9 +13513,10 @@ static int MakeAnyCert(Cert* cert, byte* derBuffer, word32 derSz, int wc_MakeCert_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType, void* key, WC_RNG* rng) { - RsaKey* rsaKey = NULL; - ecc_key* eccKey = NULL; + RsaKey* rsaKey = NULL; + ecc_key* eccKey = NULL; ed25519_key* ed25519Key = NULL; + ed448_key* ed448Key = NULL; if (keyType == RSA_TYPE) rsaKey = (RsaKey*)key; @@ -13207,16 +13524,18 @@ int wc_MakeCert_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType, eccKey = (ecc_key*)key; else if (keyType == ED25519_TYPE) ed25519Key = (ed25519_key*)key; + else if (keyType == ED448_TYPE) + ed448Key = (ed448_key*)key; return MakeAnyCert(cert, derBuffer, derSz, rsaKey, eccKey, rng, NULL, 0, - ed25519Key); + ed25519Key, ed448Key); } /* Make an x509 Certificate v3 RSA or ECC from cert input, write to buffer */ int wc_MakeCert(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng) { return MakeAnyCert(cert, derBuffer, derSz, rsaKey, eccKey, rng, NULL, 0, - NULL); + NULL, NULL); } @@ -13311,16 +13630,20 @@ static int SetReqAttrib(byte* output, char* pw, int pwPrintableString, /* encode info from cert into DER encoded format */ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey, - ecc_key* eccKey, ed25519_key* ed25519Key) + ecc_key* eccKey, ed25519_key* ed25519Key, + ed448_key* ed448Key) { (void)eccKey; (void)ed25519Key; + (void)ed448Key; if (cert == NULL || der == NULL) return BAD_FUNC_ARG; - if (rsaKey == NULL && eccKey == NULL && ed25519Key == NULL) + if (rsaKey == NULL && eccKey == NULL && ed25519Key == NULL && + ed448Key == NULL) { return PUBLIC_KEY_E; + } /* init */ XMEMSET(der, 0, sizeof(DerCert)); @@ -13357,6 +13680,13 @@ static int EncodeCertReq(Cert* cert, DerCert* der, RsaKey* rsaKey, } #endif +#ifdef HAVE_ED448 + if (cert->keyType == ED448_KEY) { + if (ed448Key == NULL) + return PUBLIC_KEY_E; + der->publicKeySz = SetEd448PublicKey(der->publicKey, ed448Key, 1); + } +#endif if (der->publicKeySz <= 0) return PUBLIC_KEY_E; @@ -13524,7 +13854,8 @@ static int WriteCertReqBody(DerCert* der, byte* buf) static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz, - RsaKey* rsaKey, ecc_key* eccKey, ed25519_key* ed25519Key) + RsaKey* rsaKey, ecc_key* eccKey, ed25519_key* ed25519Key, + ed448_key* ed448Key) { int ret; #ifdef WOLFSSL_SMALL_STACK @@ -13533,7 +13864,8 @@ static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz, DerCert der[1]; #endif - cert->keyType = eccKey ? ECC_KEY : (ed25519Key ? ED25519_KEY : RSA_KEY); + cert->keyType = eccKey ? ECC_KEY : (ed25519Key ? ED25519_KEY : + (ed448Key ? ED448_KEY: RSA_KEY)); #ifdef WOLFSSL_SMALL_STACK der = (DerCert*)XMALLOC(sizeof(DerCert), cert->heap, @@ -13542,7 +13874,7 @@ static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz, return MEMORY_E; #endif - ret = EncodeCertReq(cert, der, rsaKey, eccKey, ed25519Key); + ret = EncodeCertReq(cert, der, rsaKey, eccKey, ed25519Key, ed448Key); if (ret == 0) { if (der->total + MAX_SEQ_SZ * 2 > (int)derSz) @@ -13561,9 +13893,10 @@ static int MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz, int wc_MakeCertReq_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType, void* key) { - RsaKey* rsaKey = NULL; - ecc_key* eccKey = NULL; + RsaKey* rsaKey = NULL; + ecc_key* eccKey = NULL; ed25519_key* ed25519Key = NULL; + ed448_key* ed448Key = NULL; if (keyType == RSA_TYPE) rsaKey = (RsaKey*)key; @@ -13571,21 +13904,24 @@ int wc_MakeCertReq_ex(Cert* cert, byte* derBuffer, word32 derSz, int keyType, eccKey = (ecc_key*)key; else if (keyType == ED25519_TYPE) ed25519Key = (ed25519_key*)key; + else if (keyType == ED448_TYPE) + ed448Key = (ed448_key*)key; - return MakeCertReq(cert, derBuffer, derSz, rsaKey, eccKey, ed25519Key); + return MakeCertReq(cert, derBuffer, derSz, rsaKey, eccKey, ed25519Key, + ed448Key); } int wc_MakeCertReq(Cert* cert, byte* derBuffer, word32 derSz, RsaKey* rsaKey, ecc_key* eccKey) { - return MakeCertReq(cert, derBuffer, derSz, rsaKey, eccKey, NULL); + return MakeCertReq(cert, derBuffer, derSz, rsaKey, eccKey, NULL, NULL); } #endif /* WOLFSSL_CERT_REQ */ static int SignCert(int requestSz, int sType, byte* buf, word32 buffSz, RsaKey* rsaKey, ecc_key* eccKey, ed25519_key* ed25519Key, - WC_RNG* rng) + ed448_key* ed448Key, WC_RNG* rng) { int sigSz = 0; void* heap = NULL; @@ -13638,7 +13974,8 @@ static int SignCert(int requestSz, int sType, byte* buf, word32 buffSz, } sigSz = MakeSignature(certSignCtx, buf, requestSz, certSignCtx->sig, - MAX_ENCODED_SIG_SZ, rsaKey, eccKey, ed25519Key, rng, sType, heap); + MAX_ENCODED_SIG_SZ, rsaKey, eccKey, ed25519Key, ed448Key, rng, sType, + heap); #ifdef WOLFSSL_ASYNC_CRYPT if (sigSz == WC_PENDING_E) { /* Not free'ing certSignCtx->sig here because it could still be in use @@ -13664,9 +14001,10 @@ static int SignCert(int requestSz, int sType, byte* buf, word32 buffSz, int wc_SignCert_ex(int requestSz, int sType, byte* buf, word32 buffSz, int keyType, void* key, WC_RNG* rng) { - RsaKey* rsaKey = NULL; - ecc_key* eccKey = NULL; + RsaKey* rsaKey = NULL; + ecc_key* eccKey = NULL; ed25519_key* ed25519Key = NULL; + ed448_key* ed448Key = NULL; if (keyType == RSA_TYPE) rsaKey = (RsaKey*)key; @@ -13674,15 +14012,17 @@ int wc_SignCert_ex(int requestSz, int sType, byte* buf, word32 buffSz, eccKey = (ecc_key*)key; else if (keyType == ED25519_TYPE) ed25519Key = (ed25519_key*)key; + else if (keyType == ED448_TYPE) + ed448Key = (ed448_key*)key; - return SignCert(requestSz, sType, buf, buffSz, rsaKey, eccKey, - ed25519Key, rng); + return SignCert(requestSz, sType, buf, buffSz, rsaKey, eccKey, ed25519Key, + ed448Key, rng); } int wc_SignCert(int requestSz, int sType, byte* buf, word32 buffSz, RsaKey* rsaKey, ecc_key* eccKey, WC_RNG* rng) { - return SignCert(requestSz, sType, buf, buffSz, rsaKey, eccKey, NULL, + return SignCert(requestSz, sType, buf, buffSz, rsaKey, eccKey, NULL, NULL, rng); } @@ -13717,14 +14057,15 @@ int wc_GetSubjectRaw(byte **subjectRaw, Cert *cert) /* Set KID from public key */ static int SetKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey, byte *ntruKey, word16 ntruKeySz, - ed25519_key* ed25519Key, int kid_type) + ed25519_key* ed25519Key, ed448_key* ed448Key, + int kid_type) { byte *buf; int bufferSz, ret; if (cert == NULL || (rsakey == NULL && eckey == NULL && ntruKey == NULL && - ed25519Key == NULL) || + ed25519Key == NULL && ed448Key == NULL) || (kid_type != SKID_TYPE && kid_type != AKID_TYPE)) return BAD_FUNC_ARG; @@ -13762,6 +14103,11 @@ static int SetKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey, if (ed25519Key != NULL) bufferSz = SetEd25519PublicKey(buf, ed25519Key, 0); #endif +#ifdef HAVE_ED448 + /* ED448 public key */ + if (ed448Key != NULL) + bufferSz = SetEd448PublicKey(buffer, ed448Key, 0); +#endif if (bufferSz <= 0) { XFREE(buf, cert->heap, DYNAMIC_TYPE_TMP_BUFFER); @@ -13786,9 +14132,10 @@ static int SetKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey, int wc_SetSubjectKeyIdFromPublicKey_ex(Cert *cert, int keyType, void* key) { - RsaKey* rsaKey = NULL; - ecc_key* eccKey = NULL; + RsaKey* rsaKey = NULL; + ecc_key* eccKey = NULL; ed25519_key* ed25519Key = NULL; + ed448_key* ed448Key = NULL; if (keyType == RSA_TYPE) rsaKey = (RsaKey*)key; @@ -13796,15 +14143,18 @@ int wc_SetSubjectKeyIdFromPublicKey_ex(Cert *cert, int keyType, void* key) eccKey = (ecc_key*)key; else if (keyType == ED25519_TYPE) ed25519Key = (ed25519_key*)key; + else if (keyType == ED448_TYPE) + ed448Key = (ed448_key*)key; return SetKeyIdFromPublicKey(cert, rsaKey, eccKey, NULL, 0, ed25519Key, - SKID_TYPE); + ed448Key, SKID_TYPE); } /* Set SKID from RSA or ECC public key */ int wc_SetSubjectKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey) { - return SetKeyIdFromPublicKey(cert, rsakey, eckey, NULL, 0, NULL, SKID_TYPE); + return SetKeyIdFromPublicKey(cert, rsakey, eckey, NULL, 0, NULL, NULL, + SKID_TYPE); } #ifdef HAVE_NTRU @@ -13812,16 +14162,17 @@ int wc_SetSubjectKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey) int wc_SetSubjectKeyIdFromNtruPublicKey(Cert *cert, byte *ntruKey, word16 ntruKeySz) { - return SetKeyIdFromPublicKey(cert, NULL,NULL,ntruKey, ntruKeySz, NULL, + return SetKeyIdFromPublicKey(cert, NULL,NULL,ntruKey, ntruKeySz, NULL, NULL, SKID_TYPE); } #endif int wc_SetAuthKeyIdFromPublicKey_ex(Cert *cert, int keyType, void* key) { - RsaKey* rsaKey = NULL; - ecc_key* eccKey = NULL; + RsaKey* rsaKey = NULL; + ecc_key* eccKey = NULL; ed25519_key* ed25519Key = NULL; + ed448_key* ed448Key = NULL; if (keyType == RSA_TYPE) rsaKey = (RsaKey*)key; @@ -13829,15 +14180,18 @@ int wc_SetAuthKeyIdFromPublicKey_ex(Cert *cert, int keyType, void* key) eccKey = (ecc_key*)key; else if (keyType == ED25519_TYPE) ed25519Key = (ed25519_key*)key; + else if (keyType == ED448_TYPE) + ed448Key = (ed448_key*)key; return SetKeyIdFromPublicKey(cert, rsaKey, eccKey, NULL, 0, ed25519Key, - AKID_TYPE); + ed448Key, AKID_TYPE); } /* Set SKID from RSA or ECC public key */ int wc_SetAuthKeyIdFromPublicKey(Cert *cert, RsaKey *rsakey, ecc_key *eckey) { - return SetKeyIdFromPublicKey(cert, rsakey, eckey, NULL, 0, NULL, AKID_TYPE); + return SetKeyIdFromPublicKey(cert, rsakey, eckey, NULL, 0, NULL, NULL, + AKID_TYPE); } @@ -15560,6 +15914,9 @@ int wc_Ed25519PrivateKeyDecode(const byte* input, word32* inOutIdx, if (GetOctetString(input, inOutIdx, &privSz, inSz) < 0) return ASN_PARSE_E; + if (privSz != 32) + return ASN_PARSE_E; + priv = input + *inOutIdx; *inOutIdx += privSz; endKeyIdx = *inOutIdx; @@ -15695,6 +16052,185 @@ int wc_Ed25519PrivateKeyToDer(ed25519_key* key, byte* output, word32 inLen) #endif /* HAVE_ED25519 */ +#ifdef HAVE_ED448 + +int wc_Ed448PrivateKeyDecode(const byte* input, word32* inOutIdx, + ed448_key* key, word32 inSz) +{ + word32 oid; + int ret, version, length, endKeyIdx, privSz, pubSz; + const byte* priv; + const byte* pub; + + if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) + return BAD_FUNC_ARG; + + if (GetSequence(input, inOutIdx, &length, inSz) >= 0) { + endKeyIdx = *inOutIdx + length; + + if (GetMyVersion(input, inOutIdx, &version, inSz) < 0) + return ASN_PARSE_E; + if (version != 0) { + WOLFSSL_MSG("Unrecognized version of ED448 private key"); + return ASN_PARSE_E; + } + + if (GetAlgoId(input, inOutIdx, &oid, oidKeyType, inSz) < 0) + return ASN_PARSE_E; + if (oid != ED448k) + return ASN_PARSE_E; + + if (GetOctetString(input, inOutIdx, &length, inSz) < 0) + return ASN_PARSE_E; + + if (GetOctetString(input, inOutIdx, &privSz, inSz) < 0) + return ASN_PARSE_E; + + priv = input + *inOutIdx; + *inOutIdx += privSz; + } + else { + if (GetOctetString(input, inOutIdx, &privSz, inSz) < 0) + return ASN_PARSE_E; + + if (privSz != 57) + return ASN_PARSE_E; + + priv = input + *inOutIdx; + *inOutIdx += privSz; + endKeyIdx = *inOutIdx; + } + + if (endKeyIdx == (int)*inOutIdx) { + ret = wc_ed448_import_private_only(priv, privSz, key); + } + else { + if (GetASNHeader(input, ASN_CONTEXT_SPECIFIC | ASN_CONSTRUCTED | 1, + inOutIdx, &length, inSz) < 0) { + return ASN_PARSE_E; + } + if (GetOctetString(input, inOutIdx, &pubSz, inSz) < 0) + return ASN_PARSE_E; + pub = input + *inOutIdx; + *inOutIdx += pubSz; + + ret = wc_ed448_import_private_key(priv, privSz, pub, pubSz, key); + } + if (ret == 0 && endKeyIdx != (int)*inOutIdx) + return ASN_PARSE_E; + + return ret; +} + + +int wc_Ed448PublicKeyDecode(const byte* input, word32* inOutIdx, + ed448_key* key, word32 inSz) +{ + int length; + int ret; + + if (input == NULL || inOutIdx == NULL || key == NULL || inSz == 0) + return BAD_FUNC_ARG; + + if (GetSequence(input, inOutIdx, &length, inSz) < 0) + return ASN_PARSE_E; + + if (GetSequence(input, inOutIdx, &length, inSz) < 0) + return ASN_PARSE_E; + + ret = SkipObjectId(input, inOutIdx, inSz); + if (ret != 0) + return ret; + + /* key header */ + ret = CheckBitString(input, inOutIdx, NULL, inSz, 1, NULL); + if (ret != 0) + return ret; + + /* This is the raw point data compressed or uncompressed. */ + if (wc_ed448_import_public(input + *inOutIdx, inSz - *inOutIdx, key) != 0) + return ASN_ECC_KEY_E; + + return 0; +} + + +#ifdef WOLFSSL_KEY_GEN + +/* build DER formatted ED448 key, + * return length on success, negative on error */ +static int wc_BuildEd448KeyDer(ed448_key* key, byte* output, word32 inLen, + int pubOut) +{ + byte algoArray[MAX_ALGO_SZ]; + byte ver[MAX_VERSION_SZ]; + byte seq[MAX_SEQ_SZ]; + int ret; + word32 idx = 0, seqSz, verSz, algoSz, privSz, pubSz = 0; + + if (key == NULL || output == NULL || inLen == 0) + return BAD_FUNC_ARG; + + if (pubOut) { + pubSz = 2 + 2 + ED448_PUB_KEY_SIZE; + } + privSz = 2 + 2 + ED448_KEY_SIZE; + algoSz = SetAlgoID(ED448k, algoArray, oidKeyType, 0); + verSz = SetMyVersion(0, ver, FALSE); + seqSz = SetSequence(verSz + algoSz + privSz + pubSz, seq); + + if (seqSz + verSz + algoSz + privSz + pubSz > inLen) + return BAD_FUNC_ARG; + + /* write out */ + /* seq */ + XMEMCPY(output + idx, seq, seqSz); + idx = seqSz; + /* ver */ + XMEMCPY(output + idx, ver, verSz); + idx += verSz; + /* algo */ + XMEMCPY(output + idx, algoArray, algoSz); + idx += algoSz; + /* privKey */ + idx += SetOctetString(2 + ED448_KEY_SIZE, output + idx); + idx += SetOctetString(ED448_KEY_SIZE, output + idx); + ret = wc_ed448_export_private_only(key, output + idx, &privSz); + if (ret != 0) + return ret; + idx += privSz; + /* pubKey */ + if (pubOut) { + idx += SetExplicit(1, 2 + ED448_PUB_KEY_SIZE, output + idx); + idx += SetOctetString(ED448_KEY_SIZE, output + idx); + ret = wc_ed448_export_public(key, output + idx, &pubSz); + if (ret != 0) + return ret; + idx += pubSz; + } + + return idx; +} + +/* Write a Private ecc key, including public to DER format, + * length on success else < 0 */ +int wc_Ed448KeyToDer(ed448_key* key, byte* output, word32 inLen) +{ + return wc_BuildEd448KeyDer(key, output, inLen, 1); +} + + + +/* Write only private ecc key to DER format, + * length on success else < 0 */ +int wc_Ed448PrivateKeyToDer(ed448_key* key, byte* output, word32 inLen) +{ + return wc_BuildEd448KeyDer(key, output, inLen, 0); +} + +#endif /* WOLFSSL_KEY_GEN */ + +#endif /* HAVE_ED448 */ #if defined(HAVE_OCSP) || defined(HAVE_CRL) diff --git a/wolfcrypt/src/curve448.c b/wolfcrypt/src/curve448.c new file mode 100644 index 000000000..135f2380e --- /dev/null +++ b/wolfcrypt/src/curve448.c @@ -0,0 +1,635 @@ +/* curve448.c + * + * 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 + */ + +/* Implemented to: RFC 7748 */ + +/* Based On Daniel J Bernstein's curve25519 Public Domain ref10 work. + * Reworked for curve448 by Sean Parkinson. + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#ifdef HAVE_CURVE448 + +#include +#include +#ifdef NO_INLINE + #include +#else + #define WOLFSSL_MISC_INCLUDED + #include +#endif + + +/* Make a new curve448 private/public key. + * + * rng [in] Random number generator. + * keysize [in] Size of the key to generate. + * key [in] Curve448 key object. + * returns BAD_FUNC_ARG when rng or key are NULL, + * ECC_BAD_ARG_E when keysize is not CURVE448_KEY_SIZE, + * 0 otherwise. + */ +int wc_curve448_make_key(WC_RNG* rng, int keysize, curve448_key* key) +{ + unsigned char basepoint[CURVE448_KEY_SIZE] = {5}; + int ret = 0; + + if ((key == NULL) || (rng == NULL)) { + ret = BAD_FUNC_ARG; + } + + /* currently only a key size of 56 bytes is used */ + if ((ret == 0) && (keysize != CURVE448_KEY_SIZE)) { + ret = ECC_BAD_ARG_E; + } + + if (ret == 0) { + fe448_init(); + + /* random number for private key */ + ret = wc_RNG_GenerateBlock(rng, key->k, keysize); + } + if (ret == 0) { + /* Clamp the private key */ + key->k[0] &= 0xfc; + key->k[CURVE448_KEY_SIZE-1] |= 0x80; + + /* compute public key */ + ret = curve448(key->p, key->k, basepoint); + if (ret != 0) { + ForceZero(key->k, keysize); + ForceZero(key->p, keysize); + } + } + + return ret; +} + +#ifdef HAVE_CURVE448_SHARED_SECRET + +/* Calculate the shared secret from the private key and peer's public key. + * Calculation over curve448. + * Secret encoded big-endian. + * + * private_key [in] Curve448 private key. + * public_key [in] Curve448 public key. + * out [in] Array to hold shared secret. + * outLen [in/out] On in, the number of bytes in array. + * On out, the number bytes put into array. + * returns BAD_FUNC_ARG when a parameter is NULL or outLen is less than + * CURVE448_KEY_SIZE, + * 0 otherwise. + */ +int wc_curve448_shared_secret(curve448_key* private_key, + curve448_key* public_key, + byte* out, word32* outLen) +{ + return wc_curve448_shared_secret_ex(private_key, public_key, out, outLen, + EC448_BIG_ENDIAN); +} + +/* Calculate the shared secret from the private key and peer's public key. + * Calculation over curve448. + * + * private_key [in] Curve448 private key. + * public_key [in] Curve448 public key. + * out [in] Array to hold shared secret. + * outLen [in/out] On in, the number of bytes in array. + * On out, the number bytes put into array. + * endian [in] Endianness to use when encoding number in array. + * returns BAD_FUNC_ARG when a parameter is NULL or outLen is less than + * CURVE448_PUB_KEY_SIZE, + * 0 otherwise. + */ +int wc_curve448_shared_secret_ex(curve448_key* private_key, + curve448_key* public_key, + byte* out, word32* outLen, int endian) +{ + unsigned char o[CURVE448_PUB_KEY_SIZE]; + int ret = 0; + int i; + + /* sanity check */ + if ((private_key == NULL) || (public_key == NULL) || (out == NULL) || + (outLen == NULL) || (*outLen < CURVE448_PUB_KEY_SIZE)) { + ret = BAD_FUNC_ARG; + } + + if (ret == 0) { + ret = curve448(o, private_key->k, public_key->p); + } + if (ret == 0) { + if (endian == EC448_BIG_ENDIAN) { + /* put shared secret key in Big Endian format */ + for (i = 0; i < CURVE448_PUB_KEY_SIZE; i++) { + out[i] = o[CURVE448_PUB_KEY_SIZE - i -1]; + } + } + else { + /* put shared secret key in Little Endian format */ + XMEMCPY(out, o, CURVE448_PUB_KEY_SIZE); + } + + *outLen = CURVE448_PUB_KEY_SIZE; + } + + ForceZero(o, CURVE448_PUB_KEY_SIZE); + + return ret; +} + +#endif /* HAVE_CURVE448_SHARED_SECRET */ + +#ifdef HAVE_CURVE448_KEY_EXPORT + +/* Export the curve448 public key. + * Public key encoded big-endian. + * + * key [in] Curve448 public key. + * out [in] Array to hold public key. + * outLen [in/out] On in, the number of bytes in array. + * On out, the number bytes put into array. + * returns BAD_FUNC_ARG when a parameter is NULL, + * ECC_BAD_ARG_E when outLen is less than CURVE448_PUB_KEY_SIZE, + * 0 otherwise. + */ +int wc_curve448_export_public(curve448_key* key, byte* out, word32* outLen) +{ + return wc_curve448_export_public_ex(key, out, outLen, EC448_BIG_ENDIAN); +} + +/* Export the curve448 public key. + * + * key [in] Curve448 public key. + * out [in] Array to hold public key. + * outLen [in/out] On in, the number of bytes in array. + * On out, the number bytes put into array. + * endian [in] Endianness to use when encoding number in array. + * returns BAD_FUNC_ARG when a parameter is NULL, + * ECC_BAD_ARG_E when outLen is less than CURVE448_PUB_KEY_SIZE, + * 0 otherwise. + */ +int wc_curve448_export_public_ex(curve448_key* key, byte* out, word32* outLen, + int endian) +{ + int ret = 0; + int i; + + if ((key == NULL) || (out == NULL) || (outLen == NULL)) { + ret = BAD_FUNC_ARG; + } + + /* check and set outgoing key size */ + if ((ret == 0) && (*outLen < CURVE448_PUB_KEY_SIZE)) { + *outLen = CURVE448_PUB_KEY_SIZE; + ret = ECC_BAD_ARG_E; + } + if (ret == 0) { + *outLen = CURVE448_PUB_KEY_SIZE; + + if (endian == EC448_BIG_ENDIAN) { + /* read keys in Big Endian format */ + for (i = 0; i < CURVE448_PUB_KEY_SIZE; i++) { + out[i] = key->p[CURVE448_PUB_KEY_SIZE - i - 1]; + } + } + else { + XMEMCPY(out, key->p, CURVE448_PUB_KEY_SIZE); + } + } + + return ret; +} + +#endif /* HAVE_CURVE448_KEY_EXPORT */ + +#ifdef HAVE_CURVE448_KEY_IMPORT + +/* Import a curve448 public key from a byte array. + * Public key encoded in big-endian. + * + * in [in] Array holding public key. + * inLen [in] Number of bytes of data in array. + * key [in] Curve448 public key. + * returns BAD_FUNC_ARG when a parameter is NULL, + * ECC_BAD_ARG_E when inLen is less than CURVE448_PUB_KEY_SIZE, + * 0 otherwise. + */ +int wc_curve448_import_public(const byte* in, word32 inLen, curve448_key* key) +{ + return wc_curve448_import_public_ex(in, inLen, key, EC448_BIG_ENDIAN); +} + +/* Import a curve448 public key from a byte array. + * + * in [in] Array holding public key. + * inLen [in] Number of bytes of data in array. + * key [in] Curve448 public key. + * endian [in] Endianness of encoded number in byte array. + * returns BAD_FUNC_ARG when a parameter is NULL, + * ECC_BAD_ARG_E when inLen is less than CURVE448_PUB_KEY_SIZE, + * 0 otherwise. + */ +int wc_curve448_import_public_ex(const byte* in, word32 inLen, + curve448_key* key, int endian) +{ + int ret = 0; + int i; + + /* sanity check */ + if ((key == NULL) || (in == NULL)) { + ret = BAD_FUNC_ARG; + } + + /* check size of incoming keys */ + if ((ret == 0) && (inLen != CURVE448_PUB_KEY_SIZE)) { + ret = ECC_BAD_ARG_E; + } + + if (ret == 0) { + if (endian == EC448_BIG_ENDIAN) { + /* read keys in Big Endian format */ + for (i = 0; i < CURVE448_PUB_KEY_SIZE; i++) { + key->p[i] = in[CURVE448_PUB_KEY_SIZE - i - 1]; + } + } + else + XMEMCPY(key->p, in, inLen); + } + + return ret; +} + +/* Check the public key value (big or little endian) + * + * pub [in] Public key bytes. + * pubSz [in] Size of public key in bytes. + * endian [in] Public key bytes passed in as big-endian or little-endian. + * returns BAD_FUNC_ARGS when pub is NULL, + * ECC_BAD_ARG_E when key length is not 56 bytes, public key value is + * zero or one; + * BUFFER_E when size of public key is zero; + * 0 otherwise. + */ +int wc_curve448_check_public(const byte* pub, word32 pubSz, int endian) +{ + int ret = 0; + word32 i; + + if (pub == NULL) { + ret = BAD_FUNC_ARG; + } + + /* Check for empty key data */ + if ((ret == 0) && (pubSz == 0)) { + ret = BUFFER_E; + } + + /* Check key length */ + if ((ret == 0) && (pubSz != CURVE448_PUB_KEY_SIZE)) { + ret = ECC_BAD_ARG_E; + } + + if (ret == 0) { + if (endian == EC448_LITTLE_ENDIAN) { + /* Check for value of zero or one */ + for (i = pubSz - 1; i > 0; i--) { + if (pub[i] != 0) { + break; + } + } + if ((i == 0) && (pub[0] == 0 || pub[0] == 1)) { + return ECC_BAD_ARG_E; + } + } + else { + /* Check for value of zero or one */ + for (i = 0; i < pubSz-1; i++) { + if (pub[i] != 0) { + break; + } + } + if ((i == pubSz - 1) && (pub[i] == 0 || pub[i] == 1)) { + ret = ECC_BAD_ARG_E; + } + } + } + + return ret; +} + +#endif /* HAVE_CURVE448_KEY_IMPORT */ + + +#ifdef HAVE_CURVE448_KEY_EXPORT + +/* Export the curve448 private key raw form. + * Private key encoded big-endian. + * + * key [in] Curve448 private key. + * out [in] Array to hold private key. + * outLen [in/out] On in, the number of bytes in array. + * On out, the number bytes put into array. + * returns BAD_FUNC_ARG when a parameter is NULL, + * ECC_BAD_ARG_E when outLen is less than CURVE448_KEY_SIZE, + * 0 otherwise. + */ +int wc_curve448_export_private_raw(curve448_key* key, byte* out, word32* outLen) +{ + return wc_curve448_export_private_raw_ex(key, out, outLen, + EC448_BIG_ENDIAN); +} + +/* Export the curve448 private key raw form. + * + * key [in] Curve448 private key. + * out [in] Array to hold private key. + * outLen [in/out] On in, the number of bytes in array. + * On out, the number bytes put into array. + * endian [in] Endianness to use when encoding number in array. + * returns BAD_FUNC_ARG when a parameter is NULL, + * ECC_BAD_ARG_E when outLen is less than CURVE448_KEY_SIZE, + * 0 otherwise. + */ +int wc_curve448_export_private_raw_ex(curve448_key* key, byte* out, + word32* outLen, int endian) +{ + int ret = 0; + int i; + + /* sanity check */ + if ((key == NULL) || (out == NULL) || (outLen == NULL)) { + ret = BAD_FUNC_ARG; + } + + /* check size of outgoing buffer */ + if ((ret == 0) && (*outLen < CURVE448_KEY_SIZE)) { + *outLen = CURVE448_KEY_SIZE; + ret = ECC_BAD_ARG_E; + } + if (ret == 0) { + *outLen = CURVE448_KEY_SIZE; + + if (endian == EC448_BIG_ENDIAN) { + /* put the key in Big Endian format */ + for (i = 0; i < CURVE448_KEY_SIZE; i++) { + out[i] = key->k[CURVE448_KEY_SIZE - i - 1]; + } + } + else { + XMEMCPY(out, key->k, CURVE448_KEY_SIZE); + } + } + + return ret; +} + +/* Export the curve448 private and public keys in raw form. + * Private and public key encoded big-endian. + * + * key [in] Curve448 private key. + * priv [in] Array to hold private key. + * privSz [in/out] On in, the number of bytes in private key array. + * On out, the number bytes put into private key array. + * pub [in] Array to hold public key. + * pubSz [in/out] On in, the number of bytes in public key array. + * On out, the number bytes put into public key array. + * returns BAD_FUNC_ARG when a parameter is NULL, + * ECC_BAD_ARG_E when privSz is less than CURVE448_KEY_SIZE or pubSz is + * less than CURVE448_PUB_KEY_SIZE, + * 0 otherwise. + */ +int wc_curve448_export_key_raw(curve448_key* key, byte* priv, word32 *privSz, + byte* pub, word32 *pubSz) +{ + return wc_curve448_export_key_raw_ex(key, priv, privSz, pub, pubSz, + EC448_BIG_ENDIAN); +} + +/* Export the curve448 private and public keys in raw form. + * + * key [in] Curve448 private key. + * priv [in] Array to hold private key. + * privSz [in/out] On in, the number of bytes in private key array. + * On out, the number bytes put into private key array. + * pub [in] Array to hold public key. + * pubSz [in/out] On in, the number of bytes in public key array. + * On out, the number bytes put into public key array. + * endian [in] Endianness to use when encoding number in array. + * returns BAD_FUNC_ARG when a parameter is NULL, + * ECC_BAD_ARG_E when privSz is less than CURVE448_KEY_SIZE or pubSz is + * less than CURVE448_PUB_KEY_SIZE, + * 0 otherwise. + */ +int wc_curve448_export_key_raw_ex(curve448_key* key, byte* priv, word32 *privSz, + byte* pub, word32 *pubSz, int endian) +{ + int ret; + + /* export private part */ + ret = wc_curve448_export_private_raw_ex(key, priv, privSz, endian); + if (ret == 0) { + /* export public part */ + ret = wc_curve448_export_public_ex(key, pub, pubSz, endian); + } + + return ret; +} + +#endif /* HAVE_CURVE448_KEY_EXPORT */ + +#ifdef HAVE_CURVE448_KEY_IMPORT + +/* Import curve448 private and public keys from a byte arrays. + * Private and public keys encoded in big-endian. + * + * piv [in] Array holding private key. + * privSz [in] Number of bytes of data in private key array. + * pub [in] Array holding public key. + * pubSz [in] Number of bytes of data in public key array. + * key [in] Curve448 private/public key. + * returns BAD_FUNC_ARG when a parameter is NULL, + * ECC_BAD_ARG_E when privSz is less than CURVE448_KEY_SIZE or pubSz is + * less than CURVE448_PUB_KEY_SIZE, + * 0 otherwise. + */ +int wc_curve448_import_private_raw(const byte* priv, word32 privSz, + const byte* pub, word32 pubSz, + curve448_key* key) +{ + return wc_curve448_import_private_raw_ex(priv, privSz, pub, pubSz, key, + EC448_BIG_ENDIAN); +} + +/* Import curve448 private and public keys from a byte arrays. + * + * piv [in] Array holding private key. + * privSz [in] Number of bytes of data in private key array. + * pub [in] Array holding public key. + * pubSz [in] Number of bytes of data in public key array. + * key [in] Curve448 private/public key. + * endian [in] Endianness of encoded numbers in byte arrays. + * returns BAD_FUNC_ARG when a parameter is NULL, + * ECC_BAD_ARG_E when privSz is less than CURVE448_KEY_SIZE or pubSz is + * less than CURVE448_PUB_KEY_SIZE, + * 0 otherwise. + */ +int wc_curve448_import_private_raw_ex(const byte* priv, word32 privSz, + const byte* pub, word32 pubSz, + curve448_key* key, int endian) +{ + int ret; + + /* import private part */ + ret = wc_curve448_import_private_ex(priv, privSz, key, endian); + if (ret == 0) { + /* import public part */ + return wc_curve448_import_public_ex(pub, pubSz, key, endian); + } + + return ret; +} + +/* Import curve448 private key from a byte array. + * Private key encoded in big-endian. + * + * piv [in] Array holding private key. + * privSz [in] Number of bytes of data in private key array. + * key [in] Curve448 private/public key. + * returns BAD_FUNC_ARG when a parameter is NULL, + * ECC_BAD_ARG_E when privSz is less than CURVE448_KEY_SIZE, + * 0 otherwise. + */ +int wc_curve448_import_private(const byte* priv, word32 privSz, + curve448_key* key) +{ + return wc_curve448_import_private_ex(priv, privSz, key, EC448_BIG_ENDIAN); +} + +/* Import curve448 private key from a byte array. + * + * piv [in] Array holding private key. + * privSz [in] Number of bytes of data in private key array. + * key [in] Curve448 private/public key. + * endian [in] Endianness of encoded number in byte array. + * returns BAD_FUNC_ARG when a parameter is NULL, + * ECC_BAD_ARG_E when privSz is less than CURVE448_KEY_SIZE, + * 0 otherwise. + */ +int wc_curve448_import_private_ex(const byte* priv, word32 privSz, + curve448_key* key, int endian) +{ + int ret = 0; + int i; + + /* sanity check */ + if ((key == NULL) || (priv == NULL)) { + ret = BAD_FUNC_ARG; + } + + /* check size of incoming keys */ + if ((ret == 0) && ((int)privSz != CURVE448_KEY_SIZE)) { + ret = ECC_BAD_ARG_E; + } + + if (ret == 0) { + if (endian == EC448_BIG_ENDIAN) { + /* read the key in Big Endian format */ + for (i = 0; i < CURVE448_KEY_SIZE; i++) { + key->k[i] = priv[CURVE448_KEY_SIZE - i - 1]; + } + } + else { + XMEMCPY(key->k, priv, CURVE448_KEY_SIZE); + } + + /* Clamp the key */ + key->k[0] &= 0xfc; + key->k[CURVE448_KEY_SIZE-1] |= 0x80; + } + + return ret; +} + +#endif /* HAVE_CURVE448_KEY_IMPORT */ + + +/* Initialize the curve448 key. + * + * key [in] Curve448 key object. + * returns BAD_FUNC_ARG when key is NULL, + * 0 otherwise. + */ +int wc_curve448_init(curve448_key* key) +{ + int ret = 0; + + if (key == NULL) { + ret = BAD_FUNC_ARG; + } + + if (ret == 0) { + XMEMSET(key, 0, sizeof(*key)); + + fe448_init(); + } + + return ret; +} + + +/* Clears the curve448 key data. + * + * key [in] Curve448 key object. + */ +void wc_curve448_free(curve448_key* key) +{ + if (key != NULL) { + ForceZero(key->p, sizeof(key->p)); + ForceZero(key->k, sizeof(key->k)); + } +} + + +/* Get the curve448 key's size. + * + * key [in] Curve448 key object. + * returns 0 if key is NULL, + * CURVE448_KEY_SIZE otherwise. + */ +int wc_curve448_size(curve448_key* key) +{ + int ret = 0; + + if (key != NULL) { + ret = CURVE448_KEY_SIZE; + } + + return ret; +} + +#endif /* HAVE_CURVE448 */ + diff --git a/wolfcrypt/src/ed448.c b/wolfcrypt/src/ed448.c new file mode 100644 index 000000000..125ee3852 --- /dev/null +++ b/wolfcrypt/src/ed448.c @@ -0,0 +1,917 @@ +/* ed448.c + * + * 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 + */ + +/* Implemented to: RFC 8032 */ + +/* Based On Daniel J Bernstein's ed25519 Public Domain ref10 work. + * Reworked for curve448 by Sean Parkinson. + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +/* in case user set HAVE_ED448 there */ +#include + +#ifdef HAVE_ED448 + +#include +#include +#include +#ifdef NO_INLINE + #include +#else + #define WOLFSSL_MISC_INCLUDED + #include +#endif + +#if defined(HAVE_ED448_SIGN) || defined(HAVE_ED448_VERIFY) +/* Size of context bytes to use with hash when signing and verifying. */ +#define ED448CTX_SIZE 8 +/* Context to pass to hash when signing and verifying. */ +static const byte ed448Ctx[ED448CTX_SIZE+1] = "SigEd448"; +#endif + +/* Derive the public key for the private key. + * + * key [in] Ed448 key object. + * pubKey [in] Byte array to hold te public key. + * pubKeySz [in] Size of the array in bytes. + * returns BAD_FUNC_ARG when key is NULL or pubKeySz is not equal to + * ED448_PUB_KEY_SIZE, + * other -ve value on hash failure, + * 0 otherwise. + */ +int wc_ed448_make_public(ed448_key* key, unsigned char* pubKey, word32 pubKeySz) +{ + int ret = 0; + byte az[ED448_PRV_KEY_SIZE]; + ge448_p2 A; + + if ((key == NULL) || (pubKeySz != ED448_PUB_KEY_SIZE)) { + ret = BAD_FUNC_ARG; + } + + if (ret == 0) { + ret = wc_Shake256Hash(key->k, ED448_KEY_SIZE, az, sizeof(az)); + } + if (ret == 0) { + /* apply clamp */ + az[0] &= 0xfc; + az[55] |= 0x80; + az[56] = 0x00; + + ge448_scalarmult_base(&A, az); + ge448_to_bytes(pubKey, &A); + } + + return ret; +} + +/* Make a new ed448 private/public key. + * + * rng [in] Random number generator. + * keysize [in] Size of the key to generate. + * key [in] Ed448 key object. + * returns BAD_FUNC_ARG when rng or key is NULL or keySz is not equal to + * ED448_KEY_SIZE, + * other -ve value on random number or hash failure, + * 0 otherwise. + */ +int wc_ed448_make_key(WC_RNG* rng, int keySz, ed448_key* key) +{ + int ret = 0; + + if ((rng == NULL) || (key == NULL)) { + ret = BAD_FUNC_ARG; + } + + /* ed448 has 57 byte key sizes */ + if ((ret == 0) && (keySz != ED448_KEY_SIZE)) { + ret = BAD_FUNC_ARG; + } + + if (ret == 0) { + ret = wc_RNG_GenerateBlock(rng, key->k, ED448_KEY_SIZE); + } + if (ret == 0) { + ret = wc_ed448_make_public(key, key->p, ED448_PUB_KEY_SIZE); + if (ret != 0) { + ForceZero(key->k, ED448_KEY_SIZE); + } + } + if (ret == 0) { + /* put public key after private key, on the same buffer */ + XMEMMOVE(key->k + ED448_KEY_SIZE, key->p, ED448_PUB_KEY_SIZE); + + key->pubKeySet = 1; + } + + return ret; +} + + +#ifdef HAVE_ED448_SIGN +/* Sign the message using the ed448 private key. + * + * in [in] Message to sign. + * inLen [in] Length of the message in bytes. + * out [in] Buffer to write signature into. + * outLen [in/out] On in, size of buffer. + * On out, the length of the signature in bytes. + * key [in] Ed448 key to use when signing + * type [in] Type of signature to perform: Ed448 or Ed448ph + * context [in] Context of signing. + * contextLen [in] Length of context in bytes. + * returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and + * context is not NULL or public key not set, + * BUFFER_E when outLen is less than ED448_SIG_SIZE, + * other -ve values when hash fails, + * 0 otherwise. + */ +static int ed448_sign_msg(const byte* in, word32 inLen, byte* out, + word32 *outLen, ed448_key* key, byte type, + const byte* context, byte contextLen) +{ + ge448_p2 R; + byte nonce[ED448_SIG_SIZE]; + byte hram[ED448_SIG_SIZE]; + byte az[ED448_PRV_KEY_SIZE]; + wc_Shake sha; + int ret = 0; + + /* sanity check on arguments */ + if ((in == NULL) || (out == NULL) || (outLen == NULL) || (key == NULL) || + ((context == NULL) && (contextLen != 0))) { + ret = BAD_FUNC_ARG; + } + if ((ret == 0) && (!key->pubKeySet)) { + ret = BAD_FUNC_ARG; + } + + /* check and set up out length */ + if ((ret == 0) && (*outLen < ED448_SIG_SIZE)) { + *outLen = ED448_SIG_SIZE; + ret = BUFFER_E; + } + + if (ret == 0) { + *outLen = ED448_SIG_SIZE; + + /* step 1: create nonce to use where nonce is r in + r = H(h_b, ... ,h_2b-1,M) */ + ret = wc_Shake256Hash(key->k, ED448_KEY_SIZE, az, sizeof(az)); + } + if (ret == 0) { + /* apply clamp */ + az[0] &= 0xfc; + az[55] |= 0x80; + az[56] = 0x00; + + ret = wc_InitShake256(&sha, NULL, INVALID_DEVID); + if (ret == 0) { + ret = wc_Shake256_Update(&sha, ed448Ctx, ED448CTX_SIZE); + } + if (ret == 0) { + ret = wc_Shake256_Update(&sha, &type, sizeof(type)); + } + if (ret == 0) { + ret = wc_Shake256_Update(&sha, &contextLen, sizeof(contextLen)); + } + if (ret == 0 && context != NULL) { + ret = wc_Shake256_Update(&sha, context, contextLen); + } + if (ret == 0) { + ret = wc_Shake256_Update(&sha, az + ED448_KEY_SIZE, ED448_KEY_SIZE); + } + if (ret == 0) { + ret = wc_Shake256_Update(&sha, in, inLen); + } + if (ret == 0) { + ret = wc_Shake256_Final(&sha, nonce, sizeof(nonce)); + } + wc_Shake256_Free(&sha); + } + if (ret == 0) { + sc448_reduce(nonce); + + /* step 2: computing R = rB where rB is the scalar multiplication of + r and B */ + ge448_scalarmult_base(&R,nonce); + ge448_to_bytes(out,&R); + + /* step 3: hash R + public key + message getting H(R,A,M) then + creating S = (r + H(R,A,M)a) mod l */ + ret = wc_InitShake256(&sha, NULL, INVALID_DEVID); + if (ret == 0) { + ret = wc_Shake256_Update(&sha, ed448Ctx, ED448CTX_SIZE); + if (ret == 0) { + ret = wc_Shake256_Update(&sha, &type, sizeof(type)); + } + if (ret == 0) { + ret = wc_Shake256_Update(&sha, &contextLen, sizeof(contextLen)); + } + if (ret == 0 && context != NULL) { + ret = wc_Shake256_Update(&sha, context, contextLen); + } + if (ret == 0) { + ret = wc_Shake256_Update(&sha, out, ED448_SIG_SIZE/2); + } + if (ret == 0) { + ret = wc_Shake256_Update(&sha, key->p, ED448_PUB_KEY_SIZE); + } + if (ret == 0) { + ret = wc_Shake256_Update(&sha, in, inLen); + } + if (ret == 0) { + ret = wc_Shake256_Final(&sha, hram, sizeof(hram)); + } + wc_Shake256_Free(&sha); + } + } + + if (ret == 0) { + sc448_reduce(hram); + sc448_muladd(out + (ED448_SIG_SIZE/2), hram, az, nonce); + } + + return ret; +} + +/* Sign the message using the ed448 private key. + * Signature type is Ed448. + * + * in [in] Message to sign. + * inLen [in] Length of the message in bytes. + * out [in] Buffer to write signature into. + * outLen [in/out] On in, size of buffer. + * On out, the length of the signature in bytes. + * key [in] Ed448 key to use when signing + * context [in] Context of signing. + * contextLen [in] Length of context in bytes. + * returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and + * context is not NULL or public key not set, + * BUFFER_E when outLen is less than ED448_SIG_SIZE, + * other -ve values when hash fails, + * 0 otherwise. + */ +int wc_ed448_sign_msg(const byte* in, word32 inLen, byte* out, word32 *outLen, + ed448_key* key, const byte* context, byte contextLen) +{ + return ed448_sign_msg(in, inLen, out, outLen, key, Ed448, context, + contextLen); +} + +/* Sign the hash using the ed448 private key. + * Signature type is Ed448ph. + * + * hash [in] Hash of message to sign. + * hashLen [in] Length of hash of message in bytes. + * out [in] Buffer to write signature into. + * outLen [in/out] On in, size of buffer. + * On out, the length of the signature in bytes. + * key [in] Ed448 key to use when signing + * context [in] Context of signing. + * contextLen [in] Length of context in bytes. + * returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and + * context is not NULL or public key not set, + * BUFFER_E when outLen is less than ED448_SIG_SIZE, + * other -ve values when hash fails, + * 0 otherwise. + */ +int wc_ed448ph_sign_hash(const byte* hash, word32 hashLen, byte* out, + word32 *outLen, ed448_key* key, + const byte* context, byte contextLen) +{ + return ed448_sign_msg(hash, hashLen, out, outLen, key, Ed448ph, context, + contextLen); +} + +/* Sign the message using the ed448 private key. + * Signature type is Ed448ph. + * + * in [in] Message to sign. + * inLen [in] Length of the message to sign in bytes. + * out [in] Buffer to write signature into. + * outLen [in/out] On in, size of buffer. + * On out, the length of the signature in bytes. + * key [in] Ed448 key to use when signing + * context [in] Context of signing. + * contextLen [in] Length of context in bytes. + * returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and + * context is not NULL or public key not set, + * BUFFER_E when outLen is less than ED448_SIG_SIZE, + * other -ve values when hash fails, + * 0 otherwise. + */ +int wc_ed448ph_sign_msg(const byte* in, word32 inLen, byte* out, word32 *outLen, + ed448_key* key, const byte* context, byte contextLen) +{ + int ret = 0; + byte hash[64]; + + ret = wc_Shake256Hash(in, inLen, hash, sizeof(hash)); + if (ret == 0) { + ret = wc_ed448ph_sign_hash(hash, sizeof(hash), out, outLen, key, + context, contextLen); + } + + return ret; +} +#endif /* HAVE_ED448_SIGN */ + +#ifdef HAVE_ED448_VERIFY + +/* Verify the message using the ed448 public key. + * + * sig [in] Signature to verify. + * sigLen [in] Size of signature in bytes. + * msg [in] Message to verify. + * msgLen [in] Length of the message in bytes. + * key [in] Ed448 key to use to verify. + * type [in] Type of signature to verify: Ed448 or Ed448ph + * context [in] Context of verification. + * contextLen [in] Length of context in bytes. + * returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and + * context is not NULL or public key not set, + * BUFFER_E when sigLen is less than ED448_SIG_SIZE, + * other -ve values when hash fails, + * 0 otherwise. + */ +static int ed448_verify_msg(const byte* sig, word32 sigLen, const byte* msg, + word32 msgLen, int* res, ed448_key* key, + byte type, const byte* context, byte contextLen) +{ + byte rcheck[ED448_KEY_SIZE]; + byte h[ED448_SIG_SIZE]; + ge448_p2 A; + ge448_p2 R; + int ret = 0; + wc_Shake sha; + + /* sanity check on arguments */ + if ((sig == NULL) || (msg == NULL) || (res == NULL) || (key == NULL) || + ((context == NULL) && (contextLen != 0))) { + ret = BAD_FUNC_ARG; + } + + if (ret == 0) { + /* set verification failed by default */ + *res = 0; + + /* check on basics needed to verify signature */ + if (sigLen < ED448_SIG_SIZE) { + ret = BAD_FUNC_ARG; + } + } + + /* uncompress A (public key), test if valid, and negate it */ + if ((ret == 0) && (ge448_from_bytes_negate_vartime(&A, key->p) != 0)) { + ret = BAD_FUNC_ARG; + } + + if (ret == 0) { + /* find H(R,A,M) and store it as h */ + ret = wc_InitShake256(&sha, NULL, INVALID_DEVID); + if (ret == 0) { + ret = wc_Shake256_Update(&sha, ed448Ctx, ED448CTX_SIZE); + if (ret == 0) { + ret = wc_Shake256_Update(&sha, &type, sizeof(type)); + } + if (ret == 0) { + ret = wc_Shake256_Update(&sha, &contextLen, sizeof(contextLen)); + } + if (ret == 0 && context != NULL) { + ret = wc_Shake256_Update(&sha, context, contextLen); + } + if (ret == 0) { + ret = wc_Shake256_Update(&sha, sig, ED448_SIG_SIZE/2); + } + if (ret == 0) { + ret = wc_Shake256_Update(&sha, key->p, ED448_PUB_KEY_SIZE); + } + if (ret == 0) { + ret = wc_Shake256_Update(&sha, msg, msgLen); + } + if (ret == 0) { + ret = wc_Shake256_Final(&sha, h, sizeof(h)); + } + wc_Shake256_Free(&sha); + } + } + if (ret == 0) { + sc448_reduce(h); + + /* Uses a fast single-signature verification SB = R + H(R,A,M)A becomes + * SB - H(R,A,M)A saving decompression of R + */ + ret = ge448_double_scalarmult_vartime(&R, h, &A, + sig + (ED448_SIG_SIZE/2)); + } + + if (ret == 0) { + ge448_to_bytes(rcheck, &R); + + /* comparison of R created to R in sig */ + if (ConstantCompare(rcheck, sig, ED448_SIG_SIZE/2) != 0) { + ret = SIG_VERIFY_E; + } + else { + /* set the verification status */ + *res = 1; + } + } + + return ret; +} + +/* Verify the message using the ed448 public key. + * Signature type is Ed448. + * + * sig [in] Signature to verify. + * sigLen [in] Size of signature in bytes. + * msg [in] Message to verify. + * msgLen [in] Length of the message in bytes. + * key [in] Ed448 key to use to verify. + * context [in] Context of verification. + * contextLen [in] Length of context in bytes. + * returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and + * context is not NULL or public key not set, + * BUFFER_E when sigLen is less than ED448_SIG_SIZE, + * other -ve values when hash fails, + * 0 otherwise. + */ +int wc_ed448_verify_msg(const byte* sig, word32 sigLen, const byte* msg, + word32 msgLen, int* res, ed448_key* key, + const byte* context, byte contextLen) +{ + return ed448_verify_msg(sig, sigLen, msg, msgLen, res, key, Ed448, + context, contextLen); +} + +/* Verify the hash using the ed448 public key. + * Signature type is Ed448ph. + * + * sig [in] Signature to verify. + * sigLen [in] Size of signature in bytes. + * hash [in] Hash of message to verify. + * hashLen [in] Length of the hash in bytes. + * key [in] Ed448 key to use to verify. + * context [in] Context of verification. + * contextLen [in] Length of context in bytes. + * returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and + * context is not NULL or public key not set, + * BUFFER_E when sigLen is less than ED448_SIG_SIZE, + * other -ve values when hash fails, + * 0 otherwise. + */ +int wc_ed448ph_verify_hash(const byte* sig, word32 sigLen, const byte* hash, + word32 hashLen, int* res, ed448_key* key, + const byte* context, byte contextLen) +{ + return ed448_verify_msg(sig, sigLen, hash, hashLen, res, key, Ed448ph, + context, contextLen); +} + +/* Verify the message using the ed448 public key. + * Signature type is Ed448ph. + * + * sig [in] Signature to verify. + * sigLen [in] Size of signature in bytes. + * msg [in] Message to verify. + * msgLen [in] Length of the message in bytes. + * key [in] Ed448 key to use to verify. + * context [in] Context of verification. + * contextLen [in] Length of context in bytes. + * returns BAD_FUNC_ARG when a parameter is NULL or contextLen is zero when and + * context is not NULL or public key not set, + * BUFFER_E when sigLen is less than ED448_SIG_SIZE, + * other -ve values when hash fails, + * 0 otherwise. + */ +int wc_ed448ph_verify_msg(const byte* sig, word32 sigLen, const byte* msg, + word32 msgLen, int* res, ed448_key* key, + const byte* context, byte contextLen) +{ + int ret = 0; + byte hash[64]; + + ret = wc_Shake256Hash(msg, msgLen, hash, sizeof(hash)); + if (ret == 0) { + ret = wc_ed448ph_verify_hash(sig, sigLen, hash, sizeof(hash), res, key, + context, contextLen); + } + + return ret; +} +#endif /* HAVE_ED448_VERIFY */ + +/* Initialize the ed448 private/public key. + * + * key [in] Ed448 key. + * returns BAD_FUNC_ARG when key is NULL + */ +int wc_ed448_init(ed448_key* key) +{ + int ret = 0; + + if (key == NULL) { + ret = BAD_FUNC_ARG; + } + else { + XMEMSET(key, 0, sizeof(ed448_key)); + + fe448_init(); + } + + return ret; +} + + +/* Clears the ed448 key data + * + * key [in] Ed448 key. + */ +void wc_ed448_free(ed448_key* key) +{ + if (key != NULL) { + ForceZero(key, sizeof(ed448_key)); + } +} + + +#ifdef HAVE_ED448_KEY_EXPORT + +/* Export the ed448 public key. + * + * key [in] Ed448 public key. + * out [in] Array to hold public key. + * outLen [in/out] On in, the number of bytes in array. + * On out, the number bytes put into array. + * returns BAD_FUNC_ARG when a parameter is NULL, + * ECC_BAD_ARG_E when outLen is less than ED448_PUB_KEY_SIZE, + * 0 otherwise. + */ +int wc_ed448_export_public(ed448_key* key, byte* out, word32* outLen) +{ + int ret = 0; + + /* sanity check on arguments */ + if ((key == NULL) || (out == NULL) || (outLen == NULL)) { + ret = BAD_FUNC_ARG; + } + + if ((ret == 0) && (*outLen < ED448_PUB_KEY_SIZE)) { + *outLen = ED448_PUB_KEY_SIZE; + ret = BUFFER_E; + } + + if (ret == 0) { + *outLen = ED448_PUB_KEY_SIZE; + XMEMCPY(out, key->p, ED448_PUB_KEY_SIZE); + } + + return ret; +} + +#endif /* HAVE_ED448_KEY_EXPORT */ + + +#ifdef HAVE_ED448_KEY_IMPORT +/* Import a compressed or uncompressed ed448 public key from a byte array. + * Public key encoded in big-endian. + * + * in [in] Array holding public key. + * inLen [in] Number of bytes of data in array. + * key [in] Ed448 public key. + * returns BAD_FUNC_ARG when a parameter is NULL or key format is not supported, + * 0 otherwise. + */ +int wc_ed448_import_public(const byte* in, word32 inLen, ed448_key* key) +{ + int ret = 0; + + /* sanity check on arguments */ + if ((in == NULL) || (key == NULL)) { + ret = BAD_FUNC_ARG; + } + + if (ret == 0) { + /* compressed prefix according to draft + * https://tools.ietf.org/html/draft-ietf-openpgp-rfc4880bis-06 */ + if (in[0] == 0x40 && inLen > ED448_PUB_KEY_SIZE) { + /* key is stored in compressed format so just copy in */ + XMEMCPY(key->p, (in + 1), ED448_PUB_KEY_SIZE); + key->pubKeySet = 1; + } + /* importing uncompressed public key */ + else if (in[0] == 0x04 && inLen > 2*ED448_PUB_KEY_SIZE) { + /* pass in (x,y) and store compressed key */ + ret = ge448_compress_key(key->p, in+1, in+1+ED448_PUB_KEY_SIZE); + if (ret == 0) + key->pubKeySet = 1; + } + else if (inLen == ED448_PUB_KEY_SIZE) { + /* if not specified compressed or uncompressed check key size + * if key size is equal to compressed key size copy in key */ + XMEMCPY(key->p, in, ED448_PUB_KEY_SIZE); + key->pubKeySet = 1; + } + else { + /* bad public key format */ + ret = BAD_FUNC_ARG; + } + } + + return ret; +} + + +/* Import an ed448 private key from a byte array. + * + * priv [in] Array holding private key. + * privSz [in] Number of bytes of data in array. + * key [in] Ed448 private key. + * returns BAD_FUNC_ARG when a parameter is NULL or privSz is less than + * ED448_KEY_SIZE, + * 0 otherwise. + */ +int wc_ed448_import_private_only(const byte* priv, word32 privSz, + ed448_key* key) +{ + int ret = 0; + + /* sanity check on arguments */ + if ((priv == NULL) || (key == NULL)) { + ret = BAD_FUNC_ARG; + } + + /* key size check */ + if ((ret == 0) && (privSz < ED448_KEY_SIZE)) { + ret = BAD_FUNC_ARG; + } + + if (ret == 0) { + XMEMCPY(key->k, priv, ED448_KEY_SIZE); + } + + return ret; +} + +/* Import an ed448 private and public keys from a byte arrays. + * + * priv [in] Array holding private key. + * privSz [in] Number of bytes of data in private key array. + * pub [in] Array holding private key. + * pubSz [in] Number of bytes of data in public key array. + * key [in] Ed448 private/public key. + * returns BAD_FUNC_ARG when a parameter is NULL or privSz is less than + * ED448_KEY_SIZE or pubSz is less than ED448_PUB_KEY_SIZE, + * 0 otherwise. + */ +int wc_ed448_import_private_key(const byte* priv, word32 privSz, + const byte* pub, word32 pubSz, ed448_key* key) +{ + int ret = 0; + + /* sanity check on arguments */ + if ((priv == NULL) || (pub == NULL) || (key == NULL)) { + ret = BAD_FUNC_ARG; + } + + /* key size check */ + if ((ret == 0) && (privSz < ED448_KEY_SIZE || pubSz < ED448_PUB_KEY_SIZE)) { + ret = BAD_FUNC_ARG; + } + + if (ret == 0) { + /* import public key */ + ret = wc_ed448_import_public(pub, pubSz, key); + } + if (ret == 0) { + /* make the private key (priv + pub) */ + XMEMCPY(key->k, priv, ED448_KEY_SIZE); + XMEMCPY(key->k + ED448_KEY_SIZE, key->p, ED448_PUB_KEY_SIZE); + } + + return ret; +} + +#endif /* HAVE_ED448_KEY_IMPORT */ + + +#ifdef HAVE_ED448_KEY_EXPORT + +/* Export the ed448 private key. + * + * key [in] Ed448 private key. + * out [in] Array to hold private key. + * outLen [in/out] On in, the number of bytes in array. + * On out, the number bytes put into array. + * returns BAD_FUNC_ARG when a parameter is NULL, + * ECC_BAD_ARG_E when outLen is less than ED448_KEY_SIZE, + * 0 otherwise. + */ +int wc_ed448_export_private_only(ed448_key* key, byte* out, word32* outLen) +{ + int ret = 0; + + /* sanity checks on arguments */ + if ((key == NULL) || (out == NULL) || (outLen == NULL)) { + ret = BAD_FUNC_ARG; + } + + if ((ret == 0) && (*outLen < ED448_KEY_SIZE)) { + *outLen = ED448_KEY_SIZE; + ret = BUFFER_E; + } + + if (ret == 0) { + *outLen = ED448_KEY_SIZE; + XMEMCPY(out, key->k, ED448_KEY_SIZE); + } + + return ret; +} + +/* Export the ed448 private and public key. + * + * key [in] Ed448 private/public key. + * out [in] Array to hold private and public key. + * outLen [in/out] On in, the number of bytes in array. + * On out, the number bytes put into array. + * returns BAD_FUNC_ARG when a parameter is NULL, + * BUFFER_E when outLen is less than ED448_PRV_KEY_SIZE, + * 0 otherwise. + */ +int wc_ed448_export_private(ed448_key* key, byte* out, word32* outLen) +{ + int ret = 0; + + /* sanity checks on arguments */ + if ((key == NULL) || (out == NULL) || (outLen == NULL)) { + ret = BAD_FUNC_ARG; + } + + if ((ret == 0) && (*outLen < ED448_PRV_KEY_SIZE)) { + *outLen = ED448_PRV_KEY_SIZE; + ret = BUFFER_E; + } + + if (ret == 0) { + *outLen = ED448_PRV_KEY_SIZE; + XMEMCPY(out, key->k, ED448_PRV_KEY_SIZE); + } + + return ret; +} + +/* Export the ed448 private and public key. + * + * key [in] Ed448 private/public key. + * priv [in] Array to hold private key. + * privSz [in/out] On in, the number of bytes in private key array. + * pub [in] Array to hold public key. + * pubSz [in/out] On in, the number of bytes in public key array. + * On out, the number bytes put into array. + * returns BAD_FUNC_ARG when a parameter is NULL, + * BUFFER_E when privSz is less than ED448_PRV_KEY_SIZE or pubSz is less + * than ED448_PUB_KEY_SIZE, + * 0 otherwise. + */ +int wc_ed448_export_key(ed448_key* key, byte* priv, word32 *privSz, + byte* pub, word32 *pubSz) +{ + int ret = 0; + + /* export 'full' private part */ + ret = wc_ed448_export_private(key, priv, privSz); + if (ret == 0) { + /* export public part */ + ret = wc_ed448_export_public(key, pub, pubSz); + } + + return ret; +} + +#endif /* HAVE_ED448_KEY_EXPORT */ + +/* Check the public key of the ed448 key matches the private key. + * + * key [in] Ed448 private/public key. + * returns BAD_FUNC_ARG when key is NULL, + * PUBLIC_KEY_E when the public key is not set or doesn't match, + * other -ve value on hash failure, + * 0 otherwise. + */ +int wc_ed448_check_key(ed448_key* key) +{ + int ret = 0; + unsigned char pubKey[ED448_PUB_KEY_SIZE]; + + if (key == NULL) { + ret = BAD_FUNC_ARG; + } + + if (!key->pubKeySet) { + ret = PUBLIC_KEY_E; + } + if (ret == 0) { + ret = wc_ed448_make_public(key, pubKey, sizeof(pubKey)); + } + if ((ret == 0) && (XMEMCMP(pubKey, key->p, ED448_PUB_KEY_SIZE) != 0)) { + ret = PUBLIC_KEY_E; + } + + return ret; +} + +/* Returns the size of an ed448 private key. + * + * key [in] Ed448 private/public key. + * returns BAD_FUNC_ARG when key is NULL, + * ED448_KEY_SIZE otherwise. + */ +int wc_ed448_size(ed448_key* key) +{ + int ret = ED448_KEY_SIZE; + + if (key == NULL) { + ret = BAD_FUNC_ARG; + } + + return ret; +} + +/* Returns the size of an ed448 private plus public key. + * + * key [in] Ed448 private/public key. + * returns BAD_FUNC_ARG when key is NULL, + * ED448_PRV_KEY_SIZE otherwise. + */ +int wc_ed448_priv_size(ed448_key* key) +{ + int ret = ED448_PRV_KEY_SIZE; + + if (key == NULL) { + ret = BAD_FUNC_ARG; + } + + return ret; +} + +/* Returns the size of an ed448 public key. + * + * key [in] Ed448 private/public key. + * returns BAD_FUNC_ARG when key is NULL, + * ED448_PUB_KEY_SIZE otherwise. + */ +int wc_ed448_pub_size(ed448_key* key) +{ + int ret = ED448_PUB_KEY_SIZE; + + if (key == NULL) { + ret = BAD_FUNC_ARG; + } + + return ret; +} + +/* Returns the size of an ed448 signature. + * + * key [in] Ed448 private/public key. + * returns BAD_FUNC_ARG when key is NULL, + * ED448_SIG_SIZE otherwise. + */ +int wc_ed448_sig_size(ed448_key* key) +{ + int ret = ED448_SIG_SIZE; + + if (key == NULL) { + ret = BAD_FUNC_ARG; + } + + return ret; +} + +#endif /* HAVE_ED448 */ + diff --git a/wolfcrypt/src/fe_448.c b/wolfcrypt/src/fe_448.c new file mode 100644 index 000000000..a75f73cdb --- /dev/null +++ b/wolfcrypt/src/fe_448.c @@ -0,0 +1,2394 @@ +/* fe_448.c + * + * 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 + */ + +/* Based On Daniel J Bernstein's curve25519 Public Domain ref10 work. + * Small implementation based on Daniel Beer's curve25519 public domain work. + * Reworked for curve448 by Sean Parkinson. + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#if defined(HAVE_CURVE448) || defined(HAVE_ED448) + +#include +#include + +#ifdef NO_INLINE + #include +#else + #define WOLFSSL_MISC_INCLUDED + #include +#endif + +#if defined(CURVE448_SMALL) || defined(ED448_SMALL) + +/* Initialize the field element operations. + */ +void fe448_init(void) +{ +} + +/* Normalize the field element. + * Ensure result is in range: 0..2^448-2^224-2 + * + * a [in] Field element in range 0..2^448-1. + */ +void fe448_norm(uint8_t* a) +{ + int i; + int16_t c = 0; + int16_t o = 0; + + for (i = 0; i < 56; i++) { + c += a[i]; + if ((i == 0) || (i == 28)) + c += 1; + c >>= 8; + } + + for (i = 0; i < 56; i++) { + if ((i == 0) || (i == 28)) o += c; + o += a[i]; + a[i] = (uint8_t)o; + o >>= 8; + } +} + +/* Copy one field element into another: d = a. + * + * d [in] Destination field element. + * a [in] Source field element. + */ +void fe448_copy(uint8_t* d, const uint8_t* a) +{ + int i; + for (i = 0; i < 56; i++) { + d[i] = a[i]; + } +} + +/* Conditionally swap the elements. + * Constant time implementation. + * + * a [in] First field element. + * b [in] Second field element. + * c [in] Swap when 1. Valid values: 0, 1. + */ +static void fe448_cswap(uint8_t* a, uint8_t* b, int c) +{ + int i; + uint8_t mask = -(uint8_t)c; + uint8_t t[56]; + + for (i = 0; i < 56; i++) + t[i] = (a[i] ^ b[i]) & mask; + for (i = 0; i < 56; i++) + a[i] ^= t[i]; + for (i = 0; i < 56; i++) + b[i] ^= t[i]; +} + +/* Add two field elements. r = (a + b) mod (2^448 - 2^224 - 1) + * + * r [in] Field element to hold sum. + * a [in] Field element to add. + * b [in] Field element to add. + */ +void fe448_add(uint8_t* r, const uint8_t* a, const uint8_t* b) +{ + int i; + int16_t c = 0; + int16_t o = 0; + + for (i = 0; i < 56; i++) { + c += a[i]; + c += b[i]; + r[i] = (uint8_t)c; + c >>= 8; + } + + for (i = 0; i < 56; i++) { + if ((i == 0) || (i == 28)) o += c; + o += r[i]; + r[i] = (uint8_t)o; + o >>= 8; + } +} + +/* Subtract a field element from another. r = (a - b) mod (2^448 - 2^224 - 1) + * + * r [in] Field element to hold difference. + * a [in] Field element to subtract from. + * b [in] Field element to subtract. + */ +void fe448_sub(uint8_t* r, const uint8_t* a, const uint8_t* b) +{ + int i; + int16_t c = 0; + int16_t o = 0; + + for (i = 0; i < 56; i++) { + if (i == 28) + c += 0x1fc; + else + c += 0x1fe; + c += a[i]; + c -= b[i]; + r[i] = (uint8_t)c; + c >>= 8; + } + + for (i = 0; i < 56; i++) { + if ((i == 0) || (i == 28)) o += c; + o += r[i]; + r[i] = (uint8_t)o; + o >>= 8; + } +} + +/* Mulitply a field element by 39081. r = (39081 * a) mod (2^448 - 2^224 - 1) + * + * r [in] Field element to hold result. + * a [in] Field element to multiply. + */ +void fe448_mul39081(uint8_t* r, const uint8_t* a) +{ + int i; + int32_t c = 0; + int32_t o = 0; + + for (i = 0; i < 56; i++) { + c += a[i] * (int32_t)39081; + r[i] = (uint8_t)c; + c >>= 8; + } + + for (i = 0; i < 56; i++) { + if ((i == 0) || (i == 28)) o += c; + o += r[i]; + r[i] = (uint8_t)o; + o >>= 8; + } +} + +/* Mulitply two field elements. r = (a * b) mod (2^448 - 2^224 - 1) + * + * r [in] Field element to hold result. + * a [in] Field element to multiply. + * b [in] Field element to multiply. + */ +void fe448_mul(uint8_t* r, const uint8_t* a, const uint8_t* b) +{ + int i, k; + int32_t c = 0; + int16_t o = 0, cc = 0; + uint8_t t[112]; + + for (k = 0; k < 56; k++) { + i = 0; + for (; i <= k; i++) { + c += (int32_t)a[i] * b[k - i]; + } + t[k] = (uint8_t)c; + c >>= 8; + } + for (; k < 111; k++) { + i = k - 55; + for (; i < 56; i++) { + c += (int32_t)a[i] * b[k - i]; + } + t[k] = (uint8_t)c; + c >>= 8; + } + t[k] = (uint8_t)c; + + for (i = 0; i < 28; i++) { + o += t[i]; + o += t[i + 56]; + o += t[i + 84]; + r[i] = (uint8_t)o; + o >>= 8; + } + for (i = 28; i < 56; i++) { + o += t[i]; + o += t[i + 56]; + o += t[i + 28]; + o += t[i + 56]; + r[i] = (uint8_t)o; + o >>= 8; + } + for (i = 0; i < 56; i++) { + if ((i == 0) || (i == 28)) cc += o; + cc += r[i]; + r[i] = (uint8_t)cc; + cc >>= 8; + } +} + +/* Square a field element. r = (a * a) mod (2^448 - 2^224 - 1) + * + * r [in] Field element to hold result. + * a [in] Field element to square. + */ +void fe448_sqr(uint8_t* r, const uint8_t* a) +{ + int i, k; + int32_t c = 0; + int32_t p; + int16_t o = 0, cc = 0; + uint8_t t[112]; + + for (k = 0; k < 56; k++) { + i = 0; + for (; i <= k; i++) { + if (k - i < i) + break; + p = (int32_t)a[i] * a[k - i]; + if (k - i != i) + p *= 2; + c += p; + } + t[k] = (uint8_t)c; + c >>= 8; + } + for (; k < 111; k++) { + i = k - 55; + for (; i < 56; i++) { + if (k - i < i) + break; + p = (int32_t)a[i] * a[k - i]; + if (k - i != i) + p *= 2; + c += p; + } + t[k] = (uint8_t)c; + c >>= 8; + } + t[k] = (uint8_t)c; + + for (i = 0; i < 28; i++) { + o += t[i]; + o += t[i + 56]; + o += t[i + 84]; + r[i] = (uint8_t)o; + o >>= 8; + } + for (i = 28; i < 56; i++) { + o += t[i]; + o += t[i + 56]; + o += t[i + 28]; + o += t[i + 56]; + r[i] = (uint8_t)o; + o >>= 8; + } + for (i = 0; i < 56; i++) { + if ((i == 0) || (i == 28)) cc += o; + cc += r[i]; + r[i] = (uint8_t)cc; + cc >>= 8; + } + fe448_norm(r); +} + +/* Invert the field element. (r * a) mod (2^448 - 2^224 - 1) = 1 + * Constant time implementation - using Fermat's little theorem: + * a^(p-1) mod p = 1 => a^(p-2) mod p = 1/a + * For curve448: p - 2 = 2^448 - 2^224 - 3 + * + * r [in] Field element to hold result. + * a [in] Field element to invert. + */ +void fe448_invert(uint8_t* r, const uint8_t* a) +{ + int i; + uint8_t t[56]; + + fe448_sqr(t, a); + fe448_mul(t, t, a); + for (i = 0; i < 221; i++) { + fe448_sqr(t, t); + fe448_mul(t, t, a); + } + fe448_sqr(t, t); + for (i = 0; i < 222; i++) { + fe448_sqr(t, t); + fe448_mul(t, t, a); + } + fe448_sqr(t, t); + fe448_sqr(t, t); + fe448_mul(r, t, a); +} + +/* Scalar multiply the point by a number. r = n.a + * Uses Montogmery ladder and only requires the x-ordinate. + * + * r [in] Field element to hold result. + * n [in] Scalar as an array of bytes. + * a [in] Point to multiply - x-ordinate only. + */ +int curve448(byte* r, const byte* n, const byte* a) +{ + uint8_t x1[56]; + uint8_t x2[56] = {1}; + uint8_t z2[56] = {0}; + uint8_t x3[56]; + uint8_t z3[56] = {1}; + uint8_t t0[56]; + uint8_t t1[56]; + int i; + unsigned int swap; + unsigned int b; + + fe448_copy(x1, a); + fe448_copy(x3, a); + + swap = 0; + for (i = 447; i >= 0; --i) { + b = (n[i >> 3] >> (i & 7)) & 1; + swap ^= b; + fe448_cswap(x2, x3, swap); + fe448_cswap(z2, z3, swap); + swap = b; + + /* Montgomery Ladder - double and add */ + fe448_add(t0, x2, z2); + fe448_add(t1, x3, z3); + fe448_sub(x2, x2, z2); + fe448_sub(x3, x3, z3); + fe448_mul(t1, t1, x2); + fe448_mul(z3, x3, t0); + fe448_sqr(t0, t0); + fe448_sqr(x2, x2); + fe448_add(x3, z3, t1); + fe448_sqr(x3, x3); + fe448_sub(z3, z3, t1); + fe448_sqr(z3, z3); + fe448_mul(z3, z3, x1); + fe448_sub(t1, t0, x2); + fe448_mul(x2, t0, x2); + fe448_mul39081(z2, t1); + fe448_add(z2, t0, z2); + fe448_mul(z2, z2, t1); + } + fe448_cswap(x2, x3, swap); + fe448_cswap(z2, z3, swap); + + fe448_invert(z2, z2); + fe448_mul(r, x2, z2); + fe448_norm(r); + + return 0; +} + +#ifdef HAVE_ED448 +/* Check whether field element is not 0. + * Field element must have been normalized before call. + * + * a [in] Field element. + * returns 0 when zero, and any other value otherwise. + */ +int fe448_isnonzero(const uint8_t* a) +{ + int i; + uint8_t c = 0; + for (i = 0; i < 56; i++) + c |= a[i]; + return c; +} + +/* Negates the field element. r = -a mod (2^448 - 2^224 - 1) + * Add 0x200 to each element and subtract 2 from next. + * Top element overflow handled by subtracting 2 from index 0 and 28. + * + * r [in] Field element to hold result. + * a [in] Field element. + */ +void fe448_neg(uint8_t* r, const uint8_t* a) +{ + int i; + int16_t c = 0; + int16_t o = 0; + + for (i = 0; i < 56; i++) { + if (i == 28) + c += 0x1fc; + else + c += 0x1fe; + c -= a[i]; + r[i] = (uint8_t)c; + c >>= 8; + } + + for (i = 0; i < 56; i++) { + if ((i == 0) || (i == 28)) o += c; + o += r[i]; + r[i] = (uint8_t)o; + o >>= 8; + } +} + +/* Raise field element to (p-3) / 4: 2^446 - 2^222 - 1 + * Used for calcualting y-ordinate from x-ordinate for Ed448. + * + * r [in] Field element to hold result. + * a [in] Field element to exponentiate. + */ +void fe448_pow_2_446_222_1(uint8_t* r, const uint8_t* a) +{ + int i; + uint8_t t[56]; + + fe448_sqr(t, a); + fe448_mul(t, t, a); + for (i = 0; i < 221; i++) { + fe448_sqr(t, t); + fe448_mul(t, t, a); + } + fe448_sqr(t, t); + for (i = 0; i < 221; i++) { + fe448_sqr(t, t); + fe448_mul(t, t, a); + } + fe448_sqr(t, t); + fe448_mul(r, t, a); +} + +/* Constant time, conditional move of b into a. + * a is not changed if the condition is 0. + * + * a A field element. + * b A field element. + * c If 1 then copy and if 0 then don't copy. + */ +void fe448_cmov(uint8_t* a, const uint8_t* b, int c) +{ + int i; + uint8_t m = -(uint8_t)c; + uint8_t t[56]; + + for (i = 0; i < 56; i++) + t[i] = m & (a[i] ^ b[i]); + for (i = 0; i < 56; i++) + a[i] ^= t[i]; +} + +#endif /* HAVE_ED448 */ +#elif defined(CURVED448_128BIT) + +/* Initialize the field element operations. + */ +void fe448_init(void) +{ +} + +/* Convert the field element from a byte array to an array of 56-bits. + * + * r [in] Array to encode into. + * b [in] Byte array. + */ +void fe448_from_bytes(int64_t* r, const unsigned char* b) +{ + r[ 0] = ((int64_t) (b[ 0]) << 0) + | ((int64_t) (b[ 1]) << 8) + | ((int64_t) (b[ 2]) << 16) + | ((int64_t) (b[ 3]) << 24) + | ((int64_t) (b[ 4]) << 32) + | ((int64_t) (b[ 5]) << 40) + | ((int64_t) (b[ 6]) << 48); + r[ 1] = ((int64_t) (b[ 7]) << 0) + | ((int64_t) (b[ 8]) << 8) + | ((int64_t) (b[ 9]) << 16) + | ((int64_t) (b[10]) << 24) + | ((int64_t) (b[11]) << 32) + | ((int64_t) (b[12]) << 40) + | ((int64_t) (b[13]) << 48); + r[ 2] = ((int64_t) (b[14]) << 0) + | ((int64_t) (b[15]) << 8) + | ((int64_t) (b[16]) << 16) + | ((int64_t) (b[17]) << 24) + | ((int64_t) (b[18]) << 32) + | ((int64_t) (b[19]) << 40) + | ((int64_t) (b[20]) << 48); + r[ 3] = ((int64_t) (b[21]) << 0) + | ((int64_t) (b[22]) << 8) + | ((int64_t) (b[23]) << 16) + | ((int64_t) (b[24]) << 24) + | ((int64_t) (b[25]) << 32) + | ((int64_t) (b[26]) << 40) + | ((int64_t) (b[27]) << 48); + r[ 4] = ((int64_t) (b[28]) << 0) + | ((int64_t) (b[29]) << 8) + | ((int64_t) (b[30]) << 16) + | ((int64_t) (b[31]) << 24) + | ((int64_t) (b[32]) << 32) + | ((int64_t) (b[33]) << 40) + | ((int64_t) (b[34]) << 48); + r[ 5] = ((int64_t) (b[35]) << 0) + | ((int64_t) (b[36]) << 8) + | ((int64_t) (b[37]) << 16) + | ((int64_t) (b[38]) << 24) + | ((int64_t) (b[39]) << 32) + | ((int64_t) (b[40]) << 40) + | ((int64_t) (b[41]) << 48); + r[ 6] = ((int64_t) (b[42]) << 0) + | ((int64_t) (b[43]) << 8) + | ((int64_t) (b[44]) << 16) + | ((int64_t) (b[45]) << 24) + | ((int64_t) (b[46]) << 32) + | ((int64_t) (b[47]) << 40) + | ((int64_t) (b[48]) << 48); + r[ 7] = ((int64_t) (b[49]) << 0) + | ((int64_t) (b[50]) << 8) + | ((int64_t) (b[51]) << 16) + | ((int64_t) (b[52]) << 24) + | ((int64_t) (b[53]) << 32) + | ((int64_t) (b[54]) << 40) + | ((int64_t) (b[55]) << 48); +} + +/* Convert the field element to a byte array from an array of 56-bits. + * + * b [in] Byte array. + * a [in] Array to encode into. + */ +void fe448_to_bytes(unsigned char* b, const int64_t* a) +{ + /* Mod */ + int64_t in0 = a[0]; + int64_t in1 = a[1]; + int64_t in2 = a[2]; + int64_t in3 = a[3]; + int64_t in4 = a[4]; + int64_t in5 = a[5]; + int64_t in6 = a[6]; + int64_t in7 = a[7]; + int64_t o = in7 >> 56; + in7 -= o << 56; + in0 += o; + in4 += o; + o = (in0 + 1) >> 56; + o = (o + in1) >> 56; + o = (o + in2) >> 56; + o = (o + in3) >> 56; + o = (o + in4 + 1) >> 56; + o = (o + in5) >> 56; + o = (o + in6) >> 56; + o = (o + in7) >> 56; + in0 += o; + in4 += o; + in7 -= o << 56; + o = in0 >> 56; in1 += o; in0 -= o << 56; + o = in1 >> 56; in2 += o; in1 -= o << 56; + o = in2 >> 56; in3 += o; in2 -= o << 56; + o = in3 >> 56; in4 += o; in3 -= o << 56; + o = in4 >> 56; in5 += o; in4 -= o << 56; + o = in5 >> 56; in6 += o; in5 -= o << 56; + o = in6 >> 56; in7 += o; in6 -= o << 56; + o = in7 >> 56; in0 += o; + in4 += o; in7 -= o << 56; + + /* Output as bytes */ + b[ 0] = (in0 >> 0); + b[ 1] = (in0 >> 8); + b[ 2] = (in0 >> 16); + b[ 3] = (in0 >> 24); + b[ 4] = (in0 >> 32); + b[ 5] = (in0 >> 40); + b[ 6] = (in0 >> 48); + b[ 7] = (in1 >> 0); + b[ 8] = (in1 >> 8); + b[ 9] = (in1 >> 16); + b[10] = (in1 >> 24); + b[11] = (in1 >> 32); + b[12] = (in1 >> 40); + b[13] = (in1 >> 48); + b[14] = (in2 >> 0); + b[15] = (in2 >> 8); + b[16] = (in2 >> 16); + b[17] = (in2 >> 24); + b[18] = (in2 >> 32); + b[19] = (in2 >> 40); + b[20] = (in2 >> 48); + b[21] = (in3 >> 0); + b[22] = (in3 >> 8); + b[23] = (in3 >> 16); + b[24] = (in3 >> 24); + b[25] = (in3 >> 32); + b[26] = (in3 >> 40); + b[27] = (in3 >> 48); + b[28] = (in4 >> 0); + b[29] = (in4 >> 8); + b[30] = (in4 >> 16); + b[31] = (in4 >> 24); + b[32] = (in4 >> 32); + b[33] = (in4 >> 40); + b[34] = (in4 >> 48); + b[35] = (in5 >> 0); + b[36] = (in5 >> 8); + b[37] = (in5 >> 16); + b[38] = (in5 >> 24); + b[39] = (in5 >> 32); + b[40] = (in5 >> 40); + b[41] = (in5 >> 48); + b[42] = (in6 >> 0); + b[43] = (in6 >> 8); + b[44] = (in6 >> 16); + b[45] = (in6 >> 24); + b[46] = (in6 >> 32); + b[47] = (in6 >> 40); + b[48] = (in6 >> 48); + b[49] = (in7 >> 0); + b[50] = (in7 >> 8); + b[51] = (in7 >> 16); + b[52] = (in7 >> 24); + b[53] = (in7 >> 32); + b[54] = (in7 >> 40); + b[55] = (in7 >> 48); +} + +/* Set the field element to 0. + * + * a [in] Field element. + */ +void fe448_1(int64_t* a) +{ + a[0] = 1; + a[1] = 0; + a[2] = 0; + a[3] = 0; + a[4] = 0; + a[5] = 0; + a[6] = 0; + a[7] = 0; +} + +/* Set the field element to 0. + * + * a [in] Field element. + */ +void fe448_0(int64_t* a) +{ + a[0] = 0; + a[1] = 0; + a[2] = 0; + a[3] = 0; + a[4] = 0; + a[5] = 0; + a[6] = 0; + a[7] = 0; +} + +/* Copy one field element into another: d = a. + * + * d [in] Destination field element. + * a [in] Source field element. + */ +void fe448_copy(int64_t* d, const int64_t* a) +{ + d[0] = a[0]; + d[1] = a[1]; + d[2] = a[2]; + d[3] = a[3]; + d[4] = a[4]; + d[5] = a[5]; + d[6] = a[6]; + d[7] = a[7]; +} + +/* Conditionally swap the elements. + * Constant time implementation. + * + * a [in] First field element. + * b [in] Second field element. + * c [in] Swap when 1. Valid values: 0, 1. + */ +static void fe448_cswap(int64_t* a, int64_t* b, int c) +{ + int64_t mask = -(int64_t)c; + int64_t t0 = (a[0] ^ b[0]) & mask; + int64_t t1 = (a[1] ^ b[1]) & mask; + int64_t t2 = (a[2] ^ b[2]) & mask; + int64_t t3 = (a[3] ^ b[3]) & mask; + int64_t t4 = (a[4] ^ b[4]) & mask; + int64_t t5 = (a[5] ^ b[5]) & mask; + int64_t t6 = (a[6] ^ b[6]) & mask; + int64_t t7 = (a[7] ^ b[7]) & mask; + a[0] ^= t0; + a[1] ^= t1; + a[2] ^= t2; + a[3] ^= t3; + a[4] ^= t4; + a[5] ^= t5; + a[6] ^= t6; + a[7] ^= t7; + b[0] ^= t0; + b[1] ^= t1; + b[2] ^= t2; + b[3] ^= t3; + b[4] ^= t4; + b[5] ^= t5; + b[6] ^= t6; + b[7] ^= t7; +} + +/* Add two field elements. r = (a + b) mod (2^448 - 2^224 - 1) + * + * r [in] Field element to hold sum. + * a [in] Field element to add. + * b [in] Field element to add. + */ +void fe448_add(int64_t* r, const int64_t* a, const int64_t* 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]; +} + +/* Subtract a field element from another. r = (a - b) mod (2^448 - 2^224 - 1) + * + * r [in] Field element to hold difference. + * a [in] Field element to subtract from. + * b [in] Field element to subtract. + */ +void fe448_sub(int64_t* r, const int64_t* a, const int64_t* 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]; +} + +/* Mulitply a field element by 39081. r = (39081 * a) mod (2^448 - 2^224 - 1) + * + * r [in] Field element to hold result. + * a [in] Field element to multiply. + */ +void fe448_mul39081(int64_t* r, const int64_t* a) +{ + int64_t o; + int128_t t0 = a[0] * (int128_t)39081; + int128_t t1 = a[1] * (int128_t)39081; + int128_t t2 = a[2] * (int128_t)39081; + int128_t t3 = a[3] * (int128_t)39081; + int128_t t4 = a[4] * (int128_t)39081; + int128_t t5 = a[5] * (int128_t)39081; + int128_t t6 = a[6] * (int128_t)39081; + int128_t t7 = a[7] * (int128_t)39081; + o = t0 >> 56; t1 += o; t0 -= (int128_t)o << 56; + o = t1 >> 56; t2 += o; t1 -= (int128_t)o << 56; + o = t2 >> 56; t3 += o; t2 -= (int128_t)o << 56; + o = t3 >> 56; t4 += o; t3 -= (int128_t)o << 56; + o = t4 >> 56; t5 += o; t4 -= (int128_t)o << 56; + o = t5 >> 56; t6 += o; t5 -= (int128_t)o << 56; + o = t6 >> 56; t7 += o; t6 -= (int128_t)o << 56; + o = t7 >> 56; t0 += o; + t4 += o; t7 -= (int128_t)o << 56; + + /* Store */ + r[0] = t0; + r[1] = t1; + r[2] = t2; + r[3] = t3; + r[4] = t4; + r[5] = t5; + r[6] = t6; + r[7] = t7; +} + +/* Mulitply two field elements. r = (a * b) mod (2^448 - 2^224 - 1) + * + * r [in] Field element to hold result. + * a [in] Field element to multiply. + * b [in] Field element to multiply. + */ +void fe448_mul(int64_t* r, const int64_t* a, const int64_t* b) +{ + int64_t o; + 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[ 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 t9 = (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 t10 = (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 t11 = (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 t12 = (int128_t)a[ 5] * b[ 7] + + (int128_t)a[ 6] * b[ 6] + + (int128_t)a[ 7] * b[ 5]; + int128_t t13 = (int128_t)a[ 6] * b[ 7] + + (int128_t)a[ 7] * b[ 6]; + int128_t t14 = (int128_t)a[ 7] * b[ 7]; + + /* Reduce */ + int128_t tr0 = t0 + t8 + t12; + int128_t tr1 = t1 + t9 + t13; + int128_t tr2 = t2 + t10 + t14; + int128_t tr3 = t3 + t11; + int128_t tr4 = t4 + t12 + t8 + t12; + int128_t tr5 = t5 + t13 + t9 + t13; + int128_t tr6 = t6 + t14 + t10 + t14; + int128_t tr7 = t7 + t11; + o = tr7 >> 56; tr0 += o; + tr4 += o; tr7 -= (int128_t)o << 56; + o = tr0 >> 56; tr1 += o; tr0 -= (int128_t)o << 56; + o = tr1 >> 56; tr2 += o; tr1 -= (int128_t)o << 56; + o = tr2 >> 56; tr3 += o; tr2 -= (int128_t)o << 56; + o = tr3 >> 56; tr4 += o; tr3 -= (int128_t)o << 56; + o = tr4 >> 56; tr5 += o; tr4 -= (int128_t)o << 56; + o = tr5 >> 56; tr6 += o; tr5 -= (int128_t)o << 56; + o = tr6 >> 56; tr7 += o; tr6 -= (int128_t)o << 56; + o = tr7 >> 56; tr0 += o; + tr4 += o; tr7 -= (int128_t)o << 56; + + /* Store */ + r[0] = tr0; + r[1] = tr1; + r[2] = tr2; + r[3] = tr3; + r[4] = tr4; + r[5] = tr5; + r[6] = tr6; + r[7] = tr7; +} + +/* Square a field element. r = (a * a) mod (2^448 - 2^224 - 1) + * + * r [in] Field element to hold result. + * a [in] Field element to square. + */ +void fe448_sqr(int64_t* r, const int64_t* a) +{ + int64_t o; + int128_t t0 = (int128_t)a[ 0] * a[ 0]; + int128_t t1 = 2 * (int128_t)a[ 0] * a[ 1]; + int128_t t2 = 2 * (int128_t)a[ 0] * a[ 2] + + (int128_t)a[ 1] * a[ 1]; + int128_t t3 = 2 * (int128_t)a[ 0] * a[ 3] + + 2 * (int128_t)a[ 1] * a[ 2]; + int128_t t4 = 2 * (int128_t)a[ 0] * a[ 4] + + 2 * (int128_t)a[ 1] * a[ 3] + + (int128_t)a[ 2] * a[ 2]; + int128_t t5 = 2 * (int128_t)a[ 0] * a[ 5] + + 2 * (int128_t)a[ 1] * a[ 4] + + 2 * (int128_t)a[ 2] * a[ 3]; + int128_t t6 = 2 * (int128_t)a[ 0] * a[ 6] + + 2 * (int128_t)a[ 1] * a[ 5] + + 2 * (int128_t)a[ 2] * a[ 4] + + (int128_t)a[ 3] * a[ 3]; + int128_t t7 = 2 * (int128_t)a[ 0] * a[ 7] + + 2 * (int128_t)a[ 1] * a[ 6] + + 2 * (int128_t)a[ 2] * a[ 5] + + 2 * (int128_t)a[ 3] * a[ 4]; + int128_t t8 = 2 * (int128_t)a[ 1] * a[ 7] + + 2 * (int128_t)a[ 2] * a[ 6] + + 2 * (int128_t)a[ 3] * a[ 5] + + (int128_t)a[ 4] * a[ 4]; + int128_t t9 = 2 * (int128_t)a[ 2] * a[ 7] + + 2 * (int128_t)a[ 3] * a[ 6] + + 2 * (int128_t)a[ 4] * a[ 5]; + int128_t t10 = 2 * (int128_t)a[ 3] * a[ 7] + + 2 * (int128_t)a[ 4] * a[ 6] + + (int128_t)a[ 5] * a[ 5]; + int128_t t11 = 2 * (int128_t)a[ 4] * a[ 7] + + 2 * (int128_t)a[ 5] * a[ 6]; + int128_t t12 = 2 * (int128_t)a[ 5] * a[ 7] + + (int128_t)a[ 6] * a[ 6]; + int128_t t13 = 2 * (int128_t)a[ 6] * a[ 7]; + int128_t t14 = (int128_t)a[ 7] * a[ 7]; + + /* Reduce */ + int128_t tr0 = t0 + t8 + t12; + int128_t tr1 = t1 + t9 + t13; + int128_t tr2 = t2 + t10 + t14; + int128_t tr3 = t3 + t11; + int128_t tr4 = t4 + t12 + t8 + t12; + int128_t tr5 = t5 + t13 + t9 + t13; + int128_t tr6 = t6 + t14 + t10 + t14; + int128_t tr7 = t7 + t11; + o = tr7 >> 56; tr0 += o; + tr4 += o; tr7 -= (int128_t)o << 56; + o = tr0 >> 56; tr1 += o; tr0 -= (int128_t)o << 56; + o = tr1 >> 56; tr2 += o; tr1 -= (int128_t)o << 56; + o = tr2 >> 56; tr3 += o; tr2 -= (int128_t)o << 56; + o = tr3 >> 56; tr4 += o; tr3 -= (int128_t)o << 56; + o = tr4 >> 56; tr5 += o; tr4 -= (int128_t)o << 56; + o = tr5 >> 56; tr6 += o; tr5 -= (int128_t)o << 56; + o = tr6 >> 56; tr7 += o; tr6 -= (int128_t)o << 56; + o = tr7 >> 56; tr0 += o; + tr4 += o; tr7 -= (int128_t)o << 56; + + /* Store */ + r[0] = tr0; + r[1] = tr1; + r[2] = tr2; + r[3] = tr3; + r[4] = tr4; + r[5] = tr5; + r[6] = tr6; + r[7] = tr7; +} + +/* Invert the field element. (r * a) mod (2^448 - 2^224 - 1) = 1 + * Constant time implementation - using Fermat's little theorem: + * a^(p-1) mod p = 1 => a^(p-2) mod p = 1/a + * For curve448: p - 2 = 2^448 - 2^224 - 3 + * + * r [in] Field element to hold result. + * a [in] Field element to invert. + */ +void fe448_invert(int64_t* r, const int64_t* a) +{ + int64_t t1[8]; + int64_t t2[8]; + int64_t t3[8]; + int64_t t4[8]; + int i; + + fe448_sqr(t1, a); + /* t1 = 2 */ + fe448_mul(t1, t1, a); + /* t1 = 3 */ + fe448_sqr(t2, t1); for (i = 1; i < 2; ++i) fe448_sqr(t2, t2); + /* t2 = c */ + fe448_mul(t3, t2, a); + /* t3 = d */ + fe448_mul(t1, t2, t1); + /* t1 = f */ + fe448_sqr(t2, t1); + /* t2 = 1e */ + fe448_mul(t4, t2, a); + /* t4 = 1f */ + fe448_sqr(t2, t4); for (i = 1; i < 5; ++i) fe448_sqr(t2, t2); + /* t2 = 3e0 */ + fe448_mul(t1, t2, t4); + /* t1 = 3ff */ + fe448_sqr(t2, t1); for (i = 1; i < 10; ++i) fe448_sqr(t2, t2); + /* t2 = ffc00 */ + fe448_mul(t1, t2, t1); + /* t1 = fffff */ + fe448_sqr(t2, t1); for (i = 1; i < 5; ++i) fe448_sqr(t2, t2); + /* t2 = 1ffffe0 */ + fe448_mul(t1, t2, t4); + /* t1 = 1ffffff */ + fe448_sqr(t2, t1); for (i = 1; i < 25; ++i) fe448_sqr(t2, t2); + /* t2 = 3fffffe000000 */ + fe448_mul(t1, t2, t1); + /* t1 = 3ffffffffffff */ + fe448_sqr(t2, t1); for (i = 1; i < 5; ++i) fe448_sqr(t2, t2); + /* t2 = 7fffffffffffe0 */ + fe448_mul(t1, t2, t4); + /* t1 = 7fffffffffffff */ + fe448_sqr(t2, t1); for (i = 1; i < 55; ++i) fe448_sqr(t2, t2); + /* t2 = 3fffffffffffff80000000000000 */ + fe448_mul(t1, t2, t1); + /* t1 = 3fffffffffffffffffffffffffff */ + fe448_sqr(t2, t1); for (i = 1; i < 110; ++i) fe448_sqr(t2, t2); + /* t2 = fffffffffffffffffffffffffffc000000000000000000000000000 */ + fe448_mul(t1, t2, t1); + /* t1 = fffffffffffffffffffffffffffffffffffffffffffffffffffffff */ + fe448_sqr(t2, t1); for (i = 1; i < 4; ++i) fe448_sqr(t2, t2); + /* t2 = fffffffffffffffffffffffffffffffffffffffffffffffffffffff0 */ + fe448_mul(t3, t3, t2); + /* t3 = fffffffffffffffffffffffffffffffffffffffffffffffffffffffd */ + fe448_mul(t1, t3, a); + /* t1 = fffffffffffffffffffffffffffffffffffffffffffffffffffffffe */ + fe448_sqr(t1, t1); for (i = 1; i < 224; ++i) fe448_sqr(t1, t1); + /* t1 = fffffffffffffffffffffffffffffffffffffffffffffffffffffffe00000000000000000000000000000000000000000000000000000000 */ + fe448_mul(r, t3, t1); + /* r = fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffd */ +} + +/* Scalar multiply the point by a number. r = n.a + * Uses Montogmery ladder and only requires the x-ordinate. + * + * r [in] Field element to hold result. + * n [in] Scalar as an array of bytes. + * a [in] Point to multiply - x-ordinate only. + */ +int curve448(byte* r, const byte* n, const byte* a) +{ + int64_t x1[8]; + int64_t x2[8]; + int64_t z2[8]; + int64_t x3[8]; + int64_t z3[8]; + int64_t t0[8]; + int64_t t1[8]; + int i; + unsigned int swap; + unsigned int b; + + fe448_from_bytes(x1, a); + fe448_1(x2); + fe448_0(z2); + fe448_copy(x3, x1); + fe448_1(z3); + + swap = 0; + for (i = 447; i >= 0; --i) { + b = (n[i >> 3] >> (i & 7)) & 1; + swap ^= b; + fe448_cswap(x2, x3, swap); + fe448_cswap(z2, z3, swap); + swap = b; + + /* Montgomery Ladder - double and add */ + fe448_add(t0, x2, z2); + fe448_reduce(t0); + fe448_add(t1, x3, z3); + fe448_reduce(t1); + fe448_sub(x2, x2, z2); + fe448_sub(x3, x3, z3); + fe448_mul(t1, t1, x2); + fe448_mul(z3, x3, t0); + fe448_sqr(t0, t0); + fe448_sqr(x2, x2); + fe448_add(x3, z3, t1); + fe448_reduce(x3); + fe448_sqr(x3, x3); + fe448_sub(z3, z3, t1); + fe448_sqr(z3, z3); + fe448_mul(z3, z3, x1); + fe448_sub(t1, t0, x2); + fe448_mul(x2, t0, x2); + fe448_mul39081(z2, t1); + fe448_add(z2, t0, z2); + fe448_mul(z2, z2, t1); + } + /* Last two bits are 0 - no final swap check required. */ + + fe448_invert(z2, z2); + fe448_mul(x2, x2, z2); + fe448_to_bytes(r, x2); + + return 0; +} + +#ifdef HAVE_ED448 +/* Check whether field element is not 0. + * Must convert to a normalized form before checking. + * + * a [in] Field element. + * returns 0 when zero, and any other value otherwise. + */ +int fe448_isnonzero(const int64_t* a) +{ + uint8_t b[56]; + int i; + uint8_t c = 0; + fe448_to_bytes(b, a); + for (i = 0; i < 56; i++) + c |= b[i]; + return c; +} + +/* Check whether field element is negative. + * Must convert to a normalized form before checking. + * + * a [in] Field element. + * returns 1 when negative, and 0 otherwise. + */ +int fe448_isnegative(const int64_t* a) +{ + uint8_t b[56]; + fe448_to_bytes(b, a); + return b[0] & 1; +} + +/* Negates the field element. r = -a + * + * r [in] Field element to hold result. + * a [in] Field element. + */ +void fe448_neg(int64_t* r, const int64_t* a) +{ + r[0] = -a[0]; + r[1] = -a[1]; + r[2] = -a[2]; + r[3] = -a[3]; + r[4] = -a[4]; + r[5] = -a[5]; + r[6] = -a[6]; + r[7] = -a[7]; +} + +/* Raise field element to (p-3) / 4: 2^446 - 2^222 - 1 + * Used for calcualting y-ordinate from x-ordinate for Ed448. + * + * r [in] Field element to hold result. + * a [in] Field element to exponentiate. + */ +void fe448_pow_2_446_222_1(int64_t* r, const int64_t* a) +{ + int64_t t1[8]; + int64_t t2[8]; + int64_t t3[8]; + int64_t t4[8]; + int64_t t5[8]; + int i; + + fe448_sqr(t3, a); + /* t3 = 2 */ + fe448_mul(t1, t3, a); + /* t1 = 3 */ + fe448_sqr(t5, t1); + /* t5 = 6 */ + fe448_mul(t5, t5, a); + /* t5 = 7 */ + fe448_sqr(t2, t1); for (i = 1; i < 2; ++i) fe448_sqr(t2, t2); + /* t2 = c */ + fe448_mul(t3, t2, t3); + /* t3 = e */ + fe448_mul(t1, t2, t1); + /* t1 = f */ + fe448_sqr(t2, t1); for (i = 1; i < 3; ++i) fe448_sqr(t2, t2); + /* t2 = 78 */ + fe448_mul(t5, t2, t5); + /* t5 = 7f */ + fe448_sqr(t2, t1); for (i = 1; i < 4; ++i) fe448_sqr(t2, t2); + /* t2 = f0 */ + fe448_mul(t1, t2, t1); + /* t1 = ff */ + fe448_mul(t3, t3, t2); + /* t3 = fe */ + fe448_sqr(t2, t1); for (i = 1; i < 7; ++i) fe448_sqr(t2, t2); + /* t2 = 7f80 */ + fe448_mul(t5, t2, t5); + /* t5 = 7fff */ + fe448_sqr(t2, t1); for (i = 1; i < 8; ++i) fe448_sqr(t2, t2); + /* t2 = ff00 */ + fe448_mul(t1, t2, t1); + /* t1 = ffff */ + fe448_mul(t3, t3, t2); + /* t3 = fffe */ + fe448_sqr(t2, t5); for (i = 1; i < 15; ++i) fe448_sqr(t2, t2); + /* t2 = 3fff8000 */ + fe448_mul(t5, t2, t5); + /* t5 = 3fffffff */ + fe448_sqr(t2, t1); for (i = 1; i < 16; ++i) fe448_sqr(t2, t2); + /* t2 = ffff0000 */ + fe448_mul(t1, t2, t1); + /* t1 = ffffffff */ + fe448_mul(t3, t3, t2); + /* t3 = fffffffe */ + fe448_sqr(t2, t1); for (i = 1; i < 32; ++i) fe448_sqr(t2, t2); + /* t2 = ffffffff00000000 */ + fe448_mul(t2, t2, t1); + /* t2 = ffffffffffffffff */ + fe448_sqr(t1, t2); for (i = 1; i < 64; ++i) fe448_sqr(t1, t1); + /* t1 = ffffffffffffffff0000000000000000 */ + fe448_mul(t1, t1, t2); + /* t1 = ffffffffffffffffffffffffffffffff */ + fe448_sqr(t1, t1); for (i = 1; i < 64; ++i) fe448_sqr(t1, t1); + /* t1 = ffffffffffffffffffffffffffffffff0000000000000000 */ + fe448_mul(t4, t1, t2); + /* t4 = ffffffffffffffffffffffffffffffffffffffffffffffff */ + fe448_sqr(t2, t4); for (i = 1; i < 32; ++i) fe448_sqr(t2, t2); + /* t2 = ffffffffffffffffffffffffffffffffffffffffffffffff00000000 */ + fe448_mul(t3, t3, t2); + /* t3 = fffffffffffffffffffffffffffffffffffffffffffffffffffffffe */ + fe448_sqr(t1, t3); for (i = 1; i < 192; ++i) fe448_sqr(t1, t1); + /* t1 = fffffffffffffffffffffffffffffffffffffffffffffffffffffffe000000000000000000000000000000000000000000000000 */ + fe448_mul(t1, t1, t4); + /* t1 = fffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff */ + fe448_sqr(t1, t1); for (i = 1; i < 30; ++i) fe448_sqr(t1, t1); + /* t1 = 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffc0000000 */ + fe448_mul(r, t5, t1); + /* r = 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffff */ +} + +/* Constant time, conditional move of b into a. + * a is not changed if the condition is 0. + * + * a A field element. + * b A field element. + * c If 1 then copy and if 0 then don't copy. + */ +void fe448_cmov(int64_t* a, const int64_t* b, int c) +{ + int64_t m = -(int64_t)c; + int64_t t0 = m & (a[0] ^ b[0]); + int64_t t1 = m & (a[1] ^ b[1]); + int64_t t2 = m & (a[2] ^ b[2]); + int64_t t3 = m & (a[3] ^ b[3]); + int64_t t4 = m & (a[4] ^ b[4]); + int64_t t5 = m & (a[5] ^ b[5]); + int64_t t6 = m & (a[6] ^ b[6]); + int64_t t7 = m & (a[7] ^ b[7]); + + a[0] ^= t0; + a[1] ^= t1; + a[2] ^= t2; + a[3] ^= t3; + a[4] ^= t4; + a[5] ^= t5; + a[6] ^= t6; + a[7] ^= t7; +} + +#endif /* HAVE_ED448 */ +#else + +/* Initialize the field element operations. + */ +void fe448_init(void) +{ +} + +/* Convert the field element from a byte array to an array of 28-bits. + * + * r [in] Array to encode into. + * b [in] Byte array. + */ +void fe448_from_bytes(int32_t* r, const unsigned char* b) +{ + r[ 0] = (((int32_t)((b[ 0] ) >> 0)) << 0) + | (((int32_t)((b[ 1] ) >> 0)) << 8) + | (((int32_t)((b[ 2] ) >> 0)) << 16) + | ((((int32_t)((b[ 3] & 0xf )) >> 0)) << 24); + r[ 1] = (((int32_t)((b[ 3] ) >> 4)) << 0) + | (((int32_t)((b[ 4] ) >> 0)) << 4) + | (((int32_t)((b[ 5] ) >> 0)) << 12) + | (((int32_t)((b[ 6] ) >> 0)) << 20); + r[ 2] = (((int32_t)((b[ 7] ) >> 0)) << 0) + | (((int32_t)((b[ 8] ) >> 0)) << 8) + | (((int32_t)((b[ 9] ) >> 0)) << 16) + | ((((int32_t)((b[10] & 0xf )) >> 0)) << 24); + r[ 3] = (((int32_t)((b[10] ) >> 4)) << 0) + | (((int32_t)((b[11] ) >> 0)) << 4) + | (((int32_t)((b[12] ) >> 0)) << 12) + | (((int32_t)((b[13] ) >> 0)) << 20); + r[ 4] = (((int32_t)((b[14] ) >> 0)) << 0) + | (((int32_t)((b[15] ) >> 0)) << 8) + | (((int32_t)((b[16] ) >> 0)) << 16) + | ((((int32_t)((b[17] & 0xf )) >> 0)) << 24); + r[ 5] = (((int32_t)((b[17] ) >> 4)) << 0) + | (((int32_t)((b[18] ) >> 0)) << 4) + | (((int32_t)((b[19] ) >> 0)) << 12) + | (((int32_t)((b[20] ) >> 0)) << 20); + r[ 6] = (((int32_t)((b[21] ) >> 0)) << 0) + | (((int32_t)((b[22] ) >> 0)) << 8) + | (((int32_t)((b[23] ) >> 0)) << 16) + | ((((int32_t)((b[24] & 0xf )) >> 0)) << 24); + r[ 7] = (((int32_t)((b[24] ) >> 4)) << 0) + | (((int32_t)((b[25] ) >> 0)) << 4) + | (((int32_t)((b[26] ) >> 0)) << 12) + | (((int32_t)((b[27] ) >> 0)) << 20); + r[ 8] = (((int32_t)((b[28] ) >> 0)) << 0) + | (((int32_t)((b[29] ) >> 0)) << 8) + | (((int32_t)((b[30] ) >> 0)) << 16) + | ((((int32_t)((b[31] & 0xf )) >> 0)) << 24); + r[ 9] = (((int32_t)((b[31] ) >> 4)) << 0) + | (((int32_t)((b[32] ) >> 0)) << 4) + | (((int32_t)((b[33] ) >> 0)) << 12) + | (((int32_t)((b[34] ) >> 0)) << 20); + r[10] = (((int32_t)((b[35] ) >> 0)) << 0) + | (((int32_t)((b[36] ) >> 0)) << 8) + | (((int32_t)((b[37] ) >> 0)) << 16) + | ((((int32_t)((b[38] & 0xf )) >> 0)) << 24); + r[11] = (((int32_t)((b[38] ) >> 4)) << 0) + | (((int32_t)((b[39] ) >> 0)) << 4) + | (((int32_t)((b[40] ) >> 0)) << 12) + | (((int32_t)((b[41] ) >> 0)) << 20); + r[12] = (((int32_t)((b[42] ) >> 0)) << 0) + | (((int32_t)((b[43] ) >> 0)) << 8) + | (((int32_t)((b[44] ) >> 0)) << 16) + | ((((int32_t)((b[45] & 0xf )) >> 0)) << 24); + r[13] = (((int32_t)((b[45] ) >> 4)) << 0) + | (((int32_t)((b[46] ) >> 0)) << 4) + | (((int32_t)((b[47] ) >> 0)) << 12) + | (((int32_t)((b[48] ) >> 0)) << 20); + r[14] = (((int32_t)((b[49] ) >> 0)) << 0) + | (((int32_t)((b[50] ) >> 0)) << 8) + | (((int32_t)((b[51] ) >> 0)) << 16) + | ((((int32_t)((b[52] & 0xf )) >> 0)) << 24); + r[15] = (((int32_t)((b[52] ) >> 4)) << 0) + | (((int32_t)((b[53] ) >> 0)) << 4) + | (((int32_t)((b[54] ) >> 0)) << 12) + | (((int32_t)((b[55] ) >> 0)) << 20); +} + +/* Convert the field element to a byte array from an array of 28-bits. + * + * b [in] Byte array. + * a [in] Array to encode into. + */ +void fe448_to_bytes(unsigned char* b, const int32_t* a) +{ + /* Mod */ + int32_t in0 = a[0]; + int32_t in1 = a[1]; + int32_t in2 = a[2]; + int32_t in3 = a[3]; + int32_t in4 = a[4]; + int32_t in5 = a[5]; + int32_t in6 = a[6]; + int32_t in7 = a[7]; + int32_t in8 = a[8]; + int32_t in9 = a[9]; + int32_t in10 = a[10]; + int32_t in11 = a[11]; + int32_t in12 = a[12]; + int32_t in13 = a[13]; + int32_t in14 = a[14]; + int32_t in15 = a[15]; + int32_t o = in15 >> 28; + in15 -= o << 28; + in0 += o; + in8 += o; + o = (in0 + 1) >> 28; + o = (o + in1) >> 28; + o = (o + in2) >> 28; + o = (o + in3) >> 28; + o = (o + in4) >> 28; + o = (o + in5) >> 28; + o = (o + in6) >> 28; + o = (o + in7) >> 28; + o = (o + in8 + 1) >> 28; + o = (o + in9) >> 28; + o = (o + in10) >> 28; + o = (o + in11) >> 28; + o = (o + in12) >> 28; + o = (o + in13) >> 28; + o = (o + in14) >> 28; + o = (o + in15) >> 28; + in0 += o; + in8 += o; + in15 -= o << 28; + o = in0 >> 28; in1 += o; in0 -= o << 28; + o = in1 >> 28; in2 += o; in1 -= o << 28; + o = in2 >> 28; in3 += o; in2 -= o << 28; + o = in3 >> 28; in4 += o; in3 -= o << 28; + o = in4 >> 28; in5 += o; in4 -= o << 28; + o = in5 >> 28; in6 += o; in5 -= o << 28; + o = in6 >> 28; in7 += o; in6 -= o << 28; + o = in7 >> 28; in8 += o; in7 -= o << 28; + o = in8 >> 28; in9 += o; in8 -= o << 28; + o = in9 >> 28; in10 += o; in9 -= o << 28; + o = in10 >> 28; in11 += o; in10 -= o << 28; + o = in11 >> 28; in12 += o; in11 -= o << 28; + o = in12 >> 28; in13 += o; in12 -= o << 28; + o = in13 >> 28; in14 += o; in13 -= o << 28; + o = in14 >> 28; in15 += o; in14 -= o << 28; + o = in15 >> 28; in0 += o; + in8 += o; in15 -= o << 28; + + /* Output as bytes */ + b[ 0] = (in0 >> 0); + b[ 1] = (in0 >> 8); + b[ 2] = (in0 >> 16); + b[ 3] = (in0 >> 24) + ((in1 >> 0) << 4); + b[ 4] = (in1 >> 4); + b[ 5] = (in1 >> 12); + b[ 6] = (in1 >> 20); + b[ 7] = (in2 >> 0); + b[ 8] = (in2 >> 8); + b[ 9] = (in2 >> 16); + b[10] = (in2 >> 24) + ((in3 >> 0) << 4); + b[11] = (in3 >> 4); + b[12] = (in3 >> 12); + b[13] = (in3 >> 20); + b[14] = (in4 >> 0); + b[15] = (in4 >> 8); + b[16] = (in4 >> 16); + b[17] = (in4 >> 24) + ((in5 >> 0) << 4); + b[18] = (in5 >> 4); + b[19] = (in5 >> 12); + b[20] = (in5 >> 20); + b[21] = (in6 >> 0); + b[22] = (in6 >> 8); + b[23] = (in6 >> 16); + b[24] = (in6 >> 24) + ((in7 >> 0) << 4); + b[25] = (in7 >> 4); + b[26] = (in7 >> 12); + b[27] = (in7 >> 20); + b[28] = (in8 >> 0); + b[29] = (in8 >> 8); + b[30] = (in8 >> 16); + b[31] = (in8 >> 24) + ((in9 >> 0) << 4); + b[32] = (in9 >> 4); + b[33] = (in9 >> 12); + b[34] = (in9 >> 20); + b[35] = (in10 >> 0); + b[36] = (in10 >> 8); + b[37] = (in10 >> 16); + b[38] = (in10 >> 24) + ((in11 >> 0) << 4); + b[39] = (in11 >> 4); + b[40] = (in11 >> 12); + b[41] = (in11 >> 20); + b[42] = (in12 >> 0); + b[43] = (in12 >> 8); + b[44] = (in12 >> 16); + b[45] = (in12 >> 24) + ((in13 >> 0) << 4); + b[46] = (in13 >> 4); + b[47] = (in13 >> 12); + b[48] = (in13 >> 20); + b[49] = (in14 >> 0); + b[50] = (in14 >> 8); + b[51] = (in14 >> 16); + b[52] = (in14 >> 24) + ((in15 >> 0) << 4); + b[53] = (in15 >> 4); + b[54] = (in15 >> 12); + b[55] = (in15 >> 20); +} + +/* Set the field element to 0. + * + * a [in] Field element. + */ +void fe448_1(int32_t* a) +{ + a[0] = 1; + a[1] = 0; + a[2] = 0; + a[3] = 0; + a[4] = 0; + a[5] = 0; + a[6] = 0; + a[7] = 0; + a[8] = 0; + a[9] = 0; + a[10] = 0; + a[11] = 0; + a[12] = 0; + a[13] = 0; + a[14] = 0; + a[15] = 0; +} + +/* Set the field element to 0. + * + * a [in] Field element. + */ +void fe448_0(int32_t* a) +{ + a[0] = 0; + a[1] = 0; + a[2] = 0; + a[3] = 0; + a[4] = 0; + a[5] = 0; + a[6] = 0; + a[7] = 0; + a[8] = 0; + a[9] = 0; + a[10] = 0; + a[11] = 0; + a[12] = 0; + a[13] = 0; + a[14] = 0; + a[15] = 0; +} + +/* Copy one field element into another: d = a. + * + * d [in] Destination field element. + * a [in] Source field element. + */ +void fe448_copy(int32_t* d, const int32_t* a) +{ + d[0] = a[0]; + d[1] = a[1]; + d[2] = a[2]; + d[3] = a[3]; + d[4] = a[4]; + d[5] = a[5]; + d[6] = a[6]; + d[7] = a[7]; + d[8] = a[8]; + d[9] = a[9]; + d[10] = a[10]; + d[11] = a[11]; + d[12] = a[12]; + d[13] = a[13]; + d[14] = a[14]; + d[15] = a[15]; +} + +/* Conditionally swap the elements. + * Constant time implementation. + * + * a [in] First field element. + * b [in] Second field element. + * c [in] Swap when 1. Valid values: 0, 1. + */ +static void fe448_cswap(int32_t* a, int32_t* b, int c) +{ + int32_t mask = -(int32_t)c; + int32_t t0 = (a[0] ^ b[0]) & mask; + int32_t t1 = (a[1] ^ b[1]) & mask; + int32_t t2 = (a[2] ^ b[2]) & mask; + int32_t t3 = (a[3] ^ b[3]) & mask; + int32_t t4 = (a[4] ^ b[4]) & mask; + int32_t t5 = (a[5] ^ b[5]) & mask; + int32_t t6 = (a[6] ^ b[6]) & mask; + int32_t t7 = (a[7] ^ b[7]) & mask; + int32_t t8 = (a[8] ^ b[8]) & mask; + int32_t t9 = (a[9] ^ b[9]) & mask; + int32_t t10 = (a[10] ^ b[10]) & mask; + int32_t t11 = (a[11] ^ b[11]) & mask; + int32_t t12 = (a[12] ^ b[12]) & mask; + int32_t t13 = (a[13] ^ b[13]) & mask; + int32_t t14 = (a[14] ^ b[14]) & mask; + int32_t t15 = (a[15] ^ b[15]) & mask; + a[0] ^= t0; + a[1] ^= t1; + a[2] ^= t2; + a[3] ^= t3; + a[4] ^= t4; + a[5] ^= t5; + a[6] ^= t6; + a[7] ^= t7; + a[8] ^= t8; + a[9] ^= t9; + a[10] ^= t10; + a[11] ^= t11; + a[12] ^= t12; + a[13] ^= t13; + a[14] ^= t14; + a[15] ^= t15; + b[0] ^= t0; + b[1] ^= t1; + b[2] ^= t2; + b[3] ^= t3; + b[4] ^= t4; + b[5] ^= t5; + b[6] ^= t6; + b[7] ^= t7; + b[8] ^= t8; + b[9] ^= t9; + b[10] ^= t10; + b[11] ^= t11; + b[12] ^= t12; + b[13] ^= t13; + b[14] ^= t14; + b[15] ^= t15; +} + +/* Add two field elements. r = (a + b) mod (2^448 - 2^224 - 1) + * + * r [in] Field element to hold sum. + * a [in] Field element to add. + * b [in] Field element to add. + */ +void fe448_add(int32_t* r, const int32_t* a, const int32_t* 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]; + r[15] = a[15] + b[15]; +} + +/* Subtract a field element from another. r = (a - b) mod (2^448 - 2^224 - 1) + * + * r [in] Field element to hold difference. + * a [in] Field element to subtract from. + * b [in] Field element to subtract. + */ +void fe448_sub(int32_t* r, const int32_t* a, const int32_t* 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]; + r[15] = a[15] - b[15]; +} + +void fe448_reduce(int32_t* a) +{ + int64_t o; + + o = a[0 ] >> 28; a[1 ] += o; a[0 ] -= o << 28; + o = a[1 ] >> 28; a[2 ] += o; a[1 ] -= o << 28; + o = a[2 ] >> 28; a[3 ] += o; a[2 ] -= o << 28; + o = a[3 ] >> 28; a[4 ] += o; a[3 ] -= o << 28; + o = a[4 ] >> 28; a[5 ] += o; a[4 ] -= o << 28; + o = a[5 ] >> 28; a[6 ] += o; a[5 ] -= o << 28; + o = a[6 ] >> 28; a[7 ] += o; a[6 ] -= o << 28; + o = a[7 ] >> 28; a[8 ] += o; a[7 ] -= o << 28; + o = a[8 ] >> 28; a[9 ] += o; a[8 ] -= o << 28; + o = a[9 ] >> 28; a[10] += o; a[9 ] -= o << 28; + o = a[10] >> 28; a[11] += o; a[10] -= o << 28; + o = a[11] >> 28; a[12] += o; a[11] -= o << 28; + o = a[12] >> 28; a[13] += o; a[12] -= o << 28; + o = a[13] >> 28; a[14] += o; a[13] -= o << 28; + o = a[14] >> 28; a[15] += o; a[14] -= o << 28; + o = a[15] >> 28; a[0] += o; + a[8] += o; a[15] -= o << 28; +} +/* Mulitply a field element by 39081. r = (39081 * a) mod (2^448 - 2^224 - 1) + * + * r [in] Field element to hold result. + * a [in] Field element to multiply. + */ +void fe448_mul39081(int32_t* r, const int32_t* a) +{ + int32_t o; + int64_t t0 = a[0] * (int64_t)39081; + int64_t t1 = a[1] * (int64_t)39081; + int64_t t2 = a[2] * (int64_t)39081; + int64_t t3 = a[3] * (int64_t)39081; + int64_t t4 = a[4] * (int64_t)39081; + int64_t t5 = a[5] * (int64_t)39081; + int64_t t6 = a[6] * (int64_t)39081; + int64_t t7 = a[7] * (int64_t)39081; + int64_t t8 = a[8] * (int64_t)39081; + int64_t t9 = a[9] * (int64_t)39081; + int64_t t10 = a[10] * (int64_t)39081; + int64_t t11 = a[11] * (int64_t)39081; + int64_t t12 = a[12] * (int64_t)39081; + int64_t t13 = a[13] * (int64_t)39081; + int64_t t14 = a[14] * (int64_t)39081; + int64_t t15 = a[15] * (int64_t)39081; + o = t0 >> 28; t1 += o; t0 -= (int64_t)o << 28; + o = t1 >> 28; t2 += o; t1 -= (int64_t)o << 28; + o = t2 >> 28; t3 += o; t2 -= (int64_t)o << 28; + o = t3 >> 28; t4 += o; t3 -= (int64_t)o << 28; + o = t4 >> 28; t5 += o; t4 -= (int64_t)o << 28; + o = t5 >> 28; t6 += o; t5 -= (int64_t)o << 28; + o = t6 >> 28; t7 += o; t6 -= (int64_t)o << 28; + o = t7 >> 28; t8 += o; t7 -= (int64_t)o << 28; + o = t8 >> 28; t9 += o; t8 -= (int64_t)o << 28; + o = t9 >> 28; t10 += o; t9 -= (int64_t)o << 28; + o = t10 >> 28; t11 += o; t10 -= (int64_t)o << 28; + o = t11 >> 28; t12 += o; t11 -= (int64_t)o << 28; + o = t12 >> 28; t13 += o; t12 -= (int64_t)o << 28; + o = t13 >> 28; t14 += o; t13 -= (int64_t)o << 28; + o = t14 >> 28; t15 += o; t14 -= (int64_t)o << 28; + o = t15 >> 28; t0 += o; + t8 += o; t15 -= (int64_t)o << 28; + + /* Store */ + r[0] = t0; + r[1] = t1; + r[2] = t2; + r[3] = t3; + r[4] = t4; + r[5] = t5; + r[6] = t6; + r[7] = t7; + r[8] = t8; + r[9] = t9; + r[10] = t10; + r[11] = t11; + r[12] = t12; + r[13] = t13; + r[14] = t14; + r[15] = t15; +} + +/* Mulitply two field elements. r = a * b + * + * r [in] Field element to hold result. + * a [in] Field element to multiply. + * b [in] Field element to multiply. + */ +static WC_INLINE void fe448_mul_8(int32_t* r, const int32_t* a, const int32_t* 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[ 0] * b[ 7] + + (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)a[ 7] * b[ 0]; + int64_t t8 = (int64_t)a[ 1] * b[ 7] + + (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)a[ 7] * b[ 1]; + int64_t t9 = (int64_t)a[ 2] * b[ 7] + + (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)a[ 7] * b[ 2]; + int64_t t10 = (int64_t)a[ 3] * b[ 7] + + (int64_t)a[ 4] * b[ 6] + + (int64_t)a[ 5] * b[ 5] + + (int64_t)a[ 6] * b[ 4] + + (int64_t)a[ 7] * b[ 3]; + int64_t t11 = (int64_t)a[ 4] * b[ 7] + + (int64_t)a[ 5] * b[ 6] + + (int64_t)a[ 6] * b[ 5] + + (int64_t)a[ 7] * b[ 4]; + int64_t t12 = (int64_t)a[ 5] * b[ 7] + + (int64_t)a[ 6] * b[ 6] + + (int64_t)a[ 7] * b[ 5]; + int64_t t13 = (int64_t)a[ 6] * b[ 7] + + (int64_t)a[ 7] * b[ 6]; + int64_t t14 = (int64_t)a[ 7] * b[ 7]; + int64_t o = t14 >> 28; + int64_t t15 = o; + t14 -= o << 28; + o = t0 >> 28; t1 += o; t0 -= (int64_t)o << 28; + o = t1 >> 28; t2 += o; t1 -= (int64_t)o << 28; + o = t2 >> 28; t3 += o; t2 -= (int64_t)o << 28; + o = t3 >> 28; t4 += o; t3 -= (int64_t)o << 28; + o = t4 >> 28; t5 += o; t4 -= (int64_t)o << 28; + o = t5 >> 28; t6 += o; t5 -= (int64_t)o << 28; + o = t6 >> 28; t7 += o; t6 -= (int64_t)o << 28; + o = t7 >> 28; t8 += o; t7 -= (int64_t)o << 28; + o = t8 >> 28; t9 += o; t8 -= (int64_t)o << 28; + o = t9 >> 28; t10 += o; t9 -= (int64_t)o << 28; + o = t10 >> 28; t11 += o; t10 -= (int64_t)o << 28; + o = t11 >> 28; t12 += o; t11 -= (int64_t)o << 28; + o = t12 >> 28; t13 += o; t12 -= (int64_t)o << 28; + o = t13 >> 28; t14 += o; t13 -= (int64_t)o << 28; + o = t14 >> 28; t15 += o; t14 -= (int64_t)o << 28; + o = t15 >> 28; t0 += o; + t8 += o; t15 -= (int64_t)o << 28; + + /* Store */ + r[0] = t0; + r[1] = t1; + r[2] = t2; + r[3] = t3; + r[4] = t4; + r[5] = t5; + r[6] = t6; + r[7] = t7; + r[8] = t8; + r[9] = t9; + r[10] = t10; + r[11] = t11; + r[12] = t12; + r[13] = t13; + r[14] = t14; + r[15] = t15; +} + +/* Mulitply two field elements. r = (a * b) mod (2^448 - 2^224 - 1) + * + * r [in] Field element to hold result. + * a [in] Field element to multiply. + * b [in] Field element to multiply. + */ +void fe448_mul(int32_t* r, const int32_t* a, const int32_t* b) +{ + int32_t r0[16]; + int32_t r1[16]; + int32_t* a1 = r1; + int32_t b1[8]; + int32_t r2[16]; + a1[0] = a[0] + a[8]; + a1[1] = a[1] + a[9]; + a1[2] = a[2] + a[10]; + a1[3] = a[3] + a[11]; + a1[4] = a[4] + a[12]; + a1[5] = a[5] + a[13]; + a1[6] = a[6] + a[14]; + a1[7] = a[7] + a[15]; + b1[0] = b[0] + b[8]; + b1[1] = b[1] + b[9]; + b1[2] = b[2] + b[10]; + b1[3] = b[3] + b[11]; + b1[4] = b[4] + b[12]; + b1[5] = b[5] + b[13]; + b1[6] = b[6] + b[14]; + b1[7] = b[7] + b[15]; + fe448_mul_8(r2, a + 8, b + 8); + fe448_mul_8(r0, a, b); + fe448_mul_8(r1, a1, b1); + r[ 0] = r0[ 0] + r2[ 0] + r1[ 8] - r0[ 8]; + r[ 1] = r0[ 1] + r2[ 1] + r1[ 9] - r0[ 9]; + r[ 2] = r0[ 2] + r2[ 2] + r1[10] - r0[10]; + r[ 3] = r0[ 3] + r2[ 3] + r1[11] - r0[11]; + r[ 4] = r0[ 4] + r2[ 4] + r1[12] - r0[12]; + r[ 5] = r0[ 5] + r2[ 5] + r1[13] - r0[13]; + r[ 6] = r0[ 6] + r2[ 6] + r1[14] - r0[14]; + r[ 7] = r0[ 7] + r2[ 7] + r1[15] - r0[15]; + r[ 8] = r2[ 8] + r1[ 0] - r0[ 0] + r1[ 8]; + r[ 9] = r2[ 9] + r1[ 1] - r0[ 1] + r1[ 9]; + r[10] = r2[10] + r1[ 2] - r0[ 2] + r1[10]; + r[11] = r2[11] + r1[ 3] - r0[ 3] + r1[11]; + r[12] = r2[12] + r1[ 4] - r0[ 4] + r1[12]; + r[13] = r2[13] + r1[ 5] - r0[ 5] + r1[13]; + r[14] = r2[14] + r1[ 6] - r0[ 6] + r1[14]; + r[15] = r2[15] + r1[ 7] - r0[ 7] + r1[15]; +} + +/* Square a field element. r = a * a + * + * r [in] Field element to hold result. + * a [in] Field element to square. + */ +static WC_INLINE void fe448_sqr_8(int32_t* r, const int32_t* a) +{ + int64_t t0 = (int64_t)a[ 0] * a[ 0]; + int64_t t1 = 2 * (int64_t)a[ 0] * a[ 1]; + int64_t t2 = 2 * (int64_t)a[ 0] * a[ 2] + + (int64_t)a[ 1] * a[ 1]; + int64_t t3 = 2 * (int64_t)a[ 0] * a[ 3] + + 2 * (int64_t)a[ 1] * a[ 2]; + int64_t t4 = 2 * (int64_t)a[ 0] * a[ 4] + + 2 * (int64_t)a[ 1] * a[ 3] + + (int64_t)a[ 2] * a[ 2]; + int64_t t5 = 2 * (int64_t)a[ 0] * a[ 5] + + 2 * (int64_t)a[ 1] * a[ 4] + + 2 * (int64_t)a[ 2] * a[ 3]; + int64_t t6 = 2 * (int64_t)a[ 0] * a[ 6] + + 2 * (int64_t)a[ 1] * a[ 5] + + 2 * (int64_t)a[ 2] * a[ 4] + + (int64_t)a[ 3] * a[ 3]; + int64_t t7 = 2 * (int64_t)a[ 0] * a[ 7] + + 2 * (int64_t)a[ 1] * a[ 6] + + 2 * (int64_t)a[ 2] * a[ 5] + + 2 * (int64_t)a[ 3] * a[ 4]; + int64_t t8 = 2 * (int64_t)a[ 1] * a[ 7] + + 2 * (int64_t)a[ 2] * a[ 6] + + 2 * (int64_t)a[ 3] * a[ 5] + + (int64_t)a[ 4] * a[ 4]; + int64_t t9 = 2 * (int64_t)a[ 2] * a[ 7] + + 2 * (int64_t)a[ 3] * a[ 6] + + 2 * (int64_t)a[ 4] * a[ 5]; + int64_t t10 = 2 * (int64_t)a[ 3] * a[ 7] + + 2 * (int64_t)a[ 4] * a[ 6] + + (int64_t)a[ 5] * a[ 5]; + int64_t t11 = 2 * (int64_t)a[ 4] * a[ 7] + + 2 * (int64_t)a[ 5] * a[ 6]; + int64_t t12 = 2 * (int64_t)a[ 5] * a[ 7] + + (int64_t)a[ 6] * a[ 6]; + int64_t t13 = 2 * (int64_t)a[ 6] * a[ 7]; + int64_t t14 = (int64_t)a[ 7] * a[ 7]; + int64_t o = t14 >> 28; + int64_t t15 = o; + t14 -= o << 28; + o = t0 >> 28; t1 += o; t0 -= (int64_t)o << 28; + o = t1 >> 28; t2 += o; t1 -= (int64_t)o << 28; + o = t2 >> 28; t3 += o; t2 -= (int64_t)o << 28; + o = t3 >> 28; t4 += o; t3 -= (int64_t)o << 28; + o = t4 >> 28; t5 += o; t4 -= (int64_t)o << 28; + o = t5 >> 28; t6 += o; t5 -= (int64_t)o << 28; + o = t6 >> 28; t7 += o; t6 -= (int64_t)o << 28; + o = t7 >> 28; t8 += o; t7 -= (int64_t)o << 28; + o = t8 >> 28; t9 += o; t8 -= (int64_t)o << 28; + o = t9 >> 28; t10 += o; t9 -= (int64_t)o << 28; + o = t10 >> 28; t11 += o; t10 -= (int64_t)o << 28; + o = t11 >> 28; t12 += o; t11 -= (int64_t)o << 28; + o = t12 >> 28; t13 += o; t12 -= (int64_t)o << 28; + o = t13 >> 28; t14 += o; t13 -= (int64_t)o << 28; + o = t14 >> 28; t15 += o; t14 -= (int64_t)o << 28; + o = t15 >> 28; t0 += o; + t8 += o; t15 -= (int64_t)o << 28; + + /* Store */ + r[0] = t0; + r[1] = t1; + r[2] = t2; + r[3] = t3; + r[4] = t4; + r[5] = t5; + r[6] = t6; + r[7] = t7; + r[8] = t8; + r[9] = t9; + r[10] = t10; + r[11] = t11; + r[12] = t12; + r[13] = t13; + r[14] = t14; + r[15] = t15; +} + +/* Square a field element. r = (a * a) mod (2^448 - 2^224 - 1) + * + * r [in] Field element to hold result. + * a [in] Field element to square. + */ +void fe448_sqr(int32_t* r, const int32_t* a) +{ + int32_t r0[16]; + int32_t r1[16]; + int32_t* a1 = r1; + int32_t r2[16]; + a1[0] = a[0] + a[8]; + a1[1] = a[1] + a[9]; + a1[2] = a[2] + a[10]; + a1[3] = a[3] + a[11]; + a1[4] = a[4] + a[12]; + a1[5] = a[5] + a[13]; + a1[6] = a[6] + a[14]; + a1[7] = a[7] + a[15]; + fe448_sqr_8(r2, a + 8); + fe448_sqr_8(r0, a); + fe448_sqr_8(r1, a1); + r[ 0] = r0[ 0] + r2[ 0] + r1[ 8] - r0[ 8]; + r[ 1] = r0[ 1] + r2[ 1] + r1[ 9] - r0[ 9]; + r[ 2] = r0[ 2] + r2[ 2] + r1[10] - r0[10]; + r[ 3] = r0[ 3] + r2[ 3] + r1[11] - r0[11]; + r[ 4] = r0[ 4] + r2[ 4] + r1[12] - r0[12]; + r[ 5] = r0[ 5] + r2[ 5] + r1[13] - r0[13]; + r[ 6] = r0[ 6] + r2[ 6] + r1[14] - r0[14]; + r[ 7] = r0[ 7] + r2[ 7] + r1[15] - r0[15]; + r[ 8] = r2[ 8] + r1[ 0] - r0[ 0] + r1[ 8]; + r[ 9] = r2[ 9] + r1[ 1] - r0[ 1] + r1[ 9]; + r[10] = r2[10] + r1[ 2] - r0[ 2] + r1[10]; + r[11] = r2[11] + r1[ 3] - r0[ 3] + r1[11]; + r[12] = r2[12] + r1[ 4] - r0[ 4] + r1[12]; + r[13] = r2[13] + r1[ 5] - r0[ 5] + r1[13]; + r[14] = r2[14] + r1[ 6] - r0[ 6] + r1[14]; + r[15] = r2[15] + r1[ 7] - r0[ 7] + r1[15]; +} + +/* Invert the field element. (r * a) mod (2^448 - 2^224 - 1) = 1 + * Constant time implementation - using Fermat's little theorem: + * a^(p-1) mod p = 1 => a^(p-2) mod p = 1/a + * For curve448: p - 2 = 2^448 - 2^224 - 3 + * + * r [in] Field element to hold result. + * a [in] Field element to invert. + */ +void fe448_invert(int32_t* r, const int32_t* a) +{ + int32_t t1[16]; + int32_t t2[16]; + int32_t t3[16]; + int32_t t4[16]; + int i; + + fe448_sqr(t1, a); + /* t1 = 2 */ + fe448_mul(t1, t1, a); + /* t1 = 3 */ + fe448_sqr(t2, t1); for (i = 1; i < 2; ++i) fe448_sqr(t2, t2); + /* t2 = c */ + fe448_mul(t3, t2, a); + /* t3 = d */ + fe448_mul(t1, t2, t1); + /* t1 = f */ + fe448_sqr(t2, t1); + /* t2 = 1e */ + fe448_mul(t4, t2, a); + /* t4 = 1f */ + fe448_sqr(t2, t4); for (i = 1; i < 5; ++i) fe448_sqr(t2, t2); + /* t2 = 3e0 */ + fe448_mul(t1, t2, t4); + /* t1 = 3ff */ + fe448_sqr(t2, t1); for (i = 1; i < 10; ++i) fe448_sqr(t2, t2); + /* t2 = ffc00 */ + fe448_mul(t1, t2, t1); + /* t1 = fffff */ + fe448_sqr(t2, t1); for (i = 1; i < 5; ++i) fe448_sqr(t2, t2); + /* t2 = 1ffffe0 */ + fe448_mul(t1, t2, t4); + /* t1 = 1ffffff */ + fe448_sqr(t2, t1); for (i = 1; i < 25; ++i) fe448_sqr(t2, t2); + /* t2 = 3fffffe000000 */ + fe448_mul(t1, t2, t1); + /* t1 = 3ffffffffffff */ + fe448_sqr(t2, t1); for (i = 1; i < 5; ++i) fe448_sqr(t2, t2); + /* t2 = 7fffffffffffe0 */ + fe448_mul(t1, t2, t4); + /* t1 = 7fffffffffffff */ + fe448_sqr(t2, t1); for (i = 1; i < 55; ++i) fe448_sqr(t2, t2); + /* t2 = 3fffffffffffff80000000000000 */ + fe448_mul(t1, t2, t1); + /* t1 = 3fffffffffffffffffffffffffff */ + fe448_sqr(t2, t1); for (i = 1; i < 110; ++i) fe448_sqr(t2, t2); + /* t2 = fffffffffffffffffffffffffffc000000000000000000000000000 */ + fe448_mul(t1, t2, t1); + /* t1 = fffffffffffffffffffffffffffffffffffffffffffffffffffffff */ + fe448_sqr(t2, t1); for (i = 1; i < 4; ++i) fe448_sqr(t2, t2); + /* t2 = fffffffffffffffffffffffffffffffffffffffffffffffffffffff0 */ + fe448_mul(t3, t3, t2); + /* t3 = fffffffffffffffffffffffffffffffffffffffffffffffffffffffd */ + fe448_mul(t1, t3, a); + /* t1 = fffffffffffffffffffffffffffffffffffffffffffffffffffffffe */ + fe448_sqr(t1, t1); for (i = 1; i < 224; ++i) fe448_sqr(t1, t1); + /* t1 = fffffffffffffffffffffffffffffffffffffffffffffffffffffffe00000000000000000000000000000000000000000000000000000000 */ + fe448_mul(r, t3, t1); + /* r = fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffffffffffffffffffffffffffffffffffffffffffffffffffffd */ +} + +/* Scalar multiply the point by a number. r = n.a + * Uses Montogmery ladder and only requires the x-ordinate. + * + * r [in] Field element to hold result. + * n [in] Scalar as an array of bytes. + * a [in] Point to multiply - x-ordinate only. + */ +int curve448(byte* r, const byte* n, const byte* a) +{ + int32_t x1[16]; + int32_t x2[16]; + int32_t z2[16]; + int32_t x3[16]; + int32_t z3[16]; + int32_t t0[16]; + int32_t t1[16]; + int i; + unsigned int swap; + unsigned int b; + + fe448_from_bytes(x1, a); + fe448_1(x2); + fe448_0(z2); + fe448_copy(x3, x1); + fe448_1(z3); + + swap = 0; + for (i = 447; i >= 0; --i) { + b = (n[i >> 3] >> (i & 7)) & 1; + swap ^= b; + fe448_cswap(x2, x3, swap); + fe448_cswap(z2, z3, swap); + swap = b; + + /* Montgomery Ladder - double and add */ + fe448_add(t0, x2, z2); + fe448_reduce(t0); + fe448_add(t1, x3, z3); + fe448_reduce(t1); + fe448_sub(x2, x2, z2); + fe448_sub(x3, x3, z3); + fe448_mul(t1, t1, x2); + fe448_mul(z3, x3, t0); + fe448_sqr(t0, t0); + fe448_sqr(x2, x2); + fe448_add(x3, z3, t1); + fe448_reduce(x3); + fe448_sqr(x3, x3); + fe448_sub(z3, z3, t1); + fe448_sqr(z3, z3); + fe448_mul(z3, z3, x1); + fe448_sub(t1, t0, x2); + fe448_mul(x2, t0, x2); + fe448_mul39081(z2, t1); + fe448_add(z2, t0, z2); + fe448_mul(z2, z2, t1); + } + /* Last two bits are 0 - no final swap check required. */ + + fe448_invert(z2, z2); + fe448_mul(x2, x2, z2); + fe448_to_bytes(r, x2); + + return 0; +} + +#ifdef HAVE_ED448 +/* Check whether field element is not 0. + * Must convert to a normalized form before checking. + * + * a [in] Field element. + * returns 0 when zero, and any other value otherwise. + */ +int fe448_isnonzero(const int32_t* a) +{ + uint8_t b[56]; + int i; + uint8_t c = 0; + fe448_to_bytes(b, a); + for (i = 0; i < 56; i++) + c |= b[i]; + return c; +} + +/* Check whether field element is negative. + * Must convert to a normalized form before checking. + * + * a [in] Field element. + * returns 1 when negative, and 0 otherwise. + */ +int fe448_isnegative(const int32_t* a) +{ + uint8_t b[56]; + fe448_to_bytes(b, a); + return b[0] & 1; +} + +/* Negates the field element. r = -a + * + * r [in] Field element to hold result. + * a [in] Field element. + */ +void fe448_neg(int32_t* r, const int32_t* a) +{ + r[0] = -a[0]; + r[1] = -a[1]; + r[2] = -a[2]; + r[3] = -a[3]; + r[4] = -a[4]; + r[5] = -a[5]; + r[6] = -a[6]; + r[7] = -a[7]; + r[8] = -a[8]; + r[9] = -a[9]; + r[10] = -a[10]; + r[11] = -a[11]; + r[12] = -a[12]; + r[13] = -a[13]; + r[14] = -a[14]; + r[15] = -a[15]; +} + +/* Raise field element to (p-3) / 4: 2^446 - 2^222 - 1 + * Used for calcualting y-ordinate from x-ordinate for Ed448. + * + * r [in] Field element to hold result. + * a [in] Field element to exponentiate. + */ +void fe448_pow_2_446_222_1(int32_t* r, const int32_t* a) +{ + int32_t t1[16]; + int32_t t2[16]; + int32_t t3[16]; + int32_t t4[16]; + int32_t t5[16]; + int i; + + fe448_sqr(t3, a); + /* t3 = 2 */ + fe448_mul(t1, t3, a); + /* t1 = 3 */ + fe448_sqr(t5, t1); + /* t5 = 6 */ + fe448_mul(t5, t5, a); + /* t5 = 7 */ + fe448_sqr(t2, t1); for (i = 1; i < 2; ++i) fe448_sqr(t2, t2); + /* t2 = c */ + fe448_mul(t3, t2, t3); + /* t3 = e */ + fe448_mul(t1, t2, t1); + /* t1 = f */ + fe448_sqr(t2, t1); for (i = 1; i < 3; ++i) fe448_sqr(t2, t2); + /* t2 = 78 */ + fe448_mul(t5, t2, t5); + /* t5 = 7f */ + fe448_sqr(t2, t1); for (i = 1; i < 4; ++i) fe448_sqr(t2, t2); + /* t2 = f0 */ + fe448_mul(t1, t2, t1); + /* t1 = ff */ + fe448_mul(t3, t3, t2); + /* t3 = fe */ + fe448_sqr(t2, t1); for (i = 1; i < 7; ++i) fe448_sqr(t2, t2); + /* t2 = 7f80 */ + fe448_mul(t5, t2, t5); + /* t5 = 7fff */ + fe448_sqr(t2, t1); for (i = 1; i < 8; ++i) fe448_sqr(t2, t2); + /* t2 = ff00 */ + fe448_mul(t1, t2, t1); + /* t1 = ffff */ + fe448_mul(t3, t3, t2); + /* t3 = fffe */ + fe448_sqr(t2, t5); for (i = 1; i < 15; ++i) fe448_sqr(t2, t2); + /* t2 = 3fff8000 */ + fe448_mul(t5, t2, t5); + /* t5 = 3fffffff */ + fe448_sqr(t2, t1); for (i = 1; i < 16; ++i) fe448_sqr(t2, t2); + /* t2 = ffff0000 */ + fe448_mul(t1, t2, t1); + /* t1 = ffffffff */ + fe448_mul(t3, t3, t2); + /* t3 = fffffffe */ + fe448_sqr(t2, t1); for (i = 1; i < 32; ++i) fe448_sqr(t2, t2); + /* t2 = ffffffff00000000 */ + fe448_mul(t2, t2, t1); + /* t2 = ffffffffffffffff */ + fe448_sqr(t1, t2); for (i = 1; i < 64; ++i) fe448_sqr(t1, t1); + /* t1 = ffffffffffffffff0000000000000000 */ + fe448_mul(t1, t1, t2); + /* t1 = ffffffffffffffffffffffffffffffff */ + fe448_sqr(t1, t1); for (i = 1; i < 64; ++i) fe448_sqr(t1, t1); + /* t1 = ffffffffffffffffffffffffffffffff0000000000000000 */ + fe448_mul(t4, t1, t2); + /* t4 = ffffffffffffffffffffffffffffffffffffffffffffffff */ + fe448_sqr(t2, t4); for (i = 1; i < 32; ++i) fe448_sqr(t2, t2); + /* t2 = ffffffffffffffffffffffffffffffffffffffffffffffff00000000 */ + fe448_mul(t3, t3, t2); + /* t3 = fffffffffffffffffffffffffffffffffffffffffffffffffffffffe */ + fe448_sqr(t1, t3); for (i = 1; i < 192; ++i) fe448_sqr(t1, t1); + /* t1 = fffffffffffffffffffffffffffffffffffffffffffffffffffffffe000000000000000000000000000000000000000000000000 */ + fe448_mul(t1, t1, t4); + /* t1 = fffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffffffffffffffffffffffffffffffffffffffffffff */ + fe448_sqr(t1, t1); for (i = 1; i < 30; ++i) fe448_sqr(t1, t1); + /* t1 = 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffc0000000 */ + fe448_mul(r, t5, t1); + /* r = 3fffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffffffffffffffffffffffffffffffffffffffffffffffffffffff */ +} + +/* Constant time, conditional move of b into a. + * a is not changed if the condition is 0. + * + * a A field element. + * b A field element. + * c If 1 then copy and if 0 then don't copy. + */ +void fe448_cmov(int32_t* a, const int32_t* b, int c) +{ + int32_t m = -(int32_t)c; + int32_t t0 = m & (a[0] ^ b[0]); + int32_t t1 = m & (a[1] ^ b[1]); + int32_t t2 = m & (a[2] ^ b[2]); + int32_t t3 = m & (a[3] ^ b[3]); + int32_t t4 = m & (a[4] ^ b[4]); + int32_t t5 = m & (a[5] ^ b[5]); + int32_t t6 = m & (a[6] ^ b[6]); + int32_t t7 = m & (a[7] ^ b[7]); + int32_t t8 = m & (a[8] ^ b[8]); + int32_t t9 = m & (a[9] ^ b[9]); + int32_t t10 = m & (a[10] ^ b[10]); + int32_t t11 = m & (a[11] ^ b[11]); + int32_t t12 = m & (a[12] ^ b[12]); + int32_t t13 = m & (a[13] ^ b[13]); + int32_t t14 = m & (a[14] ^ b[14]); + int32_t t15 = m & (a[15] ^ b[15]); + + a[0] ^= t0; + a[1] ^= t1; + a[2] ^= t2; + a[3] ^= t3; + a[4] ^= t4; + a[5] ^= t5; + a[6] ^= t6; + a[7] ^= t7; + a[8] ^= t8; + a[9] ^= t9; + a[10] ^= t10; + a[11] ^= t11; + a[12] ^= t12; + a[13] ^= t13; + a[14] ^= t14; + a[15] ^= t15; +} + +#endif /* HAVE_ED448 */ +#endif + +#endif /* HAVE_CURVE448 || HAVE_ED448 */ diff --git a/wolfcrypt/src/ge_448.c b/wolfcrypt/src/ge_448.c new file mode 100644 index 000000000..7795a962d --- /dev/null +++ b/wolfcrypt/src/ge_448.c @@ -0,0 +1,10780 @@ +/* ge_448.c + * + * 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 + */ + +/* Based On Daniel J Bernstein's ed25519 Public Domain ref10 work. + * Small implementation based on Daniel Beer's ed25519 public domain work. + * Reworked for ed448 by Sean Parkinson. + */ + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#ifdef HAVE_ED448 + +#include +#include +#include +#ifdef NO_INLINE + #include +#else + #define WOLFSSL_MISC_INCLUDED + #include +#endif + +/* +sc means scalar. +ge means group element. + +Here the group is the set of pairs (x,y) of field elements (see ge_448.h) +satisfying -x^2 + y^2 = 1 + d x^2y^2 +where d = -39081 + +Representations: + ge448_p2 (projective) : (X:Y:Z) satisfying x=X/Z, y=Y/Z + ge448_precomp (affine): (X:Y) +*/ + + +#ifdef ED448_SMALL + +/* Base point of ed448 */ +static const ge448_p2 ed448_base = { + { 0x5e, 0xc0, 0x0c, 0xc7, 0x2b, 0xa8, 0x26, 0x26, 0x8e, 0x93, 0x00, 0x8b, + 0xe1, 0x80, 0x3b, 0x43, 0x11, 0x65, 0xb6, 0x2a, 0xf7, 0x1a, 0xae, 0x12, + 0x64, 0xa4, 0xd3, 0xa3, 0x24, 0xe3, 0x6d, 0xea, 0x67, 0x17, 0x0f, 0x47, + 0x70, 0x65, 0x14, 0x9e, 0xda, 0x36, 0xbf, 0x22, 0xa6, 0x15, 0x1d, 0x22, + 0xed, 0x0d, 0xed, 0x6b, 0xc6, 0x70, 0x19, 0x4f }, + { 0x14, 0xfa, 0x30, 0xf2, 0x5b, 0x79, 0x08, 0x98, 0xad, 0xc8, 0xd7, 0x4e, + 0x2c, 0x13, 0xbd, 0xfd, 0xc4, 0x39, 0x7c, 0xe6, 0x1c, 0xff, 0xd3, 0x3a, + 0xd7, 0xc2, 0xa0, 0x05, 0x1e, 0x9c, 0x78, 0x87, 0x40, 0x98, 0xa3, 0x6c, + 0x73, 0x73, 0xea, 0x4b, 0x62, 0xc7, 0xc9, 0x56, 0x37, 0x20, 0x76, 0x88, + 0x24, 0xbc, 0xb6, 0x6e, 0x71, 0x46, 0x3f, 0x69 }, + { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}; + +/* Part of order of ed448 that needs tp be multiplied when reducing */ +static const uint8_t ed448_order_mul[56] = { + 0x0d, 0xbb, 0xa7, 0x54, 0x6d, 0x3d, 0x87, 0xdc, 0xaa, 0x70, 0x3a, 0x72, + 0x8d, 0x3d, 0x93, 0xde, 0x6f, 0xc9, 0x29, 0x51, 0xb6, 0x24, 0xb1, 0x3b, + 0x16, 0xdc, 0x35, 0x83, +}; + +/* Reduce scalar mod the order of the curve. + * Scalar Will be 114 bytes. + * + * b [in] Scalar to reduce. + */ +void sc448_reduce(uint8_t* b) +{ + int i, j; + uint32_t t[114]; + uint8_t o; + + for (i = 0; i < 86; i++) { + t[i] = b[i]; + } + for (i = 0; i < 58; i++) { + for (j = 0; j < 28; j++) + t[i+j] += b[i+56] * ((uint32_t)ed448_order_mul[j] << 2); + t[i+56] = 0; + } + for (i = 54; i < 87; i++) { + t[i+1] += t[i] >> 8; + t[i] &= 0xff; + } + for (i = 0; i < 31; i++) { + for (j = 0; j < 28; j++) + t[i+j] += t[i+56] * ((uint32_t)ed448_order_mul[j] << 2); + t[i+56] = 0; + } + for (i = 54; i < 60; i++) { + t[i+1] += t[i] >> 8; + t[i] &= 0xff; + } + for (i = 0; i < 4; i++) { + for (j = 0; j < 28; j++) + t[i+j] += t[i+56] * ((uint32_t)ed448_order_mul[j] << 2); + t[i+56] = 0; + } + for (i = 0; i < 55; i++) { + t[i+1] += t[i] >> 8; + t[i] &= 0xff; + } + o = t[55] >> 6; + t[55] &= 0x3f; + for (j = 0; j < 28; j++) + t[j] += o * (uint32_t)ed448_order_mul[j]; + for (i = 0; i < 55; i++) { + t[i+1] += t[i] >> 8; + b[i] = t[i] & 0xff; + } + b[i] = t[i] & 0xff; + b[i+1] = 0; +} + +/* Multiply a by b and add d. r = (a * b + d) mod order + * + * r [in] Scalar to hold result. + * a [in] Scalar to multiply. + * b [in] Scalar to multiply. + * d [in] Scalar to add to multiplicative result. + */ +void sc448_muladd(uint8_t* r, const uint8_t* a, const uint8_t* b, + const uint8_t* d) +{ + int i, j; + uint32_t t[112]; + uint8_t o; + + /* a * b + d */ + for (i = 0; i < 56; i++) + t[i] = d[i]; + for (i = 0; i < 56; i++) { + for (j = 0; j < 56; j++) + t[i+j] += (int16_t)a[i] * b[j]; + t[i+56] = 0; + } + + for (i = 0; i < 111; i++) { + t[i+1] += t[i] >> 8; + t[i] &= 0xff; + } + for (i = 0; i < 56; i++) { + for (j = 0; j < 28; j++) + t[i+j] += t[i+56] * ((uint32_t)ed448_order_mul[j] << 2); + t[i+56] = 0; + } + for (i = 54; i < 85; i++) { + t[i+1] += t[i] >> 8; + t[i] &= 0xff; + } + for (i = 0; i < 29; i++) { + for (j = 0; j < 28; j++) + t[i+j] += t[i+56] * ((uint32_t)ed448_order_mul[j] << 2); + t[i+56] = 0; + } + for (i = 54; i < 58; i++) { + t[i+1] += t[i] >> 8; + t[i] &= 0xff; + } + for (i = 0; i < 2; i++) { + for (j = 0; j < 28; j++) + t[i+j] += t[i+56] * ((uint32_t)ed448_order_mul[j] << 2); + t[i+56] = 0; + } + for (i = 0; i < 55; i++) { + t[i+1] += t[i] >> 8; + t[i] &= 0xff; + } + o = t[55] >> 6; + t[55] &= 0x3f; + for (j = 0; j < 28; j++) + t[j] += o * (uint32_t)ed448_order_mul[j]; + for (i = 0; i < 55; i++) { + t[i+1] += t[i] >> 8; + r[i] = t[i] & 0xff; + } + r[i] = t[i] & 0xff; + r[i+1] = 0; +} + +/* Double the point on the Twisted Edwards curve. r = 2.p + * + * r [in] Point to hold result. + * p [in] Point to double. + */ +static WC_INLINE void ge448_dbl(ge448_p2 *r,const ge448_p2 *p) +{ + ge448 t0[GE448_WORDS]; + ge448 t1[GE448_WORDS]; + + fe448_add(t0, p->X, p->Y); /* t0 = B1 = X1+Y1 */ + fe448_reduce(t0); + fe448_sqr(t0, t0); /* t0 = B = (X1+Y1)^2 */ + fe448_sqr(r->X, p->X); /* r->X = C = X1^2 */ + fe448_sqr(r->Y, p->Y); /* r->Y = D = Y1^2 */ + fe448_add(t1, r->X, r->Y); /* t1 = E = C+D */ + fe448_reduce(t1); + fe448_sub(r->Y, r->X, r->Y); /* r->Y = Y31 = C-D */ + fe448_sqr(r->Z, p->Z); /* r->Z = H = Z1^2 */ + fe448_add(r->Z, r->Z, r->Z); /* r->Z = J1 = 2*H */ + fe448_sub(r->Z, t1, r->Z); /* r->Z = J = E-2*H */ + fe448_reduce(r->Z); + fe448_sub(r->X, t0, t1); /* r->X = X31 = B-E */ + fe448_mul(r->X, r->X, r->Z); /* r->X = X3 = (B-E)*J */ + fe448_mul(r->Y, r->Y, t1); /* r->Y = Y3 = E*(C-D) */ + fe448_mul(r->Z, t1, r->Z); /* r->Z = Z3 = E*J */ +} + +/* Add two point on the Twisted Edwards curve. r = p + q + * + * r [in] Point to hold result. + * p [in] Point to add. + * q [in] Point to add. + */ +static WC_INLINE void ge448_add(ge448_p2* r, const ge448_p2* p, + const ge448_p2* q) +{ + ge448 t0[GE448_WORDS]; + ge448 t1[GE448_WORDS]; + ge448 t2[GE448_WORDS]; + ge448 t3[GE448_WORDS]; + ge448 t4[GE448_WORDS]; + + fe448_mul(t1, p->X, q->X); /* t1 = C = X1*X2 */ + fe448_mul(t2, p->Y, q->Y); /* t2 = D = Y1*Y2 */ + fe448_mul(t3, t1, t2); /* t3 = E1 = C*D */ + fe448_mul39081(t3, t3); /* t3 = E = d*C*D */ + fe448_mul(r->Z, p->Z, q->Z); /* r->Z = A = Z1*Z2 */ + fe448_sqr(t0, r->Z); /* t0 = B = A^2 */ + fe448_add(t4, t0, t3); /* t4 = F = B-(-E) */ + fe448_sub(t0, t0, t3); /* t0 = G = B+(-E) */ + fe448_reduce(t0); + fe448_add(r->X, p->X, p->Y); /* r->X = H1 = X1+Y1 */ + fe448_reduce(r->X); + fe448_add(r->Y, q->X, q->Y); /* r->Y = H2 = X2+Y2 */ + fe448_reduce(r->Y); + fe448_mul(r->X, r->X, r->Y); /* r->X = H = (X1+Y1)*(X2+Y2) */ + fe448_sub(r->X, r->X, t1); /* r->X = X31 = H-C */ + fe448_sub(r->X, r->X, t2); /* r->X = X32 = H-C-D */ + fe448_reduce(r->X); + fe448_mul(r->X, r->X, t4); /* r->X = X33 = F*(H-C-D) */ + fe448_mul(r->X, r->X, r->Z); /* r->X = X3 = A*F*(H-C-D) */ + fe448_sub(r->Y, t2, t1); /* r->Y = Y31 = D-C */ + fe448_reduce(r->Y); + fe448_mul(r->Y, r->Y, t0); /* r->Y = Y32 = G*(D-C) */ + fe448_mul(r->Y, r->Y, r->Z); /* r->Y = Y3 = A*F*(D-C) */ + fe448_mul(r->Z, t4, t0); /* r->Z = Z3 = F*G */ +} + +/* Convert point to byte array assuming projective ordinates. + * + * b [in] Array of bytes to hold compressed point. + * p [in] Point to convert. + */ +void ge448_to_bytes(uint8_t *s, const ge448_p2 *h) +{ + ge448 recip[56]; + ge448 x[56]; + + fe448_invert(recip, h->Z); + fe448_mul(x, h->X, recip); + fe448_mul(s, h->Y, recip); + fe448_norm(x); + fe448_norm(s); + s[56] = (x[0] & 1) << 7; +} + +/* Compress the point to y-ordinate and negative bit. + * + * out [in] Array of bytes to hold compressed key. + * xIn [in] The x-ordinate. + * yIn [in] The y-ordinate. + */ +int ge448_compress_key(uint8_t* out, const uint8_t* xIn, const uint8_t* yIn) +{ + ge448 x[56]; + + fe448_copy(x, xIn); + fe448_copy(out, yIn); + fe448_norm(x); + fe448_norm(out); + out[56] = (x[0] & 1) << 7; + + return 0; +} + +/* Perform a scalar multiplication of the a point. r = p * base + * + * r [in] Point to hold result. + * a [in] Scalar to multiply by. + */ +static void ge448_scalarmult(ge448_p2* h, const ge448_p2* p, const uint8_t* a) +{ + ge448_p2 r; + ge448_p2 s; + int i; + + XMEMSET(&r, 0, sizeof(r)); + r.Y[0] = 1; + r.Z[0] = 1; + + for (i = 447; i >= 0; i--) { + const byte bit = (a[i >> 3] >> (i & 7)) & 1; + + ge448_dbl(&r, &r); + ge448_add(&s, &r, p); + + fe448_cmov(r.X, s.X, bit); + fe448_cmov(r.Y, s.Y, bit); + fe448_cmov(r.Z, s.Z, bit); + } + + XMEMCPY(h, &r, sizeof(r)); +} + +/* Perform a scalar multiplication of the base point. r = a * base + * + * r [in] Point to hold result. + * a [in] Scalar to multiply by. + */ +void ge448_scalarmult_base(ge448_p2* h, const uint8_t* a) +{ + ge448_scalarmult(h, &ed448_base, a); +} + +/* Perform a scalar multplication of the base point and public point. + * r = a * p + b * base + * Uses a sliding window of 5 bits. + * Not constant time. + * + * r [in] Point to hold result. + * a [in] Scalar to multiply by. + */ +int ge448_double_scalarmult_vartime(ge448_p2 *r, const uint8_t *a, + const ge448_p2 *A, const uint8_t *b) +{ + ge448_p2 t; + + ge448_scalarmult(&t, &ed448_base, b); + ge448_scalarmult(r, A, a); + ge448_add(r, r, &t); + + return 0; +} + +/* Convert compressed point to negative of affine point. + * Calculates x from the y and the negative bit. + * Not constant time. + * + * r [in] Uncompressed point. + * b [in] Array of bytes representing point. + * returns 0 on success and -1 on failure. + */ +int ge448_from_bytes_negate_vartime(ge448_p2 *r, const uint8_t *b) +{ + int ret = 0; + ge448 u[GE448_WORDS]; + ge448 v[GE448_WORDS]; + ge448 u3[GE448_WORDS]; + ge448 vxx[GE448_WORDS]; + ge448 check[GE448_WORDS]; + + fe448_copy(r->Y, b); + XMEMSET(r->Z, 0, sizeof(r->Z)); + r->Z[0] = 1; + fe448_sqr(u, r->Y); /* u = y^2 */ + fe448_mul39081(v, u); /* v = 39081.y^2 */ + fe448_sub(u, u, r->Z); /* u = y^2-1 */ + fe448_add(v, v, r->Z); /* v = 39081.y^2-1 */ + fe448_neg(v, v); /* v = -39081.y^2-1 = d.y^2-1 */ + + fe448_sqr(r->X, v); /* x = v^2 */ + fe448_mul(r->X, r->X, v); /* x = v^3 */ + fe448_sqr(u3, u); /* x = u^2.v^3 */ + fe448_mul(r->X, r->X, u3); /* x = u^2.v^3 */ + fe448_mul(u3, u3, u); /* u3 = u^3 */ + fe448_mul(r->X, r->X, u3); /* x = u^5.v^3 */ + + fe448_pow_2_446_222_1(r->X, r->X); /* x = (u^5.v^3)^((q-3)/4) */ + fe448_mul(r->X, r->X, u3); /* x = u^3(u^5.v^3)^((q-3)/4) */ + fe448_mul(r->X, r->X, v); /* x = u^3.v(u^5.v^3)^((q-3)/4) */ + + fe448_sqr(vxx, r->X); + fe448_mul(vxx, vxx, v); + fe448_sub(check, vxx, u); /* check = v.x^2-u */ + fe448_norm(check); + fe448_norm(r->X); + fe448_norm(r->Y); + /* Note; vx^2+u is NOT correct. */ + if (fe448_isnonzero(check)) { + ret = -1; + } + + /* Calculating negative of point in bytes - negate only if X is correct. */ + if ((r->X[0] & 1) == (b[56] >> 7)) { + fe448_neg(r->X, r->X); + } + + return ret; +} + +#else /* !ED448_SMALL */ + +#if defined(CURVED448_128BIT) + +/* Reduce scalar mod the order of the curve. + * Scalar Will be 114 bytes. + * + * b [in] Scalar to reduce. + */ +void sc448_reduce(uint8_t* b) +{ + uint64_t d[8]; + uint128_t t[17]; + uint128_t c; + uint64_t o; + + /* Load from bytes */ + t[ 0] = ((int64_t) (b[ 0]) << 0) + | ((int64_t) (b[ 1]) << 8) + | ((int64_t) (b[ 2]) << 16) + | ((int64_t) (b[ 3]) << 24) + | ((int64_t) (b[ 4]) << 32) + | ((int64_t) (b[ 5]) << 40) + | ((int64_t) (b[ 6]) << 48); + t[ 1] = ((int64_t) (b[ 7]) << 0) + | ((int64_t) (b[ 8]) << 8) + | ((int64_t) (b[ 9]) << 16) + | ((int64_t) (b[10]) << 24) + | ((int64_t) (b[11]) << 32) + | ((int64_t) (b[12]) << 40) + | ((int64_t) (b[13]) << 48); + t[ 2] = ((int64_t) (b[14]) << 0) + | ((int64_t) (b[15]) << 8) + | ((int64_t) (b[16]) << 16) + | ((int64_t) (b[17]) << 24) + | ((int64_t) (b[18]) << 32) + | ((int64_t) (b[19]) << 40) + | ((int64_t) (b[20]) << 48); + t[ 3] = ((int64_t) (b[21]) << 0) + | ((int64_t) (b[22]) << 8) + | ((int64_t) (b[23]) << 16) + | ((int64_t) (b[24]) << 24) + | ((int64_t) (b[25]) << 32) + | ((int64_t) (b[26]) << 40) + | ((int64_t) (b[27]) << 48); + t[ 4] = ((int64_t) (b[28]) << 0) + | ((int64_t) (b[29]) << 8) + | ((int64_t) (b[30]) << 16) + | ((int64_t) (b[31]) << 24) + | ((int64_t) (b[32]) << 32) + | ((int64_t) (b[33]) << 40) + | ((int64_t) (b[34]) << 48); + t[ 5] = ((int64_t) (b[35]) << 0) + | ((int64_t) (b[36]) << 8) + | ((int64_t) (b[37]) << 16) + | ((int64_t) (b[38]) << 24) + | ((int64_t) (b[39]) << 32) + | ((int64_t) (b[40]) << 40) + | ((int64_t) (b[41]) << 48); + t[ 6] = ((int64_t) (b[42]) << 0) + | ((int64_t) (b[43]) << 8) + | ((int64_t) (b[44]) << 16) + | ((int64_t) (b[45]) << 24) + | ((int64_t) (b[46]) << 32) + | ((int64_t) (b[47]) << 40) + | ((int64_t) (b[48]) << 48); + t[ 7] = ((int64_t) (b[49]) << 0) + | ((int64_t) (b[50]) << 8) + | ((int64_t) (b[51]) << 16) + | ((int64_t) (b[52]) << 24) + | ((int64_t) (b[53]) << 32) + | ((int64_t) (b[54]) << 40) + | ((int64_t) (b[55]) << 48); + t[ 8] = ((int64_t) (b[56]) << 0) + | ((int64_t) (b[57]) << 8) + | ((int64_t) (b[58]) << 16) + | ((int64_t) (b[59]) << 24) + | ((int64_t) (b[60]) << 32) + | ((int64_t) (b[61]) << 40) + | ((int64_t) (b[62]) << 48); + t[ 9] = ((int64_t) (b[63]) << 0) + | ((int64_t) (b[64]) << 8) + | ((int64_t) (b[65]) << 16) + | ((int64_t) (b[66]) << 24) + | ((int64_t) (b[67]) << 32) + | ((int64_t) (b[68]) << 40) + | ((int64_t) (b[69]) << 48); + t[10] = ((int64_t) (b[70]) << 0) + | ((int64_t) (b[71]) << 8) + | ((int64_t) (b[72]) << 16) + | ((int64_t) (b[73]) << 24) + | ((int64_t) (b[74]) << 32) + | ((int64_t) (b[75]) << 40) + | ((int64_t) (b[76]) << 48); + t[11] = ((int64_t) (b[77]) << 0) + | ((int64_t) (b[78]) << 8) + | ((int64_t) (b[79]) << 16) + | ((int64_t) (b[80]) << 24) + | ((int64_t) (b[81]) << 32) + | ((int64_t) (b[82]) << 40) + | ((int64_t) (b[83]) << 48); + t[12] = ((int64_t) (b[84]) << 0) + | ((int64_t) (b[85]) << 8) + | ((int64_t) (b[86]) << 16) + | ((int64_t) (b[87]) << 24) + | ((int64_t) (b[88]) << 32) + | ((int64_t) (b[89]) << 40) + | ((int64_t) (b[90]) << 48); + t[13] = ((int64_t) (b[91]) << 0) + | ((int64_t) (b[92]) << 8) + | ((int64_t) (b[93]) << 16) + | ((int64_t) (b[94]) << 24) + | ((int64_t) (b[95]) << 32) + | ((int64_t) (b[96]) << 40) + | ((int64_t) (b[97]) << 48); + t[14] = ((int64_t) (b[98]) << 0) + | ((int64_t) (b[99]) << 8) + | ((int64_t) (b[100]) << 16) + | ((int64_t) (b[101]) << 24) + | ((int64_t) (b[102]) << 32) + | ((int64_t) (b[103]) << 40) + | ((int64_t) (b[104]) << 48); + t[15] = ((int64_t) (b[105]) << 0) + | ((int64_t) (b[106]) << 8) + | ((int64_t) (b[107]) << 16) + | ((int64_t) (b[108]) << 24) + | ((int64_t) (b[109]) << 32) + | ((int64_t) (b[110]) << 40) + | ((int64_t) (b[111]) << 48); + t[16] = ((int64_t) (b[112]) << 0) + | ((int64_t) (b[113]) << 8); + + /* Mod curve order */ + /* 2^446 - 0x8335dc163bb124b65129c96fde933d8d723a70aadc873d6d54a7bb0d */ + /* Mod top half of extra words */ + t[ 4] += (int128_t)0x21cf5b5529eec34L * t[12]; + t[ 5] += (int128_t)0x0f635c8e9c2ab70L * t[12]; + t[ 6] += (int128_t)0x2d944a725bf7a4cL * t[12]; + t[ 7] += (int128_t)0x20cd77058eec490L * t[12]; + t[ 5] += (int128_t)0x21cf5b5529eec34L * t[13]; + t[ 6] += (int128_t)0x0f635c8e9c2ab70L * t[13]; + t[ 7] += (int128_t)0x2d944a725bf7a4cL * t[13]; + t[ 8] += (int128_t)0x20cd77058eec490L * t[13]; + t[ 6] += (int128_t)0x21cf5b5529eec34L * t[14]; + t[ 7] += (int128_t)0x0f635c8e9c2ab70L * t[14]; + t[ 8] += (int128_t)0x2d944a725bf7a4cL * t[14]; + t[ 9] += (int128_t)0x20cd77058eec490L * t[14]; + t[ 7] += (int128_t)0x21cf5b5529eec34L * t[15]; + t[ 8] += (int128_t)0x0f635c8e9c2ab70L * t[15]; + t[ 9] += (int128_t)0x2d944a725bf7a4cL * t[15]; + t[10] += (int128_t)0x20cd77058eec490L * t[15]; + t[ 8] += (int128_t)0x21cf5b5529eec34L * t[16]; + t[ 9] += (int128_t)0x0f635c8e9c2ab70L * t[16]; + t[10] += (int128_t)0x2d944a725bf7a4cL * t[16]; + t[11] += (int128_t)0x20cd77058eec490L * t[16]; + t[12] = 0; + /* Propagate carries */ + c = t[ 4] >> 56; t[ 5] += c; t[ 4] = t[ 4] & 0xffffffffffffff; + c = t[ 5] >> 56; t[ 6] += c; t[ 5] = t[ 5] & 0xffffffffffffff; + c = t[ 6] >> 56; t[ 7] += c; t[ 6] = t[ 6] & 0xffffffffffffff; + c = t[ 7] >> 56; t[ 8] += c; t[ 7] = t[ 7] & 0xffffffffffffff; + c = t[ 8] >> 56; t[ 9] += c; t[ 8] = t[ 8] & 0xffffffffffffff; + c = t[ 9] >> 56; t[10] += c; t[ 9] = t[ 9] & 0xffffffffffffff; + c = t[10] >> 56; t[11] += c; t[10] = t[10] & 0xffffffffffffff; + c = t[11] >> 56; t[12] += c; t[11] = t[11] & 0xffffffffffffff; + /* Mod bottom half of extra words */ + t[ 0] += (int128_t)0x21cf5b5529eec34L * t[ 8]; + t[ 1] += (int128_t)0x0f635c8e9c2ab70L * t[ 8]; + t[ 2] += (int128_t)0x2d944a725bf7a4cL * t[ 8]; + t[ 3] += (int128_t)0x20cd77058eec490L * t[ 8]; + t[ 1] += (int128_t)0x21cf5b5529eec34L * t[ 9]; + t[ 2] += (int128_t)0x0f635c8e9c2ab70L * t[ 9]; + t[ 3] += (int128_t)0x2d944a725bf7a4cL * t[ 9]; + t[ 4] += (int128_t)0x20cd77058eec490L * t[ 9]; + t[ 2] += (int128_t)0x21cf5b5529eec34L * t[10]; + t[ 3] += (int128_t)0x0f635c8e9c2ab70L * t[10]; + t[ 4] += (int128_t)0x2d944a725bf7a4cL * t[10]; + t[ 5] += (int128_t)0x20cd77058eec490L * t[10]; + t[ 3] += (int128_t)0x21cf5b5529eec34L * t[11]; + t[ 4] += (int128_t)0x0f635c8e9c2ab70L * t[11]; + t[ 5] += (int128_t)0x2d944a725bf7a4cL * t[11]; + t[ 6] += (int128_t)0x20cd77058eec490L * t[11]; + t[ 4] += (int128_t)0x21cf5b5529eec34L * t[12]; + t[ 5] += (int128_t)0x0f635c8e9c2ab70L * t[12]; + t[ 6] += (int128_t)0x2d944a725bf7a4cL * t[12]; + t[ 7] += (int128_t)0x20cd77058eec490L * t[12]; + t[ 8] = 0; + /* Propagate carries */ + c = t[ 0] >> 56; t[ 1] += c; t[ 0] = t[ 0] & 0xffffffffffffff; + c = t[ 1] >> 56; t[ 2] += c; t[ 1] = t[ 1] & 0xffffffffffffff; + c = t[ 2] >> 56; t[ 3] += c; t[ 2] = t[ 2] & 0xffffffffffffff; + c = t[ 3] >> 56; t[ 4] += c; t[ 3] = t[ 3] & 0xffffffffffffff; + c = t[ 4] >> 56; t[ 5] += c; t[ 4] = t[ 4] & 0xffffffffffffff; + c = t[ 5] >> 56; t[ 6] += c; t[ 5] = t[ 5] & 0xffffffffffffff; + c = t[ 6] >> 56; t[ 7] += c; t[ 6] = t[ 6] & 0xffffffffffffff; + c = t[ 7] >> 56; t[ 8] += c; t[ 7] = t[ 7] & 0xffffffffffffff; + t[ 0] += (int128_t)0x21cf5b5529eec34L * t[ 8]; + t[ 1] += (int128_t)0x0f635c8e9c2ab70L * t[ 8]; + t[ 2] += (int128_t)0x2d944a725bf7a4cL * t[ 8]; + t[ 3] += (int128_t)0x20cd77058eec490L * t[ 8]; + /* Propagate carries */ + c = t[ 0] >> 56; t[ 1] += c; d[ 0] = (int64_t)(t[ 0] & 0xffffffffffffff); + c = t[ 1] >> 56; t[ 2] += c; d[ 1] = (int64_t)(t[ 1] & 0xffffffffffffff); + c = t[ 2] >> 56; t[ 3] += c; d[ 2] = (int64_t)(t[ 2] & 0xffffffffffffff); + c = t[ 3] >> 56; t[ 4] += c; d[ 3] = (int64_t)(t[ 3] & 0xffffffffffffff); + c = t[ 4] >> 56; t[ 5] += c; d[ 4] = (int64_t)(t[ 4] & 0xffffffffffffff); + c = t[ 5] >> 56; t[ 6] += c; d[ 5] = (int64_t)(t[ 5] & 0xffffffffffffff); + c = t[ 6] >> 56; t[ 7] += c; d[ 6] = (int64_t)(t[ 6] & 0xffffffffffffff); + d[ 7] = t[7]; + /* Mod bits over 56 in last word */ + o = d[7] >> 54; d[ 7] &= 0x3fffffffffffff; + d[ 0] += 0x873d6d54a7bb0dL * o; + d[ 1] += 0x3d8d723a70aadcL * o; + d[ 2] += 0xb65129c96fde93L * o; + d[ 3] += 0x8335dc163bb124L * o; + /* Propagate carries */ + o = d[ 0] >> 56; d[ 1] += o; d[ 0] = d[ 0] & 0xffffffffffffff; + o = d[ 1] >> 56; d[ 2] += o; d[ 1] = d[ 1] & 0xffffffffffffff; + o = d[ 2] >> 56; d[ 3] += o; d[ 2] = d[ 2] & 0xffffffffffffff; + o = d[ 3] >> 56; d[ 4] += o; d[ 3] = d[ 3] & 0xffffffffffffff; + o = d[ 4] >> 56; d[ 5] += o; d[ 4] = d[ 4] & 0xffffffffffffff; + o = d[ 5] >> 56; d[ 6] += o; d[ 5] = d[ 5] & 0xffffffffffffff; + o = d[ 6] >> 56; d[ 7] += o; d[ 6] = d[ 6] & 0xffffffffffffff; + + /* Convert to bytes */ + b[ 0] = (d[0 ] >> 0); + b[ 1] = (d[0 ] >> 8); + b[ 2] = (d[0 ] >> 16); + b[ 3] = (d[0 ] >> 24); + b[ 4] = (d[0 ] >> 32); + b[ 5] = (d[0 ] >> 40); + b[ 6] = (d[0 ] >> 48); + b[ 7] = (d[1 ] >> 0); + b[ 8] = (d[1 ] >> 8); + b[ 9] = (d[1 ] >> 16); + b[10] = (d[1 ] >> 24); + b[11] = (d[1 ] >> 32); + b[12] = (d[1 ] >> 40); + b[13] = (d[1 ] >> 48); + b[14] = (d[2 ] >> 0); + b[15] = (d[2 ] >> 8); + b[16] = (d[2 ] >> 16); + b[17] = (d[2 ] >> 24); + b[18] = (d[2 ] >> 32); + b[19] = (d[2 ] >> 40); + b[20] = (d[2 ] >> 48); + b[21] = (d[3 ] >> 0); + b[22] = (d[3 ] >> 8); + b[23] = (d[3 ] >> 16); + b[24] = (d[3 ] >> 24); + b[25] = (d[3 ] >> 32); + b[26] = (d[3 ] >> 40); + b[27] = (d[3 ] >> 48); + b[28] = (d[4 ] >> 0); + b[29] = (d[4 ] >> 8); + b[30] = (d[4 ] >> 16); + b[31] = (d[4 ] >> 24); + b[32] = (d[4 ] >> 32); + b[33] = (d[4 ] >> 40); + b[34] = (d[4 ] >> 48); + b[35] = (d[5 ] >> 0); + b[36] = (d[5 ] >> 8); + b[37] = (d[5 ] >> 16); + b[38] = (d[5 ] >> 24); + b[39] = (d[5 ] >> 32); + b[40] = (d[5 ] >> 40); + b[41] = (d[5 ] >> 48); + b[42] = (d[6 ] >> 0); + b[43] = (d[6 ] >> 8); + b[44] = (d[6 ] >> 16); + b[45] = (d[6 ] >> 24); + b[46] = (d[6 ] >> 32); + b[47] = (d[6 ] >> 40); + b[48] = (d[6 ] >> 48); + b[49] = (d[7 ] >> 0); + b[50] = (d[7 ] >> 8); + b[51] = (d[7 ] >> 16); + b[52] = (d[7 ] >> 24); + b[53] = (d[7 ] >> 32); + b[54] = (d[7 ] >> 40); + b[55] = (d[7 ] >> 48); + b[56] = 0; +} + +/* Multiply a by b and add d. r = (a * b + d) mod order + * + * r [in] Scalar to hold result. + * a [in] Scalar to multiply. + * b [in] Scalar to multiply. + * d [in] Scalar to add to multiplicative result. + */ +void sc448_muladd(uint8_t* r, const uint8_t* a, const uint8_t* b, + const uint8_t* d) +{ + uint64_t ad[8], bd[8], dd[8], rd[8]; + uint128_t t[16]; + uint128_t c; + uint64_t o; + + /* Load from bytes */ + ad[ 0] = ((int64_t) (a[ 0]) << 0) + | ((int64_t) (a[ 1]) << 8) + | ((int64_t) (a[ 2]) << 16) + | ((int64_t) (a[ 3]) << 24) + | ((int64_t) (a[ 4]) << 32) + | ((int64_t) (a[ 5]) << 40) + | ((int64_t) (a[ 6]) << 48); + ad[ 1] = ((int64_t) (a[ 7]) << 0) + | ((int64_t) (a[ 8]) << 8) + | ((int64_t) (a[ 9]) << 16) + | ((int64_t) (a[10]) << 24) + | ((int64_t) (a[11]) << 32) + | ((int64_t) (a[12]) << 40) + | ((int64_t) (a[13]) << 48); + ad[ 2] = ((int64_t) (a[14]) << 0) + | ((int64_t) (a[15]) << 8) + | ((int64_t) (a[16]) << 16) + | ((int64_t) (a[17]) << 24) + | ((int64_t) (a[18]) << 32) + | ((int64_t) (a[19]) << 40) + | ((int64_t) (a[20]) << 48); + ad[ 3] = ((int64_t) (a[21]) << 0) + | ((int64_t) (a[22]) << 8) + | ((int64_t) (a[23]) << 16) + | ((int64_t) (a[24]) << 24) + | ((int64_t) (a[25]) << 32) + | ((int64_t) (a[26]) << 40) + | ((int64_t) (a[27]) << 48); + ad[ 4] = ((int64_t) (a[28]) << 0) + | ((int64_t) (a[29]) << 8) + | ((int64_t) (a[30]) << 16) + | ((int64_t) (a[31]) << 24) + | ((int64_t) (a[32]) << 32) + | ((int64_t) (a[33]) << 40) + | ((int64_t) (a[34]) << 48); + ad[ 5] = ((int64_t) (a[35]) << 0) + | ((int64_t) (a[36]) << 8) + | ((int64_t) (a[37]) << 16) + | ((int64_t) (a[38]) << 24) + | ((int64_t) (a[39]) << 32) + | ((int64_t) (a[40]) << 40) + | ((int64_t) (a[41]) << 48); + ad[ 6] = ((int64_t) (a[42]) << 0) + | ((int64_t) (a[43]) << 8) + | ((int64_t) (a[44]) << 16) + | ((int64_t) (a[45]) << 24) + | ((int64_t) (a[46]) << 32) + | ((int64_t) (a[47]) << 40) + | ((int64_t) (a[48]) << 48); + ad[ 7] = ((int64_t) (a[49]) << 0) + | ((int64_t) (a[50]) << 8) + | ((int64_t) (a[51]) << 16) + | ((int64_t) (a[52]) << 24) + | ((int64_t) (a[53]) << 32) + | ((int64_t) (a[54]) << 40) + | ((int64_t) (a[55]) << 48); + /* Load from bytes */ + bd[ 0] = ((int64_t) (b[ 0]) << 0) + | ((int64_t) (b[ 1]) << 8) + | ((int64_t) (b[ 2]) << 16) + | ((int64_t) (b[ 3]) << 24) + | ((int64_t) (b[ 4]) << 32) + | ((int64_t) (b[ 5]) << 40) + | ((int64_t) (b[ 6]) << 48); + bd[ 1] = ((int64_t) (b[ 7]) << 0) + | ((int64_t) (b[ 8]) << 8) + | ((int64_t) (b[ 9]) << 16) + | ((int64_t) (b[10]) << 24) + | ((int64_t) (b[11]) << 32) + | ((int64_t) (b[12]) << 40) + | ((int64_t) (b[13]) << 48); + bd[ 2] = ((int64_t) (b[14]) << 0) + | ((int64_t) (b[15]) << 8) + | ((int64_t) (b[16]) << 16) + | ((int64_t) (b[17]) << 24) + | ((int64_t) (b[18]) << 32) + | ((int64_t) (b[19]) << 40) + | ((int64_t) (b[20]) << 48); + bd[ 3] = ((int64_t) (b[21]) << 0) + | ((int64_t) (b[22]) << 8) + | ((int64_t) (b[23]) << 16) + | ((int64_t) (b[24]) << 24) + | ((int64_t) (b[25]) << 32) + | ((int64_t) (b[26]) << 40) + | ((int64_t) (b[27]) << 48); + bd[ 4] = ((int64_t) (b[28]) << 0) + | ((int64_t) (b[29]) << 8) + | ((int64_t) (b[30]) << 16) + | ((int64_t) (b[31]) << 24) + | ((int64_t) (b[32]) << 32) + | ((int64_t) (b[33]) << 40) + | ((int64_t) (b[34]) << 48); + bd[ 5] = ((int64_t) (b[35]) << 0) + | ((int64_t) (b[36]) << 8) + | ((int64_t) (b[37]) << 16) + | ((int64_t) (b[38]) << 24) + | ((int64_t) (b[39]) << 32) + | ((int64_t) (b[40]) << 40) + | ((int64_t) (b[41]) << 48); + bd[ 6] = ((int64_t) (b[42]) << 0) + | ((int64_t) (b[43]) << 8) + | ((int64_t) (b[44]) << 16) + | ((int64_t) (b[45]) << 24) + | ((int64_t) (b[46]) << 32) + | ((int64_t) (b[47]) << 40) + | ((int64_t) (b[48]) << 48); + bd[ 7] = ((int64_t) (b[49]) << 0) + | ((int64_t) (b[50]) << 8) + | ((int64_t) (b[51]) << 16) + | ((int64_t) (b[52]) << 24) + | ((int64_t) (b[53]) << 32) + | ((int64_t) (b[54]) << 40) + | ((int64_t) (b[55]) << 48); + /* Load from bytes */ + dd[ 0] = ((int64_t) (d[ 0]) << 0) + | ((int64_t) (d[ 1]) << 8) + | ((int64_t) (d[ 2]) << 16) + | ((int64_t) (d[ 3]) << 24) + | ((int64_t) (d[ 4]) << 32) + | ((int64_t) (d[ 5]) << 40) + | ((int64_t) (d[ 6]) << 48); + dd[ 1] = ((int64_t) (d[ 7]) << 0) + | ((int64_t) (d[ 8]) << 8) + | ((int64_t) (d[ 9]) << 16) + | ((int64_t) (d[10]) << 24) + | ((int64_t) (d[11]) << 32) + | ((int64_t) (d[12]) << 40) + | ((int64_t) (d[13]) << 48); + dd[ 2] = ((int64_t) (d[14]) << 0) + | ((int64_t) (d[15]) << 8) + | ((int64_t) (d[16]) << 16) + | ((int64_t) (d[17]) << 24) + | ((int64_t) (d[18]) << 32) + | ((int64_t) (d[19]) << 40) + | ((int64_t) (d[20]) << 48); + dd[ 3] = ((int64_t) (d[21]) << 0) + | ((int64_t) (d[22]) << 8) + | ((int64_t) (d[23]) << 16) + | ((int64_t) (d[24]) << 24) + | ((int64_t) (d[25]) << 32) + | ((int64_t) (d[26]) << 40) + | ((int64_t) (d[27]) << 48); + dd[ 4] = ((int64_t) (d[28]) << 0) + | ((int64_t) (d[29]) << 8) + | ((int64_t) (d[30]) << 16) + | ((int64_t) (d[31]) << 24) + | ((int64_t) (d[32]) << 32) + | ((int64_t) (d[33]) << 40) + | ((int64_t) (d[34]) << 48); + dd[ 5] = ((int64_t) (d[35]) << 0) + | ((int64_t) (d[36]) << 8) + | ((int64_t) (d[37]) << 16) + | ((int64_t) (d[38]) << 24) + | ((int64_t) (d[39]) << 32) + | ((int64_t) (d[40]) << 40) + | ((int64_t) (d[41]) << 48); + dd[ 6] = ((int64_t) (d[42]) << 0) + | ((int64_t) (d[43]) << 8) + | ((int64_t) (d[44]) << 16) + | ((int64_t) (d[45]) << 24) + | ((int64_t) (d[46]) << 32) + | ((int64_t) (d[47]) << 40) + | ((int64_t) (d[48]) << 48); + dd[ 7] = ((int64_t) (d[49]) << 0) + | ((int64_t) (d[50]) << 8) + | ((int64_t) (d[51]) << 16) + | ((int64_t) (d[52]) << 24) + | ((int64_t) (d[53]) << 32) + | ((int64_t) (d[54]) << 40) + | ((int64_t) (d[55]) << 48); + + /* a * b + d */ + t[ 0] = dd[ 0] + (int128_t)ad[ 0] * bd[ 0]; + t[ 1] = dd[ 1] + (int128_t)ad[ 0] * bd[ 1] + + (int128_t)ad[ 1] * bd[ 0]; + t[ 2] = dd[ 2] + (int128_t)ad[ 0] * bd[ 2] + + (int128_t)ad[ 1] * bd[ 1] + + (int128_t)ad[ 2] * bd[ 0]; + t[ 3] = dd[ 3] + (int128_t)ad[ 0] * bd[ 3] + + (int128_t)ad[ 1] * bd[ 2] + + (int128_t)ad[ 2] * bd[ 1] + + (int128_t)ad[ 3] * bd[ 0]; + t[ 4] = dd[ 4] + (int128_t)ad[ 0] * bd[ 4] + + (int128_t)ad[ 1] * bd[ 3] + + (int128_t)ad[ 2] * bd[ 2] + + (int128_t)ad[ 3] * bd[ 1] + + (int128_t)ad[ 4] * bd[ 0]; + t[ 5] = dd[ 5] + (int128_t)ad[ 0] * bd[ 5] + + (int128_t)ad[ 1] * bd[ 4] + + (int128_t)ad[ 2] * bd[ 3] + + (int128_t)ad[ 3] * bd[ 2] + + (int128_t)ad[ 4] * bd[ 1] + + (int128_t)ad[ 5] * bd[ 0]; + t[ 6] = dd[ 6] + (int128_t)ad[ 0] * bd[ 6] + + (int128_t)ad[ 1] * bd[ 5] + + (int128_t)ad[ 2] * bd[ 4] + + (int128_t)ad[ 3] * bd[ 3] + + (int128_t)ad[ 4] * bd[ 2] + + (int128_t)ad[ 5] * bd[ 1] + + (int128_t)ad[ 6] * bd[ 0]; + t[ 7] = dd[ 7] + (int128_t)ad[ 0] * bd[ 7] + + (int128_t)ad[ 1] * bd[ 6] + + (int128_t)ad[ 2] * bd[ 5] + + (int128_t)ad[ 3] * bd[ 4] + + (int128_t)ad[ 4] * bd[ 3] + + (int128_t)ad[ 5] * bd[ 2] + + (int128_t)ad[ 6] * bd[ 1] + + (int128_t)ad[ 7] * bd[ 0]; + t[ 8] = (int128_t)ad[ 1] * bd[ 7] + + (int128_t)ad[ 2] * bd[ 6] + + (int128_t)ad[ 3] * bd[ 5] + + (int128_t)ad[ 4] * bd[ 4] + + (int128_t)ad[ 5] * bd[ 3] + + (int128_t)ad[ 6] * bd[ 2] + + (int128_t)ad[ 7] * bd[ 1]; + t[ 9] = (int128_t)ad[ 2] * bd[ 7] + + (int128_t)ad[ 3] * bd[ 6] + + (int128_t)ad[ 4] * bd[ 5] + + (int128_t)ad[ 5] * bd[ 4] + + (int128_t)ad[ 6] * bd[ 3] + + (int128_t)ad[ 7] * bd[ 2]; + t[10] = (int128_t)ad[ 3] * bd[ 7] + + (int128_t)ad[ 4] * bd[ 6] + + (int128_t)ad[ 5] * bd[ 5] + + (int128_t)ad[ 6] * bd[ 4] + + (int128_t)ad[ 7] * bd[ 3]; + t[11] = (int128_t)ad[ 4] * bd[ 7] + + (int128_t)ad[ 5] * bd[ 6] + + (int128_t)ad[ 6] * bd[ 5] + + (int128_t)ad[ 7] * bd[ 4]; + t[12] = (int128_t)ad[ 5] * bd[ 7] + + (int128_t)ad[ 6] * bd[ 6] + + (int128_t)ad[ 7] * bd[ 5]; + t[13] = (int128_t)ad[ 6] * bd[ 7] + + (int128_t)ad[ 7] * bd[ 6]; + t[14] = (int128_t)ad[ 7] * bd[ 7]; + t[15] = 0; + + /* Mod curve order */ + /* 2^446 - 0x8335dc163bb124b65129c96fde933d8d723a70aadc873d6d54a7bb0d */ + /* Propagate carries */ + c = t[ 0] >> 56; t[ 1] += c; t[ 0] = t[ 0] & 0xffffffffffffff; + c = t[ 1] >> 56; t[ 2] += c; t[ 1] = t[ 1] & 0xffffffffffffff; + c = t[ 2] >> 56; t[ 3] += c; t[ 2] = t[ 2] & 0xffffffffffffff; + c = t[ 3] >> 56; t[ 4] += c; t[ 3] = t[ 3] & 0xffffffffffffff; + c = t[ 4] >> 56; t[ 5] += c; t[ 4] = t[ 4] & 0xffffffffffffff; + c = t[ 5] >> 56; t[ 6] += c; t[ 5] = t[ 5] & 0xffffffffffffff; + c = t[ 6] >> 56; t[ 7] += c; t[ 6] = t[ 6] & 0xffffffffffffff; + c = t[ 7] >> 56; t[ 8] += c; t[ 7] = t[ 7] & 0xffffffffffffff; + c = t[ 8] >> 56; t[ 9] += c; t[ 8] = t[ 8] & 0xffffffffffffff; + c = t[ 9] >> 56; t[10] += c; t[ 9] = t[ 9] & 0xffffffffffffff; + c = t[10] >> 56; t[11] += c; t[10] = t[10] & 0xffffffffffffff; + c = t[11] >> 56; t[12] += c; t[11] = t[11] & 0xffffffffffffff; + c = t[12] >> 56; t[13] += c; t[12] = t[12] & 0xffffffffffffff; + c = t[13] >> 56; t[14] += c; t[13] = t[13] & 0xffffffffffffff; + c = t[14] >> 56; t[15] += c; t[14] = t[14] & 0xffffffffffffff; + /* Mod top half of extra words */ + t[ 4] += (int128_t)0x21cf5b5529eec34L * t[12]; + t[ 5] += (int128_t)0x0f635c8e9c2ab70L * t[12]; + t[ 6] += (int128_t)0x2d944a725bf7a4cL * t[12]; + t[ 7] += (int128_t)0x20cd77058eec490L * t[12]; + t[ 5] += (int128_t)0x21cf5b5529eec34L * t[13]; + t[ 6] += (int128_t)0x0f635c8e9c2ab70L * t[13]; + t[ 7] += (int128_t)0x2d944a725bf7a4cL * t[13]; + t[ 8] += (int128_t)0x20cd77058eec490L * t[13]; + t[ 6] += (int128_t)0x21cf5b5529eec34L * t[14]; + t[ 7] += (int128_t)0x0f635c8e9c2ab70L * t[14]; + t[ 8] += (int128_t)0x2d944a725bf7a4cL * t[14]; + t[ 9] += (int128_t)0x20cd77058eec490L * t[14]; + t[ 7] += (int128_t)0x21cf5b5529eec34L * t[15]; + t[ 8] += (int128_t)0x0f635c8e9c2ab70L * t[15]; + t[ 9] += (int128_t)0x2d944a725bf7a4cL * t[15]; + t[10] += (int128_t)0x20cd77058eec490L * t[15]; + /* Propagate carries */ + c = t[ 4] >> 56; t[ 5] += c; t[ 4] = t[ 4] & 0xffffffffffffff; + c = t[ 5] >> 56; t[ 6] += c; t[ 5] = t[ 5] & 0xffffffffffffff; + c = t[ 6] >> 56; t[ 7] += c; t[ 6] = t[ 6] & 0xffffffffffffff; + c = t[ 7] >> 56; t[ 8] += c; t[ 7] = t[ 7] & 0xffffffffffffff; + c = t[ 8] >> 56; t[ 9] += c; t[ 8] = t[ 8] & 0xffffffffffffff; + c = t[ 9] >> 56; t[10] += c; t[ 9] = t[ 9] & 0xffffffffffffff; + c = t[10] >> 56; t[11] += c; t[10] = t[10] & 0xffffffffffffff; + /* Mod bottom half of extra words */ + t[ 0] += (int128_t)0x21cf5b5529eec34L * t[ 8]; + t[ 1] += (int128_t)0x0f635c8e9c2ab70L * t[ 8]; + t[ 2] += (int128_t)0x2d944a725bf7a4cL * t[ 8]; + t[ 3] += (int128_t)0x20cd77058eec490L * t[ 8]; + t[ 1] += (int128_t)0x21cf5b5529eec34L * t[ 9]; + t[ 2] += (int128_t)0x0f635c8e9c2ab70L * t[ 9]; + t[ 3] += (int128_t)0x2d944a725bf7a4cL * t[ 9]; + t[ 4] += (int128_t)0x20cd77058eec490L * t[ 9]; + t[ 2] += (int128_t)0x21cf5b5529eec34L * t[10]; + t[ 3] += (int128_t)0x0f635c8e9c2ab70L * t[10]; + t[ 4] += (int128_t)0x2d944a725bf7a4cL * t[10]; + t[ 5] += (int128_t)0x20cd77058eec490L * t[10]; + t[ 3] += (int128_t)0x21cf5b5529eec34L * t[11]; + t[ 4] += (int128_t)0x0f635c8e9c2ab70L * t[11]; + t[ 5] += (int128_t)0x2d944a725bf7a4cL * t[11]; + t[ 6] += (int128_t)0x20cd77058eec490L * t[11]; + /* Propagate carries */ + c = t[ 0] >> 56; t[ 1] += c; rd[ 0] = (int64_t)(t[ 0] & 0xffffffffffffff); + c = t[ 1] >> 56; t[ 2] += c; rd[ 1] = (int64_t)(t[ 1] & 0xffffffffffffff); + c = t[ 2] >> 56; t[ 3] += c; rd[ 2] = (int64_t)(t[ 2] & 0xffffffffffffff); + c = t[ 3] >> 56; t[ 4] += c; rd[ 3] = (int64_t)(t[ 3] & 0xffffffffffffff); + c = t[ 4] >> 56; t[ 5] += c; rd[ 4] = (int64_t)(t[ 4] & 0xffffffffffffff); + c = t[ 5] >> 56; t[ 6] += c; rd[ 5] = (int64_t)(t[ 5] & 0xffffffffffffff); + c = t[ 6] >> 56; t[ 7] += c; rd[ 6] = (int64_t)(t[ 6] & 0xffffffffffffff); + rd[ 7] = t[7]; + /* Mod bits over 56 in last word */ + o = rd[7] >> 54; rd[ 7] &= 0x3fffffffffffff; + rd[ 0] += 0x873d6d54a7bb0dL * o; + rd[ 1] += 0x3d8d723a70aadcL * o; + rd[ 2] += 0xb65129c96fde93L * o; + rd[ 3] += 0x8335dc163bb124L * o; + /* Propagate carries */ + o = rd[ 0] >> 56; rd[ 1] += o; rd[ 0] = rd[ 0] & 0xffffffffffffff; + o = rd[ 1] >> 56; rd[ 2] += o; rd[ 1] = rd[ 1] & 0xffffffffffffff; + o = rd[ 2] >> 56; rd[ 3] += o; rd[ 2] = rd[ 2] & 0xffffffffffffff; + o = rd[ 3] >> 56; rd[ 4] += o; rd[ 3] = rd[ 3] & 0xffffffffffffff; + o = rd[ 4] >> 56; rd[ 5] += o; rd[ 4] = rd[ 4] & 0xffffffffffffff; + o = rd[ 5] >> 56; rd[ 6] += o; rd[ 5] = rd[ 5] & 0xffffffffffffff; + o = rd[ 6] >> 56; rd[ 7] += o; rd[ 6] = rd[ 6] & 0xffffffffffffff; + + /* Convert to bytes */ + r[ 0] = (rd[0 ] >> 0); + r[ 1] = (rd[0 ] >> 8); + r[ 2] = (rd[0 ] >> 16); + r[ 3] = (rd[0 ] >> 24); + r[ 4] = (rd[0 ] >> 32); + r[ 5] = (rd[0 ] >> 40); + r[ 6] = (rd[0 ] >> 48); + r[ 7] = (rd[1 ] >> 0); + r[ 8] = (rd[1 ] >> 8); + r[ 9] = (rd[1 ] >> 16); + r[10] = (rd[1 ] >> 24); + r[11] = (rd[1 ] >> 32); + r[12] = (rd[1 ] >> 40); + r[13] = (rd[1 ] >> 48); + r[14] = (rd[2 ] >> 0); + r[15] = (rd[2 ] >> 8); + r[16] = (rd[2 ] >> 16); + r[17] = (rd[2 ] >> 24); + r[18] = (rd[2 ] >> 32); + r[19] = (rd[2 ] >> 40); + r[20] = (rd[2 ] >> 48); + r[21] = (rd[3 ] >> 0); + r[22] = (rd[3 ] >> 8); + r[23] = (rd[3 ] >> 16); + r[24] = (rd[3 ] >> 24); + r[25] = (rd[3 ] >> 32); + r[26] = (rd[3 ] >> 40); + r[27] = (rd[3 ] >> 48); + r[28] = (rd[4 ] >> 0); + r[29] = (rd[4 ] >> 8); + r[30] = (rd[4 ] >> 16); + r[31] = (rd[4 ] >> 24); + r[32] = (rd[4 ] >> 32); + r[33] = (rd[4 ] >> 40); + r[34] = (rd[4 ] >> 48); + r[35] = (rd[5 ] >> 0); + r[36] = (rd[5 ] >> 8); + r[37] = (rd[5 ] >> 16); + r[38] = (rd[5 ] >> 24); + r[39] = (rd[5 ] >> 32); + r[40] = (rd[5 ] >> 40); + r[41] = (rd[5 ] >> 48); + r[42] = (rd[6 ] >> 0); + r[43] = (rd[6 ] >> 8); + r[44] = (rd[6 ] >> 16); + r[45] = (rd[6 ] >> 24); + r[46] = (rd[6 ] >> 32); + r[47] = (rd[6 ] >> 40); + r[48] = (rd[6 ] >> 48); + r[49] = (rd[7 ] >> 0); + r[50] = (rd[7 ] >> 8); + r[51] = (rd[7 ] >> 16); + r[52] = (rd[7 ] >> 24); + r[53] = (rd[7 ] >> 32); + r[54] = (rd[7 ] >> 40); + r[55] = (rd[7 ] >> 48); + r[56] = 0; +} + +/* Precomputed multiples of the base point. */ +static const ge448_precomp base[58][8] = { +{ + { + { 0x26a82bc70cc05eL, 0x80e18b00938e26L, 0xf72ab66511433bL, + 0xa3d3a46412ae1aL, 0x0f1767ea6de324L, 0x36da9e14657047L, + 0xed221d15a622bfL, 0x4f1970c66bed0dL }, + { 0x08795bf230fa14L, 0x132c4ed7c8ad98L, 0x1ce67c39c4fdbdL, + 0x05a0c2d73ad3ffL, 0xa3984087789c1eL, 0xc7624bea73736cL, + 0x248876203756c9L, 0x693f46716eb6bcL } + }, + { + { 0x55555555555555L, 0x55555555555555L, 0x55555555555555L, + 0x55555555555555L, 0xaaaaaaaaaaaaa9L, 0xaaaaaaaaaaaaaaL, + 0xaaaaaaaaaaaaaaL, 0xaaaaaaaaaaaaaaL }, + { 0xeafbcdea9386edL, 0xb2bed1cda06bdaL, 0x833a2a3098bbbcL, + 0x8ad8c4b80d6565L, 0x884dd7b7e36d72L, 0xc2b0036ed7a035L, + 0x8db359d6205086L, 0xae05e9634ad704L } + }, + { + { 0x28173286ff2f8fL, 0xb769465da85757L, 0xf7f6271fd6e862L, + 0x4a3fcfe8daa9cbL, 0xda82c7e2ba077aL, 0x943332241b8b8cL, + 0x6455bd64316cb6L, 0x0865886b9108afL }, + { 0x22ac13588ed6fcL, 0x9a68fed02dafb8L, 0x1bdb6767f0bffaL, + 0xec4e1d58bb3a33L, 0x56c3b9fce43c82L, 0xa6449a4a8d9523L, + 0xf706cbda7ad43aL, 0xe005a8dbd5125cL } + }, + { + { 0xce42ac48ba7f30L, 0xe1798949e120e2L, 0xf1515dd8ba21aeL, + 0x70c74cc301b7bdL, 0x0891c693fda4beL, 0x29ea255a09cf4eL, + 0x2c1419a17226f9L, 0x49dcbc5c6c0cceL }, + { 0xe236f86de51839L, 0x44285d0d4f5b32L, 0x7ea1ca9472b5d4L, + 0x7b8a5bc1c0d8f9L, 0x57d845c90dc322L, 0x1b979cb7c02f04L, + 0x27164b33a5de02L, 0xd49077e4accde5L } + }, + { + { 0xa99d1092030034L, 0x2d8cefc6f950d0L, 0x7a920c3c96f07bL, + 0x958812808bc0d5L, 0x62ada756d761e8L, 0x0def80cbcf7285L, + 0x0e2ba7601eedb5L, 0x7a9f9335a48dcbL }, + { 0xb4731472f435ebL, 0x5512881f225443L, 0xee59d2b33c5840L, + 0xb698017127d7a4L, 0xb18fced86551f7L, 0x0ade260ca1823aL, + 0xd3b9109ce4fd58L, 0xadfd751a2517edL } + }, + { + { 0x7fd7652abef79cL, 0x6c20a07443a878L, 0x5c1840d12a7109L, + 0x4a06e4a876451cL, 0x3bed0b4ad95f65L, 0x25d2e673fb0260L, + 0x2e00349aebd971L, 0x54523e04498b72L }, + { 0xea5d1da07c7bccL, 0xcce776938ea98cL, 0x80284e861d2b3eL, + 0x48de76b6e1ff1bL, 0x7b121869c58522L, 0xbfd053a2765a1aL, + 0x2d743ec056c667L, 0x3f99b9cd8ab61cL } + }, + { + { 0xdf9567ceb5eaf7L, 0x110a6b478ac7d7L, 0x2d335014706e0bL, + 0x0df9c7b0b5a209L, 0xba4223d568e684L, 0xd78af2d8c3719bL, + 0x77467b9a5291b6L, 0x079748e5c89befL }, + { 0xe20d3fadac377fL, 0x34e866972b5c09L, 0xd8687a3c40bbb7L, + 0x7b3946fd2f84c9L, 0xd00e40ca78f50eL, 0xb87594417e7179L, + 0x9c7373bcb23583L, 0x7ddeda3c90fd69L } + }, + { + { 0x2538a67153bde0L, 0x223aca9406b696L, 0xf9080dc1ad713eL, + 0x6c4cb47d816a64L, 0xbc285685dc8b97L, 0xd97b037c08e2d7L, + 0x5b63fb45d0e66bL, 0xd1f1bc5520e8a3L }, + { 0x4eb873ce69e09bL, 0x1663164bc8ee45L, 0x08f7003ba8d89fL, + 0x4b98ead386ad82L, 0xa4b93b7bd94c7bL, 0x46ba408c6b38b3L, + 0xdae87d1f3574ffL, 0xc7564f4e9bea9bL } + }, +}, +{ + { + { 0x2e4fdb25bfac1cL, 0xf0d79aaf5f3bcaL, 0xe756b0d20fb7ccL, + 0xe3696beb39609aL, 0xa019fc35a5ab58L, 0xa2b24853b281ddL, + 0xe3e2be761ac0a2L, 0xf19c34feb56730L }, + { 0x2d25ce8a30241eL, 0xf5661eab73d7a1L, 0x4611ed0daac9f4L, + 0xd5442344ced72cL, 0xce78f52e92e985L, 0x6fe5dd44da4aadL, + 0xfcaddc61d363ceL, 0x3beb69cc9111bfL } + }, + { + { 0xd2e7660940ebc9L, 0xe032018b17bbe0L, 0xad4939175c0575L, + 0xdd0b14721c7f34L, 0x52c2ba43e147e0L, 0x7dd03c60ee8973L, + 0x5472e8decf2754L, 0x17a1cd1d6482bbL }, + { 0xdd43b848128b3fL, 0xf0cae34ea7dd25L, 0x81ca99fff07df2L, + 0x1c8959792ebbdcL, 0x45c7a6872155e6L, 0x907a50e39ddd08L, + 0xbe398c2bb2d89bL, 0x38063f91b3b536L } + }, + { + { 0x149fafbf843b23L, 0x00ab582ac7f22aL, 0xa3b981bf2f4d4cL, + 0x2ce1a654341a22L, 0x68a40747c03b63L, 0x63206a212f2cf8L, + 0xc9961d35149741L, 0xfb85430bc7099eL }, + { 0x9c9107290a9e59L, 0x734e94a06de367L, 0x5cf3cbedb99214L, + 0xc6bce3245b1fb9L, 0x1a82abedd7be0dL, 0xf74976aede7d1cL, + 0x7025b7c21503bdL, 0xf7894910d096abL } + }, + { + { 0x6bd48bb555a41bL, 0xfbdd0d067de206L, 0x98bc477dd6dfd1L, + 0x1d0693b3e40b8aL, 0x6e15563da32ae4L, 0x0194a20fcebaa2L, + 0xda116150980a93L, 0x8e119200109cecL }, + { 0x8ea0552ffb9726L, 0xeba50a4047e44bL, 0xc050d2460ddf76L, + 0xe009204ac690e0L, 0x47b86399b18edcL, 0x2f5b76ac77f23fL, + 0x4296c240792905L, 0x73f6b4a06f6dc7L } + }, + { + { 0xb6ef9ea3b10cadL, 0x312843df7c8fceL, 0x5bdcd528bedf86L, + 0x2889059f6dd823L, 0x04578e908bfde0L, 0x3245df3123e2e5L, + 0xbf461d57ee9e3aL, 0xddec2d46f94cebL }, + { 0x21b43b9145768fL, 0xe79a8f9dae962aL, 0xff1972bcbb043fL, + 0xe3dcf6d239649bL, 0xed592bdc533b85L, 0x14ff94fdbe22d0L, + 0x6c4eb87f1d8e22L, 0xd8d4c71d18cf6dL } + }, + { + { 0xcda666c8d96345L, 0x9ecaa25836cd21L, 0x6e885bd984606eL, + 0x1dd5fef804f054L, 0x9dfff6b6959ae4L, 0x99b9cf8c9b55ccL, + 0xb4716b062b9b80L, 0x13ec87c554b128L }, + { 0xe696d1f75aacc2L, 0xf78c99387fc5ffL, 0x76c09473809d42L, + 0x99ce62db618fa8L, 0x35e3e022f53341L, 0x62fc1ac0db6c5eL, + 0xa1fb8e600d8b47L, 0x0bc107058f0d1eL } + }, + { + { 0x1f4526916da513L, 0x1f2fc04f5cf341L, 0xae9208664d23e0L, + 0x4e33082da8a113L, 0x2688ec61cfc085L, 0x6f2e8de6e5327fL, + 0x2070db3b4e48a8L, 0xd6626973240adeL }, + { 0xa6b317ffbd997bL, 0x9fa1b5649e26bdL, 0xcbf0d258cba0f3L, + 0x4a7791b17b4745L, 0x25f555b5c9e190L, 0x7cd3940923ec4cL, + 0x16f4c6ae98f1b6L, 0x7962116bcd4e0fL } + }, + { + { 0x8d58fa302491e3L, 0x7cf76c67ab3898L, 0xbc2f657647ebc7L, + 0x5f4bfe0d25f5a3L, 0x503f478d69505dL, 0x4a889fc3fb6645L, + 0x33e1bc1fa86b18L, 0xabb234f5508dd8L }, + { 0x5348e1b9a05b48L, 0x57ac5f164dc858L, 0x21f4d38ec8a2d3L, + 0x5ec6d3ca3a3e9dL, 0xcd4062e560a0b8L, 0x49b74f73433f59L, + 0xefd9d87cab14e3L, 0x858ce7feb964f5L } + }, +}, +{ + { + { 0x7577254eb731b4L, 0x9fff1fb4e2397eL, 0x749b145c821715L, + 0x40619fe2e65e67L, 0x57b82812e618d8L, 0x063186c707b83eL, + 0xcfc80cb31b24a2L, 0xcca6185ac75169L }, + { 0x6539f44b255818L, 0x5895da00368bceL, 0x841a30917c7482L, + 0x85469e1b1a9c9eL, 0x05664c0e4f7d9dL, 0x8a063187b35cc0L, + 0x214763aa0e9b0aL, 0x1bd872c4b26ac2L } + }, + { + { 0x3578f97a93762bL, 0x434f69a72d52bcL, 0xddcca4022cb565L, + 0xa7d1e41ff20544L, 0x823475d8a66588L, 0x9fc97c799d7bafL, + 0x15542f1660e421L, 0xa7d1f60843faf6L }, + { 0xbbfaab54063cccL, 0x3ad9bada49855aL, 0xffd5f1c5bddbfeL, + 0x0e419c2ae87e59L, 0xdce6ed6f89956bL, 0xf047c21ccd8951L, + 0x6ed4a1ba83c991L, 0x85af86e2d28e0aL } + }, + { + { 0x04433c49ed48a8L, 0xeffa8580bc375dL, 0xfb0e1b2fa6e3b5L, + 0x51483a2a1aaddaL, 0x733448df8b2ea8L, 0xaa0513cf639f0cL, + 0x6bc61a3a23bf84L, 0x3e64f68dc2430dL }, + { 0x51bf502c5876b1L, 0x6b833751c0dd2aL, 0xe597be1342914fL, + 0x43d5ab0f8e632cL, 0x2696715d62587bL, 0xe87d20aed34f24L, + 0x25b7e14e18baf7L, 0xf5eb753e22e084L } + }, + { + { 0x51da71724d8295L, 0xd478e4318d1340L, 0xacf94f42cf7f66L, + 0x230d7d13760711L, 0x078a66a5abc626L, 0xd78b0bd6b5f6daL, + 0x23a971396d1d0bL, 0x87623d64bd960fL }, + { 0x0841a9977db53fL, 0x23c1a53f4d03eeL, 0x2f62c2e1f95df1L, + 0xd1e2ec1116f4e7L, 0x896d2fe34811a9L, 0xad65e2bec8096eL, + 0x09d36f9b1744a6L, 0x564bac7ff5ddf7L } + }, + { + { 0x48b41e2c3f77cbL, 0x52276730968938L, 0xff1b899fd9b452L, + 0x67cf3bf2e03908L, 0x3731d90248a6fbL, 0xd800a05256598fL, + 0x347d2f2bdc8530L, 0xc72a3007ad08a1L }, + { 0x5e5be741d65f73L, 0x183d4ae4206eadL, 0xcb50c1cade4013L, + 0x39db43d3102483L, 0x0eb49fa70d6325L, 0xa18f6a2c1f02b9L, + 0x3e6fe30dbf5e66L, 0xac4eeb93a82aa5L } + }, + { + { 0x295affd3613d47L, 0x7b7e68ab56f343L, 0x980629692b173bL, + 0x937061ebad35fbL, 0x25019785c21eeaL, 0xe92721b787a746L, + 0x463c46c3651631L, 0x6da4b5dc6f2d5aL }, + { 0xcb67cc16e6d18cL, 0x1b30d520010588L, 0x1bb6ea6db1d1e8L, + 0x9c6308aad11474L, 0xc3167413d19b1cL, 0xf2e84d7be4fb79L, + 0xeccb873e050f77L, 0xf7c8d80cc2bf86L } + }, + { + { 0x16fe2e17ab20e5L, 0x274deadecf3a92L, 0x9f434870972f67L, + 0x9a65a454605751L, 0x9351f07b8980b2L, 0x412962b0eb08a5L, + 0xb8c9bfd733f440L, 0xac2cd641ca250fL }, + { 0x68cdd0f2ba7d26L, 0xd3d2a4a4e0beeaL, 0x50135c19f4a258L, + 0xb475e53f0d02e4L, 0x432d8c6589283aL, 0x29141bfa0a2b6cL, + 0xd7379ec13704bcL, 0x831562c52459bfL } + }, + { + { 0x676b366eeec506L, 0xdd6cad545da557L, 0x9de39cb77057d2L, + 0x388c5fedf05bf1L, 0x6e55650dfb1f03L, 0xdbceffa52126c9L, + 0xe4d187b3a4a220L, 0xac914f9eb27020L }, + { 0x3f4ab98d2e5f30L, 0x6ae97dadd94451L, 0x64af6950d80981L, + 0x36b4b90f2aa2ceL, 0x6adcd7a18fcf59L, 0x3ddfe6dc116c81L, + 0x661072b549b9e3L, 0xd9e3134ec4584dL } + }, +}, +{ + { + { 0x6e46707a1e400cL, 0xcdc990b551e806L, 0xfa512513a07724L, + 0x500553f1b3e4f5L, 0x67e8b58ef4dac3L, 0x958349f2cb4cc7L, + 0x948b4ed7f9143cL, 0xe646d092b7822bL }, + { 0xd185dd52bc3c26L, 0x34ba16ec837fc9L, 0x516d4ba5a788b7L, + 0x72f2de756142b0L, 0x5846f61f445b3dL, 0xdaec5c9f4631a1L, + 0xa10b18d169ea9bL, 0x85d2998af6751bL } + }, + { + { 0xda0cac443ddf31L, 0x0966e171860911L, 0x9c3a7173cba600L, + 0x5781880571f895L, 0x5e2a927737ac21L, 0x8a461486c253fbL, + 0xe801cf595ee626L, 0x271166a5f84fc0L }, + { 0x306937fba856bdL, 0x80cb179be80a43L, 0x70393b2ffb5980L, + 0xa8e4a1c660fc64L, 0x5078abfc0d5c98L, 0x62ba530fbd31ffL, + 0xda608449e51b88L, 0xdb6ecb0355ae15L } + }, + { + { 0xbcbb6ea23c5d49L, 0x08906ba87959bcL, 0x61cc0880991665L, + 0x21d6b41d90d13cL, 0x0c27ac1d03afe9L, 0x159995f5cfea52L, + 0x4057e20bdfe220L, 0xdd1b349cbdf058L }, + { 0x0cd66262e37159L, 0x8cea8e43eb0d17L, 0x553af085bce7f0L, + 0xb94cb5f5b6511dL, 0x7b8d3a550e0330L, 0x415911057ab7e7L, + 0x320820e6aa886fL, 0x130d4d6c5b6b81L } + }, + { + { 0x2f98059c7bb2edL, 0x33ebf4ca49bdfbL, 0x04c72a1b0a675bL, + 0x94f9ea4adb6c14L, 0x03376d8cf728c0L, 0x5c059d34c6eb6aL, + 0x0178408eb8da48L, 0x8bf607b2956817L }, + { 0x7ad2822ceb3d28L, 0xd07a40337ae653L, 0xbc68739c1e46b2L, + 0x15d7cca9154ba9L, 0x6b97103a26617dL, 0xa610314b2e0d28L, + 0x52a08bafd4d363L, 0x80c2638c7dc2afL } + }, + { + { 0x0cde7ef3187140L, 0x93b92ca4b70acdL, 0x5696e507a79cdcL, + 0x73cc9728eaab66L, 0x6b8c5b68f1b0c7L, 0xb39a3184f7e0b1L, + 0x72cfb0d376108aL, 0x0c53efc98536a7L }, + { 0x03b52a824c2f1eL, 0x717132e6399b78L, 0x31ebd25349a85dL, + 0x265ee811a200d4L, 0x0b1aad2407d7adL, 0x9a9ebc894d2962L, + 0x994e6cd41171d9L, 0x09178d86c8fa83L } + }, + { + { 0x7d1d238a2593a1L, 0x863e93ab38fb19L, 0xd23a4cce7712a9L, + 0x7477b1327efcd5L, 0x3ba69ff1392f6cL, 0x63e0c32f7bb5a5L, + 0x20412c0026effdL, 0xd3ee8e4ef424abL }, + { 0x14c0b2d64e5174L, 0x2a611f2e58c47bL, 0xaa58a06c1e8635L, + 0x1870c3ecf17034L, 0xb0d5e3483f1bf3L, 0xb19905c16c7eb3L, + 0xbf85d626efa4caL, 0xfd16b2f180f92bL } + }, + { + { 0xc0431af3adcb48L, 0xc9a7a8dba90496L, 0xd765a163895294L, + 0xb02a41a551de70L, 0xb71b261749b8a1L, 0x0dfa89ec6f3e47L, + 0x392c0d80f5d9ceL, 0x43c59d831aee3cL }, + { 0x94bfb6d4d76f49L, 0xe8f5b8227d68a5L, 0x78ae1d9630fd08L, + 0x1379029ce1bdaeL, 0x9689da066715dcL, 0x5d4cb24d3278c7L, + 0x77c98339e84fbcL, 0xc8478dcea1048cL } + }, + { + { 0xe4b8f31770d2baL, 0x744f65242ea095L, 0xd06e090036f138L, + 0xd3a3d5b3b078caL, 0xc7ae54178b8417L, 0xad6c5d4c738fd7L, + 0x61789844676454L, 0xfbf34235d9a392L }, + { 0x8e451a7fff772fL, 0x8605bb75ffbeadL, 0x6f75cc1930d59fL, + 0xd4f47558f3f460L, 0xefd2d796700c8aL, 0xceb462a2406421L, + 0x8ed0f979dfe8f1L, 0x0280bf1d1d7600L } + }, +}, +{ + { + { 0x761c219dd9a54dL, 0x1127fcb86a39c0L, 0x7d0e4f04c9beddL, + 0x27c017a4d976b6L, 0x800c973da042cfL, 0xe7419af2593f11L, + 0xbd49448ae67960L, 0xd3b60b7744fd85L }, + { 0x5e74ed961676feL, 0x7383ef339af627L, 0x34407e05e62df7L, + 0xb0534618bf3196L, 0xd6b7184583b407L, 0xe3d068555011beL, + 0x94083d02124b52L, 0xa908324f780aafL } + }, + { + { 0xb27af1a73ec9c3L, 0xb66ad9f70fa725L, 0x07724f58cf73e4L, + 0xc3fcd579949358L, 0x06efb79da0cc01L, 0x1e977d210597c9L, + 0xcd732be703e8d6L, 0x6fd29bf6d0b69eL }, + { 0xca658ac667128eL, 0xca0036ac7872b3L, 0xc9698585355837L, + 0x59f3be8075cf1cL, 0x9f1b9b03809a11L, 0x6881ced9733871L, + 0x8cda0fbe902a5fL, 0x4d8c69b4e3871eL } + }, + { + { 0x5c3bd07ddee82fL, 0xe52dd312f9723bL, 0xcf8761174f1be8L, + 0xd9ecbd835f8657L, 0x4f77393fbfea17L, 0xec9579fd78fe2cL, + 0x320de920fb0450L, 0xbfc9b8d95d9c47L }, + { 0x818bd425e1b4c3L, 0x0e0c41c40e2c78L, 0x0f7ce9abccb0d0L, + 0xc7e9fa45ef81fbL, 0x2561d6f73574adL, 0xa2d8d99d2efb0bL, + 0xcf8f316e96cd0aL, 0x088f0f14964807L } + }, + { + { 0x0a8498945d5a19L, 0x47ab39c6c2131fL, 0x5c02824f3fc35dL, + 0x3be77c89ee8127L, 0xa8491b7c90b80aL, 0x5397631a28aa93L, + 0x54d6e816c0b344L, 0x22878be876d0e4L }, + { 0xeecb8a46db3bf6L, 0x340f29554577a3L, 0xa7798689a00f85L, + 0x98465d74bb9147L, 0x9532d7dda3c736L, 0x6d574f17504b20L, + 0x6e356f4d86e435L, 0x70c2e8d4533887L } + }, + { + { 0xdce5a0ad293980L, 0x32d7210069010eL, 0x64af59f06deaaaL, + 0xd6b43c459239e4L, 0x74bf2559199c29L, 0x3efff4111e1e2bL, + 0x1aa7b5ecb0f8d8L, 0x9baa22b989e395L }, + { 0xf78db807b33ac1L, 0x05a3b4354ce80aL, 0x371defc7bc8e12L, + 0x63305a01224610L, 0x028b1ae6d697efL, 0x7aba39c1cd8051L, + 0x76ed7a928ee4b4L, 0x31bd02a7f99901L } + }, + { + { 0xf9dab7af075566L, 0x84e29a5f56f18bL, 0x3a4c45af64e56dL, + 0xcf3644a6a7302dL, 0xfb40808156b658L, 0xf33ef9cf96be52L, + 0xfe92038caa2f08L, 0xcfaf2e3b261894L }, + { 0xf2a0dbc224ce3fL, 0xed05009592eb27L, 0x501743f95889d0L, + 0xa88a47877c95c2L, 0x86755fbdd63da9L, 0x9024acfc7ee828L, + 0x634b020f38113bL, 0x3c5aacc6056e64L } + }, + { + { 0xe03ff3aa2ef760L, 0x3b95767b1c3bacL, 0x51ce6aa940d754L, + 0x7cbac3f47a9a3dL, 0xa864ac434f8d1aL, 0x1eff3f280dbd47L, + 0xd8ab6607ebd5caL, 0xc4df5c405b07edL }, + { 0x3dc92dfa4f095bL, 0x5ae36a57cdbd9aL, 0x7ff29737891e04L, + 0x37c03130a5fe7bL, 0x210d7b0aa6e35eL, 0x6edfb53bf200d8L, + 0x787b68d84afb85L, 0x9b5c49b72c6de3L } + }, + { + { 0x51857164010f4eL, 0xe0b144b0536ebeL, 0xacabb14887d663L, + 0xac1caededf584fL, 0xb43fb8faf175a3L, 0x310b6d5f992a3cL, + 0xf2c4aa285178a4L, 0x69c99698bd56bfL }, + { 0x73d6372a4d972eL, 0x3d5bb2e9583803L, 0x7bf7d18d891581L, + 0xa5ce5d7568a34aL, 0x670b4331f45c81L, 0x97265a71f96910L, + 0xdb14eb3b07c1eaL, 0xdf008eafed447cL } + }, +}, +{ + { + { 0x0379f5a00c2f10L, 0xb320b4fd350285L, 0x74e560e8efdd7dL, + 0xf2f017ef46a140L, 0x2ced1a60f34624L, 0x7c4b4e3ca08ec9L, + 0xdffc2a15d8bc6bL, 0xcc8f3f3527b007L }, + { 0x59f8ac4861fe83L, 0x8d48d2cd03144cL, 0xa8457d2bfa6dceL, + 0xd7ed333677c136L, 0xcb8e219c228e18L, 0x5f70bc916ab1e4L, + 0x2ae3a3d3780370L, 0x9f3365488f17adL } + }, + { + { 0xeab0710960e4bbL, 0xc668a78ab9cfd3L, 0x2e85553b0ef946L, + 0xa43c4b98df5df3L, 0x0ecd5593cb3646L, 0x6f543c418dbe71L, + 0xee7edaaf59818bL, 0xc44e8d290911c1L }, + { 0xafb38b1269b509L, 0x9e2737c52afe2cL, 0x5b2ef02ccfa664L, + 0x1e0aeace1cc58bL, 0x37a57e95ea134eL, 0xc9c465a83b9fc2L, + 0x4b9e8c76e3eccaL, 0xca07dbe9bdbab5L } + }, + { + { 0xd297f3cb0d7807L, 0xee441a5f59ce61L, 0x728553bb2db844L, + 0x90f87e5640e9e0L, 0xaa72cbfcb76dffL, 0x065c6864012d57L, + 0xd5ee88f9678b44L, 0x3d74b852177603L }, + { 0x3f9c947748b68eL, 0x03856d98f44d44L, 0xde34b84462426cL, + 0xc16d1bb845ab29L, 0x9df6217d2e18deL, 0xec6d219b154643L, + 0x22a8ec32ee0f8fL, 0x632ad3891c5175L } + }, + { + { 0x19d9d236869267L, 0x628df94fe5532aL, 0x458d76c6dc9a01L, + 0x405fe6c2cc39c8L, 0x7dddc67f3a04baL, 0xfee630312500c7L, + 0x580b6f0a50e9deL, 0xfb5918a6090604L }, + { 0xd7159253af6b2dL, 0x83d62d61c7d1ecL, 0x94398c185858c4L, + 0x94643dc14bfb64L, 0x758fa38af7db80L, 0xe2d7d93a8a1557L, + 0xa569e853562af1L, 0xd226bdd84346aaL } + }, + { + { 0xc2d0a5ed0ccd20L, 0xeb9adb85dbc0cfL, 0xe0a29ee26d7e88L, + 0x8bb39f884a8e98L, 0x511f1c137396eaL, 0xbc9ec5ac8b2fb3L, + 0x299d81c090e5bcL, 0xe1dfe344cdd587L }, + { 0x80f61f45e465b7L, 0x5699c531bad59eL, 0x85e92e4b79ff92L, + 0x1e64fce9db244cL, 0x3748574a22097dL, 0xe2aa6b9efff24eL, + 0xb951be70a10bc6L, 0x66853269067a1cL } + }, + { + { 0xf716ddfa6114d3L, 0x9e515f5037ec1fL, 0x773454144944a6L, + 0x1540c4caba97ccL, 0xe41e5488b54bb7L, 0x4363156cae37bcL, + 0xc384eaff3d2ce8L, 0x72a4f454c58ba4L }, + { 0x0ceb530dcaf3fcL, 0x72d536578dcdbbL, 0x9b44084c6320faL, + 0x6262d34eb74c70L, 0x8abac85608e6dcL, 0x82a526410dd38dL, + 0xbc39911a819b8dL, 0xbda15fe03ad0d9L } + }, + { + { 0xadbf587f9dc60bL, 0xf9d814f7d846d2L, 0xccdd241b77bde0L, + 0x89cb6d72242f50L, 0x95c0e3ee6360a8L, 0x7c7dd5adf49713L, + 0x68e0e4957d5814L, 0x3aa097d0c16571L }, + { 0xb56b672267d03aL, 0x4f557088c44af4L, 0x67c49e7f3252a5L, + 0x871d6cfc94a469L, 0x57ae99801fbfaaL, 0x5c0e48f48a5d8eL, + 0xe9bf9c85e240b9L, 0xa41018999d41caL } + }, + { + { 0x6beb0c7b2889b4L, 0x78b7f899455370L, 0xd43421447ca364L, + 0xdd9d2da9f21e5bL, 0xa0c7c180a7e4aaL, 0x022c0d4da1660cL, + 0xe1f5c165a57002L, 0x51c7c9e518f68fL }, + { 0x6d521b62586502L, 0xa0f2cb3183ec1bL, 0x578b4e0caa5e16L, + 0x7bd4fbd764997fL, 0x7ec56c364b1804L, 0xb75a2540ee08e4L, + 0x6bf74a6dc19080L, 0x6ec793d97d6e59L } + }, +}, +{ + { + { 0x16789d60a4beb9L, 0x512b2cd9b9c801L, 0xf8b6d108c7bb9cL, + 0xd85651e9ebdc8cL, 0xc9450829ba971aL, 0x852d9ea7e1cf78L, + 0x6a45e350af01e2L, 0xe6cdadf6151dcfL }, + { 0xc454bb42b8c01bL, 0x59e0c493d54cd2L, 0x8e1e686454d608L, + 0x0dbae4bd8c6103L, 0xa5603a16c18b18L, 0x227a6b23369093L, + 0xf1e89295f3de1cL, 0x42f0b588ab63c5L } + }, + { + { 0xf1974cc5b596d8L, 0xee8093f44719f0L, 0x40ba933f6f5b54L, + 0xd6e53652f3d654L, 0x9aeb83526d73b8L, 0x50ed5350776382L, + 0x3be47d6ad43875L, 0x21d56dfc786e48L }, + { 0x8a75e18b73bb39L, 0x9eba84cf265a78L, 0x7c02a4d2e772e7L, + 0xf7df6d44c1ecd2L, 0xa8d9ea06cef71bL, 0x86e8f91cae3b68L, + 0x2fd141199efefaL, 0x0b36ab2214e6f6L } + }, + { + { 0xd79065cbdce61cL, 0xcb562ffdecb229L, 0xef5d3d14600849L, + 0x348b31b1d23ac8L, 0xb2ea69915c36b8L, 0x268683d4822836L, + 0x083edbec6f0b7dL, 0xaf4f39d1a7821cL }, + { 0x23be6e84e64841L, 0xe9e246365bf791L, 0xa3208ac02bfd7cL, + 0x231989cd01357dL, 0x79b8aad6422ab4L, 0x57d2b7e91b8564L, + 0x28ebbcc8c04421L, 0xdc787d87d09c05L } + }, + { + { 0xeb99f626c7bed5L, 0x326b15f39cd0e8L, 0xd9d53dcd860615L, + 0xdf636e71bf4205L, 0x1eaa0bf0752209L, 0x17ce69a4744abbL, + 0x474572df3ea2fbL, 0xc4f6f73224a7f3L }, + { 0x7ed86ad63081b4L, 0xcd4cdc74a20afbL, 0x7563831b301b2eL, + 0x5b4d2b1e038699L, 0xa15d1fa802a15fL, 0x6687aaf13e9172L, + 0x3eccd36ba6da90L, 0x34e829d7474e83L } + }, + { + { 0x4cea19b19c9b27L, 0xa14c37a5f52523L, 0x248b16d726625cL, + 0x8c40f9f6cabc21L, 0x918470c32a5c65L, 0x314056b2a98d5bL, + 0x6c974cf34a0714L, 0x0c8f8a94f6314aL }, + { 0x484455770bccfdL, 0xf5835db740c9fdL, 0x12e59b5a21407cL, + 0xbe338e0db1689dL, 0x5a50ce9dd5e915L, 0xb1780e9ef99f39L, + 0x1262b55ee4d833L, 0x4be3f2289c5340L } + }, + { + { 0xbb99b906c4b858L, 0xa7724d1550ca53L, 0x7d31f5a826962eL, + 0xf239322a5804daL, 0x3e113200275048L, 0xcbb1bb83ee4cb6L, + 0xdb865251331191L, 0xb7caf9e7d1d903L }, + { 0x06e3b0577d7a9dL, 0x7a132b0b3bbbf5L, 0xd61fbc57c50575L, + 0x393f712af4b646L, 0xef77972cb7efe9L, 0x20e6d5d5ea4995L, + 0x0ac23d4fbbe4c6L, 0x8456617c807f2aL } + }, + { + { 0x4995fb35396143L, 0xa8b4bd1b99dc46L, 0x2293e8e4150064L, + 0x2f77d4922a3545L, 0xe866b03b2192c4L, 0x58b01f05e0aa38L, + 0xe406b232ed246bL, 0x447edb3ed60974L }, + { 0xf541b338869703L, 0x6959fe0383420aL, 0xd6b39db4be4e48L, + 0x048f3b4b5714efL, 0x68b49685d9e4b8L, 0xbda8e6c2177963L, + 0x5094e35c4211feL, 0xea591c32d46d1aL } + }, + { + { 0x3a768ff2fef780L, 0x4218d2832970c6L, 0xce598e4ec6da17L, + 0xf675645fbb126aL, 0xb04c23f0427617L, 0xc9f93fbe4fce74L, + 0x44a414b3c91b00L, 0x4d982f31d3b3ccL }, + { 0xb1d40e8b24cce0L, 0x5a21c07133e73dL, 0x6e9358e0bb589dL, + 0x39cfb172399844L, 0x83f7647166080eL, 0xcfe7bf8450b468L, + 0x2a288f71e8434fL, 0xd39f1e521a81e3L } + }, +}, +{ + { + { 0x78c6f13528af6fL, 0x0001fe294b74d9L, 0xae7742501aab44L, + 0x7cbe937ef0039cL, 0xaf3e4f00fa2a67L, 0xe28175fda1378eL, + 0x72adeed8ccd90eL, 0x16a8ce100af22fL }, + { 0x69fae17cbf63ddL, 0x67861729e39e26L, 0xe92b3d5f827a18L, + 0x4d75e418403682L, 0x01a4fd99056a79L, 0x89efb2d20008f5L, + 0xa2f6918b78ff15L, 0xf41c870a3437f5L } + }, + { + { 0xc840ae57be353cL, 0x465a5eb3fb2691L, 0x34a89f07eba833L, + 0xf620896013346eL, 0x563b5f0e875df2L, 0x5f7fc8bfbc44ceL, + 0x22fcb5acfedf9dL, 0x7cf68d47dc691bL }, + { 0x37f7c2d76a103fL, 0x728a128fd87b7dL, 0x7db2ad8ccf2132L, + 0xa4c13feb100e63L, 0xcd28a517b511d5L, 0xb910280721ca5cL, + 0xec1305fd84bd52L, 0xb9646422729791L } + }, + { + { 0x83fccdf5bc7462L, 0x01f3ddad6f012fL, 0x57f11713a6a87cL, + 0xedb47ceff403acL, 0x6c184e5baab073L, 0x5b17c7d6f0d6a1L, + 0x45a4c4f3ef2c91L, 0x26c3f7e86a8f41L }, + { 0x81a6db0b646514L, 0xf84059fca8b9aeL, 0xd73dab69f02305L, + 0x0de3faec4b7c6cL, 0x18abb88696df2fL, 0x45dd1b975d7740L, + 0x3aeccc69ee35bcL, 0x478252eb029f88L } + }, + { + { 0x66bf85b8b2ce15L, 0x1175425335709dL, 0x00169ef8123874L, + 0xfd3c18c9b89868L, 0xb3612f9775204eL, 0x4b8d09dc2cd510L, + 0xafa12e614559adL, 0x1ddaa889657493L }, + { 0x87d700b1e77a08L, 0xaf4cf2f14d2e71L, 0xe00835dbf90c94L, + 0xb16a6ec6dc8429L, 0x02a7210f8a4d92L, 0x5a5ab403d0c48dL, + 0x0052b3ab5b9beaL, 0x6242739e138f89L } + }, + { + { 0x7c215d316b2819L, 0xdacb65efeb9d7aL, 0xc3c569ed833423L, + 0xbc08435886a058L, 0x132c4db7e5cb61L, 0x6373a279422affL, + 0x43b9d7efca9fc4L, 0xe3319a5dbe465fL }, + { 0x51d36870b39da7L, 0xcb6d7984b75492L, 0x77eb272eadd87aL, + 0xf2fb47de0d3f6cL, 0x807fd86f9f791cL, 0xf01086b975e885L, + 0xf9314b5b6a3604L, 0x8cd453867be852L } + }, + { + { 0x7c1e6b3858f79bL, 0xf0477c4938caf9L, 0xb311bbf3e88c44L, + 0x9234c091e3a3c1L, 0x531af2b95a1d4dL, 0xf3cc969b8d1c64L, + 0x6f3c328b51e78dL, 0x5a1bd6c34e8881L }, + { 0x2e312393a9336fL, 0x020f0cc5ced897L, 0x4b45d7b5fab121L, + 0x8068b1c1841210L, 0x1bd85fc8349170L, 0xfe816d80f97fe5L, + 0x108981814b84fcL, 0x1d4fabbb93cd48L } + }, + { + { 0x1f11d45aef599eL, 0x8d91243b09c58aL, 0xd2eec7bd08c3c3L, + 0x5a6039b3b02793L, 0xb27fed58fb2c00L, 0xb5de44de8acf5eL, + 0x2c3e0cd6e6c698L, 0x2f96ed4777180dL }, + { 0x67de8bf96d0e36L, 0xd36a2b6c9b6d65L, 0x8df5d37637d59cL, + 0x951899fc8d9878L, 0x0fa090db13fcf8L, 0xa5270811f5c7b4L, + 0x56a6560513a37aL, 0xc6f553014dc1feL } + }, + { + { 0x7f6def794945d6L, 0x2f52fe38cc8832L, 0x0228ad9a812ff5L, + 0xcd282e5bb8478aL, 0xa0bc9afbe91b07L, 0x0360cdc11165e2L, + 0xb5240fd7b857e4L, 0x67f1665fa36b08L }, + { 0x84ce588ad2c93fL, 0x94db722e8ff4c0L, 0xad2edbb489c8a3L, + 0x6b2d5b87e5f278L, 0x0265e58d1d0798L, 0xd2c9f264c5589eL, + 0xde81f094e4074dL, 0xc539595303089fL } + }, +}, +{ + { + { 0x183492f83e882cL, 0x4d58203b5e6c12L, 0x1ac96c3efec20bL, + 0xabd5a5be1cd15eL, 0x7e1e242cbbb14bL, 0x9f03f45d0543b3L, + 0xc94bc47d678158L, 0x7917be0a446cadL }, + { 0x53f2be29b37394L, 0x0cb0a6c064cc76L, 0x3a857bcfba3da3L, + 0xac86bc580fcb49L, 0x9d5336e30ab146L, 0xafb093d5bc1270L, + 0x996689de5c3b6eL, 0x55189faea076baL } + }, + { + { 0x99ef986646ce03L, 0xa155f8130e6100L, 0x75bef1729b6b07L, + 0xc46f08e1de077bL, 0xf52fdc57ed0526L, 0xe09d98961a299aL, + 0x95273297b8e93aL, 0x11255b50acd185L }, + { 0x57919db4a6acddL, 0x708a5784451d74L, 0x5b0bd01283f7b3L, + 0xe82f40cc3d9260L, 0x2ab96ec82bbdc2L, 0x921f680c164d87L, + 0xf0f7883c17a6a9L, 0xc366478382a001L } + }, + { + { 0x5c9aa072e40791L, 0xf0b72d6a0776bfL, 0x445f9b2eaa50dcL, + 0xa929fa96bda47fL, 0x539dc713bbfc49L, 0x4f16dd0006a78bL, + 0x331ba3deef39c7L, 0xbfa0a24c34157cL }, + { 0x0220beb6a3b482L, 0x3164d4d6c43885L, 0xa03bb5dacdea23L, + 0xd6b8b5a9d8f450L, 0xd218e65bd208feL, 0x43948ed35c476fL, + 0x29a0dd80a2ed2bL, 0xa6ccf3325295b7L } + }, + { + { 0xf68f15fac38939L, 0xb3dd5a2f8010c1L, 0xf7ac290a35f141L, + 0xdc8f3b27388574L, 0x7ec3de1e95fed2L, 0xc625451257ac7dL, + 0x66fc33e664e55aL, 0xd3968d34832ba5L }, + { 0x980291bc026448L, 0xfcb212524da4a5L, 0xbca7df4827a360L, + 0xfcc395c85ca63bL, 0xcf566ec8e9f733L, 0x835ee9bd465f70L, + 0xe66d111372f916L, 0xc066cf904d9211L } + }, + { + { 0xb9763a38b48818L, 0xa6d23cc4288f96L, 0xe27fcf5ed3a229L, + 0x6aebf9cabaff00L, 0xf3375038131cd1L, 0x13ad41dffabd58L, + 0x1bee6af861c83bL, 0x274fe969c142e7L }, + { 0x70ebcc99b84b5bL, 0xe1a57d78191cfcL, 0x46ccd06cbf00b8L, + 0xc233e8eefe402dL, 0xb4ab215beebeb3L, 0xb7424eabd14e7bL, + 0x351259aa679578L, 0x6d6d01e471d684L } + }, + { + { 0x755c465815ae38L, 0xadc3e85611db56L, 0x633999b188dd50L, + 0xfdf7509c12d907L, 0x25bcfde238b6afL, 0x50d705d397f5e7L, + 0xb65f60b944c974L, 0x8867fc327ac325L }, + { 0x2edc4413763effL, 0x892c0b3341fb63L, 0xb34b83ab3a7f28L, + 0x9aa106d15c2f18L, 0x720bbc61bb2277L, 0x637f72a5cfaefdL, + 0xf57db6ef43e565L, 0xceb7c67b58e772L } + }, + { + { 0x2793da56ecc1deL, 0x4e1097438f31b2L, 0x4229b4f8781267L, + 0xe5d2272dec04a1L, 0x6abb463ec17cffL, 0x28aaa7e0cbb048L, + 0x41dc081d22ef85L, 0xcbc361e5e63d0fL }, + { 0xb78aafcad5dbaaL, 0x0111505fc1edc3L, 0x63ed66d92c7bfaL, + 0x2982284e468919L, 0x30f1f21b8c0d8cL, 0xf0567472685093L, + 0x0e085b6f03dd0fL, 0xa8c8db85581e66L } + }, + { + { 0x42009a6264ad0cL, 0x13bf2b8593bef4L, 0x1d111905d4e8b1L, + 0xfe3e940ef7bddcL, 0xa012275624e62cL, 0xcb659241d6d3ccL, + 0xc7bcc70edb7ab6L, 0xff9fafbb750b1cL }, + { 0xf65df297fea84bL, 0x17c84a890b0e02L, 0xa92a859301e821L, + 0xbee8cb2fb480d1L, 0x7010b8c59c604eL, 0x47bf3f4e803c43L, + 0xd64514247b3fffL, 0xc4c5dcb9f0da13L } + }, +}, +{ + { + { 0x8af700cb5253b3L, 0x31ca605206957aL, 0x25744393eafdcdL, + 0x2ba5ae1d3ae15eL, 0x710b7385b82579L, 0x145ab57112b95aL, + 0x4b133a038c55c5L, 0xf7559c92a16fefL }, + { 0x70c3e68d9ba896L, 0x475dd32c33d07aL, 0xe084e473a41e40L, + 0xddc9382fd2e706L, 0x34b727579510bdL, 0x5e78a69a5f901eL, + 0x429dfd7dcfb823L, 0x1d9dc18014f0a3L } + }, + { + { 0x364fcdfaf403d7L, 0xd9ea4ffb7d7b34L, 0x21a3426cbb1dacL, + 0xfa51052143b4f5L, 0x2bca0736df2409L, 0x7e6985a8ad7285L, + 0x3a1a9d04aaa27fL, 0x1a815e19fc0c6cL }, + { 0xfab6147bb65bb3L, 0xa36dc0d33ced0bL, 0x26a88592062d78L, + 0x343861728a5fb7L, 0xe82da254ebb1adL, 0x70f5071d05aa11L, + 0x0b7f847adaac48L, 0xeb812bc93cb269L } + }, + { + { 0xcb317ccf7cacccL, 0xd3410d9cf85098L, 0xca68c8d7f078d7L, + 0xfe9e812b782efcL, 0x32e7c0f5f544b5L, 0x44fe95a3a7b7f2L, + 0xf4f1543e91327bL, 0x27d118d76645edL }, + { 0x690547cd7abc2cL, 0xf64680fb53c8afL, 0xbe0cbe079ea989L, + 0x6cf0ccea91af28L, 0xa3b85a29daa2f9L, 0xd4b663c91faed0L, + 0x782c7b7a8b20baL, 0xf494fafb8d98ceL } + }, + { + { 0x080c0d7002f55aL, 0xf4f8f142d6d9ddL, 0xb326229382f025L, + 0x58fd0b5ad28c20L, 0x704b9928d06a15L, 0xf4545d97fbd8e4L, + 0xc32fa63ed55581L, 0x3ab793601ac0fdL }, + { 0x13ece526099fd1L, 0x776dba89c79178L, 0x8d28212ce26c45L, + 0x09fddaf60d739cL, 0xf9931eda84826eL, 0x6e73d90b29439eL, + 0x94cfefc9095e61L, 0x3050d16802f474L } + }, + { + { 0x0898f8f9f6394bL, 0x48b8cea88b0e91L, 0x4bc99254c1b362L, + 0xe3fccb4827d9ecL, 0x5d4cf9ad950d6aL, 0xa16f1ef39b5b38L, + 0x3c76d1d620f288L, 0x9fdd059e119390L }, + { 0x7b5de9efb5edf8L, 0x3e290b9769d14eL, 0x4df3a916bd10b5L, + 0xae99bca82f8f7bL, 0x5481d5dc9524afL, 0xf112e4f69504f1L, + 0xb048f0951931ecL, 0xbff876a18f51b1L } + }, + { + { 0x932e2a746c1c37L, 0x903ad529aea4c1L, 0x717ac918f161f2L, + 0xa57d197f425e2aL, 0xae89dac7f39e0eL, 0x91655c0baa2a58L, + 0xe3dc28654836ddL, 0xb5f0baaa9ec9e6L }, + { 0xf7c4662bdbda04L, 0xbe5393b51059c0L, 0xb16d552dd95b0fL, + 0xde495b31b3bd96L, 0xb2a6e02c0206c5L, 0x045cc09014d3a9L, + 0xf66a3152a2f490L, 0x208c108c5dea05L } + }, + { + { 0x6e38b6865237eaL, 0x93a13039f27fc6L, 0x9a6d510a95068aL, + 0x6fbf216e7c9e54L, 0x7824290571ac1dL, 0x8cb23ba91c2a0cL, + 0x611202ec7e434dL, 0x8f901bf76058b4L }, + { 0xef0ac050849588L, 0xe0d2ddedd31804L, 0xaf5417ceb2ca81L, + 0x420ac065d1a509L, 0x46e345e9683bb6L, 0x6daf635f613f7fL, + 0xc9e829148a9576L, 0x5f9f1d1176d147L } + }, + { + { 0xd24ae1d77e9709L, 0x77751dc0047b8aL, 0xe325334c6a1593L, + 0x9baf962671f86aL, 0x425af6ac29a15eL, 0x31086002796e33L, + 0xb6ea78cfc253a5L, 0x4c733e0afae0eaL }, + { 0x4b7443a97c99b9L, 0xc14e9e450203a6L, 0xd1bb51552680baL, + 0xa56a3efd55533aL, 0xa66e38c169e1a0L, 0xb3e4df9eed7da0L, + 0x022c937ddce3d9L, 0x8552089f6e36b4L } + }, +}, +{ + { + { 0x8e4bf95f5cc82eL, 0x2ad80c3c3ed6c9L, 0xf2e5b2cc9045e1L, + 0x42c906559b06d4L, 0xc1f73797b43b84L, 0x1710dbf72d7992L, + 0xe98cf47767b41cL, 0xe713fce7bfb9e9L }, + { 0x9f54ae99fa5134L, 0x3002fd8de40d0eL, 0xdc282b79311334L, + 0x5519810bfeb360L, 0x31539c70f96ffeL, 0x04eacc0d27777bL, + 0x59824108ff5053L, 0x598236632b67adL } + }, + { + { 0x6eb45546bea5c2L, 0x82cfae0d509a33L, 0x6a69bd8394bb59L, + 0x1880d8d5770ee1L, 0x63518447dacf9eL, 0x5b1ecc5f02b891L, + 0xeb7d900b6c9a5aL, 0xdab8a768897da8L }, + { 0x28c7be598851a6L, 0x0101d4f4d73c3bL, 0x3c2569c5084996L, + 0xb9bc911280bde0L, 0x513a22acd0d4f9L, 0xdf2986d2a15f3bL, + 0x231c28f2aa4943L, 0x29623ad0333870L } + }, + { + { 0x2ceb1784084416L, 0x924cf1c49516cdL, 0x76536c04be856fL, + 0x11b59cd47a265bL, 0x720dc844999494L, 0x910f794007b795L, + 0x8434e142d3df83L, 0x8f53878bd478d3L }, + { 0xd9b072eaeb9c2fL, 0x16f87eafd8a29fL, 0x8c42f9b2fd0de1L, + 0x916721e0e816efL, 0x2ecb47018bde37L, 0xcde3b7a2375da2L, + 0x30d0657ef94281L, 0x51054565cd7af8L } + }, + { + { 0x7230b334bdced3L, 0x0c6a3e10838569L, 0xf19c9ece3493b8L, + 0xf2759270d97c57L, 0xf14181e0c862ebL, 0xfd3bac132c72bcL, + 0x620563ff3be362L, 0x672ccaf47283b7L }, + { 0x191e3fa2b7bf16L, 0xf838633520dad7L, 0xd3dde553629d87L, + 0x14d8836af86ebeL, 0x3db7dfb221b2ceL, 0x3872abb0aed72aL, + 0xb60de528c665b7L, 0x89c259644982cbL } + }, + { + { 0x799a2de4dbba25L, 0xd818aaea42715eL, 0xbc88f4df55c362L, + 0x142a163713c9aeL, 0x411e8eefbfb33fL, 0x34b46296bb684aL, + 0x4344becdc81817L, 0xcc9573d17f9d46L }, + { 0xf85f8bcff38a7dL, 0xa14bf730caf117L, 0x126874f4ba6429L, + 0xcc9bf22aa5db97L, 0x62b56df6aba827L, 0xfee1cb89c9772aL, + 0xe36838f177e541L, 0x698815dadd438fL } + }, + { + { 0xc9fd89438ed1adL, 0x73cd79d7b6a601L, 0x2210e6205e8d20L, + 0x72384ac3592af5L, 0x5ccc079763d07eL, 0x2f31a4aa5f79ebL, + 0x693f4ed2945a95L, 0xc7120178056fdcL }, + { 0x361ecd2df4b09aL, 0xa5644eab7d929aL, 0x34abc0b3fabe9aL, + 0x1a2473ce942a8cL, 0xe00c9246454bc3L, 0xab324bcdff7366L, + 0xe1412f121b8f99L, 0x970b572e33551eL } + }, + { + { 0x6ca4cacbd0a6b5L, 0x5584787921d654L, 0x18e5253c809bdaL, + 0x01b32c3f0cbe5eL, 0xb9aa7540f987ddL, 0x628f4bb6dfa4dbL, + 0x0255f0b891890bL, 0x25b7df4874e590L }, + { 0xbded3188ed5f95L, 0x9dc428dca93023L, 0xc68f25abccf520L, + 0xc4f3764e616e6cL, 0xd9a57f1a1d9993L, 0xd1964a5533431bL, + 0x06cd77f02ab6d0L, 0xa66079103e52e0L } + }, + { + { 0xab088645f72700L, 0xf77b2ff0a1a44eL, 0x43ebdd8c2a24b5L, + 0xa6d67114f564d7L, 0x495df63f414160L, 0xf5bacd776f6de6L, + 0x3011aff7c2b43dL, 0xbb1e64c3241928L }, + { 0xf70c5725034073L, 0x891c62a68f1e97L, 0xed8eb2eb22e374L, + 0xd3a53e97dbcc2fL, 0x1d06281dc8f220L, 0x9eef48face4393L, + 0x96014f5d2abecdL, 0x1da7e092653cebL } + }, +}, +{ + { + { 0x7593318d00bc94L, 0x586f3c6c7262a2L, 0xea68f52958ad31L, + 0x6707fccd4e8bedL, 0xb7e35d6cb3f9ceL, 0x2cbb6f7f4b1be8L, + 0xa5352687b41aeeL, 0x1d77845f7b39b8L }, + { 0xb1f3995eaf9554L, 0x3250f70fe9e7d4L, 0x62e5d1ba00c23cL, + 0x5e422f5c10e3bfL, 0x7a18039c25cec4L, 0xb4e66a17cc4d5bL, + 0xad7c5f636d0e0cL, 0x9f40b12a4cf347L } + }, + { + { 0x697f88251e3696L, 0xc89bc40ab0a648L, 0x8f261a59785804L, + 0x4c7f900b51a2bdL, 0xd00e7af8a2dfcfL, 0xf9c534db642aebL, + 0xea2a79fb63df0eL, 0x392a69af2f64a4L }, + { 0x0c0f01cc331b6cL, 0x414bf2e6a5edb5L, 0xfe5ed815068391L, + 0x0a8078d62fbc34L, 0x78a438254bca98L, 0xf7a49ae3d727c7L, + 0x96c1de1ab4dffeL, 0x45901f73b9440aL } + }, + { + { 0x3f1189facfe46eL, 0xdca6f464467443L, 0xac385422eb5bcfL, + 0xb02dce9906bf72L, 0xdd8cdacfe1d454L, 0xc26f04c65f7218L, + 0xb4748596ea145dL, 0xc53dc6b5bdb315L }, + { 0xbe5be749ad7197L, 0x627e91918b5eccL, 0x57c889c9ea405dL, + 0x2e5650c1a5360bL, 0x42290df1b30b27L, 0x4a071575242687L, + 0x553ed1fd379133L, 0xb9d7a0701db019L } + }, + { + { 0xcfe551c56597dcL, 0x81af92a925ebd6L, 0x83efe16f4e8d57L, + 0x61bb4311f640d3L, 0xf80440f78b414aL, 0x72f3c636c9e3b4L, + 0xb55f43a6a03c66L, 0x47a9dede417037L }, + { 0x1a7e287dbb612bL, 0x895c3c7dbb9220L, 0xd50c86e6c04764L, + 0xed5269853cf7caL, 0xc78d799f74af55L, 0xb2ba0f2b969ff2L, + 0x06d48151c6530bL, 0x764a1fe165a575L } + }, + { + { 0x4383a3bc1b5eceL, 0x0563c8854ff148L, 0x9a452795af796eL, + 0xffba7c088e9953L, 0xfe9fb5eb6a3001L, 0x795098825b6b19L, + 0x67c899ad81be5eL, 0xc89ac8d2f9d29bL }, + { 0x7c76ba329ab8f7L, 0xb2a18c96e40f74L, 0x1b5056e3864d9bL, + 0xdfa503d9b582b8L, 0xfb035197c9c68eL, 0xdc501316b3c22bL, + 0x38ab231a6c96ffL, 0x4ea527c8cb1c10L } + }, + { + { 0xd632f20c05b4edL, 0xe0199fab2a032dL, 0x373295626812d7L, + 0x2aed855013df13L, 0x92ca24b39f96acL, 0x620273dbb9751aL, + 0x5d0d21ef7437a1L, 0x9de2a43077de56L }, + { 0x0569b1211a4674L, 0xfc3923e89c3989L, 0x3d127042c5c770L, + 0x0072b9084e8c37L, 0x7178d4dac39f9aL, 0x5f8292f778d345L, + 0x9e5bf0f77c7307L, 0x7691610c3a20f5L } + }, + { + { 0x7c4ead5705fe96L, 0x377ec35c8e464cL, 0x3e5b9907689954L, + 0xc0f6949a2d31eaL, 0x839d395c580671L, 0x2f347a6b215b09L, + 0xfdcfa33683df83L, 0x6e12cc26af39a8L }, + { 0xae46ec813a3bd2L, 0x03a7d3b59366f8L, 0xe2029d5b87aed4L, + 0xbdc4e43fe1b83dL, 0x768437cdb8a1a8L, 0xe47acc3ea0dd7fL, + 0x550e0cc62a0af4L, 0xcaf2cbc1a20962L } + }, + { + { 0x5a784f7f28a78fL, 0x952a9b507e9724L, 0x8ac5e411bab7a3L, + 0x1251e3fb7bc1e1L, 0xe360f82dc15e22L, 0x3ac72da95213f5L, + 0x65ee9ba4dcd47bL, 0xdfeab7b3af5952L }, + { 0x34c5c8026fd3c6L, 0xd977b08f3ac7eeL, 0x003bd017dba2f6L, + 0xcfc5cf8ac98c8dL, 0x05eb6040e46922L, 0xc248b17faa9352L, + 0xfa41c0f395c7a7L, 0x29931d4b71ee44L } + }, +}, +{ + { + { 0xac087bb07861c5L, 0x3bd37db5ae8240L, 0x94c68ecf94518fL, + 0xd32a378ff88a5bL, 0x42c8aaf9b441d1L, 0x089db70fc07f12L, + 0x211c386d3d4455L, 0x1db9af7546b158L }, + { 0xdfd1b6551bc927L, 0x69c04930733df4L, 0xdc72cd42aeb586L, + 0xeebdace823aa13L, 0x51b3b3c56ad643L, 0xb983a99d4e0426L, + 0xa1e5b6c69c4eccL, 0x37cd38245e6668L } + }, + { + { 0x158ce6d9f73aeaL, 0x36a774914ff475L, 0x0d4e424dc0b018L, + 0xc2c44483946f09L, 0x7a7de3ffacda62L, 0x49a19e6b486709L, + 0x65094d8db61da7L, 0x09edfd98f5ee87L }, + { 0xe460fcfb37226dL, 0x3b9d03969bf470L, 0x3d4d511247ca22L, + 0xc7248d6c782cb1L, 0x91189a000ad293L, 0x1244942e8abe75L, + 0x9f88d12bf52cdbL, 0x368463ebbbcadfL } + }, + { + { 0x419e4b38074f45L, 0xd3f8e2e0771c83L, 0xd2743b42e68d34L, + 0xc68b7dbb116a00L, 0xfad2cf7d84cc37L, 0xcfd27c0b7a0f4dL, + 0x3b9e23f190e587L, 0x7bab499751ca9eL }, + { 0x3270861a8f12eeL, 0xee1f38d31b36d5L, 0x748bb31e4c0eedL, + 0x9be5c9b110ebadL, 0x728660bc8b6cb6L, 0x7bc9df793d914aL, + 0x73a4f2cc88c859L, 0xbe4a2fdb4e7f0eL } + }, + { + { 0xe566ff8a450e77L, 0xb0b40066a13abaL, 0x483a510cd7dc90L, + 0xb1a20135fa9cccL, 0xeb0b631a80e67cL, 0x7c34e1f020801aL, + 0x0257dc8f4e447cL, 0x7abe7d174c6f0fL }, + { 0xf115a3ab19a576L, 0x8f0474a064ca0eL, 0x999bb6b351f99bL, + 0x855254b773edc3L, 0x49f6c2f427d717L, 0x9f682532e0cef2L, + 0x1fe126c2ee34f5L, 0x1ec2cae80150f7L } + }, + { + { 0x862c5afc005b7aL, 0x61adea7ec4ef17L, 0xf885fd3007b446L, + 0x25c129d9b0e30eL, 0xbc10f25feec7e0L, 0x3901ac4df79ee1L, + 0xad49db7fe9e19fL, 0xc8624d9360d050L }, + { 0xc74a576bf3260bL, 0xbde80248c010c2L, 0xf15532909b6977L, + 0x6a5a82ed52dcf8L, 0x4fbf59d29b9dfcL, 0x337d049c7b730cL, + 0xb3deac63a89cd4L, 0x1e07595ad2f2ebL } + }, + { + { 0xa0b0a4d3b7c84eL, 0xf132c378cf2b00L, 0x192814beaaa8ecL, + 0xe7929f97b4b5dfL, 0xf08a68e42d0ab7L, 0x814afb17b60cddL, + 0x78c348c7d9c160L, 0xf8a948844db217L }, + { 0xcdefd88eaa2578L, 0xf717f56bd0e260L, 0x7754e131694d02L, + 0x1254c14181dbd8L, 0x0dacdd26e5f312L, 0xb8abdfbcef87bfL, + 0xb985972e74e2eaL, 0x1717621002b424L } + }, + { + { 0x92cc75e162df70L, 0x1e20c0618ee849L, 0xc036b4626aa590L, + 0x31be67e4da5155L, 0x04911b5f7213b0L, 0x39261d7bb2e72eL, + 0x9e844665c015a3L, 0x2f59fc0298ae67L }, + { 0xa3ea7ba1701fccL, 0x87a5fa90ebd651L, 0xa607ed4301d7b1L, + 0xbd4ec5f3b2e271L, 0x732a1a2dc4180fL, 0xbe15d82feaa8c1L, + 0x103670266f2f3fL, 0xccfd3979e79ce8L } + }, + { + { 0x82ab83570a54adL, 0x5c1dee8e3bec75L, 0xf583ff454b556bL, + 0x9220199f461e60L, 0xdf61ca887fc4e7L, 0x6641fd20776dadL, + 0x00c6edd8edd061L, 0xaf9b14255f7e87L }, + { 0x73f15e49bbe3ecL, 0xdd3b788f8bc1faL, 0xb24cc071b8ff86L, + 0x6c260d241be58bL, 0xec1c4e36b10adaL, 0xf6b42097fdb985L, + 0x0d0ac85d47c212L, 0x967191c07d78d1L } + }, +}, +{ + { + { 0x3b11638843d0f3L, 0x4b89297f27f10eL, 0x477236e863ba2aL, + 0x1949622add280cL, 0x7cd523504da757L, 0xe0e99d279e4ff7L, + 0xb4ef894537da41L, 0xc55dde45a24ff1L }, + { 0x18d8e21b587521L, 0x8010b5d3777833L, 0x4af522dd3a54c8L, + 0x7cd476b4c0ac13L, 0x4587e614099f67L, 0x494d0ed605ee64L, + 0x3218ba2cc80903L, 0x5ff56aa0b2e169L } + }, + { + { 0x51ec94e3a06c69L, 0xa26d7be5e65c52L, 0x156f113d44ee96L, + 0x70f0968bf5b9b4L, 0x9b7e4695f5332dL, 0x36c295f6703829L, + 0x1522690d04f492L, 0xcf35ca4728043bL }, + { 0xf9ca3e1190a7c3L, 0x53d2413f971b07L, 0xae596529c48b49L, + 0x74672b8fefff5cL, 0x0a3018ba7643b0L, 0x51919e83e9b0a8L, + 0x89ad33dc932fb5L, 0x52a4419643e687L } + }, + { + { 0x7778990d2d0acdL, 0x3bdbcce487fdf1L, 0xdc413ca2b03dd2L, + 0x278755b9a2b7d0L, 0x4ebb8b535ddd7fL, 0x0465152bcbdb92L, + 0x34f22d6671d051L, 0x1ba04c787192b9L }, + { 0xb1693f483560c1L, 0xe08a5937d174e9L, 0x47ffdc464dc9afL, + 0x1123596ce8126cL, 0x632d95f1124628L, 0x66287abfee7c76L, + 0xb40fe60c552332L, 0x3f11729e304e1eL } + }, + { + { 0x97a6ea05030a8cL, 0x692419809c27b2L, 0x3308501ac9dd5dL, + 0x9fed7fabe73fdcL, 0xea555440535286L, 0xc7c07ab6c9b832L, + 0x178c882c51b967L, 0x6fa0c6986ee075L }, + { 0xbaa4a15b8b5c4aL, 0xf83c0ea3130c0aL, 0xcf8624b2800331L, + 0xade85cd7ccbcb8L, 0x971d7f6f08445dL, 0xfd480b76a546dcL, + 0xdc15a38c93761cL, 0xc4c495c9d04631L } + }, + { + { 0x5f4cee89470efeL, 0x9fe896188d93adL, 0x24783b3f4e49ceL, + 0x1bc7ed752ffb3eL, 0xa3abe6a6d81e17L, 0xd6bb8b47a333c3L, + 0x3485c0b10a3527L, 0x7cddc9c31a9d10L }, + { 0x0c78112c38ca37L, 0x10e249ddd2f8d8L, 0x72c88ccc511911L, + 0x4d75b5a29a6c84L, 0xc74b267a227b1eL, 0x698390cf8e35adL, + 0x8f27edfe98d230L, 0xec922f26bdc7f4L } + }, + { + { 0xac34023fc32e11L, 0xe0ae2f547200d1L, 0xa7c7492bd98c82L, + 0x3910b687b02154L, 0x6fdd06ce28ab6dL, 0xd3a7e49d98b012L, + 0x4c1c82b9f54207L, 0xef5bbe645c176fL }, + { 0x3d17960d3e71ebL, 0x90d7e84080e70cL, 0x83e6438bff5d9eL, + 0x1877e1f535d85cL, 0x931ed6efbb69ccL, 0xcf962651247848L, + 0x76d618b750da4eL, 0xc076708717fbf6L } + }, + { + { 0x80a5ac5eec5126L, 0x6d05dd13379c80L, 0x514b0892336d32L, + 0x586c0066725137L, 0xab2365a574f954L, 0x3c89ea0ac7d356L, + 0xf1f2edd27460baL, 0xf200ddbab9870fL }, + { 0xc8f1b2ca35e885L, 0x5d22f86e6e7550L, 0x24b9a409554615L, + 0xcb41107616314fL, 0xca752f0c976a11L, 0x3e2f839a08291aL, + 0x0cff22ff2c420eL, 0xafd603e82b9747L } + }, + { + { 0xaddeddc810a3daL, 0x78b6c2dd3a87bfL, 0xbc7020bde3a04cL, + 0x47ab9739b6d045L, 0x3b046d60959358L, 0x0f953e7509ee3eL, + 0x803dc8669fc61bL, 0xcceaec0893c8d4L }, + { 0x21f8c40b048a45L, 0xb535073fcaea8aL, 0xe712c3590e360bL, + 0x5d0f3f48403338L, 0xe0ea26c7207f2dL, 0x20f6b57ffd9e05L, + 0xb97d68e4788b00L, 0xb1215541889cceL } + }, +}, +{ + { + { 0x0079817464238eL, 0x21103020d381caL, 0x1cc4c6ed9f01b5L, + 0x5e35dc55a131b1L, 0xb61848d06944ebL, 0x83792a029631a3L, + 0xbe1017fafca0ddL, 0x70aaa01782fcbbL }, + { 0xc63b7a099945e7L, 0xe9164ecc4486c1L, 0xb133e35885f2c1L, + 0x186f0d3c99ae02L, 0x2fca4922bf53e6L, 0xf922aa248a02bcL, + 0x4fe64900dd3dcaL, 0xe8c313ff6a8207L } + }, + { + { 0xc5b358397caf1eL, 0xa001922922a4b6L, 0x67e36bedf07c95L, + 0xabaa0aeb2f4f34L, 0x66dc926dedc333L, 0x82021c438ec5b3L, + 0x82b4f2600ab176L, 0x1b7c22e69c45afL }, + { 0x07b0dbe0924ad9L, 0xe030936a407ddeL, 0x66e1ce926ccd06L, + 0xb50c108e3505a9L, 0x8b921e1da98f51L, 0x449ca1a20cf7c7L, + 0xadb80c7e67d079L, 0x205aa54834372dL } + }, + { + { 0x1482b4819bf847L, 0xd6c16ab5906f0fL, 0x323fb1723ad060L, + 0x0346389c832be7L, 0xe71b2d82ee45bfL, 0x761c37dfb22276L, + 0xa9b33345d70be2L, 0x81a06565a0627aL }, + { 0x337750399a6282L, 0xafc8d2ed0436f0L, 0x22f71d3c53342fL, + 0x66ca56d8939ad3L, 0x15a919230e09baL, 0x261091ea6de890L, + 0x609d700e78f2d5L, 0x8aa52ee8eaaf78L } + }, + { + { 0xa398788ce76258L, 0x3031d07494b975L, 0x4a6d652043dfe2L, + 0xdb1a849b4401ecL, 0xf81ebbbce8bbccL, 0x937dd4716efe9eL, + 0x9c19350ef85eccL, 0x260d932214273bL }, + { 0x1d7e21e77bf1a3L, 0x199d689a544eb7L, 0x9da594194ced50L, + 0x71a60be8a0aeaaL, 0x183a0ae26d3b51L, 0x49f176a8df9728L, + 0x744376e3230674L, 0xb2cb21ae25541cL } + }, + { + { 0x7a721589a0071fL, 0xe19dd29e7d2a6bL, 0x3deb34e55113f0L, + 0xef1f8ebede573bL, 0xa8f7ff95665e37L, 0xa2c21eaf2d7777L, + 0x1387afa91e2e39L, 0x04057b97db68f6L }, + { 0x8b9d5ae1c241f7L, 0x689588a8e75993L, 0x79585b45c0e2d4L, + 0xba1ef167b64974L, 0x72685bc1c08a75L, 0xf0a5814d572eddL, + 0x71464a35ab0e70L, 0xc93c92b339aea7L } + }, + { + { 0x1917e2a5b8a87dL, 0xea5db763a82756L, 0x5bba2fb6420e2bL, + 0x5cc0501019372aL, 0xb1ef8beccc5efdL, 0xaf06393f49c57dL, + 0x3ab1adf87a0bc4L, 0x2ee4cca34fe6b6L }, + { 0xd1606686b8ba9bL, 0xef137d97efec13L, 0x7b6046550abb76L, + 0xb40ec2bf753a00L, 0x696ed22eaf8f1dL, 0x398c91fd8ba3d8L, + 0x11f203437db313L, 0xe1ec33bfe5079eL } + }, + { + { 0x8a10c00bdc81f0L, 0x5f392566fe8e05L, 0xa595dab14a368eL, + 0x32b318138cec6bL, 0xd77afde1b00d00L, 0x3c979284d9923dL, + 0x78f0e7a76e13ddL, 0x5ee8e59bf75675L }, + { 0x49ec89391b130cL, 0x9416182a47a441L, 0x54555b576e2ce8L, + 0xcbdd2fd349c40bL, 0x10ae7379392bbeL, 0x270b1112e2dab0L, + 0x5cb7712af293f4L, 0xfc22a33d6095c6L } + }, + { + { 0xdcb5bbd0f15878L, 0xbcf27adb6bba48L, 0x979913e7b70ebaL, + 0x4c0f34b158578aL, 0x53f59a76ed6088L, 0x19b3b2c75b0fc2L, + 0xad628dc0153f3cL, 0x5195a2bcec1607L }, + { 0x95f8b84dfe0f7aL, 0x935c6b0152920bL, 0x25f9e314da1056L, + 0x4910a94b28c229L, 0x54b03b48ee4d6eL, 0xc991fc3694e3edL, + 0x68c4c26dbe5709L, 0xc9cfce463d7657L } + }, +}, +{ + { + { 0x21c9227f52a44eL, 0x7f105a2e85bfbdL, 0x887781f6268fc2L, + 0x56ee808a2d7e35L, 0x14f9de52d3930fL, 0x4a4e356dcb561aL, + 0x87362267f95598L, 0x211c3425f34151L }, + { 0x8fcb75b0eaf9cbL, 0xcc9edf93d60ce2L, 0x54412c9a5fe627L, + 0x6036a72842dd09L, 0x71ce668a6c6099L, 0x02b30d75386764L, + 0xb69bed36f18e23L, 0x124c9b1d1de9f4L } + }, + { + { 0xe8f8d95e69b531L, 0xe1e115eaff1049L, 0x9087cd1eddea0cL, + 0x8ed55a57449916L, 0x8009f547808404L, 0x990f21617fea55L, + 0x68ba624fe8ecf9L, 0x8ac295056d1f47L }, + { 0x3257887529dfb0L, 0xc4a613f244c080L, 0xabb1ac028672faL, + 0xb2915c531eb291L, 0x6e368ca8fababaL, 0x6b8c2591fde498L, + 0x67724a1f2a548cL, 0x6b3b7e8f90409bL } + }, + { + { 0x5415003fae20aaL, 0x95858a985df5ceL, 0x42bc9870ac6beeL, + 0x8d843c539ea1a9L, 0x5de200cb571043L, 0x084fcd51741a33L, + 0xe1ca20c0009d1cL, 0x0271d28e957e6dL }, + { 0x84cbf809e3be55L, 0xc804dda1c578c6L, 0xea85489409a93aL, + 0x64a450a972021dL, 0xc6a2161e681312L, 0x280bff965bc111L, + 0xd358a4b0f8526fL, 0xd967be8953a3abL } + }, + { + { 0x4c5e6157dd066cL, 0x37afd33634c8d4L, 0xa3ac88a42d8b87L, + 0x9681e9b938b607L, 0x7a286ab37fe4c8L, 0xdeee5742494245L, + 0x184b9d36af75a8L, 0x20f696a3670c04L }, + { 0x1340adfa39e8b9L, 0x03c19290850b2eL, 0x435ebd42c0e1efL, + 0x49de18b142ee9bL, 0xb440b273f116f2L, 0xd94e9fa2214463L, + 0x1b0ddd36311543L, 0x1ae042a991ba3cL } + }, + { + { 0xbc322f85bb47aaL, 0x9e2562554a5845L, 0x96b65ae21115f3L, + 0x46fbed4bb5757bL, 0x18aec4f4c42dceL, 0xc59caf68d801f0L, + 0x91894631205521L, 0x66bd8e089feb7aL }, + { 0x39ebe95c529ee7L, 0x28d89928eadb99L, 0x6058c786927544L, + 0x877e7a5d3808ecL, 0x8f651111c52eafL, 0xfb59812ae221cdL, + 0x22289c6f890391L, 0xa97695b4966e92L } + }, + { + { 0xf0a91226ff10f0L, 0x49a931ba2a65c8L, 0x3fcebbcb1d3cb0L, + 0x70eb79bca9685fL, 0x82520b5ab38cb6L, 0xccf991b76304c3L, + 0x575aab1af8b07cL, 0xec8166a5ed5efbL }, + { 0xddc5698c8689b1L, 0x227c949b2e78d7L, 0x61323218e07d91L, + 0x658a11d22cfd62L, 0x908fb44004dd5fL, 0xe3d14f090d21b1L, + 0x6f3db9da6a1639L, 0x09d86c0333a525L } + }, + { + { 0xd83eaf06f043f7L, 0x88ab648b52d5f6L, 0x67c664d57144d7L, + 0x55d7644eafc8b5L, 0x1c89f20cceb291L, 0x51aec7b831ac47L, + 0x51172fa6148854L, 0x8fabf7ef6d7bfeL }, + { 0x5910316477ee27L, 0x5f299dd20fe61eL, 0x48079a842826abL, + 0xf4a83ba22591faL, 0x8fac66055482ecL, 0x48fd5f16b65b3bL, + 0x4288a7c9fd9e19L, 0x27db8199377894L } + }, + { + { 0x2936ee47fd9dd6L, 0xcce5f0e9ec87c6L, 0x15a50e3db6e3b4L, + 0x61df105ad701c8L, 0x3601add1dff1f7L, 0xb761e06e8a16e1L, + 0x4341e021af3f91L, 0x9156a4a933fa3fL }, + { 0x9dc46ae54bc01dL, 0x605577a64eb910L, 0x22b99f85a59a99L, + 0xab2dbaf0a229d8L, 0xa8bfb656599364L, 0x39ed4a5e94ebf0L, + 0x7b46a1e0dbb23eL, 0x117b1958751422L } + }, +}, +{ + { + { 0xd19e8fd423bddfL, 0x9d77042387ef59L, 0x315cbdd849590aL, + 0xfdc637c7866c1eL, 0x72be83d03515a6L, 0xd44a4a00376780L, + 0x3b9613119e0c2bL, 0x023aca37b1a689L }, + { 0xf5f368782282eaL, 0x44710898a8b5c7L, 0xcd2f00a17a3066L, + 0x754e11281ed681L, 0x9c6c70c0bfcefdL, 0xd6aced03b6f29bL, + 0xe443d562817a2aL, 0xe590ef4e7c0012L } + }, + { + { 0xc2f96763e62e2aL, 0x661816eb2daa26L, 0x3515fd2dd5f512L, + 0xdc36e2756b6e75L, 0x0bdde4674cc658L, 0x102908600e7644L, + 0xfdf00451694a09L, 0x454bcb6ceac169L }, + { 0xf4c92ab6481eb6L, 0x8b77afa09750e7L, 0xe6f42316362d6dL, + 0x0d45deef53a3aeL, 0xdac7aacd7dcf98L, 0x628cb7f125ec4aL, + 0x41e8a20aec0320L, 0x7418c7eea2e35bL } + }, + { + { 0x4d649abdf40519L, 0x8cb22d43525833L, 0x15f6d137a5333fL, + 0x8c3991b72c23eeL, 0x248b9a50cd44a3L, 0x6b4c4e0ccc1a75L, + 0x3221efb15c99a9L, 0x236d5040a9c504L }, + { 0x401c7fbd559100L, 0xcf0e07507c524dL, 0x39647c034a9275L, + 0x2355422f7e8683L, 0x3e0a16eb3ae670L, 0x1c83bcbad61b7fL, + 0x491bcb19ca6cbeL, 0xe668dc45e29458L } + }, + { + { 0xe44c65b219379eL, 0x211381bbb607eeL, 0xd4c7428b7bc6dbL, + 0xba62a03b76a2e8L, 0xe1729c98bb0b31L, 0x3caeb50c6bbc10L, + 0x6c66727b0187aaL, 0xbf9d2f0fb90dcfL }, + { 0xec693501184dc6L, 0xd58d2a32698eb5L, 0xb366d8da316b07L, + 0xe1e39bb251c017L, 0xbe44ba9adb157fL, 0xbaa9a9a8a8b06cL, + 0xd0f46356e473e1L, 0xd25a8f61d681c6L } + }, + { + { 0xba39d5fcb102c7L, 0x66eba21d8aa1ebL, 0xcc2591a697fbf4L, + 0x5adb5792317f54L, 0xa01ae71f76c6f9L, 0x2c525de5042705L, + 0xc8f42724f4479fL, 0x26ab54ae6d7a5bL }, + { 0xda217b5dc28106L, 0xc7cadeaeb2ae6aL, 0x0b1609453ea3b2L, + 0xcddcc1ccc6111bL, 0x5c47affa7a7bebL, 0xf9931bd0e52dabL, + 0x5231835c6dcf96L, 0x7095bdef27ea4eL } + }, + { + { 0xee8adaec33b4e2L, 0x300665163ceb44L, 0xf1476fb880b086L, + 0x07033289569ce8L, 0x2cabf9a238b595L, 0x85017bc26c8158L, + 0x420b5b568d5144L, 0xa9f5f1ef9c696fL }, + { 0x1409c3ac8fec5aL, 0x541516f28e9579L, 0x06573f70e1f446L, + 0x3e3c7062311b96L, 0x0033f1a3c2ffd8L, 0x8e808fcca6711cL, + 0x716752d07aef98L, 0x5e53e9a92525b3L } + }, + { + { 0xce98a425a1c29fL, 0xaa703483ca6dc9L, 0xe77d822edfa48bL, + 0xd2e3455068abcaL, 0xb456e81482cfcaL, 0xc5aa9817fbfb08L, + 0x8979f258243194L, 0x727f2172cd043dL }, + { 0x7cca616aa53923L, 0x387c5aee9bcb72L, 0x0173fd437580bbL, + 0xdd7795b75fc0d9L, 0x47d1c37345deaeL, 0x2eb5d7fb0d1c03L, + 0xf7a1b92958f002L, 0x7365cf48f61b67L } + }, + { + { 0x4b22c3b562a5edL, 0x711216f5c7cd07L, 0x51f72c49ba0648L, + 0xc10d0930de9e6fL, 0xaca479bfda63baL, 0x4722a55af532b0L, + 0x8d59eb77236f39L, 0x5cad8744465c34L }, + { 0xa2119e5722b0c1L, 0xb670264f343ea4L, 0x6910f02c19f387L, + 0xcfec5bc0381fbaL, 0x5f5de0d52c0a1dL, 0x4e474d56378cb6L, + 0x2fc802727e2ba3L, 0xa215da3159b541L } + }, +}, +{ + { + { 0xed535858499895L, 0xa0aefd565c998dL, 0x210d8502d5a561L, + 0xc2cc23ca2cd9d6L, 0x2371d46c4d297eL, 0x88b2143d18d441L, + 0xbebdad9043993dL, 0x6ba91e7ad5f28dL }, + { 0xc2bb3f13a731f4L, 0xd35cfac5d0d5c3L, 0x995099835ac427L, + 0x8938bb55458adbL, 0x0bd738cab26f3bL, 0x56db3d5a28cd8dL, + 0x87eb95fa1d8b4bL, 0xd6700efe7f3b4bL } + }, + { + { 0x962c920ea1e57bL, 0xd3be37e6dded6dL, 0xf499b622c96a73L, + 0x3eaf7b46c99752L, 0xa310c89025590bL, 0x535aa4a721db23L, + 0x56ab57819714a0L, 0xeecb4fad4048c1L }, + { 0x7b79ec4470c466L, 0xc4e8f2e1383ceeL, 0x0f5d7765750c45L, + 0xa3b3bc3725527dL, 0x2f5deb66d00cceL, 0x5d5a0f495a8d81L, + 0x50a442ee02b824L, 0xafb04462a11628L } + }, + { + { 0x72b67bc0c613deL, 0x0150d4be6f0b24L, 0x847854e8ed289dL, + 0xe08292fa320f88L, 0xd5b6da329c6160L, 0x2a48e2d4fb9d06L, + 0x55d9e412de087cL, 0x65683b54f02100L }, + { 0x4dc8c2ea8886c6L, 0xe966dd220d6114L, 0x99745eba57af97L, + 0x23a9a71b854725L, 0x8effe05621a047L, 0xf16d284049a4beL, + 0x95828c25b0660fL, 0xd5b69ba56e96b0L } + }, + { + { 0x0b5b4244ffa0b8L, 0x0585b45096cc5eL, 0x413e1aef505d37L, + 0xe5652a30c7ab8dL, 0xab32fb72990120L, 0x6b8b16e3f09368L, + 0xbf9fadbefe128eL, 0x85f366b14b7671L }, + { 0xcb2f294090608dL, 0x25e2769ac3045fL, 0x069c4f06131904L, + 0x1c57cf1329a779L, 0x72fe0d5b7cace7L, 0x04d9f430897a45L, + 0xbaf32f6359a645L, 0x0fa854ffa7485aL } + }, + { + { 0xae3533c5f56f60L, 0x9773bbb0ad9360L, 0x769b34a38fbe6bL, + 0xb5ba8e9ffb0c00L, 0xa93931875472e4L, 0x12cac92ce5f30fL, + 0x514fc06a9e7dbcL, 0xd7ca86558b4734L }, + { 0xd101ff365a730bL, 0x92da451abe70e9L, 0xfb5f94aef7bf4bL, + 0x8c3ef4c1d56c7bL, 0xb0857668435c10L, 0x7fbbbdae7ed4ccL, + 0x1da6eaf24f372fL, 0x0ab2c1f59b8ae3L } + }, + { + { 0x63a1a78f10a4b9L, 0xbb5278d0c7e510L, 0x97b224ef874142L, + 0x0a9ff52b2517b1L, 0x1b5a485c5cd920L, 0x1a8e2eba1823b9L, + 0x2b088c00e914a8L, 0xe5ec3adcf13432L }, + { 0x0d6ab3e6e7e253L, 0x9f0f5cd6f18458L, 0x839a744f459a6dL, + 0xb4b4f941eb15f7L, 0xe0313acc72cb14L, 0x58ee933b20472dL, + 0x5f73d7a872543eL, 0xb1700c5501f067L } + }, + { + { 0xb70428e085f67fL, 0x5441d5143cabe5L, 0x4d0e8c2e0a6055L, + 0x8d39a080882e4fL, 0x615bb32c1cb39dL, 0x113f18df7a1642L, + 0xbab8cf5250681fL, 0x3017ba2677b72aL }, + { 0xcd2b6e95a3a876L, 0x04765012035a69L, 0x31d6440efa2ea0L, + 0xde8f8d156874d5L, 0xcbc71cd0199d4aL, 0xc546b61e7f2170L, + 0x4e57e4e112c4c3L, 0x58955a8d1622baL } + }, + { + { 0x0064cd704e2f6fL, 0xe9d458de0edd38L, 0xeb1a5977e0a5c8L, + 0xe322ece01fc0a8L, 0x8b9d1661032a19L, 0x3e7b539a89de94L, + 0xfa30262001c754L, 0xe33de4ddb588f6L }, + { 0x4dafbdb954eb94L, 0xbb436480584c1bL, 0x622c93e5dbe29bL, + 0x968f9e3f57b931L, 0x98f03be0f6453bL, 0xb0ecc7f08f696cL, + 0x5af55f4a505335L, 0x028533efb3fa9bL } + }, +}, +{ + { + { 0x3bc8e6827e8d86L, 0x4e43b3063f105aL, 0x5301b7d4981250L, + 0x8b0a75e9f72fa8L, 0x88f59db357348cL, 0x5f0ebb1ec4208eL, + 0x4712561c043d3bL, 0x9e5ded0c806b97L }, + { 0xf9bd0a62121d09L, 0x1759ecbe337cd1L, 0xd1acc0ee945542L, + 0x3683febbd2f63aL, 0x44f1bccda5dfe9L, 0xa3606c9707f22fL, + 0x45ef0642d96ca5L, 0xfc3107d9022df9L } + }, + { + { 0xe81320b44be755L, 0xdf213d55c7c761L, 0xf43d2d5b4e5db9L, + 0x3bcfd828dedcd2L, 0xdf368a6d37a9ecL, 0xfef20aef475a77L, + 0x22f5894162c064L, 0x956bc660142a7dL }, + { 0xaaa10e27daec78L, 0x3cb9b72b6e9a78L, 0xa740bade383f72L, + 0xc31b4017759007L, 0xdada964a7afc50L, 0x6bf062cfd3d11fL, + 0x9470d535db3679L, 0x339447303abf13L } + }, + { + { 0x533f44046e5d7fL, 0xd1793e349048c8L, 0x59e11501929b94L, + 0xcddbbcb8364134L, 0x795c794582774fL, 0x114dfc4e03081aL, + 0x541ef68ef54042L, 0x159295b23f18cdL }, + { 0xfb7e2ba48a2c8cL, 0xe2d4572bb6d116L, 0x7bb0b22d750b53L, + 0xc58888cd142ee8L, 0xd11537a90c9e2dL, 0x77d5858d02eb9eL, + 0x1fa4c75d444a79L, 0xf19b2d3d58a68dL } + }, + { + { 0x37e5b73eb8b90fL, 0x3737f7a3f2a963L, 0x87913fa9de35e0L, + 0xec7f9928731eddL, 0x6e6259e219491eL, 0xb2148a04de236cL, + 0x89700e8fdd309bL, 0x9ce51e49f0bf80L }, + { 0xe7ec421301f17bL, 0xa4b570a3bc5f4fL, 0xc2b1b2a1285ee2L, + 0x5e86bc8c53db73L, 0xb65fceaf24fa90L, 0x9e74c5608ab024L, + 0x5c8003df9ed877L, 0xa632e9e4a2cbbcL } + }, + { + { 0x32a4546c91c8b5L, 0xc122b5ac969363L, 0xbbbec5e3648b3aL, + 0xd5a365e25143b0L, 0xcf3e46454157ceL, 0x9712f04f9bab64L, + 0xc12d43a04b4008L, 0x51932d72edf1c7L }, + { 0xaef1655b2f8470L, 0xaa8e3f36c24aceL, 0x7da75da6b4e761L, + 0xd371827b90bca2L, 0x84db4500afb45cL, 0xae12045ef46b5dL, + 0x91639a5d962f98L, 0x669cbe672f2ac0L } + }, + { + { 0x851bb3183a4356L, 0x7d436bf9a1bf15L, 0x46a3f0e120b378L, + 0x9302abc3f5b357L, 0x1e0672693fef53L, 0xb12f4a95fd2ee9L, + 0x94a884c7de9433L, 0x2645234a6f2874L }, + { 0x6fb56f5cdb8dfaL, 0x4a17dfc9e0ee4eL, 0xe269d8383ab01eL, + 0xda932dab77c10fL, 0x463af0c0321243L, 0xbe1d68216fc8a3L, + 0x2eae3ea48b39e3L, 0x94230213b03e7bL } + }, + { + { 0xaeb507cb22f28aL, 0xa77458b49a6b44L, 0x232ed5ac03dc17L, + 0x79dfc169c61ac6L, 0x7c48be9cd71b93L, 0x983d68ac429cd9L, + 0x7709c4798ae2c8L, 0xe4765c0a5df075L }, + { 0x23c4deb3367f33L, 0xbdf2b7e37d72a7L, 0xbaab5c70af2d26L, + 0xd609f7ffd026abL, 0x23b72b2541b039L, 0x8d06bac83be852L, + 0x911d4a9cb23d1cL, 0xeae815cfb0dbd7L } + }, + { + { 0x487c35c2c33481L, 0xffab636b6136dbL, 0xccd4daea3d3aa4L, + 0x87149bbc3704e0L, 0x9de8119c0e8396L, 0xd49357a58e7ca6L, + 0x68789181562d75L, 0xc7453815ab1fadL }, + { 0x0f1579802c9b91L, 0x7ffc3f0b1ddde5L, 0xa01d5e06aae50dL, + 0x6a97e65e279873L, 0x4bcf42fb5b1b41L, 0x1c6410f32f5982L, + 0xd4f760050701c8L, 0xff02663873b90dL } + }, +}, +{ + { + { 0xdc53ea2e5b2de2L, 0x94b352d38acecbL, 0x37d960b0d9d5e5L, + 0xabd868f90bd997L, 0x781668f35a7376L, 0x043d59710118bfL, + 0xd4da719f57928aL, 0x01942f6983e46cL }, + { 0xab97fc8728bd76L, 0x825956b4b5c1c5L, 0x202809fc82a104L, + 0xdb63e9cc8e3132L, 0xa41c701c2181afL, 0xd28018043e066aL, + 0xc734e4124044ceL, 0x4d9ab23505193cL } + }, + { + { 0x0bcd42af9f0c3fL, 0xda21a46b94a218L, 0xe55243c0ffc788L, + 0x318aae647a5551L, 0x8c2938b79af9cbL, 0x5d15232ec1dce5L, + 0x3d310ba8ad2e5cL, 0xd3d972494f792aL }, + { 0xdeb4ca112a9553L, 0x2f1ed04eb54d9dL, 0xaa9c9cf69fb7a1L, + 0xeb73c3a54dcd3aL, 0xee3eddcf5f201fL, 0x35f9e1cba7d234L, + 0x1d1d04cd2e242fL, 0x48df9d80df7515L } + }, + { + { 0x4ecc77da81dd9aL, 0xa6ac4bb03aa015L, 0x7645842bbc4fedL, + 0x9ae34cd9d6cf52L, 0xf8ff0335917e0bL, 0x7c9da37c2cc175L, + 0x1e74dccaaacfbeL, 0xa8f2df07999af8L }, + { 0xd06c4ea102a466L, 0x2156e87ae190ddL, 0xc95db8aec4a863L, + 0x49edffd244a6feL, 0x110fae6904f81eL, 0xbaa3e50a1cd104L, + 0x5bd38a20478b65L, 0x2b57d05daefbccL } + }, + { + { 0x1ce92ba86f4534L, 0xb2a8592414f5e3L, 0xdd7a4c69979436L, + 0x7599aff3f0add7L, 0xe0ce4d3e2d4f64L, 0x74475cc401a29fL, + 0xaef6541a2377d9L, 0x54048f53f917b6L }, + { 0x1b86b2205312ecL, 0x779ba2231493cbL, 0xc718369aac9320L, + 0xeab01a8617fce4L, 0x17b1f10f7187faL, 0xe68eda0a1aca46L, + 0x61033fe2586342L, 0xfc14e790b6ca43L } + }, + { + { 0x9f2231913d2491L, 0x66bdb537997202L, 0x0bafb0c4617f34L, + 0x5917831f3bb7b3L, 0x6feb2a6b45bddbL, 0x08662b30202c19L, + 0x0bc2b5705852f6L, 0x2c00fd491818c2L }, + { 0xca7672cda37dacL, 0xfe4c04c5a30865L, 0x5f1399f322e92aL, + 0xe7d67ea25b1bebL, 0xe08b014dce7f68L, 0x24df52af2f2b3cL, + 0x2028b23750ecd1L, 0x9b25d4bc810a45L } + }, + { + { 0xa35b7157a9d799L, 0x6da1eb301f9c99L, 0x33ef91ce363ba8L, + 0x21c0e2ece140daL, 0xb0b11bf158cd84L, 0x6a8744293da438L, + 0x924f10d3db585bL, 0xf5ddd7310c6159L }, + { 0xb72dcb86a74c21L, 0x6d14198cc8f79fL, 0x99f4b6c9c5a8d6L, + 0x063968890e135cL, 0x330edb883f6385L, 0xe1a5a6b9079675L, + 0x6e37fa8b8f5fe0L, 0x60e2fd961dca1eL } + }, + { + { 0xc6cb40366c395eL, 0x03b21a7b51d0f1L, 0xbc478a5e693181L, + 0x0017c2fc6cff33L, 0x740a5b839d8d1eL, 0x3968d664d9ec6dL, + 0xfd53738b0ef1b0L, 0x73ca8fd1ed0a04L }, + { 0x4ace93875ab371L, 0xd602936ddad7e9L, 0x1f5424a750bcc2L, + 0xfe09b3668c7a17L, 0x165f7de58341ecL, 0x95b825a6ce61e5L, + 0x9d31e1966c83c4L, 0x65b3e08cc5887bL } + }, + { + { 0xd37e93221482d1L, 0x9af659708b6380L, 0x279426a7d61e4bL, + 0x80dd0ec80997adL, 0x7239b0dd5b76d4L, 0x92e6c73e76c098L, + 0xeeb2321eab3e1dL, 0xa69c4a7eb1a910L }, + { 0x46d6aa7833d9aeL, 0x3ee6957572b0feL, 0x44ccbedcdb3d97L, + 0x342f29dcbea01bL, 0x0d518c58926876L, 0xaaabae75585d2cL, + 0xc548c77e008f58L, 0x819e2fa21fab2cL } + }, +}, +{ + { + { 0x468e149c16e981L, 0x286c7909ddbb7cL, 0x2a92d47db7a38aL, + 0xde614e68a27cb2L, 0x8dc8822e5b0ab6L, 0x38441aecf48565L, + 0x11ed5c9089435bL, 0x238928682d0d31L }, + { 0xc6698d472f2f31L, 0x295242c56d76afL, 0x4099205eba563bL, + 0xae7de5a3ab7384L, 0xccdf127d0ed86cL, 0xb9b6d5b965c3c3L, + 0xe351a8f2c31ad7L, 0xa761dd8ac12f13L } + }, + { + { 0xda115ddf171ab7L, 0x2de17b1401f93dL, 0x95019ca40964b4L, + 0x169d1f465ba3c3L, 0x534a0070090d08L, 0x805c5e282bf410L, + 0x15dfe1165f8d90L, 0x827a416ca72456L }, + { 0x5af888433a36c4L, 0x8bfa54cd8ee604L, 0x08fd1419ce290fL, + 0x2db5e8c287b3a6L, 0xe5be98103cdad2L, 0x155b874bf810b9L, + 0x2ae42de670f473L, 0x22185847f74657L } + }, + { + { 0x54b2a5023ffa43L, 0xcf87b16a24d919L, 0x1ff540263524e8L, + 0x73c94e056d1e54L, 0x76515523899fb5L, 0x13a721418723bfL, + 0x39afbdd3561517L, 0x49b790a9f2862eL }, + { 0xc8c1f4f527d2ceL, 0x1997aec7609bb7L, 0x583ad8002a3400L, + 0xac2374e4f79706L, 0xbf1f9a821b7183L, 0x06158ab6600fe0L, + 0xfcc9b2ebd56751L, 0xe1de5acddaaec7L } + }, + { + { 0x230baa1788fdabL, 0xf30860a7d04597L, 0xa2c7ece99f4caaL, + 0xbd39f106ad065eL, 0xfd92f5d3bef7bdL, 0x6069fad96d2203L, + 0xbff38cac4d9e0dL, 0x419a0171fda313L }, + { 0x5d77fd8572f035L, 0x5af99f2b282b40L, 0x7257d3b23facffL, + 0xf2ee22358c90afL, 0xcc2687d9b6a52aL, 0x140892c302430eL, + 0xa934d5e3ec4f38L, 0xc087d7c3bd18beL } + }, + { + { 0x7e94138a2c5ed7L, 0xbc8ceef53610bfL, 0xe89356bd86f803L, + 0x9a3a3805a55330L, 0xe894aba11ad648L, 0x2e68fbaba95918L, + 0x643e2bafcad344L, 0x0dd025661640aaL }, + { 0xc02e479e25cbddL, 0xd78c4d813a1b3fL, 0xa6dae8fcca9692L, + 0x3dd91e9e5de8a0L, 0x78ae0ce764ea36L, 0xb4ad99985dbc5eL, + 0x967ff23e82a169L, 0xaeb26ecbaee1fcL } + }, + { + { 0x8c502559a6f90cL, 0x56e7abe0ea374aL, 0x675c72256413b2L, + 0xd3fc17e946753fL, 0x28c4e1fe235f7cL, 0xe209bcdb028eb0L, + 0x7d0f93a489fe88L, 0xb966a2e063706aL }, + { 0xb6c228c4a30319L, 0x6868efeca6d674L, 0x0610a70057311aL, + 0x0808112bad7f89L, 0x2a2462c1dd6181L, 0x52ed9feb58e88aL, + 0xbbff16f33821a2L, 0xda53e9617f882aL } + }, + { + { 0xb6ffca38c30e5dL, 0xa90f9915c905f5L, 0x72fb200d753e88L, + 0xe509d4c7256c6aL, 0x369e552d866500L, 0xee4b7e033cf8aeL, + 0x280d954efcf6ebL, 0x5b275d3d557f0eL }, + { 0xeb17211b5cecf8L, 0xd6ad50fbdb2f8dL, 0x2478c7b35e04b7L, + 0x97e7143ac73bd3L, 0x09d6ede4817e24L, 0x68fea712c405e1L, + 0x34adbc905f67a1L, 0xd20ab7073edf99L } + }, + { + { 0xe116a96569f191L, 0xb3f0bce4d6e29aL, 0x30b9e1af51dbabL, + 0x1dd36f3346d276L, 0x83151030749a27L, 0x242f148ab47f70L, + 0xe8a5bcf5585681L, 0x8b801845ed79baL }, + { 0xa4042fd3894ad1L, 0x82f781d2b88bc6L, 0x2d34cacbe4c397L, + 0x8731aeadd99c9fL, 0x0f95498ef1d382L, 0xcaba2e1dd0bbc9L, + 0x78889e954064e8L, 0x8cd9c9761a8ab9L } + }, +}, +{ + { + { 0xf31f53ffa0459eL, 0xf8742a1315cd6bL, 0xabe2f50ae64e97L, + 0xbd787419b9da48L, 0x4521a3351e526eL, 0xfa05935e10ba45L, + 0x5c947e1e8f903cL, 0x0aa47d15a754eeL }, + { 0xb2849efd814825L, 0x9c2a5d25c9968dL, 0x24dbb2604e634cL, + 0x33f3a4cdb38194L, 0xe04f609c8a2b6bL, 0xcaefd8eabbbfdbL, + 0x683119a404498bL, 0x24ab7a98b21cbdL } + }, + { + { 0x6f1326921fa2ddL, 0xd79e61cc10a4bcL, 0xac4b3ce4bd6d46L, + 0x52459b6bd3f37bL, 0xce0f0a3a396966L, 0x050d1d5a1ed488L, + 0x1b9c403e0b17faL, 0xee1abd004a2e66L }, + { 0x97065c35cf3e3bL, 0x6513d5fbe33441L, 0xcd3463479047aeL, + 0x45cbb1cfd22df1L, 0x7a173ae967b17cL, 0x75f5ba72223cdaL, + 0xe3d12dbefe0a73L, 0x3b7f94dfd7adcfL } + }, + { + { 0xd596a13f1e9b7dL, 0x04f5bdd6734e0cL, 0x18b694f8be163aL, + 0x15620c7d959fa3L, 0x65fc2c553d2a3bL, 0xd44a364c4d36f2L, + 0xc8b421f268ceabL, 0x564139abfe2bd4L }, + { 0xb52461019d4633L, 0x5ab3f886346934L, 0x96691fe9819422L, + 0xdfdec898b39b82L, 0x84b1c7997cfb27L, 0xe59a98d4d6d004L, + 0x5e5d0c612c350fL, 0xb431220d415774L } + }, + { + { 0x3d0ca736aae0a2L, 0x7b1991f48c2d8cL, 0x00ae8565cdae72L, + 0xdbb6ca0bd55128L, 0x3c2ab2a45c82bfL, 0xea5a55979545caL, + 0xeba9a26d5927d0L, 0xb52e40183257fcL }, + { 0x55ed517ca9650aL, 0xbdaa081e3ebff2L, 0x8cf7ce49f8831bL, + 0x1d0b5bd6e3b8d3L, 0xa314a9fd8fc869L, 0x07f2079b892babL, + 0xb700dbfa0cc9d9L, 0x7105a086dc0a39L } + }, + { + { 0x0c7e05d8c7d901L, 0xa7ff681af3182bL, 0xb88e3caf9a0d06L, + 0xfe20a12c343b7fL, 0x9f0257703251f9L, 0xf225dedc40c5ebL, + 0x50e0cecb208ea7L, 0x5b250f0e6eeb65L }, + { 0x807a1534806b6eL, 0xded120afa94139L, 0x237ddc749366fbL, + 0xdd3674e5a34bcbL, 0xef6cdff9c4a61dL, 0x036194bb2fb896L, + 0x38659539528cd9L, 0x0723c596936a52L } + }, + { + { 0x1f84cd5e17719dL, 0x545939bc73b394L, 0xefbf3c583e84e7L, + 0x6cc46f1f77fd66L, 0xa629f591383ab8L, 0x9177ffacd35cd2L, + 0x039187f9dd411bL, 0xa9cf1cf7b7eea8L }, + { 0xa3b105aac47e5dL, 0xa755bead0a9da4L, 0x50cfbae73da15eL, + 0x9456cbc60b628cL, 0x7ffc3629b7a910L, 0x30b5924cd6d6a4L, + 0x198629f0b04ab6L, 0xc74609c624dea9L } + }, + { + { 0x27d4d77af12fa6L, 0xdd8a216690aeb2L, 0xe48fc02fe24417L, + 0x1970403720e17eL, 0x95013fdce37b42L, 0x06817d2de4bd9bL, + 0xc5863e763d0ba2L, 0xa1bafc0a556f5dL }, + { 0xf28ec7b410a78aL, 0x0dcac420a01a63L, 0xfcd3fa4b5bce11L, + 0x054d7e5d278b89L, 0x5195db85ce49e3L, 0x4c0b1672c73d96L, + 0xd94307720a1bdbL, 0x66fa8b359c77a7L } + }, + { + { 0xb9e93aed7462feL, 0xbfe54b218dde4fL, 0xaabb5283dbb08eL, + 0x8c367020e5fc45L, 0x35028888e69be3L, 0x6d2efc1c12a11dL, + 0xfce5cebf265e30L, 0x58c8bb35742c7eL }, + { 0x32e89dcccf7fa0L, 0xa811f33dd020a4L, 0xa10d6205129fe5L, + 0x3841c88e4ed29bL, 0xf3303a9d8b1ea6L, 0xa9a0cad1781f58L, + 0x4502b388f3ef0bL, 0x2b7587e74c6d35L } + }, +}, +{ + { + { 0xc6eaea123ae7cdL, 0xa1884d473c0caaL, 0x901e76fef1ea88L, + 0xdb9935ca14269dL, 0xe8b2486947f1deL, 0x4ad56f4a657588L, + 0xe7680542913fb1L, 0x2abff5d37600daL }, + { 0xa814813a81a797L, 0x63e76a446acb69L, 0xb1038394ab8277L, + 0x587de349d8e759L, 0xdfaeb8dddf62dfL, 0x24fe1cf9239d49L, + 0x7de7409e130d1cL, 0x3ecfef9581d070L } + }, + { + { 0x8d177a0f87c72dL, 0xae7e5818c6d1deL, 0x0077b5f8cece85L, + 0x382483832d2187L, 0x49d8b156db2bd2L, 0xe9e5513c8d85b9L, + 0x63c410ce05c53fL, 0xceaf2fbd86f752L }, + { 0x0b432fe93806c5L, 0x18eb15d3d06c75L, 0xcaad82612cfc02L, + 0x581e0401e2d045L, 0xd573cb595edcfdL, 0xce71948dbc66e3L, + 0xcf68721acc14eaL, 0xf68bea26cac4dcL } + }, + { + { 0xd8576afcb74da2L, 0x8771c29c433f46L, 0x7315af6e2f5b8eL, + 0xc195481ba33928L, 0xb77dcc22fb1f94L, 0xcb3e57ca610f75L, + 0xeb2a92753907dfL, 0x916f14923eff95L }, + { 0xbb378e4b6cd291L, 0xa2a5e2b2f13ce1L, 0xa8a0e60bcd00b0L, + 0x5902741682b75aL, 0xa0882c93f65a77L, 0x2069f75c93cfffL, + 0x1ede40570c0cb9L, 0x13840c90d526c4L } + }, + { + { 0xdc2caaa03ced48L, 0x2079219a0315beL, 0xca493563b1f642L, + 0x0202dc7b0665f2L, 0xe5d6bbdb7a5238L, 0x36fbd5e26eab32L, + 0xb3988f1f5819b4L, 0x5b15dc84aa4d69L }, + { 0xa52feed54e5c24L, 0x927471be91a797L, 0xd119bfdd57f677L, + 0xde38f7b78e4c4fL, 0xa7af516b150bc3L, 0x403b21e26b76c2L, + 0x589067d92300dcL, 0x04e406a066802aL } + }, + { + { 0x28e7d09a9ca9bbL, 0xaa84fd5fccf4a0L, 0xdbe9fb8635b7edL, + 0x9ede3f5d56fc7cL, 0xa4b5031b01cb29L, 0x584299d7f93703L, + 0xbd28868b6fe825L, 0x1d385d48b9c2d9L }, + { 0x6606f4a822be80L, 0xb5a0165626d0fdL, 0x9920a2014568adL, + 0x7d430f41c6d174L, 0xc243e16e02e9e9L, 0x367f1d2a6bd649L, + 0x693910071b8c36L, 0x2ede1314de2984L } + }, + { + { 0xdc781875beec32L, 0x1fff0cca525ff4L, 0x6e86425676df34L, + 0x2b4e8a63f638e1L, 0xc4991d29b1e59fL, 0x399d0011589717L, + 0x406464ebe041cdL, 0x901cb3d9e65bb0L }, + { 0xf5f4572fb42307L, 0xf81b3b0f1b7307L, 0x8fb695cf2094d1L, + 0x7db4792db56f7bL, 0x36836d55a794e0L, 0x2da477b09bc879L, + 0x1cdfadb1887c40L, 0x65dc6c2f2699b6L } + }, + { + { 0x36f9f214737972L, 0x48f0c8b7a387b0L, 0xa156ed339a1d24L, + 0x375293a0fed268L, 0xf679f487ff75cbL, 0xd15a00f1cc9e62L, + 0x92a7dc722c3877L, 0xe9870636fb0ed4L }, + { 0xfd8e59c16f5f3cL, 0x375732eaeeb48eL, 0x2dd9213ca1ab42L, + 0xcb062099ffcceaL, 0xfc611f6b23edfdL, 0x271634999b060eL, + 0xb938b5d820de8aL, 0x138f6e7eb49a32L } + }, + { + { 0x7feda63e485f70L, 0x646380aeb27b2cL, 0xcf8fe32c4511c7L, + 0x2c68e1eff9406aL, 0xa9f2fd920b6020L, 0x1c98fc63b3e465L, + 0xb8dac3593e53aaL, 0x2fb47b6a750e96L }, + { 0xea373ef1950bb3L, 0x81566944ac7aecL, 0x8d6b3c2b55b931L, + 0x5d13f2db62ef7dL, 0x4647f2aab9182bL, 0x8f56c5a33bf07cL, + 0xc5ab284b35a221L, 0x0747ab75a46a6bL } + }, +}, +{ + { + { 0x5b9236c86b85c5L, 0x5967a0dc482448L, 0x397c9557df6ae0L, + 0xf83ee1c5378f2bL, 0xf82df656e05dd1L, 0x4c424f619d7c8bL, + 0xa612550a6d5f2aL, 0xfe8482a63c3ebfL }, + { 0xcb8d4030142c82L, 0x08b06623679e6cL, 0x3ea51463eca5eeL, + 0x089eb3b1370500L, 0xcbfb19c5a0d306L, 0x2f6858842a65bbL, + 0xe3e1db5e51e119L, 0x2c150e7110895eL } + }, + { + { 0xf323488f6d4c4cL, 0x5fc931f63b87e2L, 0x8867da035c759fL, + 0xb6f1eff9746d4cL, 0x8a8172d990be0aL, 0x1113eee5c407b4L, + 0xd80dacf378ed8aL, 0x99b57cf3fa7fd1L }, + { 0xf5bb6d95176405L, 0x6b8963a92e83b5L, 0xac55b6b8a7ef8dL, + 0xe73fa126c1fbf0L, 0xdb3756060148dfL, 0x72f1a98f3f1fbaL, + 0x1f71d0aea550f2L, 0xc3ea4f09544a87L } + }, + { + { 0x5b09da24322bf3L, 0x2a573d561264e1L, 0x93cb2e1803acc4L, + 0x397b4fbe502fc6L, 0xddfb21239e0ebcL, 0xeccd8f5bbcbc57L, + 0x49d3bed4663788L, 0x37192aa1218df9L }, + { 0x8a05bc92ffa3c6L, 0xc38c28123ebf4dL, 0xc80d547fe343a8L, + 0xa8d5a5b6c63516L, 0xc5d8ce18d8fa6bL, 0xeb5e87224a87c0L, + 0x9806e9e75bfa23L, 0x11f0889689469aL } + }, + { + { 0x81005f68e75666L, 0xb84d861d349505L, 0xe0832829f321eaL, + 0xb751d7acfa33a1L, 0x793cf6f067c550L, 0x073a6b21027e56L, + 0x53f40ee66a6012L, 0x70bfaa8c210fa9L }, + { 0x1518e39e4b5998L, 0x8f0b53024b8d9cL, 0xd91c281afdf923L, + 0xc5cfb2824e3f69L, 0x63a529a870871fL, 0x3d3e8872128dadL, + 0xed658dccb30cceL, 0xf9373b9afb7baeL } + }, + { + { 0x22d4dbede58ed2L, 0x4fefc1d03f8789L, 0x6b0a1fe344817fL, + 0x96bef40a56b0b2L, 0x32684eeda249faL, 0x8298864524a91bL, + 0xa958baf0c736a1L, 0xd033a7def2f3e5L }, + { 0x5be3edc43f4d6aL, 0x326a39d9c89abbL, 0x90c44f755d997aL, + 0x20581066e966c2L, 0xdbae4906548038L, 0xac7bc97d473fc1L, + 0xb34488b4b2603aL, 0x27aea275e9bb98L } + }, + { + { 0xa59e7281b88773L, 0xe2f05d40c241f6L, 0xa56229e4e75749L, + 0x8f00c0b1b10705L, 0x855994619394d3L, 0x0d7e352aaf5e32L, + 0x526c462787b8eaL, 0x89297d9a179d48L }, + { 0xeff17e6ef43892L, 0x17091eb221f841L, 0x82f5eb34a4b848L, + 0x6bea4778eb7b76L, 0x21f227176c536cL, 0xd9ef2c896c81bbL, + 0x7c2754654bf4d3L, 0x9dd4662d7c28c8L } + }, + { + { 0xe7fff0020e1a6bL, 0x26a35c6a08d467L, 0xb3c773d3248c91L, + 0xa646615ba7d935L, 0xa91f453b0d26faL, 0xdcf9c3460c6d32L, + 0x63668619e3e3dcL, 0x3012813f30f3e2L }, + { 0xac6623dc2fc61aL, 0x108dc252bfd2ffL, 0xd7f5c0d231d6eaL, + 0xa904f9aad1107eL, 0x46941c20d1e9c8L, 0xe5b6451c810cf2L, + 0xaba8e674f511d1L, 0x5b4b94f08373feL } + }, + { + { 0x002d4e2849c230L, 0x9bed0efd8ba391L, 0x745e0c0828e319L, + 0xcd40907ca58de2L, 0x2c87ab11abaa4aL, 0x3c17a97db64391L, + 0x36b184e86c72d2L, 0xb03d202485f7aaL }, + { 0x2b6b79bde24abaL, 0xdcb78542325fb2L, 0xf5d1db966ebae2L, + 0x35a4d5b903840aL, 0x7afeb09190e9daL, 0x1818f6a35c1792L, + 0x90091fa3faa269L, 0xc4ccff62570235L } + }, +}, +{ + { + { 0xa177619ec85940L, 0xfca24db7ef7eeeL, 0xb2450f37a90c11L, + 0x29d256ddbf4f85L, 0x920c8d051316c3L, 0x2f7f7ba04474daL, + 0x308117f2ec9a0bL, 0xd0a231ad0d2085L }, + { 0xf3288fc7ab641dL, 0xc68bade9f4fa32L, 0x768f014bbf8253L, + 0x5eff260c0a33f0L, 0xc71b4536bb93ceL, 0xa71d045680697fL, + 0xb62444cce72bc3L, 0x11f03e8d1379f3L } + }, + { + { 0x1f54789c16df92L, 0x874c642e3ed142L, 0x6699f60fa2a9f1L, + 0xbd1b8d33fecfc1L, 0x59682d58a3d953L, 0xf17c0214a36b81L, + 0xeb9621d181a666L, 0x7c2c3ab3cf1ad8L }, + { 0xe6888c3e529f7cL, 0x197b66ab355315L, 0x63b558a83e31acL, + 0x4aa7bc5891c68eL, 0xc17d989592e360L, 0xc750a291363666L, + 0x0d534704909ac0L, 0xd6d02724594a10L } + }, + { + { 0x35c541b3fbb635L, 0x50016d05982afaL, 0x58ebce496b0ca0L, + 0xb940027577ea56L, 0xf29d305e38480fL, 0x43705b0ebd6a2cL, + 0x0e4acdae90c639L, 0xbe94a29f56e05eL }, + { 0xc61f4a030659adL, 0x39074adc402211L, 0xfe0d8d551b621dL, + 0x2d02e8dd1d5222L, 0x05ece3c46c2683L, 0xf70705ac689d41L, + 0xe3caf444d837bfL, 0xfda058475ba6d0L } + }, + { + { 0x1098163cb7d458L, 0x12b645ff5ba834L, 0x70a318128af72cL, + 0x5f4727ef32e5ddL, 0x7cbae1510a21b4L, 0xa80bf806785389L, + 0x9827402b8f93b7L, 0xe385f8208349daL }, + { 0x2d054619589f6eL, 0x6aa5b26e7c0191L, 0xe79ae12bd5574dL, + 0x5d13f914148e61L, 0x7b2be0f13716ffL, 0x82b0fe680bb81fL, + 0x697633c3e2569cL, 0x6c1f083873f8b3L } + }, + { + { 0x6e26d850be1674L, 0xe4e47f6ab8044fL, 0xfdf46e882fc434L, + 0x639ae2cc89cadcL, 0x2244a524b85bdcL, 0xb1e4790b7cf4eaL, + 0x51dce037e0bb8fL, 0xdd143352716ceeL }, + { 0x1c049b48e8841dL, 0x6bf26dcb97c621L, 0x21d6255ba01178L, + 0x477258a8e4f0e4L, 0xf5e437e68f8ef1L, 0xd118fbc8b03e1eL, + 0x3d6bc51e1c91b3L, 0xa259486d5b6907L } + }, + { + { 0x4159cfc7b6f5dcL, 0x05a52b3493694aL, 0xeeb511c83b8883L, + 0x19d79e42b06400L, 0x8e503a2738f37eL, 0xa30e5795a94ad9L, + 0x3981c75262618dL, 0x06b6c692dcba19L }, + { 0xd7242ee4d1b051L, 0x6274ccb3b350c4L, 0x66df0bbf540019L, + 0x4d66be65ae12d5L, 0xcea29601049cbaL, 0x40473398df84b3L, + 0x7d6c96b75a31c8L, 0xbb80159874174cL } + }, + { + { 0xf0f7be059f1aa4L, 0x798f39adcff451L, 0x96763ff8014e1eL, + 0x03987a809cc5ecL, 0x4919656893650aL, 0x92e8eef75e24dfL, + 0x54e97cde89d639L, 0x8081d067682cc0L }, + { 0xb9ef41aa8ceb71L, 0xb8173a4a4d7aaaL, 0x93d81b1c54ee10L, + 0xabe180570a445aL, 0xac0ff9764d569dL, 0x86946b23e570beL, + 0x8e11dd24180641L, 0x3d0b33c99f67dcL } + }, + { + { 0x2c9637e48bf5a4L, 0x9fdec19ccaf112L, 0xe5cde9d5c42023L, + 0x9869620878f0ccL, 0xcf970a21fe6ebaL, 0x1df5ec854e678bL, + 0x4667f0128d00ddL, 0xfa7260db0b3fa8L }, + { 0x6bd2895b34239bL, 0x04c8bc52d2a50dL, 0x14e55ef6cb23e2L, + 0x6440c273a278d5L, 0xf4b12e32193046L, 0x46adf645dd4c08L, + 0x70e29984656e8cL, 0xe7b36eae4acd44L } + }, +}, +{ + { + { 0xea64a5716cf664L, 0x8497ee426fd357L, 0x44d94b4814e851L, + 0xf4aac225a6a2cfL, 0x947b30980c301fL, 0xf390ba17865383L, + 0x16c4fc6d1773d3L, 0x61b98146227220L }, + { 0x07dd03a1dd0270L, 0x290ca820f160dfL, 0x8f2205444ba955L, + 0x4e85e450b6f1b3L, 0xfd73ce9ad78089L, 0x67c12702f2cb0eL, + 0xa7de0d7ee33a61L, 0x6a811cc6553261L } + }, + { + { 0x5ef05742d0a427L, 0xe8d2e95220a341L, 0xdd28cbf8044886L, + 0xdad7b4ba1aa58bL, 0xb28f3738ec901bL, 0x1841a935bbe3dbL, + 0x8fd7cd1a075feeL, 0x93b603fc0d3cddL }, + { 0xca54fd55edd859L, 0xa4cb05f64ed687L, 0x3138668ed1a3d7L, + 0x1224fdaee32be5L, 0xf1f532bc80aeb3L, 0xa4f65d0e8d4d69L, + 0xc697a015905fe5L, 0x514da7a6690ce4L } + }, + { + { 0xc7b9af83de4a55L, 0xc79bad7b318d93L, 0x1808071f5b1c83L, + 0x92112efb965b16L, 0x655ab387bb740aL, 0x53dbc8b384ff87L, + 0xd153c2872dc6f2L, 0x2ec20e199c7819L }, + { 0x65e46ea3b854b5L, 0x272d5aec711db5L, 0xfd1bb5326e19e8L, + 0x33280b83dc0665L, 0x95b986eb8f1c4aL, 0xa671fc4a685c4aL, + 0xa03cbd583bdbbfL, 0xd329402ab77544L } + }, + { + { 0x40fa6518e62b35L, 0x3913b11f9e55a6L, 0x4e8089b5270a41L, + 0x565f52a80d1886L, 0x93b5f05512749bL, 0x35c869c141c547L, + 0x9a44a1af86717fL, 0x2b9984b9c2b2cbL }, + { 0x61fb6074952322L, 0x2d4072f7af1464L, 0x9b2fa8c600eb30L, + 0x6071fb7f10668eL, 0x27cc24d90634caL, 0x3875bc2471d32bL, + 0x678590ba11210cL, 0x352b447fcc5a9aL } + }, + { + { 0x795d5415fa3200L, 0xadaa557a92949fL, 0x42fff063cc88c4L, + 0x26d683171b68a5L, 0x3286549e67ad8cL, 0x5bf636386396b2L, + 0x41229b6e12c8eaL, 0x05320c9748952eL }, + { 0xae36b63900b460L, 0x9354ff2f2b6affL, 0x10b810b065ee0cL, + 0x4d6925fcc8bb38L, 0x31c03fd7a22f14L, 0x76b7f4457544e8L, + 0x3a9123cc0eed26L, 0x77acd67e0cd1ccL } + }, + { + { 0x2e9053007ec527L, 0x32388ef62937cfL, 0xa445389e229188L, + 0xa44b68e33bcebeL, 0x5a8722e4c4e701L, 0xfd066e8cf07e41L, + 0xa3c1a4f95fab62L, 0xb4d6a1be542f24L }, + { 0xe6a92e4af6c9b5L, 0x9452484c83d61dL, 0x422b55b0062276L, + 0x261973a5279688L, 0xde8be263999fb2L, 0x64e96287b029caL, + 0xd8edfaa06897d4L, 0x408319c6955511L } + }, + { + { 0xff6baed50a5632L, 0x922b7d05c5885aL, 0xdf0f3b31b45864L, + 0x27e49c0c04340eL, 0x618c566122c447L, 0x7863a38eafee7eL, + 0x7143affb828cb0L, 0x51fcf4cf9d054eL }, + { 0xc4a4b3127f5e09L, 0x021f47a90be2bdL, 0x1a060197ab956dL, + 0xe77fa1586ea86bL, 0x9ccde87d550ef3L, 0x7dee53a6532654L, + 0x8b4f060e826387L, 0xda38637ad077b5L } + }, + { + { 0xbc901b30e9fac8L, 0xfa082046fb2a2aL, 0x92f68ab5e04efcL, + 0x184a30a9ac12d0L, 0x1aa11aab25d479L, 0x8bc5f4c0f03161L, + 0x7e3a083cfc8817L, 0x84d9355597f93fL }, + { 0xc014478239abc6L, 0xb226b098d37b04L, 0xb056942f575789L, + 0x816b95aba745ebL, 0x2a49d39b98ddb6L, 0xc41ca26291af81L, + 0xb3afe99ab26347L, 0x59c31bc604b638L } + }, +}, +{ + { + { 0xa16a8b9c42befdL, 0x731c9c92052f00L, 0x1ad49b41f5dfa0L, + 0x7a289e3bffce36L, 0x868fac00c79cf1L, 0x6d6d28486721abL, + 0x590f928e726c94L, 0x0e802cb51f3841L }, + { 0x6a6a57a0b694bcL, 0xb9bb0cd8120fb8L, 0xad96ac79c05826L, + 0x294da8c7768df0L, 0xfe32311b56c6c6L, 0x291c2c6ae8d050L, + 0x1c765e7e7db4c9L, 0xe058298d65f9f7L } + }, + { + { 0x4bfa85b7e8d345L, 0xa04ef95de1dfc8L, 0xb5f7f21324ace3L, + 0x4b350a1574b14aL, 0x11436bff8e5c8dL, 0x1c789f97642369L, + 0xeb5e335fb623ceL, 0x9deacd2442d562L }, + { 0x4ff989f531ee71L, 0x43e2c49aacb52aL, 0xa76319885bfadcL, + 0x08b6d5cd0161a0L, 0x010e3fa541f197L, 0x83a589e3279a16L, + 0xf0991376309f9bL, 0x07c093bf1cea10L } + }, + { + { 0x1ce3f0f33d2192L, 0x07b559ac37ce73L, 0xaa2ad38207be27L, + 0x84f053b7ed93deL, 0xbc5c7973b98a4bL, 0xc92346163aa9b9L, + 0x807cc16231a10cL, 0x8ffdf57a061209L }, + { 0xa9ca741497070fL, 0xf608ec9d113b3aL, 0x51327268d0384dL, + 0x96686acf5ec307L, 0x437bbbd71c4665L, 0xdef09d57c379caL, + 0xf8be033621747cL, 0x2775b378ae8047L } + }, + { + { 0x4009798b2c4fc2L, 0x148d7d1203772eL, 0x9d9392df8423fbL, + 0xa5bd72eaf8cef4L, 0x579d58d4380b53L, 0x2ff88f18c39d24L, + 0x9ca2fbc5706466L, 0xb42987d1e56af2L }, + { 0xcc2556e5d94ea8L, 0x4e5c2b35369d76L, 0x5de35742a94f9cL, + 0x8d068c95cb4145L, 0x4d553ff51bfcbfL, 0x3ab71648a23fceL, + 0xc9cb3a9d0fa7f3L, 0xf81209bed9ced1L } + }, + { + { 0xde7356ee5b66f5L, 0x7b2bf1ae8a25e0L, 0x09a444a2c9b725L, + 0xfd8a2f44906c55L, 0x409cc8082514f3L, 0x47e009928999a9L, + 0x0a582a66a312f4L, 0xf7946f8f6723deL }, + { 0xa55f6ba92d8affL, 0xb62c3c8a544b1cL, 0xa1d14115c16a94L, + 0xc3783192ad5e71L, 0x13d784706b1dd6L, 0x99005f8ee7ff55L, + 0xfb5ea3f8a1e7d8L, 0xdc7f53cb4cac39L } + }, + { + { 0x482abaf36e3794L, 0xc23e9e5c74684fL, 0x4544cf6f1629beL, + 0xd8a8ee52f40374L, 0x2eea87ff433bdbL, 0x489a99cae9990eL, + 0xefc131e54b23b6L, 0x25fe6998600270L }, + { 0x03d2d9ec059a7eL, 0xa6445b56979c3cL, 0x491a10c9bfbceaL, + 0x15b5974e937af1L, 0x4be8002797c7fcL, 0xbed8a49fedcfeeL, + 0x35751cea9e0691L, 0xe9a9fa39ef5982L } + }, + { + { 0xeffeaca3065de7L, 0x841d544ac4d4e2L, 0x8144679caf199fL, + 0x98cf4f9443967aL, 0x8cd57f4f33183cL, 0x390832ac1b15ebL, + 0xc4b1feaa53b500L, 0xd762a10dff24b5L }, + { 0xccd3eedb0ee2a9L, 0xa6dd4a9362d485L, 0xeb4ff26f1d047aL, + 0xc0771fd23860fcL, 0xdbb4e394b64114L, 0x2ff3f244d29b29L, + 0x9cac005387b365L, 0x05b7aa6de5994aL } + }, + { + { 0x5e71752c03dd63L, 0xad10fe9bc74687L, 0x51a5b0c54c76abL, + 0x763fd501f586d4L, 0xc7bd5ce816048bL, 0x8fc83d23f744dcL, + 0x0561802109df9aL, 0x18fb01fccf0e43L }, + { 0xe4606fc038ab23L, 0x5878f1fa664c98L, 0x3aedbbd5da7356L, + 0x3c578f5516746aL, 0x259477f1a17210L, 0xc7a869d028248fL, + 0x6517a6148cbf95L, 0xbc5f91d3d04d47L } + }, +}, +{ + { + { 0x15fd9a9083ca53L, 0x1161da02697ca6L, 0xf516af356b676cL, + 0x8a420d575eec13L, 0x72d67421a9526bL, 0x8d8c29e76b463fL, + 0x38a4f588815627L, 0xf7e528be0650f9L }, + { 0x2cfa78e382edcaL, 0x638d183c4ad83cL, 0x96d3b9de4a0119L, + 0x5769ccba7c1101L, 0xc3b3b792b8d04aL, 0x96212f64951bdeL, + 0xad7905a481161eL, 0x8fd676241c5edfL } + }, + { + { 0xf7b063539d6cdeL, 0x69d0549115a84aL, 0x4a976c6cbd9fe4L, + 0xc92953f950ff96L, 0x1d7f0fe654d127L, 0x7293870da0f75dL, + 0x7bb3652cf2277fL, 0x64798c9834484fL }, + { 0xb94d8bfac3a76cL, 0xf5721a97ff776bL, 0x23a6e9f2722e31L, + 0xe9da9969a5c034L, 0xb9bbf83456ebc3L, 0x239f58a96956a4L, + 0x8b75beb18b7f00L, 0x6c2b5b8a51cb97L } + }, + { + { 0x78b1c627eb41f3L, 0x0638fcf17c4352L, 0x939edd80c5709cL, + 0x0a8dfc3edc906cL, 0x3942f47efb01edL, 0x4c8275749986feL, + 0x792545c4dffa57L, 0xeee68836c3ff26L }, + { 0x824d08e12b1218L, 0x515a478902457fL, 0xc70cc9cbae55b3L, + 0x1240737bcef9d4L, 0xf22e6162f9db7fL, 0x98c4f0291f8da2L, + 0xa89219cafaaa67L, 0xf35fd87e7d27e2L } + }, + { + { 0x19b0cd701b80d0L, 0x3d7e29df9aebd1L, 0xd39c9ca0477cbcL, + 0xac0f6155ff0d3dL, 0x8a51993520fd01L, 0x508ff54b22d6fbL, + 0x8786c47318d3abL, 0x4312c464a683f8L }, + { 0x73b1d3995359f6L, 0x0d94fa5963011eL, 0x5723af29bfe83eL, + 0xafa90016841df3L, 0x791e92ab7c498aL, 0xbc931ad7ea4253L, + 0x438e016b783c06L, 0x1347db22ca662bL } + }, + { + { 0x41df37dfbaa861L, 0x98ecb23329e4deL, 0xdaf1560507e018L, + 0xa902269b088e32L, 0xad898a5e4cab2fL, 0xd84e9ed02c1e1bL, + 0xc20a5d58488af3L, 0xc7165af6cc77c6L }, + { 0x8526f3adeb7461L, 0x03577b14a2d332L, 0x28e469de4760b5L, + 0x442c7f9b276266L, 0x90d5c77f9c90faL, 0x7aa87163e211bdL, + 0x56d8ff05decfd6L, 0xa204b56ee23e6eL } + }, + { + { 0x2e4374e4aceafcL, 0x978743b6fcd5e5L, 0xa0f6345c4855caL, + 0x9bc7e4fe98074bL, 0x3835d57c33d08aL, 0xeec7c8b6f00566L, + 0x71628a21acf55cL, 0x5da375097fb19eL }, + { 0x6904a8e01a7125L, 0xad33c85e6e3780L, 0x1702928c19f94aL, + 0xb424ff27c04b3dL, 0xb212e3919e2ba3L, 0x4cca8e8c9af4c9L, + 0x98ab7aefd9bf0eL, 0x21d245d9799db5L } + }, + { + { 0x6b034dcec08806L, 0xfd763f2b40f2d9L, 0x5e16de029cb906L, + 0x02b70148a0e16aL, 0x463c8eee071e12L, 0x644728125ad509L, + 0x9ee6f2ddc0e07aL, 0x188895c68d4d97L }, + { 0x092fff3b27f971L, 0xb3c159fc9b7722L, 0xe27d8ff3cae42dL, + 0xf8a5ed6e87071dL, 0x318388f607ebd2L, 0x924967b53486f1L, + 0x77304947c46e1fL, 0xf279c60f21d196L } + }, + { + { 0xef2bc0384f3201L, 0xf8750c71f94c51L, 0xbaa4f5a986ec65L, + 0x6f8a5de2732a33L, 0x0f13d80299e365L, 0x2709530e85261fL, + 0x097d922f527d56L, 0x4969687be1f3f8L }, + { 0x9f3f5043e1708dL, 0xac67b874aa4be4L, 0x75fb042320a87eL, + 0xa361ad36e2cad6L, 0xcb01470203e9f6L, 0xe3807b7c9b76c6L, + 0xf086833b907c09L, 0xe9bed3c7e85a01L } + }, +}, +{ + { + { 0xa7ea98991780c7L, 0x04e4eccd2476b6L, 0x0af9f58c494b68L, + 0xe0f269fdee64fdL, 0x85a61f6021bd26L, 0xc265c35b5d284bL, + 0x58755ea3775afdL, 0x617f1742ecf2c6L }, + { 0x50109e25ec556aL, 0x235366bfd57e39L, 0x7b3c97644b6b2eL, + 0xf7f9e82b2b7b9cL, 0xb6196ab0ec6409L, 0x88f1d160a20d9eL, + 0xe3be3b4586f761L, 0x9983c26e26395dL } + }, + { + { 0x1d7605c6909ee2L, 0xfc4d970995ec8aL, 0x2d82e9dcf2b361L, + 0x07f0ef61225f55L, 0xa240c13aee9c55L, 0xd449d1e5627b54L, + 0x07164a73a44575L, 0x61a15fdbd4bd71L }, + { 0x30696b9d3a9fe4L, 0x68308c77e7e326L, 0x3ac222bce0b8c8L, + 0x83ee319304db8eL, 0xeca503b5e5db0bL, 0x78a8dceb1c6539L, + 0x4a8b05e2d256bcL, 0xa1c3cb8bd9fd57L } + }, + { + { 0x5685531d95aa96L, 0xc6f11746bd51ffL, 0xb38308ac9c2343L, + 0x52ee64a2921841L, 0x60809c478f3b01L, 0xe297a99ae403acL, + 0x7edc18fcb09a5bL, 0x4808bcb81ac92aL }, + { 0x3ec1bb234dc89aL, 0x1e8b42e4e39da5L, 0xde67d5ee526486L, + 0x237654876f0684L, 0x0a583bd285a3ddL, 0x3d8b87dfe9b009L, + 0x45bd7360413979L, 0xb5d5f9038a727fL } + }, + { + { 0x7b8820f4bde3eeL, 0xea712ef24d5170L, 0x517f88cdf6ec7bL, + 0xb15cecf983ea9aL, 0x9eeee4431a4592L, 0x786c784ebb013eL, + 0x2f06cb31f4e15dL, 0x5603fd84f4fda1L }, + { 0xf6790e99e1321fL, 0x274c66a74a4c09L, 0xa4b70b49a41a4eL, + 0x7700bddada5157L, 0xe54a60d51be8dcL, 0xfaf92761a477e0L, + 0x6661c72b027eacL, 0x50e2340280b917L } + }, + { + { 0x635f40f96ec123L, 0x4a331337a766a4L, 0x9ce4416b935587L, + 0xbb6e1f595d97e4L, 0x26147239d4197dL, 0xabd4478490e896L, + 0xf6a1b2a8bba895L, 0x401fa405e27a45L }, + { 0x7354ba50620900L, 0xc443a29385678bL, 0x48aba1053cf5faL, + 0xd67e723bbe152dL, 0x4b858e02a63d68L, 0x174e1ee72be4eeL, + 0xad0fbb39ab8d46L, 0xa0fdffbce17dd7L } + }, + { + { 0xa1ea3259c46fd8L, 0xeca122e9fb96efL, 0xf9074a26767acdL, + 0x9b004a22787082L, 0x389f8077f3ba8eL, 0x6463de90d5aabeL, + 0xf30ceaab090585L, 0x71b31e85634ab8L }, + { 0x0dee65caf02aedL, 0x506886e20ac252L, 0x0665f7886b8a59L, + 0xb9b784df2bb328L, 0x46e443adc6b089L, 0x3d5de1966c27fdL, + 0x0419265f0fde70L, 0xed946122b5c034L } + }, + { + { 0x5a52ad213b0056L, 0x9fbeb92b909ee3L, 0xb42ba18bdaab08L, + 0xec127c4ffc8a77L, 0xc6d2985fda906aL, 0x5355547994bbe7L, + 0xa7470c09cdfd62L, 0x31a3971d2e675aL }, + { 0x8d8311ccc8b356L, 0xabb0bf801b4372L, 0x33c1cad0294566L, + 0xe2e649ce07b672L, 0x9084d882ae3284L, 0x7a90d4c1835ce2L, + 0xb4d1cd5809d44cL, 0x78227149f0528fL } + }, + { + { 0xca884cfbf5844bL, 0x9dd05c48524cf9L, 0xdbffa1936ba889L, + 0xef94fdd29e7666L, 0x358f81b3eaf48fL, 0x96734d51530d56L, + 0x378b2d14adf9e5L, 0x2f850464731f61L }, + { 0xd6ae90599dcb83L, 0xa4f89e06199239L, 0x64052498f0f958L, + 0x2866d99cc27707L, 0x64681a2f551c0fL, 0x2c7b0d04c37080L, + 0x218925b00ac301L, 0x8d57fb354df895L } + }, +}, +{ + { + { 0xdaebde0809c8d7L, 0x58c761c0e95ea1L, 0xbd9965000ae5e2L, + 0x6117a85cd51acdL, 0xc4424d87c55d56L, 0xe9b1ddedfbeeafL, + 0xda98bb50db4791L, 0xff3a5a63fca108L }, + { 0x172fb8e5ccbea1L, 0x9fe12a7a9f6cc9L, 0x1de4b0b8967ce2L, + 0xc1ab60f671dbc6L, 0x338385a5dedcdaL, 0x647a4203a043feL, + 0xe9abc6428ebc89L, 0xc357ff003ba3c8L } + }, + { + { 0x37061e7de39ebdL, 0xebb91352be567aL, 0xa9a6f6bd6bb80aL, + 0x039345d99f0ba2L, 0x215494e98bbf47L, 0xf2cb7a4a2a1ccbL, + 0xf51aa1037f67c9L, 0xd29c85c17fff71L }, + { 0x8d4e4f24d30b87L, 0x20fdf5593a8309L, 0x9b9f9cf757075cL, + 0x09142adcd70101L, 0x901d0ee766ca55L, 0x6a5d86a32e418bL, + 0x550ad92d7fcaecL, 0x64e8818d91b26eL } + }, + { + { 0x5cea0f747e5ee5L, 0x8ca1d31be99699L, 0x52db8465c136c7L, + 0x8cecb3890e0d74L, 0xb8efe9dede2ad8L, 0x18d6ff8f17ade8L, + 0xd2227352d66c20L, 0xc46593ef2005fdL }, + { 0xe5ebe6ff7141e1L, 0xc968315e0126f2L, 0x95adc731cb91b6L, + 0x753b54c38a6003L, 0xa6141254230a61L, 0x23ac6eb559feceL, + 0x9816b603865c23L, 0x567014e543a570L } + }, + { + { 0xd46091ddd2b71fL, 0x3999a5d97d24ffL, 0xce2a4f11ecff3cL, + 0xab2687c581c6f0L, 0xa9fb2ebcba70b4L, 0x6fde35642093e1L, + 0x00253ecaee724aL, 0xa08ce3c2b81bddL }, + { 0xa251238935a2b3L, 0x8cae1d4584f750L, 0x011469e988a219L, + 0x61f7ed35a6a50eL, 0xe13ebaa01fcebdL, 0x794b97631d8867L, + 0xf25755ccda32e7L, 0x368a97b4564cd1L } + }, + { + { 0x0d22224aa3397bL, 0x1dbb3e638066dbL, 0xfe0b5ee0ce8e32L, + 0x09c17c87bab4dcL, 0x5cc65ddf188b64L, 0x74c4abf211b5faL, + 0xdcc17b7ab0ba86L, 0xfbdf46fa535501L }, + { 0x4775087aca569eL, 0x6575f9006a1718L, 0xb5c45a9b94de93L, + 0x0fc80068497171L, 0x775d965489f7abL, 0x8775b58f5c0c89L, + 0x05d4e201a06254L, 0x8cab349b6d73a5L } + }, + { + { 0xca7816339465b0L, 0x3ef914814498fdL, 0x9ca1f346255c11L, + 0x389fd15b7f38f1L, 0xdac2089354b8f3L, 0x82d07fca840a70L, + 0xf53fd731dd483aL, 0xa6e4eae1590578L }, + { 0x7bf65af3c01b77L, 0x27542f3a75c982L, 0xc5bd947716cfceL, + 0xba5fe76884b9e7L, 0x39bae14d55725dL, 0x982f64efae0eabL, + 0xcfae6627a5293aL, 0x22a25a1d60f464L } + }, + { + { 0x74caecc7dd5e16L, 0x23678a2ce7bca3L, 0x467393257f1ba1L, + 0x4eb9948a4c1697L, 0x5d400e8eaba18dL, 0x128d1c89807871L, + 0x78f9627bff38a6L, 0xf80b813a39d4ccL }, + { 0x8aeefa031d3aadL, 0x504219927db664L, 0x244fc694cb6383L, + 0x319047772192a3L, 0xcc86075bbfb57bL, 0xbae3a134451511L, + 0x16cf416f6174f0L, 0xb343cc0d376813L } + }, + { + { 0x31ac9b9d1824b7L, 0x6282260ec8f61aL, 0xbbeb9f8c781765L, + 0x06ab5c02d110daL, 0xd583e2247146b8L, 0x79a16084100d05L, + 0x16dbbb4f0a5c95L, 0xfe2af1de331667L }, + { 0x26f0364af8710eL, 0x1cb8c91eec08feL, 0x436bce61d95e9fL, + 0xfe9050c57944a0L, 0x5f45acf07b626bL, 0x48dc93f9cf1276L, + 0x4491371a05bfb7L, 0x51063044bcf785L } + }, +}, +{ + { + { 0xac2e294ed0b3b6L, 0x5c5ade6671637bL, 0x2f289ce1140677L, + 0xaf446e2754eb53L, 0x70911b720421adL, 0x4b73836e0b7556L, + 0xcadf1042a97827L, 0x4824e498005bc6L }, + { 0xb0eeccd937c28aL, 0x1ce061d0c3ee97L, 0xcb076319f33faaL, + 0x9980bf4aea66dcL, 0x2bd0755d111d98L, 0x43feaf67fe4de0L, + 0xe76fb80b077b2fL, 0x227dc9f5793b04L } + }, + { + { 0xea24ae514f49baL, 0xbc39ea611436e7L, 0x9d7fed278485d8L, + 0xb6ef00cdf8b131L, 0x0237b4bfdbc7afL, 0x08745b564ccd27L, + 0xaf8595dafc5a76L, 0x43657af29f5500L }, + { 0x300718348470f8L, 0x51f91fd640fd53L, 0x859c807be15512L, + 0x7d1a474ab3e9c5L, 0x5d714d981553e5L, 0x07573436f62310L, + 0xedc5be06b02a62L, 0x5a4b9b7ea47832L } + }, + { + { 0x03e0a24e93dbb3L, 0x25841dccadc884L, 0xabc1a818d10ad5L, + 0x207e38a2042dddL, 0x7fffbdbfeba8d8L, 0x74efebba3ec9b5L, + 0x0bc39ca0b40a9fL, 0x69ee9c90267febL }, + { 0xd402facbc62919L, 0xe9f8fc11cf53c6L, 0xe76fa5a7cc7d81L, + 0x4f2d87696bb19dL, 0xd4fb7f9adc67c7L, 0x40621d596702dcL, + 0x5b6a98e438f6c5L, 0xa7c64def1a1036L } + }, + { + { 0x84c5e809a092c7L, 0x9e40e0a11c22b7L, 0x820a091d06c99bL, + 0x45fdc77eecca8fL, 0xfe1b8a35794f16L, 0x31f7e5b4ce3d6dL, + 0xfd5e01082c74c8L, 0xfdabf30c1f6f7dL }, + { 0xbfa6017b9248a0L, 0xe898d30546b941L, 0x878c492207ff65L, + 0xbf22e8db874e64L, 0x43fdb1b53a547eL, 0xb66deda5fbd464L, + 0x59127a6c7ae1b5L, 0xa4636466a7515aL } + }, + { + { 0x22c4e66de9ab2eL, 0xfaf60c20203c58L, 0xed2d7bf0d5c5edL, + 0xdbc16fe4ca0f19L, 0x54e8ef6465b979L, 0xe2d64b1a310ef9L, + 0xa0f2c953778636L, 0xf3b4aa4281883bL }, + { 0x4ac9af09be6629L, 0xba455e11ca90c5L, 0x0147538856f492L, + 0xc80db7eabd7840L, 0xb3526d96beb9cdL, 0x37657fb9d81503L, + 0x8729a16193cec3L, 0xd9a93fbd69952aL } + }, + { + { 0xfce017594f47c6L, 0x228da21e366d05L, 0x27ce0b2dc8baf3L, + 0x8cc660b6b4a951L, 0xf678947384bb01L, 0xc629d7d44d980cL, + 0x47980e4e85e81fL, 0xa2e636a1cd723eL }, + { 0x6b6ebae77fb207L, 0x70179614c92891L, 0x5569541b4d279cL, + 0xbb6b36a41758cbL, 0xecaa22227a8e30L, 0x8b6746ab470ad9L, + 0x4c4601763e2d3dL, 0xe19c4edd3edaecL } + }, + { + { 0x0b43fec34718c8L, 0x553c407f33499fL, 0x8272efb970d1dbL, + 0x008c62ca8e8d1cL, 0xe4b79d763eec45L, 0x1fd4230f2d71a3L, + 0x090fdafa368c36L, 0xf62c101fca7baaL }, + { 0x1c9e6c8d2395b3L, 0x671ed6304c5513L, 0x577d933299a465L, + 0x286890e63f9986L, 0xd92a95dbfc979cL, 0xcebd79d2b51019L, + 0xe74d88b3d07251L, 0x8b6db73906f9adL } + }, + { + { 0xc0c43db7b3d90cL, 0x85d154e4304a06L, 0xe8aceefaf2f38eL, + 0x5e0429383d9459L, 0x65e5e32431afd1L, 0x9e5f050a900a65L, + 0xcbaa1718a26671L, 0x33d0b249c93de7L }, + { 0x3dcbf92d5b6680L, 0xc47e5ec20006f9L, 0xc9711299a51924L, + 0x665d9b8cd0ed46L, 0xed2d63fa5fcab6L, 0xa817eb6cfbfc5aL, + 0xb38169fb76eb76L, 0x8b93544f11160bL } + }, +}, +{ + { + { 0x02eca52693bdcdL, 0xbbf09232ae01d6L, 0x0b0a2de8b44b3eL, + 0xdb82449b250dffL, 0x0c42b866e1c530L, 0xcd226dca64c2c4L, + 0xcfb2bb1f046b5fL, 0x97e2fae3fccb0dL }, + { 0xdf9290745ed156L, 0x224dcb9f641229L, 0x2126abc5f1f67eL, + 0xa7eed5ae9c8a6bL, 0x40abedc9857d9bL, 0x3f9c7f6de941c6L, + 0x2158d42d725ddfL, 0xbdd10158c69543L } + }, + { + { 0xa7dd24e8df2fbcL, 0x3adbcfd13d1aeeL, 0xf6a32d113b2177L, + 0x89a72327a9a14cL, 0xe3aef43dc65df9L, 0xeaec3e3a64d74cL, + 0x4d387d84fec33bL, 0xaba2a0521a2128L }, + { 0x2382c226b85e30L, 0x4352d85cd2aad3L, 0xb0c6001d9772c4L, + 0x7ed82635f3653fL, 0x3626a6f0300f47L, 0x23909de6ca7e4eL, + 0xb43dd81c154141L, 0x9a49fad7e4bc68L } + }, + { + { 0xa3661df2428f88L, 0xbe48b0256e0db2L, 0x3cd1871ce79aa9L, + 0x90ab87123dddacL, 0x9c58fb971871a6L, 0xf031f7fa34910eL, + 0xb501eea81060e4L, 0xdb668ba791224eL }, + { 0x240bbcb6a705bcL, 0x7e76fbd2d1865eL, 0x6e2cd022513641L, + 0xe6c522546365c9L, 0xe46a8b8a5a01fbL, 0x696fa7bb67618bL, + 0x418b3b90db6792L, 0x7204acd7108b9cL } + }, + { + { 0xb5a143b8456b45L, 0x8a3ab25f53b4d9L, 0xb112a58e13a570L, + 0x613ca3281487d2L, 0x837d8233b1e7c9L, 0x592baded41e9d5L, + 0xdc1893a5cd02f2L, 0x08795028972e23L }, + { 0x7003c08cb76261L, 0x14bde9e332a5e0L, 0x14b2872cbbd78eL, + 0x5594061de238e8L, 0xad12645067466cL, 0xa8d0e64f5e4952L, + 0x5b44b82c7f8d06L, 0xb51bea8fb1b828L } + }, + { + { 0xebad6853f0daccL, 0x5c31b8b1cbebbcL, 0x6746975fa5a2dcL, + 0x2d9596531d9faaL, 0x343797d00fc0e4L, 0x38d821c55fe01bL, + 0x0bfdb247323aa0L, 0x42613c4f962a8eL }, + { 0x599a211e134bc0L, 0x75fa4a147a7084L, 0x6e719487f734b5L, + 0xd5ced2d6dfca2bL, 0x9fa0fdc8aeabd2L, 0x5e6b03f12361daL, + 0xad23d315859fcfL, 0x3120ef125a5fc8L } + }, + { + { 0x990ef628e9f638L, 0xfdaa240626a60cL, 0x4a3de202abddabL, + 0xd5d10b7d8872b2L, 0xa01b7301ea5880L, 0x481697fa81b9d8L, + 0x29841533471ed8L, 0xefd73f8292d37cL }, + { 0xdda76269994bebL, 0xa0377036a4f865L, 0xda992ece5b47d5L, + 0x912a427e53edbaL, 0x64675989264e45L, 0xd3b68c3af71222L, + 0x9d3436c6dedc5fL, 0x1e027af076b2adL } + }, + { + { 0xd56fca14382f4aL, 0x83712a48966b7bL, 0xd6b2cf5a4c9ddbL, + 0xa66be29f602875L, 0x70e4266894f3d0L, 0x007d220b3195caL, + 0xba38d8f82c74d4L, 0xdccc5fcd975cbdL }, + { 0x03e1610c88b38bL, 0xeb9f9a152e0d8dL, 0x6a57ecab646eb7L, + 0x161641fc76b6c1L, 0xf9025adbd2e12bL, 0x87c74db5c0e26dL, + 0xed5cb51bfeca74L, 0x603dfb6e34a08cL } + }, + { + { 0xc4be728cb03307L, 0xde34c0ec2741ccL, 0xe01db05a74eb17L, + 0x1bfce0c8905e4bL, 0xb18830ad1b1826L, 0xcacbb41e87bbfbL, + 0x8696842d2f1a79L, 0xa80e5fb08c83eaL }, + { 0xe48f1633f1439cL, 0xc1d4108cd6987bL, 0x05705c4b751814L, + 0xa9bffd0c1c622dL, 0x23de4af46cd053L, 0xf782f5e39457c3L, + 0x815276b5e5d243L, 0x31320416161ae3L } + }, +}, +{ + { + { 0x245966177f2542L, 0x203be7e8372b25L, 0xc7c9426ee2007bL, + 0xc5641380621799L, 0xda56589c28c3ceL, 0x13e8a7c7afc1e3L, + 0xdba81e9e352082L, 0xf43054904435c7L }, + { 0x4d26533691de4aL, 0x364408cfb777abL, 0xccdfb43eae7f88L, + 0xbc40f44a525b11L, 0x8e112a53c60627L, 0x7f7c581e17e696L, + 0x0fd78781ea774aL, 0xd09e6320b1f582L } + }, + { + { 0x44390bd70aab15L, 0x41112bc889c3f2L, 0x6b02894d685349L, + 0x71030015584dfeL, 0x373cb1b1ba7887L, 0x53d286c2a017c7L, + 0x2ed03883c81fdcL, 0x3bfc5e3fbcc6fcL }, + { 0xd38ac6ffd6418dL, 0xc667e96bfad89eL, 0x46f4f77eab4d66L, + 0x194c04f0911293L, 0x0fd09cf68c48d5L, 0x6f5b05563cf7f4L, + 0x0c0a8c4acd562fL, 0x94c1d8336d965dL } + }, + { + { 0x94fc8f0caa127aL, 0xc762d5dd803690L, 0x8bfdfd11ebf0d3L, + 0xa98cdf248eac50L, 0x3d7365d8b5ff10L, 0x20dc29bc65b4deL, + 0x62ac28e8ec7c68L, 0x7f5a13290372d2L }, + { 0xf3d8a253246658L, 0xa4bebd39ac202aL, 0x078ede75cc1697L, + 0x5525800c8fc022L, 0x302a8025fae77bL, 0x018013957917b6L, + 0x7c8806d864bf55L, 0x4e2d87812f06f1L } + }, + { + { 0x8d351183d66e88L, 0xfb861a1a91d02aL, 0x8c27c2a7850e5fL, + 0x9fd6399a5496f6L, 0x52152ae8080049L, 0x600e2fffd1c2dcL, + 0xc75902affe8b2eL, 0x5c4d2cce03b175L }, + { 0x8ad7c424f57e78L, 0x77cf6061736f87L, 0x2876012f85038aL, + 0xff328451b97b95L, 0x3cc6dd5392dfc8L, 0x72f1363a6f5075L, + 0x028ec4471de894L, 0x7030f2f6f45a86L } + }, + { + { 0x66400f59695817L, 0xeda0a7df20ea36L, 0x855be51d394992L, + 0x2d082c18336f62L, 0x30944ddf28c868L, 0xfb5f8530dc86d0L, + 0x9562ae5564a0bdL, 0x1f7ea12b6b9b51L }, + { 0x5bd74e0d0a7148L, 0x6c8247fb91e572L, 0x699aba547da498L, + 0xed825811f7c814L, 0x434674b62057b9L, 0x8b4df5e15c15b4L, + 0x2a97da1b110081L, 0x2a96b0c4c417feL } + }, + { + { 0x4f75dfc237639dL, 0xe5ad6bc1db7029L, 0xd43e06eb3d28f7L, + 0x89f3bb5e447989L, 0xc426a2c01a1a6eL, 0x33ea71c315878fL, + 0x8a7784ab1b5705L, 0xa59e86e77ca811L }, + { 0xddb133c36ae155L, 0x49f1d4c0d51b42L, 0x55080829d05519L, + 0x20e23be5291816L, 0x35047ec67181ecL, 0x6237dc47aad091L, + 0xa1d3ce1e2e25a2L, 0x1de05220d3db4cL } + }, + { + { 0xe9a5e19d9fd423L, 0x0c2c3d09801e43L, 0x043c2dd28df2daL, + 0x4eecab4e1ad12aL, 0x97e17979615aa5L, 0xe57b879ca7bb5eL, + 0xa2a903ccc92619L, 0x5cef370aa56e93L }, + { 0xbef29fa7f3232cL, 0x1cf35ed2b7ad5cL, 0x35c48933b6077aL, + 0xe0651487a1d47dL, 0xedb4673ce14572L, 0xdc9e98c0b17629L, + 0xef98ebe9a02a5cL, 0x1f772e311d03c0L } + }, + { + { 0xcbdbdcd4608f72L, 0xb4352235a13c6fL, 0xa6497f64bb3c21L, + 0x3af238312c15c9L, 0xfbbf4b36322d11L, 0x520a5c6c641775L, + 0x18cd967e81e0e1L, 0x980b2c63de3871L }, + { 0xfa9db619ae44a2L, 0x0281dd2176bc56L, 0xfd037118a7f817L, + 0x9c485454129b30L, 0xb439648039626dL, 0x355050ee4ada6bL, + 0xc9c16d67f5d98cL, 0xf53ccc318c4d5eL } + }, +}, +{ + { + { 0x50ae9423ffb20bL, 0xa6c0b426865eb4L, 0x4677f7d09930f1L, + 0x742e0b64a16427L, 0x521d18ef976f9aL, 0x43ac9cfa454749L, + 0xda3a91dc51f50dL, 0xf657029ad6f954L }, + { 0xfe5f0646b4f99aL, 0xd92a5d963ad4ceL, 0xfcb55092e0e081L, + 0xadc85ab8d8a858L, 0x8e9b9660632f0fL, 0xe7a4f168d7216dL, + 0x00a4cc559c3b99L, 0xed6d0bdba09dc1L } + }, + { + { 0x7236d141621bebL, 0x1751fd4bc7ca95L, 0xaa619d12f5319cL, + 0xfc2b15b4e9316fL, 0x2d1a9069fd4d33L, 0x28c3bac8ced829L, + 0xf2efab51dd998fL, 0x2c133303b149edL }, + { 0x65237c9f601ac6L, 0xb54dd6507d6a45L, 0xa1ce391fb1a4cfL, + 0x2957533115f67eL, 0x6456da8465279bL, 0x02890aaa993e02L, + 0x6891853b7175e4L, 0x3fda2030f3e59bL } + }, + { + { 0xe99fe12d8c6e0bL, 0x7cb07ff5341c56L, 0xc292c7bdf77b24L, + 0xf52dfd0ca29906L, 0x4a6aa26772f02cL, 0x26f7684e1bbd09L, + 0xec56b2bee7c2a8L, 0x67709e6ad4a312L }, + { 0x99c57b2c570263L, 0xeb0100b2faafaeL, 0x980d5d1ff25ecaL, + 0xace35e682cf936L, 0x5a82ce544679edL, 0x5c76a41074b81eL, + 0xf36fa43a00abb1L, 0x064281904ffb2dL } + }, + { + { 0x68f6bc804bdd28L, 0xc311d96b5dc7adL, 0xff0d646ed32e45L, + 0xaf3cdc6e0f712dL, 0xd4508e9d483861L, 0xb624be50e1c277L, + 0xc510275c5dd841L, 0x451c5c3298dc02L }, + { 0xf87d479dd34d6bL, 0xda7f293dd06a38L, 0x575e129b699e9fL, + 0x79e5fb2215b2ccL, 0xd280028657e690L, 0x7fecd09e702a71L, + 0x85160abfa13677L, 0x5de3427ce65f64L } + }, + { + { 0x84e4bf6e8fff38L, 0x16f3725b358b1cL, 0x360371c3b472a5L, + 0xe64c06152f217aL, 0x8e673790501241L, 0x88e81d6ab2dd96L, + 0xf3e218a1385604L, 0x9736cafe84184dL }, + { 0xb55a043dbb93a3L, 0x335088f9301088L, 0xcea7a2db2a4959L, + 0x48e5d4ab882c33L, 0x114f09bad46179L, 0x4416467b446576L, + 0x01cb23e34c6c2fL, 0xddebf04a02db8aL } + }, + { + { 0x36d60cc9bde8a1L, 0x20fd2f2676e4adL, 0xebdcfb78936581L, + 0x245d0d5dbfc2c3L, 0x104c62ca9f82e5L, 0x7387457d654d9bL, + 0xe966777ae7f10eL, 0xefeb16f1d8e582L }, + { 0x4faf4f170364b5L, 0x0e1ab58d612472L, 0x11bbfe7fed6085L, + 0xb360a14a59a09aL, 0x61d96e9722fdb6L, 0x16a12f194068bdL, + 0x225bf07f73c2beL, 0x1e64665c8bd24eL } + }, + { + { 0x27a478a3698c75L, 0x778ccd36202aa2L, 0x0149c638d87f1fL, + 0xa660e5f784edaeL, 0xe0d4d2f82adfa8L, 0xf512dd61ba1f9dL, + 0x90cfed96245c58L, 0x6c3a54818b53ddL }, + { 0x833f70cbdc094fL, 0xa5f26f5b1514e7L, 0x93e7cf51c8cf13L, + 0x1436601186ec43L, 0x81924ace78170aL, 0xcc880a08694368L, + 0x2dfa9550b62cbbL, 0x0bc6aa496b4a2cL } + }, + { + { 0x5157a7e3561aa2L, 0x525c5008645c1eL, 0x22feb4ece7cbb3L, + 0x36d0d25c89a58bL, 0x43131f7c9bde9cL, 0x74afdda881f731L, + 0x99ab87c7c8e36aL, 0xf07a476c1d4fb2L }, + { 0x1b82056bebc606L, 0x95a1e5afcf089fL, 0xc5bccfa2b55d5cL, + 0x8fbc18e00eb0b1L, 0x93a06fe9efb483L, 0xcafd7252d74c57L, + 0xc7518f03de4350L, 0x9a719bfc6fd762L } + }, +}, +{ + { + { 0x5ee0d832362087L, 0x7f2c0d70b167e8L, 0xb7327895e0e865L, + 0xef5b2e898c4e65L, 0x222797d8fe9cc1L, 0xfe6d73e82d1e15L, + 0xc7c0e9cf62dc4bL, 0x962acfe937cedaL }, + { 0xd763711c1e85c7L, 0x8f2dbbc2836978L, 0xbadc0558c44e98L, + 0xed63eaba3e93f8L, 0x807e85741b55c7L, 0xd51ae5e6d1207bL, + 0xa0ef9a639d541bL, 0x58855f9a0c56a5L } + }, + { + { 0x7d88eaa213091dL, 0xcbdfee745b6a0dL, 0x826a0124f5e077L, + 0xb04fc1390f1e4cL, 0x1961ac3aea69aaL, 0x3afb719d5bb63eL, + 0x2a378374ac7e5cL, 0x78efcc1c50ca45L }, + { 0x346e8f0b8abdefL, 0x27e3dbd88095d0L, 0x56d3379ffc6c22L, + 0x67d416cfa4b291L, 0xc3baaf63b1b373L, 0x0184e1fdf73baeL, + 0x38ae8f79167528L, 0x7329d4c35d6297L } + }, + { + { 0x45d2ac9f568c52L, 0x51348149808593L, 0x0c92d8331b7ed8L, + 0x921327a0876ecdL, 0xf752d75052736aL, 0x7b56487bc6b837L, + 0x6b1a320a23b4ccL, 0x1983937ec0d665L }, + { 0x2c3017c08554abL, 0x40ad955366e87fL, 0x88c4edf8ed7f02L, + 0x64a7db13cc5e6dL, 0x5ac91fa2dc978bL, 0x016a20d925d2a2L, + 0x3604dfeabb57b4L, 0xc3683ecd7e2e85L } + }, + { + { 0xc47150a4c0c6d0L, 0x30af45ee22adcfL, 0x39b5acb022ea4bL, + 0xfbe318577203b5L, 0xe5aaa346fd9b59L, 0x0062c90dd1c8dcL, + 0xcf113f354049acL, 0xd8fba4d63a31b5L }, + { 0x73b54881056a69L, 0x3be6cbcd780bdaL, 0x5776ec230ba2b9L, + 0xbe883cf8e8d6f7L, 0x64efe945c2be6fL, 0x064f704f1ade8dL, + 0x41cfd17743110eL, 0xaac94114c20abeL } + }, + { + { 0x91f9192f1c1468L, 0x8176e744563e13L, 0xa48b5f90bda15dL, + 0x2a085aeda42af6L, 0xfd38ab2425c018L, 0x2884ba408abafbL, + 0x356f318cbd091dL, 0x454e450817871bL }, + { 0xe080e818ada531L, 0xa40f1eb3152ba8L, 0x051049f0c38eb1L, + 0x37e4bb3bd45003L, 0x6d0980454a01e5L, 0x6de932feeb824aL, + 0xccdef37dc93481L, 0x8633e0793a05e8L } + }, + { + { 0xbe94256034675cL, 0x376c01d08db789L, 0x8707ee79af1b6bL, + 0x633b3ef11bfbacL, 0x694f33fd06db60L, 0x2a68bfcbb13407L, + 0x1c860c9da27c3aL, 0xbca16ded701ac3L }, + { 0x2b76cfac59ffd0L, 0xf9a116554d718dL, 0xf86a1db67f0878L, + 0xe313e05af34e85L, 0xa1888113343159L, 0xdbe4c3f0bb7ed1L, + 0x73b67e80c732bcL, 0xa4e1c87e74110eL } + }, + { + { 0xce1106b5c6770cL, 0x422c70b5c0bcb7L, 0x32a39908195e7fL, + 0xa24968d1ccd4aaL, 0x8f08ecf720e557L, 0x5da10a454bcc81L, + 0x9d3c73b6cd846eL, 0xaeb12c7368d065L }, + { 0x2110859cf9fd1bL, 0xd2a4801ee2bd6dL, 0x376e556e9466acL, + 0x767803b3b5aa35L, 0x343f842b8a89baL, 0x3263cc16726bbfL, + 0x26caf1725871b0L, 0xef66ad641b8578L } + }, + { + { 0xc9f2249638068cL, 0x96d282c1ccf9afL, 0x71df30c69b435aL, + 0x88c943acb9d5c9L, 0xbf98ef12a8f378L, 0xffc1824114c6ffL, + 0xda3ad2cd52e8c7L, 0xf1222bc1afcb59L }, + { 0x459e94b0ee334aL, 0xd4477b8421933aL, 0x60fb7b0a1e401eL, + 0xfde6e820d1e330L, 0xcecfe9b3233fdeL, 0x09ec4662e93523L, + 0xa5ba64930775b9L, 0xcc397e5adf80f2L } + }, +}, +{ + { + { 0x2fe182d4ddc8a8L, 0x88d6e79ac056bfL, 0xc3ff2d10e41e4eL, + 0x32ec7f92c3679fL, 0x3561f094e61051L, 0x4553f5a6c6250aL, + 0x2b765efdd25c5bL, 0xe3a40a26a1cd7fL }, + { 0xb27309b5d821ddL, 0x950fb8dc2c17caL, 0xfeed0158fb0d4cL, + 0x762c479f550179L, 0x306cf44e095840L, 0x84b413ad379e66L, + 0xd6e5d5abb2e4f1L, 0x8bc12b794b085dL } + }, + { + { 0xc0d4cb804b5532L, 0x7a31525b9940a6L, 0x010e7dd68c69d1L, + 0xd81f29d2a18c35L, 0x08ae7703f11e73L, 0x5358f876e55106L, + 0x299e8cac960ef5L, 0x89a6fb4acfc8dcL }, + { 0x5996a406dc7d4aL, 0x21e5112e51b96eL, 0x95b8c3d09a202bL, + 0x306ab0fd441f1fL, 0x2834fed98d4245L, 0xc29c387d0abbdeL, + 0xf6a9bf1b805c15L, 0x602f4f8c4e458dL } + }, + { + { 0xf041486e5a893aL, 0x53b891d8934327L, 0x11e000d4000758L, + 0xa4ccde8662bad9L, 0xe34d3edb9a1b64L, 0x72d967584e7a6dL, + 0x773da2f6627be4L, 0xa11c946e835ae3L }, + { 0x02e8203650bc15L, 0x2d35936e58b78dL, 0xe9cfbe8f21a3ccL, + 0x55ad8311049222L, 0xbf99de438fff47L, 0xebbfd803831db5L, + 0xe990636af2af42L, 0xc26ae52b7f5a0eL } + }, + { + { 0xb5d85b1fa8f846L, 0x4166489b3b1455L, 0x768260dd36a305L, + 0xc6a82354ff5645L, 0xd241cd8d6e93e5L, 0xeed9aa1a406e74L, + 0x9e96ab05f600d9L, 0xa26b8b56eca2a1L }, + { 0x78321cfd705aefL, 0xc4fb6b3c0161ecL, 0xdc324415199cf1L, + 0x33627d0d0a5067L, 0x13490cb15143eeL, 0x77e0ede85b4f44L, + 0x904f12e394b165L, 0x90f50f5efab32dL } + }, + { + { 0x4aa0a16bc2de96L, 0x172596aaa9c12bL, 0xd512e1e60e8a29L, + 0x77d35c1f637e83L, 0xbb0d141d2aae0bL, 0x8a878a58c03738L, + 0x6d24c01ab0e525L, 0xb7d3136f760887L }, + { 0xdbc3f8f3f91b7cL, 0xe7b4bcaa8722c0L, 0x3286a91da0ae65L, + 0x8372274225b084L, 0x5884cd5ae1886cL, 0xb4e63ef3a23cf7L, + 0xfe5f202f2dd0daL, 0x951fac9653916cL } + }, + { + { 0x05e2e8f854fa4eL, 0xf411f941edaf10L, 0x26cc562a0a928dL, + 0x78fd34e4abce65L, 0x1d8760998a32e2L, 0x85dc76f4c37518L, + 0xdcaeef500e8021L, 0x7fcb2f84e9b2a5L }, + { 0x9eba91ef382c06L, 0x2052e8524cae53L, 0x617336ef5c1519L, + 0xf1546d5b4e632bL, 0xa9edc81d7b8ffdL, 0xdb2914f29ab68cL, + 0xe805070debbabaL, 0x775e53bc3b719eL } + }, + { + { 0xa40e294065256aL, 0x9f113868fb031aL, 0xac03af8059667cL, + 0x432eb3a0475f58L, 0x22332bf01faad0L, 0xc8132e9bc57a11L, + 0x27d5a173bc3f8bL, 0x5471fc6930bf3eL }, + { 0xba28bc0e6bff40L, 0x198d57e555e564L, 0x13ce8319c65b8fL, + 0xb0a5c9d5681b51L, 0x467588bdeb9e11L, 0xf1891a7bb4250bL, + 0x10b938bd12b433L, 0x0b8c80224dcda4L } + }, + { + { 0xc428703cf332d3L, 0x9d0053cf2a5b98L, 0x4e4c6207838a15L, + 0x2e92919fbf8a43L, 0x39ad52421cd9a5L, 0x584ed6c1561588L, + 0x20af30517a95c8L, 0xa223077b70e1c8L }, + { 0x679cfea2fa4871L, 0x54f2a46ac633c7L, 0x60306514cdc5f1L, + 0xc4facda75a1dc7L, 0x710a2882d07d19L, 0xd55864e6b44992L, + 0x44d4b6c454c5b2L, 0x2855d2872f9981L } + }, +}, +{ + { + { 0x4071b3ec7b0674L, 0x800eb14f8794d5L, 0x70573afbe6783eL, + 0xafaa4407785901L, 0x112d2a1405f32cL, 0x3761a52169b3e2L, + 0xe168b31842a366L, 0x5bc322f9bf4734L }, + { 0x36ef240976c4a0L, 0x066f3d6fea4e64L, 0x0e954bda989e57L, + 0xe36ef5ef9466e4L, 0x6bb615abeb9226L, 0x5571e5f3d5a2caL, + 0xa86efe24897a86L, 0xed7e9cf28a9f77L } + }, + { + { 0xdf10c971f82c68L, 0x796ba1e3b597e6L, 0x1ac77ece718cbfL, + 0xc8175bb410eac8L, 0x0cdf9a1bc555efL, 0x6b889f17524e05L, + 0x6bf1e61ae26d82L, 0xb3f6ad5d2e97d9L }, + { 0x94dcff9f226487L, 0x60e6356be03ddeL, 0xda1f93b6a3dd7dL, + 0xf1be72179ca90cL, 0x05ed3131e6bce5L, 0xcf50908d48af3eL, + 0x3b0e85c61e554fL, 0xfe7e35ba2778d3L } + }, + { + { 0x42c503275ac5a9L, 0xa66a66dda062c2L, 0xa4f4f82caa7023L, + 0x489d47664b4f86L, 0x10b108897311adL, 0x55dd637177b2ecL, + 0xa5ccff09a267b1L, 0xf07690bff327b0L }, + { 0x39162ed2250cd2L, 0x1426de08b255f1L, 0xf227afd1bdd731L, + 0x78f8a36fa4c844L, 0x267a211157379cL, 0x3f05f92cc04acbL, + 0x374496cfc69caeL, 0xbf2c5d016ebfecL } + }, + { + { 0x605418bd0518d1L, 0x3237f809e1cbc6L, 0x37a7005286c019L, + 0xf1fb0e0b15af0bL, 0xfc3b97caa853c0L, 0x1f48bd0e6beba2L, + 0x8e5d7c5e6a72f1L, 0x575e66d26ebf0cL }, + { 0x099477662eae3dL, 0x53f074f96c9c65L, 0x6cfbfdbb81badeL, + 0x98b4efe3fed7d1L, 0xdaa112338c3382L, 0xdf88b7347b8ec6L, + 0x9b0fe4b9504a4fL, 0x2e7df4cf30c1c3L } + }, + { + { 0x25380cb2fc1833L, 0xb8e248c18d62deL, 0x91c8f59d82f9dbL, + 0x5ec2b202444750L, 0x3f3a1f766b6f74L, 0x0180aa9dd7d14dL, + 0xd0a342d2956b9cL, 0x26e910e7139873L }, + { 0x2261dc4139e23dL, 0x7edb181b8343ddL, 0xfcf1073b4038ddL, + 0x88870efa3bfea3L, 0x4e98ba964a263eL, 0x3c6e5dc70811f5L, + 0x17d28f5f86055dL, 0xca9c27666e4199L } + }, + { + { 0x0b2d8bd964ef8cL, 0x5a99b8588e2ba6L, 0x9e927b204498ceL, + 0x9ff20c5756eb25L, 0x97cc27b3f27736L, 0xf32dd6d4729583L, + 0xbdc26580381a94L, 0x70fef15ef2c06fL }, + { 0x50a619149252ccL, 0x9eb4a14236b4b9L, 0x9b1b2158e00f78L, + 0x27add366ea9c23L, 0xef61763c3a8e79L, 0xed4542fd82ce56L, + 0xa8737e70caed75L, 0xeca0ac2d452d76L } + }, + { + { 0x20c07793d082d0L, 0x6e3ce64c9e9f3bL, 0xb3a4dce75a195fL, + 0x3a3c305bdd9f24L, 0xe2545c88688942L, 0xa463c82080f32bL, + 0x442974842686b8L, 0xf50e20d7213866L }, + { 0x265ac523826e74L, 0x26fba57228e8ecL, 0x8a1e1dbe6b3ed8L, + 0x7c7b278f0fe65aL, 0x9a6df23c395234L, 0x99562060b0f114L, + 0x440c8c4ef90837L, 0x21ad22a3645f65L } + }, + { + { 0x1e023a6edd31b2L, 0xf76d1459ff8668L, 0x970705617b45c8L, + 0x06120781e88e37L, 0x85c51c8922faacL, 0x4df392e22756d9L, + 0x8907fd0a03c98eL, 0x626f46a52ea51cL }, + { 0xf8f766a486c8a2L, 0x8c499a288ed18cL, 0x44d2dc63c4f0deL, + 0x47dde686f2a0b6L, 0x9a655f84a973fdL, 0x3e7124e786ac80L, + 0x699e61ce8a0574L, 0xdf0ba9a31cdd0dL } + }, +}, +{ + { + { 0x76270add73e69bL, 0x991120fc67d38aL, 0x7be58309469f0cL, + 0x93aba597db40acL, 0x2b707bc822fc08L, 0x4199fc069551cdL, + 0x38deed4f367324L, 0xca518e12228787L }, + { 0x72f1befd9a9277L, 0x57d4aabe49ae90L, 0x13810d5db23478L, + 0x2a8b7809b4b77fL, 0xb542f4e1b4e004L, 0x4080fd03ec77f0L, + 0xb49e9fecec6596L, 0x20338d33f16037L } + }, + { + { 0x4adcdae53554b0L, 0xfea4906e04c4dbL, 0x0808bec7748233L, + 0xde7477c47148d7L, 0xdd9124c03da38cL, 0x6b2503125ee8e9L, + 0xae67399b0d6161L, 0x70c4acd82203b6L }, + { 0x9683916d31dae8L, 0x34775031ac7f69L, 0x9553153988e4adL, + 0xb58f41153a15e1L, 0xb65a2d492ba2ddL, 0x7c3efb1a90169cL, + 0x210f45e6b1747dL, 0x16e8d1bcff488dL } + }, + { + { 0x252adf89d703dbL, 0x259ac1dfdfeb39L, 0x7faf6af115e806L, + 0x7aaefd6c1aff21L, 0x80542107c0113dL, 0x481f1a5e19b4b1L, + 0x7c17d43fcc8c61L, 0x8b04452bb0bbbeL }, + { 0xe51e5f54cebae1L, 0x05341ba56a414cL, 0x0083a2c7fb8a30L, + 0xb4663f277f4952L, 0xce72eec4bb0074L, 0x74fdd66a3584d1L, + 0x6b9e58eb02e076L, 0x5be45d53b961f4L } + }, + { + { 0xc7474f31ab2e0bL, 0x2838ccbf4bf454L, 0x634392ef3c3eacL, + 0x440e40a137602bL, 0xeea67e9d1ae8e3L, 0xafdf93a77e221eL, + 0x3c9f3da2719a10L, 0x466ecef32c8256L }, + { 0x1061c19f9c432fL, 0xa1332d9b1c7d98L, 0xbc735f2a425c2cL, + 0x1429cdf4b1bccbL, 0x77b42a16bbb5f9L, 0x30078e35955ae4L, + 0x8acd77721cc315L, 0xaa90d5fe86fa99L } + }, + { + { 0xfcfd460721115aL, 0x6a7de3e08269b8L, 0xe5964a696dd47eL, + 0x6717cd58dca975L, 0x7ea4ebe98b149eL, 0x6f894d5b7b8057L, + 0xbd6f9607f30e31L, 0x61ca45323df092L }, + { 0x32241f99d782f3L, 0x55173b02abfae2L, 0x0abe0edd15bbbdL, + 0xb6d3c0ab438abbL, 0x62fb4679ffa20bL, 0x30926b5d31560aL, + 0x44bf27c2a0aa6dL, 0xf7473131a4cb97L } + }, + { + { 0xa2f6c0db0535deL, 0xcb02ae1c855166L, 0xc699e6bb3422f0L, + 0x774febe281ba8aL, 0x1d9d24fffabcc7L, 0x0b31ba1fe12ba5L, + 0x4c8680313d0af7L, 0x90640d32f47160L }, + { 0xa0c4bf45876603L, 0x717f6fa950ab08L, 0xf12bb53a710de8L, + 0xc500c616a88f50L, 0x0070f992645351L, 0x57aab5d2446893L, + 0xd553fa8b68f657L, 0xe8537c1693c55dL } + }, + { + { 0x58e86eb7fc7684L, 0xdf330f7bfc73a9L, 0x41e337dcc11936L, + 0x36d92006e35759L, 0x01327033500d8bL, 0xfa684059483354L, + 0xc8f2980667851bL, 0x538ec8918296b0L }, + { 0xa2a2c4fcff55f9L, 0xb260d4d60d20bdL, 0x3ed576fd9cc59fL, + 0x4ed8c64d514fccL, 0x37ebfb2c22b315L, 0xca67a3694c212cL, + 0x4f8e08c3a1795eL, 0x498f9264e7261fL } + }, + { + { 0xfea7382c59b3d4L, 0xb9942ed3f2925fL, 0xe4b00dc8ea77e8L, + 0x74a18ec3cab02eL, 0xbbbb752ef16d0bL, 0x639da4fffab032L, + 0xc371a4a3aa30f0L, 0x8e26b22caa175bL }, + { 0x94e41567e2b62eL, 0x7cceea625a794cL, 0x931d2f4479f015L, + 0x946183d90b25b2L, 0x1504e9768a2807L, 0xa7577d3fa49dddL, + 0x24fc87edd48699L, 0x9edefd63d7d99cL } + }, +}, +{ + { + { 0x0508b340f0b450L, 0xe0069a5c36f7f4L, 0x26556642a5a761L, + 0x0193fd8848e04dL, 0xc108cf573fe2e7L, 0x05eb0ecfd787d4L, + 0x1555ccbff28985L, 0xb5af09f651b995L }, + { 0x167d72ce1134beL, 0xd6d98bf57c669aL, 0x40fb7166dd76faL, + 0xeabbf202a41b31L, 0x300ff0e09b75b0L, 0x32b6fadd9a0c1eL, + 0x805188365a80e0L, 0x8bef69332110feL } + }, + { + { 0x637802fbef47d4L, 0xfac114b2d16eaaL, 0x7b3f3ab0415644L, + 0x17ab8d12dd895bL, 0x271b7fe87195f3L, 0xa3f867ea71f65fL, + 0x39ba40cc80583aL, 0x6db067256e1fccL }, + { 0x4feab4e06662a8L, 0xc857415c74bd46L, 0x18032ed732b126L, + 0x87c8aea7a099eaL, 0xb4a753536fe0a8L, 0x33a98da27673f6L, + 0x3e40c022b8e549L, 0x2def1af9a4c587L } + }, + { + { 0x9618b68a8c9ad9L, 0xd70b4aa49defdaL, 0xae8b1385f788efL, + 0x87c3542dd523f4L, 0xe42c7055c5b004L, 0x6303360fa7df57L, + 0x33e27a75f6d068L, 0x9b3268e8ff331aL }, + { 0x845cc9623ee0c3L, 0x003af70ac80084L, 0x6a9f931530c41dL, + 0xa1d7051bb127f0L, 0x642ce05ca36245L, 0xc34205b0323ee9L, + 0x7cc8912b7b3513L, 0x6252cc8076cbdbL } + }, + { + { 0x10e68a07089522L, 0x36c136158fc658L, 0x490397d74723a4L, + 0x42692c0519d56cL, 0x69d251bf1ff235L, 0xe689d03c2cbf37L, + 0xf04ceba825b7f4L, 0xd6b9bee2281c2eL }, + { 0xc52ef3fe0043abL, 0x351bf28d1d1be8L, 0x277615f0f18a5aL, + 0x31f717f5d6800fL, 0xf5fb82dab922e2L, 0x99aee2f2d6ae43L, + 0x42477fec63b982L, 0x904aeb1a594a01L } + }, + { + { 0xaa82174eb39974L, 0xbc38e6195e6aa0L, 0x6a3df8a25c0675L, + 0xf324203ffbe739L, 0xfa5a0b4a3f0649L, 0x79c87327a7a6b8L, + 0xeb65ecd40ad3f5L, 0x718d416e4e45c5L }, + { 0x029dbf4e2326fdL, 0x0c63416e7942f0L, 0x6d0c7286f4e678L, + 0x59f0b10a138601L, 0x8a1d9788d92ea9L, 0x9f8d712c22eca5L, + 0x73970447b6b96bL, 0xa2d49eee6fb955L } + }, + { + { 0x249f900bf14a19L, 0xd3522da63a8cd2L, 0x28a32f386964d2L, + 0xacf712bc1fa743L, 0x98a9bfc0bb94d3L, 0x318ece1bc06824L, + 0xfc476754fce7f0L, 0x19caec9e4135b7L }, + { 0x6de68a8c6817bbL, 0x7121960f3b6d89L, 0xa7d4261f5a818eL, + 0x0c0ba519157455L, 0x78b6acf450d5ffL, 0x198b4934e8649aL, + 0x0941a3cfd05da3L, 0x264ea4adb55951L } + }, + { + { 0xcfee91c46e5a31L, 0x47b6806fff7366L, 0xdb14be45df849dL, + 0x3c5e22bac66cc7L, 0x7f3f284a5f4769L, 0x4e00815383be36L, + 0x39a9f0b8072b0bL, 0x9887cd5c7eadd6L }, + { 0x7dd8f05b659511L, 0x15c796dd2e1cb9L, 0xe5edb0c0d31345L, + 0x2025df06939c60L, 0x6314c08bf15de1L, 0x03c154804c7fb5L, + 0x413337fbb5d3edL, 0xfc20b40477e983L } + }, + { + { 0x7f968805db0ef9L, 0x05562dee9c2a70L, 0x071e5bc7dae133L, + 0xa8cdd12237fc4aL, 0x6d565e74ea492bL, 0xa17cf94381ee52L, + 0x6ab8a4e9f5c546L, 0xbb642f340288efL }, + { 0x64e59215df5c2dL, 0x43696e3bb906f4L, 0x73a841a74ae46cL, + 0xe264883c506b8aL, 0x9542e1aa1be548L, 0x89385395e81b4aL, + 0x5642cfaeaca6ceL, 0xed8077b806e0f9L } + }, +}, +{ + { + { 0x1c776c47e13597L, 0x0ec8b289e584fdL, 0x0bb6043b8b61e8L, + 0xdcc17489cd835bL, 0x493e6ac39fef9aL, 0xb44eb34d133e17L, + 0xfebcd0071cb6f9L, 0xe6cf543d20eff2L }, + { 0xf265cad0a004c7L, 0x9b06c9dd35cc12L, 0x769f985cb4ea53L, + 0x29160a20993434L, 0xdf8dd108d939c4L, 0xefa177c6711e2fL, + 0x1695790cd7a2cdL, 0x38da3d777f6642L } + }, + { + { 0x9bfcfd96307b74L, 0xc26a36dbfdabc3L, 0x9341be04abe28eL, + 0xdb20b5273d1387L, 0xf8d229c3d1949cL, 0xf1e0afeb8b3a41L, + 0x29c60dfed565d0L, 0x6930bb58b43b2cL }, + { 0x1d76527fc0718fL, 0xdb981431f67189L, 0x0c62f6451f32ccL, + 0x70a66268bd35e5L, 0x1725641c1cece7L, 0x7f130a8f96f4a4L, + 0x72319e9f06ee98L, 0x215b73867bf9b2L } + }, + { + { 0x8d1bec20aaddd7L, 0xfb8b95bb8be4f9L, 0xeac193efde1026L, + 0xa5edea79d5860cL, 0x4adbaea44280d3L, 0xce8b67038f4798L, + 0x914c107ec30deaL, 0xbdc5cf7000776bL }, + { 0xb6fd7d1a206a13L, 0x9941ebadae986eL, 0x76c27a81f1caaaL, + 0x6967c123f108b4L, 0x6f115284aea2d0L, 0x9bb4319144ddacL, + 0x1a4d3eac8ec6fcL, 0xfe4b0b8bf37420L } + }, + { + { 0x5d9a4a1ec0ac6fL, 0x84b79f2fc7c80dL, 0x64222f7c14fac3L, + 0xdd9e039c23b3f2L, 0x4a84abdea956bbL, 0x370dcbaebe09dcL, + 0x79a9ea8e0eaf82L, 0x4cfb60aaee375fL }, + { 0x6a10dbf9106827L, 0xa3ba5cf43f305bL, 0x481b885c1bb083L, + 0x2f52380b3117b1L, 0x0066122ddd6791L, 0x4f8923e63bace3L, + 0x5c5f499ecb88d4L, 0xfdc780a3bac146L } + }, + { + { 0x34b70ae7ba1f71L, 0x909182945bd184L, 0x3b39778e707313L, + 0xdeefc5e6164e91L, 0xbb55bed4971f39L, 0x7d523398dafc8bL, + 0x82391bfa6adf0fL, 0xfd6f90ae319522L }, + { 0x60fdf77f29bbc9L, 0xeff9ed8aaa4030L, 0x978e045f8c0d3fL, + 0xe0502c3eed65cdL, 0x3104d8f3cfd4c8L, 0xab1be44a639005L, + 0xe83f4319eeab3fL, 0x01970e8451d797L } + }, + { + { 0xbc972f83180f4bL, 0xac053c0617779dL, 0x89392c57fa149fL, + 0xdc4699bbcb6263L, 0x0ae8b28ce12882L, 0xdca19a7af1a4dcL, + 0xd3d719f64e1a74L, 0xbb50201affdd5dL }, + { 0x56f73107ac30e9L, 0x65cc9c71878900L, 0x83f586627338a3L, + 0x122adefac5bb13L, 0x97de2001bcd4d5L, 0x6ed3985b8aa3a0L, + 0x8680f1d6821f9bL, 0xcb42028dda9f98L } + }, + { + { 0xcdb07080ec2db3L, 0xe28c8333dad1a1L, 0x2093e32de2da07L, + 0x731707383b8987L, 0xad17871f552b8dL, 0x846da9851cf70aL, + 0xf94a16e5c4f5e1L, 0x84299960f8348aL }, + { 0x4bf3f6898db78aL, 0xad77fa83d19b52L, 0x69767728b972dcL, + 0x7dfa35a5321be0L, 0x9881846dd344a6L, 0xe550292ad4e2a8L, + 0x8075217bc68bf1L, 0xdd837c4893be15L } + }, + { + { 0x09c931ed4fab5bL, 0xb2dcf08b77a0f1L, 0x7dac5c0e0d38a6L, + 0xa5570b00ae73afL, 0xc7c19d3f5aed28L, 0x575fa6f5251e92L, + 0xb843cd6cdf7275L, 0xd9d3d8e9a01287L }, + { 0xf94e356b3c370bL, 0xc62b99ffe464b0L, 0x7792650a986057L, + 0xeaa67d5c4b1874L, 0xba1ba4d0b07078L, 0xdbf636d7a03699L, + 0x1a16c34edd32a3L, 0x6ce2495a45cb5dL } + }, +}, +{ + { + { 0xd7c4d9aa684441L, 0xce62af630cd42aL, 0xcd2669b43014c4L, + 0xce7e7116f65b24L, 0x1847ce9576fa19L, 0x82585ac9dd8ca6L, + 0x3009096b42e1dbL, 0x2b2c83e384ab8bL }, + { 0xe171ffcb4e9a6eL, 0x9de42187374b40L, 0x5701f9fdb1d616L, + 0x211e122a3e8cbcL, 0x04e8c1a1e400bfL, 0x02974700f37159L, + 0x41775d13df8c28L, 0xcfaad4a61ac2dbL } + }, + { + { 0x6341b4d7dc0f49L, 0xaff6c2df471a53L, 0x20ec795fb8e91eL, + 0x4c7a4dfc3b7b62L, 0x9f33ff2d374938L, 0x38f8c653a60f2eL, + 0xc1168ac2efef73L, 0x046146fce408eeL }, + { 0x9b39ac0308b0c3L, 0xe032d6136b8570L, 0xee07d8dfc4aacfL, + 0x0a82acbd5a41ddL, 0xbe0ded27c3d726L, 0xce51d60b926ce9L, + 0xfa2f7f45806c1eL, 0xe367c6d1dec59cL } + }, + { + { 0x64511b6da2547bL, 0x76a349c0761405L, 0x37d662601223abL, + 0x0e243c1f4d7c48L, 0xdc9c8b4da756a0L, 0xc7430dfd72e7e9L, + 0x0eb130827b4210L, 0x7a9c044cf11cbdL }, + { 0x2c08ff6e8dd150L, 0x18b738c2932fc6L, 0x07d565104513e8L, + 0x0ca5cffaa40a17L, 0xd48634101baa8fL, 0xfb20fafb72b79eL, + 0x1a051e5654020fL, 0xe3b33174e17f23L } + }, + { + { 0x05910484de9428L, 0x620542a5abdf97L, 0xaa0ededa16a4d1L, + 0xa93f71c6d65bb9L, 0x88be135b8dfaf9L, 0x1d9f4e557ca8eeL, + 0x4c896aa26781adL, 0xd3fbe316c6c49fL }, + { 0x088d8522c34c3dL, 0xbb6d645badff1eL, 0xe3080b8385450dL, + 0x5ccc54c50ab1f3L, 0x4e07e6eac0657dL, 0xa7ba596b7ef2c0L, + 0xcceca8a73a81e9L, 0xa0b804c8284c35L } + }, + { + { 0x7c55956f17a6a2L, 0xb451d81789cfa8L, 0xdf414e82506eaaL, + 0x6ef40fbae96562L, 0x63ea2830e0297eL, 0xf5df26e73c46faL, + 0xe00641caac8bceL, 0xc89ed8f64371f3L }, + { 0xd22b08e793202eL, 0x39a9033875cb50L, 0xe64eec0f85ddb4L, + 0xdce45a77acf7b5L, 0x39d1e71b9b802dL, 0xafdfe7cbd559acL, + 0x17ec1f8809eeb5L, 0x8c0e38a4889b8cL } + }, + { + { 0x47eabfe17089daL, 0x2d18466ec90c50L, 0xa511aa45861531L, + 0xebb3d348c39b39L, 0xa0ac4daf1b5282L, 0xea26be7a9dadbaL, + 0x8992ba8554d86eL, 0x7fcbdb6d5f2ef5L }, + { 0x320e79b56863e7L, 0xeb9d0c0a7dce2dL, 0xb9f4031784cbc6L, + 0x68823ee7ac1f81L, 0xa6b6f4f9d87497L, 0x83c67b657f9b6eL, + 0x37357470fef2a7L, 0xf38028f59596e2L } + }, + { + { 0x9ea57ab7e82886L, 0x18221c548c44d5L, 0xbf8e6cf314a24fL, + 0x70ff18efd025e5L, 0x08d03de5334468L, 0x2b206d57404fb7L, + 0xb92327155e36b0L, 0xcc7604ab88ddd9L }, + { 0x3df51524a746f0L, 0x8fdebd8168e3fcL, 0xffc550c7f8c32cL, + 0x1dbbc17148743eL, 0xd48af29b88e18bL, 0x8dca11c750027cL, + 0x717f9db1832be3L, 0x22923e02b06019L } + }, + { + { 0xd4e06f5c1cc4d3L, 0x0fa32e32b4f03aL, 0x956b9afc4628d0L, + 0x95c39ce939dad1L, 0x39d41e08a00416L, 0xfd7ff266fb01aaL, + 0xc6033d545af340L, 0x2f655428e36584L }, + { 0x14cfb1f8dff960L, 0x7236ffcda81474L, 0xc6a6788d452d0fL, + 0x2ad4a5277f6094L, 0x369d65a07eea74L, 0x27c6c38d6229aaL, + 0xe590e098863976L, 0x361ca6eb38b142L } + }, +}, +{ + { + { 0x6803413dfeb7efL, 0xb669d71d3f4fadL, 0x5df402ac941606L, + 0xe5d17768e6c5b7L, 0x131bcb392ab236L, 0x7f1fb31ce2e0e0L, + 0xa2c020d9e98c35L, 0x33b23c0f28657bL }, + { 0xed14e739cf7879L, 0x10d4867b4357b3L, 0x127cea331e4e04L, + 0xc60d25faa5f8a7L, 0xfef840a025b987L, 0x78081d666f2a0aL, + 0x0fa0b97ac36198L, 0xe0bb919134dc9fL } + }, + { + { 0xc1d2461cc32eaeL, 0x0fdbfdf0f79a37L, 0x70f2bc21c95f02L, + 0x7d68bec372cddfL, 0x44f78178439342L, 0xa3d56784843a6cL, + 0xbadf77a07f8959L, 0xf45819873db4caL }, + { 0xe8eaaf3d54f805L, 0x2f529d1b84c1e7L, 0x404e32e21e535cL, + 0xabac85c159b5f5L, 0x4e8e594b00466fL, 0x40fcaabc941873L, + 0x3b4e370be407c6L, 0xccd57885b2e58dL } + }, + { + { 0x3ee615e88b74a8L, 0xd7d6608eab4e69L, 0x27cf9f1e4ace36L, + 0x282359e7aebabbL, 0x96e509bf6d162fL, 0xad906f3f1a290aL, + 0xe7d6c4f1314a58L, 0xeecffe4218431dL }, + { 0xa66e0e9e2cfed9L, 0xb0887ec71f0544L, 0xd34e36ba04c5d7L, + 0x094daa5ed4392dL, 0xcda83adc8aa925L, 0x1adef91b979786L, + 0x3124dcbfddc5d6L, 0x5cc27ed0b70c14L } + }, + { + { 0x386dbc00eac2d8L, 0xa716ecbc50ca30L, 0x9e3fc0580d9f04L, + 0x37dde44cfeacebL, 0xd88d74da3522d5L, 0x6bb9e9f2cf239aL, + 0x9e7fb49a7cbfecL, 0xe1a75f00a5c0efL }, + { 0x6e434e7fb9229dL, 0x0ec6df5c8a79b3L, 0x7046380d3fb311L, + 0xe957ef052e20faL, 0x0f4fe9a9ef4614L, 0x1b37d9c54d8f2bL, + 0x23b2dc139d84a2L, 0xf62c4f6724e713L } + }, + { + { 0xbd6922c747e219L, 0x34d14383869b7bL, 0x8c875a596f2272L, + 0xd9602c03fe361eL, 0x081348f744839fL, 0x61bd16c61ac1f1L, + 0x993b727d8da4e1L, 0xbb40ba87741271L }, + { 0xe6dcc9881dcfffL, 0x9f513f593ce616L, 0xdc09683618cd8fL, + 0xc3b1d1026639beL, 0xe8f149fc762ee2L, 0x59f26efb244aaeL, + 0x3f2de27693dd96L, 0xd8b68f79c3a7deL } + }, + { + { 0x6fa20b9970bd5bL, 0x87242d775f6179L, 0xa95a6c672d9308L, + 0x6eb251837a8a58L, 0xfdea12ac59562cL, 0x4419c1e20f1fc3L, + 0x0c1bd999d66788L, 0x4b7428832c0547L }, + { 0x4f38accdf479abL, 0x01f6271c52a942L, 0xe3298f402ca9a7L, + 0x533dacab718fc8L, 0x133602ab093ca8L, 0xc04da808f98104L, + 0xd0f2e23af08620L, 0x882c817178b164L } + }, + { + { 0x28e6678ec30a71L, 0xe646879f78aca1L, 0x868a64b88fa078L, + 0x671030afee3433L, 0xb2a06bb87c0211L, 0x202eca946c406aL, + 0x64d6284e4f0f59L, 0x56ae4a23c9f907L }, + { 0x5abbb561dcc100L, 0x6fef6cf07c7784L, 0xb6e25cddb7302dL, + 0xa26785b42980e8L, 0xe7d4043fb96801L, 0x46df55d8e4282bL, + 0x9c0a5f5c602d6eL, 0xf06560475dfe29L } + }, + { + { 0x0e82a1a3dcbc90L, 0xb1ee285656feacL, 0xfa4353b0d3d3b2L, + 0xc2e7a6edd5c5dfL, 0x13707e1416ce53L, 0xc84ce0787ebc07L, + 0xdd273ce8a9a834L, 0x432a6175e8e1e7L }, + { 0xa359670bd0064aL, 0xc899dd56534516L, 0x666560edb27169L, + 0x1537b22a19a068L, 0x3420507eac7527L, 0x479f25e6fc13a7L, + 0xc847acc1bc19b3L, 0xecdecf00b20d45L } + }, +}, +{ + { + { 0x6f241004acea57L, 0xdace1c6da68597L, 0xea7dd4150ce77fL, + 0x1aecb841585884L, 0x92ff208ea4a85cL, 0xde9433c88eebd2L, + 0x53cd3183f4d289L, 0x397085826539afL }, + { 0x4b57599b827d87L, 0xdc82ac03d77638L, 0x694336652f6e61L, + 0xb8fc4b0ad5e8a6L, 0x1b6f7dcf388642L, 0x6f24533a74dd57L, + 0xc66937841750cfL, 0x06757eb28a37afL } + }, + { + { 0x0e70d53c133995L, 0x88a5e0c7c8c97dL, 0x4e59dbf85f3be3L, + 0x0f364ac0e92698L, 0x3a1e79bef6940fL, 0xc8a3941d85d23aL, + 0x143bb999a00e58L, 0x61cf7d6c6f2f10L }, + { 0x979c99485150feL, 0xcfd0df259d773fL, 0xce97b9daab7bcdL, + 0xc9fff8e6afd8fcL, 0x246befd89a4628L, 0xf6302821567090L, + 0x15393426749c58L, 0xff47d0ea0f3fd3L } + }, + { + { 0x09b0bfd35f6706L, 0x74645812c82e69L, 0xb60729f50d5fe9L, + 0xf13324595c74f1L, 0x33647e3bb76c89L, 0x01264045a9afccL, + 0x46d57ee0f154abL, 0x2efa55525680a4L }, + { 0x12ebfc65329d90L, 0xcb37ae579800afL, 0x5bb53496f8e310L, + 0x9b59c63f1bb936L, 0x5b49baaf4610e9L, 0x2bbeeef4f2d6acL, + 0x87ee21e0badc67L, 0x12e2aadf1ddfa0L } + }, + { + { 0x5b4668fa9109eeL, 0xfa951338a6cea2L, 0xe45e6fc4068e16L, + 0x8ae9a0c0205ed8L, 0x2993b96679b79bL, 0xc6b878fed604d3L, + 0x01d020832c77f3L, 0xd45d890495a1abL }, + { 0x99348fa29d2030L, 0x961f9a661f8f7aL, 0xfd53212674f74bL, + 0x45cee23b3e72bcL, 0x3fccb86b77e2d5L, 0xdff03104219cb7L, + 0x233771dc056871L, 0x1214e327d2c521L } + }, + { + { 0x9f51e15ff2a8e1L, 0x86571c5138bc70L, 0xbfc4caf0c09d46L, + 0x65e33fec2a0c18L, 0x8214392426867dL, 0x51ce6c080ae4edL, + 0x6cbe8d7b110de6L, 0x7f6e947fd22ea4L }, + { 0x7373a75cadefc4L, 0x6fca1d2b0c682fL, 0xcd2140df3c7c1eL, + 0x8653a37558b7a5L, 0x653e74e55eb321L, 0xbe0c6b3c31af73L, + 0x3376379f4fc365L, 0x3570b3771add4dL } + }, + { + { 0x9061ec183c3494L, 0xaf2f28d677bc95L, 0x6fe72793bf8768L, + 0xc5f50e30fa86d8L, 0x6c03060a3293ceL, 0x4d53357e2355a6L, + 0x43a59eae4df931L, 0x6f48f5d13b79c6L }, + { 0xa4d073dddc5192L, 0x6d0e318a65773fL, 0x1008792765de9eL, + 0xa724ed239a0375L, 0x510ff1497d7c9eL, 0x251f6225baa863L, + 0x86464fe648a351L, 0xf85e98fd50fd91L } + }, + { + { 0x29c963486ee987L, 0x93e8e5210dcc9fL, 0xa1fc4d1c910b1fL, + 0x015acacfeb603eL, 0xc9f25f80844a5fL, 0x50de93c73f4dacL, + 0x1758783310a4aaL, 0x544d570358f106L }, + { 0x4eeec7b1dc68caL, 0x6238e6fe00fbcbL, 0x34d394cb4e83c9L, + 0x764ffa22292656L, 0x5614cd1f641f2eL, 0x4252eb69e07234L, + 0xcbaef4568d2ba4L, 0x8c9c5508a98b17L } + }, + { + { 0xf235d9d4106140L, 0x1bf2fc39eb601eL, 0x6fb6ca9375e0c3L, + 0x4bf5492c0024d2L, 0x3d97093eb54cc6L, 0xc60931f5c90cb5L, + 0xfa88808fbe0f1aL, 0xc22b83dd33e7d4L }, + { 0x9cfec53c0abbf5L, 0x52c3f0a93723dfL, 0x0622b7e39b96b6L, + 0x300de281667270L, 0x50b66c79ef426aL, 0x8849189c6eb295L, + 0xeaec3a98914a7eL, 0x7ed56b0c4c99e0L } + }, +}, +{ + { + { 0x7926403687e557L, 0xa3498165310017L, 0x1b06e91d43a8fdL, + 0xf201db46ac23cbL, 0x6f172ad4f48750L, 0x5ed8c8ce74bd3eL, + 0x492a654daba648L, 0x123010ba9b64ffL }, + { 0xa83125b6e89f93L, 0x3a3b0b0398378aL, 0x9622e0b0aebe7cL, + 0xb9cbfdc49512a4L, 0x13edffd6aaf12aL, 0x555dff59f5eafdL, + 0x3cba6fe1212efaL, 0xd07b744d9bb0f8L } + }, + { + { 0x45732b09a48920L, 0xf3080fc13ff36dL, 0x9347395de8f950L, + 0x14d025a382b897L, 0x60c5a7404d72adL, 0x30be7e511a9c71L, + 0x43ffabd31ac33aL, 0x97b06f335cbb14L }, + { 0xe4ff5c57740de9L, 0x5fed090aacf81eL, 0x97196eee8b7c9dL, + 0x316dcd1045910bL, 0x7a2b2f55ad8c63L, 0x674fffdc5b03bbL, + 0xc1cd133e65953cL, 0x3c060520a83556L } + }, + { + { 0x797c3f6091c23dL, 0x2ea2de339c9c05L, 0x5d958b4a31f67cL, + 0xf97afe5d5f088cL, 0xbcfbd2a0b37243L, 0xc43ad3eeca630cL, + 0xb92a33742845e0L, 0x970bff7a9a0f16L }, + { 0x86355115970a79L, 0xcee332ef205928L, 0x2c58d70c04c208L, + 0xdbfe19a3f5e5bfL, 0x8f8f2c88e51c56L, 0xb61f58e8e2da75L, + 0x4046a19624d93fL, 0x7de64dbe1f9538L } + }, + { + { 0xd018e1cc2d850eL, 0x8cdb64363a723cL, 0x9a65abe90a42afL, + 0xfeece9616f20ccL, 0xc906800d5cff56L, 0x0acf23a3f0deedL, + 0x2143061728dd3aL, 0x66276e2b8ce34cL }, + { 0x23700dc73cc9c7L, 0xdb448515b1778bL, 0x330f41e4aab669L, + 0x2f5aabcf5282a4L, 0xff837a930f9e01L, 0x1a1eb2f901cc98L, + 0xd3f4ed9e69bd7fL, 0xa6b11418a72a7dL } + }, + { + { 0x34bde809ea3b43L, 0x5ddcb705ced6aeL, 0x8257f5b95a6cb8L, + 0xaac205dc77dcb8L, 0x77d740d035b397L, 0xca7847fcf7e0a6L, + 0x9404dd6085601bL, 0x0a5046c457e4f9L }, + { 0xcaee868bc11470L, 0xb118796005c5f6L, 0xcc04976ec79173L, + 0x7f51ba721f6827L, 0xa8e3f0c486ff7eL, 0x327163af87838cL, + 0xcf2883e6d039fdL, 0x6fb7ab6db8b0e2L } + }, + { + { 0x8ca5bac620d669L, 0xff707c8ed7caa9L, 0xdaefa2b927909bL, + 0x1d2f9557029da3L, 0x52a3ba46d131a0L, 0xe5a94fd3ab1041L, + 0x508917799bc0aeL, 0xf750354fa1bd16L }, + { 0xdd4e83a6cd31fdL, 0xd33505392fac84L, 0xf914cbc1691382L, + 0x669683fda6ade6L, 0x69446438878513L, 0x429d3cc4b1a72dL, + 0x655c46a61eec36L, 0x881eded4bc4970L } + }, + { + { 0x5b39d377ca647fL, 0x41533c1e917b34L, 0xea2aeb57daf734L, + 0xf1ef1eb1286560L, 0x582f2e008e0473L, 0x5913d7d5edc74aL, + 0x588c7ec3c1e754L, 0xbd6db057146fe1L }, + { 0x3b0d49e7634907L, 0x4c65ce4e43b9ccL, 0xb87e9582d92d5bL, + 0x05135727ab1519L, 0x03ec0848c3aed0L, 0x4d7aa21561a641L, + 0xe5f821199e92adL, 0x379b55f48a457cL } + }, + { + { 0x8317c34d6a8442L, 0xb0ab4a5ae499daL, 0xebcb16e720e8ebL, + 0xfd5c5639a96908L, 0xcab4d67ad23acfL, 0xa600a79bcdf748L, + 0x18a6340a2a6a51L, 0xf2f415c3aabd69L }, + { 0xdb38a4f747258aL, 0xb6ea5602e24415L, 0xfad1ea9f1f7655L, + 0x4e27eb5c957684L, 0xf8283e1b2e1cfcL, 0x8f83bd6aa6291cL, + 0x28d23b55619e84L, 0xb9f34e893770a4L } + }, +}, +{ + { + { 0x1bb84377515fb1L, 0xac73f2a7b860a6L, 0x78afdfa22b390fL, + 0x815502b66048aaL, 0xf513b9785bf620L, 0x2524e653fc5d7cL, + 0xa10adc0178c969L, 0xa1d53965391c8dL }, + { 0x09fccc5a8bcc45L, 0xa1f97d67710e1eL, 0xd694442897d0a1L, + 0x7030beb5f42400L, 0xdebe08c7127908L, 0x96b715c2187637L, + 0xc598250b528129L, 0x0f62f45a1ccb07L } + }, + { + { 0x8404941b765479L, 0xfdecff45837dc4L, 0x1796372adbd465L, + 0x5f84c793159806L, 0x6d2e46b6aaad34L, 0xd303b4a384b375L, + 0x440acd5b392002L, 0x4f2a4a7c475e87L }, + { 0x038e1da5606fc2L, 0x2d821c29c2f050L, 0xc074cb3f139db4L, + 0xde2fee74ec59beL, 0x5a819eea84ed59L, 0xd65c62c3e98711L, + 0x72eb440b9723c1L, 0xb92775401be611L } + }, + { + { 0x929fe64ab9e9fcL, 0x04379fd0bf1e85L, 0xb322093bc28ee3L, + 0x78ac4e2e4555e1L, 0xdb42b58abc5588L, 0x1c1b5e177c8b12L, + 0xf6d78dd40366c4L, 0xc21ff75bdae22eL }, + { 0x1e3d28ea211df2L, 0xc5a65a13617c0aL, 0x3fa02c058140d5L, + 0x155c346b62d10cL, 0xc9cf142e48268fL, 0xdc140831993bc3L, + 0x07c44d40ee69dcL, 0x61699505e2ac46L } + }, + { + { 0x44e4a51d0fb585L, 0x00846bef1f3ce8L, 0xedef39a8e2de1eL, + 0x430afe333b3934L, 0xac78b054337188L, 0x0f39de4c9a3f24L, + 0x039edddc9ae6a4L, 0xf4701578eacd51L }, + { 0x1e396949a2f31aL, 0xc8a40f4b19a8b1L, 0xdddd10c9d239d8L, + 0xf974245887e066L, 0xfdb51113ea28c6L, 0xb5af0fbe1122a9L, + 0xd30c89f36e0267L, 0x7b1c0f774f024cL } + }, + { + { 0x1ec995607a39bfL, 0x1c3ecf23a68d15L, 0xd8a5c4e4f59fe9L, + 0xacb2032271abc3L, 0xbc6bdf071ef239L, 0x660d7abb39b391L, + 0x2e73bb2b627a0eL, 0x3464d7e248fc7eL }, + { 0xaa492491666760L, 0xa257b6a8582659L, 0xf572cef5593089L, + 0x2f51bde73ca6bfL, 0x234b63f764cff5L, 0x29f48ead411a35L, + 0xd837840afe1db1L, 0x58ec0b1d9f4c4bL } + }, + { + { 0x8e1deba5e6f3dcL, 0xc636cf406a5ff7L, 0xe172b06c80ca0fL, + 0x56dc0985ffb90aL, 0x895c2189a05e83L, 0x6ddfaec7561ac2L, + 0xaa3574996283a0L, 0x6dfb2627e7cd43L }, + { 0x6576de52c8ca27L, 0x6a4a87249018ebL, 0x00c275c5c34342L, + 0xe34805ad2d90c4L, 0x651b161d8743c4L, 0xb3b9d9b7312bf3L, + 0x5d4b8e20bf7e00L, 0x8899bdf78d3d7eL } + }, + { + { 0x9644ad8faa9cd1L, 0x34c98bf6e0e58eL, 0x6022aad404c637L, + 0x2a11a737ac013bL, 0x5bdd1035540899L, 0x2e675721e022a4L, + 0xe32045db834c33L, 0x74a260c2f2d01cL }, + { 0x20d59e9c48841cL, 0x05045dde560359L, 0xeba779cac998acL, + 0x5bed10c00a6218L, 0x25d4f8e5327ef4L, 0xa2784744597794L, + 0xefd68ca831d11eL, 0x9ad370d934446aL } + }, + { + { 0x3089b3e73c92acL, 0x0ff3f27957a75cL, 0x843d3d9d676f50L, + 0xe547a19d496d43L, 0x68911c98e924a4L, 0xfab38f885b5522L, + 0x104881183e0ac5L, 0xcaccea9dc788c4L }, + { 0xfbe2e95e3c6aadL, 0xa7b3992b3a6cf1L, 0x5302ec587d78b1L, + 0xf589a0e1826100L, 0x2acdb978610632L, 0x1e4ea8f9232b26L, + 0xb21194e9c09a15L, 0xab13645849b909L } + }, +}, +{ + { + { 0x92e5d6df3a71c1L, 0x349ed29297d661L, 0xe58bd521713fc9L, + 0xad999a7b9ddfb5L, 0x271c30f3c28ce0L, 0xf6cd7dc2a9d460L, + 0xaf728e9207dec7L, 0x9c2a532fcb8bf0L }, + { 0xd70218468bf486L, 0x73b45be7ab8ea8L, 0xddfc6581795c93L, + 0x79416606bb8da2L, 0x658f19788e07a2L, 0xa9d5b0826d3d12L, + 0x4d7c95f9535b52L, 0xad55e25268ef8aL } + }, + { + { 0x94a9b0ba2bc326L, 0x485ecc5167e5f3L, 0x8340bc7c97fc74L, + 0x06f882b07aaa5cL, 0x4b57455849698aL, 0xd9281ebb36a0baL, + 0x8918c6c8b8108fL, 0xedd1eea5b50d1dL }, + { 0x94d737d2a25f50L, 0x0e5a8232446ad0L, 0x02a54357ced3e2L, + 0xb09a92a4af8cedL, 0x85fc498eeecef2L, 0x06a02b9e71e3d4L, + 0x00ad30784bb49aL, 0xf61585e64a5b4aL } + }, + { + { 0x915f6d8b86a4c9L, 0x944bc6ba861e1fL, 0x3091ca754465efL, + 0x11df859eb53a38L, 0xd44dde50144679L, 0x6c8da9a0994eddL, + 0xeebcebf91241efL, 0xc419354c2f6859L }, + { 0x1f4969349581b6L, 0x5712b10bb26cb4L, 0x8fcaa41b09fd59L, + 0xbd39aad72e22e3L, 0xf70e794b1199b0L, 0xdf63c0cc6f863dL, + 0xd58166fee9df4fL, 0xb9224eac45e70bL } + }, + { + { 0x80072face525f4L, 0x8597bd666a5502L, 0xf65e203dbc9725L, + 0xeccfbe3f2222a4L, 0x490aa422339834L, 0x134889162489e8L, + 0xaff3f80a735084L, 0x69d53d2f3f1bd6L }, + { 0xb123ffc813341aL, 0x359084c1173848L, 0x751425ed29b08dL, + 0x1edda523890ad4L, 0xb64974c607cf20L, 0xa8c8cb8b42ac7cL, + 0xd5cb305edd42e5L, 0xf3034dc44c090aL } + }, + { + { 0x428921dbb18e19L, 0x4cfd680fed2127L, 0x671144d92ac8c3L, + 0x2121901132c894L, 0x25d0e567604cd9L, 0xa372223afbc2a0L, + 0xcf98a5256c16f7L, 0x71f129ab5459e1L }, + { 0xf4afdc5b668b2eL, 0xc5d937a0c2d410L, 0xe2cc4af285d54aL, + 0x1c827778c53e18L, 0x270f2c369a92f6L, 0x799f9ac616327aL, + 0xce658d9d4246f2L, 0x0fb681ffb12e36L } + }, + { + { 0xc5ab11ee0690feL, 0x80261e33f74249L, 0x8eb4b4758c1cf2L, + 0x4895a80184ae9bL, 0x4a4bdb6d3e27ebL, 0xa7a1638bfd251cL, + 0x29ec144417a7e3L, 0xd0736093f1b960L }, + { 0xcb1ed8349c73d1L, 0x33fc84a8d1945aL, 0x9f668dbe965118L, + 0x3331743a82811fL, 0xf394dec28ba540L, 0x44ce601654a454L, + 0x240dbb63623645L, 0xf07e7f22e61048L } + }, + { + { 0x7c9f1763d45213L, 0x3eefa709c1f77fL, 0xde3c3c51b48350L, + 0x4a2bc649d481a7L, 0xfd4a58a7874f3dL, 0x96655d4037b302L, + 0x945252868bf5abL, 0x1b6d46a75177f6L }, + { 0x7de6763efb8d00L, 0xb2c1ba7a741b7bL, 0xcca6af47bae6edL, + 0xe4378ca5b68b3fL, 0xfb757deaf71948L, 0x7f07b5ebc6ac99L, + 0x752a56827d636dL, 0xc8b7d1d4b8a34fL } + }, + { + { 0x76cb78e325331bL, 0x41f41c9add2eedL, 0x03db2385c5f623L, + 0xbbc1d177102fa2L, 0x80f137a60182ecL, 0xfdd856955adf15L, + 0x4f53f5ee3373dcL, 0xec6faf021b669bL }, + { 0x7d4e9830b86081L, 0x10d3cd9f2d979cL, 0x0f48f5824a22c8L, + 0x86c540c02f99eeL, 0xf4c66545e6c5fcL, 0xaf0c588bc404c8L, + 0x2e6edbd423118aL, 0x86e32e90690eabL } + }, +}, +{ + { + { 0x1d12656dfbfa6fL, 0xa4980957646018L, 0x2f1071bc3597d0L, + 0x3df83f91dda80aL, 0x5853e28f3ae449L, 0xb853d319e19aadL, + 0x863f01ba0d8a46L, 0xa84fca62fef108L }, + { 0xbe4c0b7fb84de9L, 0x40a03dcc0727bfL, 0x781f841b18575cL, + 0x6a63045466cddbL, 0x6be758205dc7a2L, 0x420f87f07ae811L, + 0x28082423bf96c8L, 0x723998c51c6821L } + }, + { + { 0x38ab64181f5863L, 0xd82ecbd05ff9e1L, 0x339c94ea065856L, + 0x143054aa45156dL, 0xe6d64bf065628cL, 0xe530086a938589L, + 0x22d3a49385d79bL, 0x0b107900ab8245L }, + { 0xb0d80fbca387b5L, 0x698206e35551d7L, 0x199685da10bb73L, + 0xa8e5fa89107378L, 0x36e5724d99dbbfL, 0xd67f476d581b03L, + 0x7a15be788dd1e6L, 0x8dac8e4e5baa31L } + }, + { + { 0x4d5d88fe170ef8L, 0xb6ba5de1e9e600L, 0x4a89d41edeabc5L, + 0x737c66b8fac936L, 0x8d05b2365c3125L, 0x85a5cbcb61b68eL, + 0x8fea62620a6af9L, 0x85115ded8b50ecL }, + { 0x5430c8d6a6f30bL, 0x8bef9cf8474295L, 0x0648f5bbe77f38L, + 0xfe2b72f9e47bd7L, 0xad6c5da93106e2L, 0x4fa6f3dfa7a6c3L, + 0xdcd2ed8b396650L, 0x7de1cce1157ef9L } + }, + { + { 0x70a5f6c1f241d1L, 0x6c354d8798cd5cL, 0x23c78381a729fbL, + 0xcff8f15523cbdaL, 0x5683ff43493697L, 0xef7dbab7534f53L, + 0xd7bd08e2243d53L, 0x6f644cbf8072a9L }, + { 0xac960f9b22db63L, 0xa97f41723af04dL, 0x692b652d9798afL, + 0x0e35967fedb156L, 0x14b5e50dfe6ee8L, 0x7597edeb411070L, + 0x116f3ce442b3f9L, 0xe9b5ae81b2b6dbL } + }, + { + { 0xf4385ee2315930L, 0xc8d029827a8740L, 0x7907a8dd934a43L, + 0x20bc946c582191L, 0xa4acb3e6a405e7L, 0x8c1d6c843df2f5L, + 0x9df1593991f0b5L, 0xbb9df984d9be9dL }, + { 0x63620088e4b190L, 0xee1421eada3a88L, 0xb84f0ccf93b027L, + 0x7a5d6678e95091L, 0x3974462f3e3704L, 0xfa6fb5ec593e98L, + 0x44b6cf7a6477d2L, 0xe885b57b09a562L } + }, + { + { 0x6e339e909a0c02L, 0x57afff00e75f29L, 0x797d8d6fb7db03L, + 0xc6e11a3d25a236L, 0x643ce1c0107260L, 0xe644ec462eae1cL, + 0x821d5b83f5a3f5L, 0xa8ad453c0579d6L }, + { 0x6518ed417d43a4L, 0x46e76a53f87ccdL, 0xd6cbaabf9bef95L, + 0x25688324f7cbcfL, 0x367159a08476b4L, 0x1d1b401be6d324L, + 0x348cb98a605026L, 0x144f3fe43b6b1eL } + }, + { + { 0xbabbd787b1822cL, 0xd34ba7e2aa51f8L, 0x086f1cc41fbea4L, + 0x96f7eac746f3d9L, 0xad97f26281ecafL, 0x751a905a14ee2cL, + 0xb4e7fe90d7335fL, 0x0d97b8f4892ff0L }, + { 0xdb8a3155a5c40eL, 0x64e5de77ba567bL, 0x4f155f71eefe88L, + 0xe2297e9fb6fbf4L, 0xfe24bf96c16be5L, 0x2251847cdd83e2L, + 0x13ac2c85eda444L, 0x49d1b85283275fL } + }, + { + { 0xca08731423e08fL, 0x7046bb087d2f14L, 0x876f10c3bc846cL, + 0x2202b76358fbe3L, 0x0d4fc1c0e26ac6L, 0x1fc748bb986881L, + 0x609e61c8384a18L, 0x28a72d60d88e00L }, + { 0x1332a3178c6e2fL, 0x0367919b3526a4L, 0x53989e4698fe3eL, + 0x14b1145b16a99bL, 0xef9ec80ddbb75fL, 0x76256240e53955L, + 0x54e087a8744ae1L, 0xce50e8a672b875L } + }, +}, +{ + { + { 0x4c88b2ba29629cL, 0x946559c7b2642fL, 0x933d432f7ebe4cL, + 0x97109b663632c9L, 0x799b3fbe53184dL, 0xd4628710f069a6L, + 0x0c182a13a68351L, 0x974a8399a2437aL }, + { 0x29f19972a70278L, 0x01b98b6d9c424bL, 0xd85a60b08f4c37L, + 0xcc3523f2b1da15L, 0xf922115ddffb0fL, 0xee0fe4dde84ae2L, + 0x810440c55365beL, 0xd2f66391a457e8L } + }, + { + { 0x5e6879fe2ddd05L, 0x92a7545abdfc61L, 0x7dedd63a5cede8L, + 0x8a03b3f70df4bdL, 0xa5d1f6591f6cbbL, 0x372fde610f3fb2L, + 0x4537f9ea9dee05L, 0x7eb85bbdf7aa50L }, + { 0x963edf8e8c504dL, 0x53c8dcae7bdb6bL, 0xa246e4c6fedf2dL, + 0x75533400c55bdeL, 0x2aa748d0270a54L, 0xadb6cf005860ddL, + 0x8d314509b84763L, 0x626720deb405efL } + }, + { + { 0xa3709ae6601328L, 0x68e94fd2ac2478L, 0x38793439d5d247L, + 0xfa467af392c198L, 0x49e7b0d15df607L, 0x8c5812261792a8L, + 0x79f76581d3762fL, 0xaa38895244a39dL }, + { 0xef60af9c5cd0bcL, 0x2b0db53a33b3bbL, 0xe3e0b1f251015dL, + 0xc608afce64489eL, 0xe52b05703651aaL, 0x1dda8b91c6f7b9L, + 0x833f022ff41893L, 0x58eb0a0192818cL } + }, + { + { 0x6c1300cfc7b5a7L, 0x6d2ffe1a83ab33L, 0x7b3cd019c02eefL, + 0x6c64559ba60d55L, 0x2e9c16c19e2f73L, 0x11b24aedbe47b1L, + 0xc10a2ee1b8153bL, 0x35c0e081e02e1aL }, + { 0xa9f470c1dd6f16L, 0x4ea93b6f41a290L, 0xac240f825ee03fL, + 0x6cd88adb85aabdL, 0x378a64a1be2f8fL, 0xbf254da417bac1L, + 0x7e4e5a59231142L, 0x057aadc3b8c057L } + }, + { + { 0x607c77a80af479L, 0xd3e01ff5ccdf74L, 0x9680aaf101b4c7L, + 0xd2a7be12fc50a6L, 0x92a788db72d782L, 0x35daf2e4640b52L, + 0xc170d6939e601cL, 0x16e05f57b25c2fL }, + { 0x47a42a66fe37f8L, 0xeb74271beca298L, 0x401e11e179da16L, + 0xfb8da82aa53873L, 0xd657d635bb4783L, 0x6847758fcea0b1L, + 0x2f261fb0993154L, 0x868abe3592853aL } + }, + { + { 0x1a4c54335766abL, 0xa1c84d66f4e4eaL, 0x5d737a660ba199L, + 0x4a7b1e298b15a2L, 0x207877ffd967d3L, 0xcaec82dc262b4dL, + 0x0b278494f2a37dL, 0x34781416ac1711L }, + { 0x28e3df18fc6856L, 0xbec03f816d003fL, 0x2bd705bff39ebdL, + 0x1dcb53b2d776d3L, 0xabafa7d5c0e7ceL, 0x5b9c8c24a53332L, + 0xe9f90d99d90214L, 0x789747ec129690L } + }, + { + { 0x94d3c3954e2dfaL, 0x919f406afb2a8fL, 0x159ef0534e3927L, + 0xcdb4d14a165c37L, 0xa23e5e8288f337L, 0x95867c00f90242L, + 0x2528150e34e781L, 0x104e5016657b95L }, + { 0x695a6c9bcdda24L, 0x609b99523eb5faL, 0xcbce4f516a60f8L, + 0xec63f7df084a29L, 0x3075ada20c811fL, 0x129a1928c716a1L, + 0xd65f4d4cd4cd4aL, 0xe18fa9c62188beL } + }, + { + { 0x1672757bac60e3L, 0x525b3b9577144bL, 0x38fc997887055bL, + 0x7a7712631e4408L, 0x884f173cba2fcfL, 0x783cbdc5962ac0L, + 0x4f3ed0a22287dcL, 0x8a73e3450e20e6L }, + { 0xe7a1cd0d764583L, 0x8997d8d0d58ee6L, 0x0ea08e9aa13ed6L, + 0xed478d0cf363cbL, 0x068523d5b37bf4L, 0x8b5a9e8783f13cL, + 0xde47bbd87528a9L, 0xd6499cccaec313L } + }, +}, +{ + { + { 0x54781bbe09859dL, 0x89b6e067f5e648L, 0xb006dfe7075824L, + 0x17316600717f68L, 0x9c865540b4efe2L, 0xdbdb2575e30d8eL, + 0xa6a5db13b4d50fL, 0x3b5662cfa47bebL }, + { 0x9d4091f89d4a59L, 0x790517b550a7dcL, 0x19eae96c52965eL, + 0x1a7b3c5b5ed7a4L, 0x19e9ac6eb16541L, 0x5f6262fef66852L, + 0x1b83091c4cda27L, 0xa4adf6f3bf742bL } + }, + { + { 0x8cc2365a5100e7L, 0x3026f508592422L, 0xa4de79a3d714d0L, + 0xefa0d3f90fcb30L, 0x126d559474ada0L, 0xd68fa77c94350aL, + 0xfa80e570c7cb45L, 0xe042bb83985fbfL }, + { 0x51c80f1fe13dbaL, 0xeace234cf055d7L, 0x6b8197b73f95f7L, + 0x9ca5a89dcdbe89L, 0x2124d5fdfd9896L, 0x7c695569e7ca37L, + 0x58e806a8babb37L, 0x91b4cc7baf99ceL } + }, + { + { 0x874e253197e968L, 0x36277f53160668L, 0x0b65dda8b95dbeL, + 0x477a792f0872a1L, 0x03a7e3a314268dL, 0xa96c8420c805c7L, + 0xb941968b7bc4a8L, 0x79dce3075db390L }, + { 0x577d4ef6f4cc14L, 0x5b0d205b5d1107L, 0x64ff20f9f93624L, + 0x0b15e315034a2fL, 0x3a0f6bb8b6f35cL, 0x0399a84e0d0ec5L, + 0xd0e58230d5d521L, 0xdeb3da1cb1dd54L } + }, + { + { 0x24684ae182401aL, 0x0b79c1c21a706fL, 0xe1d81f8d8998afL, + 0xadf870f4bb069fL, 0xd57f85cf3dd7aaL, 0x62d8e06e4a40f8L, + 0x0c5228c8b55aa1L, 0xc34244aa9c0a1aL }, + { 0xb5c6cf968f544eL, 0xa560533de23ab7L, 0xaa5512047c690cL, + 0x20eda5b12aaaa6L, 0xea0a49a751a6a0L, 0x6d6cfff2baa272L, + 0x95b756ebf4c28aL, 0xd747074e6178a4L } + }, + { + { 0xa27b453221a94bL, 0xd56ad13e635f20L, 0x03574b08c95117L, + 0xf0ee953ed30b70L, 0xb48d733957796fL, 0xf5d958358c336bL, + 0x6170cd882db529L, 0xcd3ef00ec9d1eaL }, + { 0xd1bea0de4d105fL, 0xd2d670fad6a559L, 0x652d01252f9690L, + 0x5f51fb2c2529b0L, 0x5e88bf0e89df2aL, 0x9a90684cd686e4L, + 0xf519ccd882c7a1L, 0x933a0dfc2f4d37L } + }, + { + { 0x0720a9f3f66938L, 0x99356b6d8149dfL, 0xb89c419a3d7f61L, + 0xe6581344ba6e31L, 0xd130561ab936c8L, 0x0625f6c40dbef1L, + 0x7b2d6a2b6bb847L, 0x3ca8b2984d506bL }, + { 0x6bf729afb011b0L, 0x01c307833448c9L, 0x6ae95080837420L, + 0xf781a8da207fb8L, 0xcc54d5857562a9L, 0xc9b7364858c5abL, + 0xdfb5035359908fL, 0x8bf77fd9631138L } + }, + { + { 0xf523365c13fbb1L, 0x88532ea9993ed5L, 0x5318b025a73492L, + 0x94bff5ce5a8f3cL, 0x73f9e61306c2a0L, 0x00abbacf2668a3L, + 0x23ce332076237dL, 0xc867f1734c0f9bL }, + { 0x1e50995cfd2136L, 0x0026a6eb2b70f8L, 0x66cb1845077a7dL, + 0xc31b2b8a3b498eL, 0xc12035b260ec86L, 0x1cbee81e1b3df0L, + 0xfd7b8048d55a42L, 0x912a41cf47a8c8L } + }, + { + { 0xab9ffe79e157e3L, 0x9cfe46d44dc158L, 0x435551c8a4a3efL, + 0x638acc03b7e3a8L, 0x08a4ebd49954a7L, 0x295390c13194f7L, + 0x3a2b68b253892aL, 0xc1662c225d5b11L }, + { 0xcfba0723a5d2bbL, 0xffaf6d3cc327c9L, 0x6c6314bc67e254L, + 0x66616312f32208L, 0xf780f97bea72e1L, 0x495af40002122fL, + 0x3562f247578a99L, 0x5f479a377ce51eL } + }, +}, +{ + { + { 0x91a58841a82a12L, 0xa75417580f3a62L, 0x399009ff73417aL, + 0x2db1fb90a8c5cdL, 0x82c8912c046d51L, 0x0a3f5778f18274L, + 0x2ad0ede26ccae2L, 0x7d6bd8b8a4e9c2L }, + { 0xaa0d7974b3de44L, 0xf8658b996ac9bbL, 0x31e7be25f6c334L, + 0x23836ce4df12c9L, 0x029027b59eb5c9L, 0x2f225315b8649dL, + 0xa0fdf03d907162L, 0x101d9df9e80226L } + }, + { + { 0xf12037a9a90835L, 0xd2d0882f0222a7L, 0xeaf8d40c3814e2L, + 0xa986dc68b8146bL, 0x147a3318504653L, 0x734e0032feaf67L, + 0x6f27bbf602bec5L, 0xa1e21f16a688f3L }, + { 0x5a8eeab73c4ae5L, 0x4dbaddbe70b412L, 0x871cebacfd2af1L, + 0x18603827d7a286L, 0x024059db5bb401L, 0x2557c093c39b73L, + 0xfc5a7116681697L, 0xf881c0f891b57cL } + }, + { + { 0x3c443f18ea191aL, 0x76faa58d700ad0L, 0x6fe6cfabe7fcbfL, + 0xaefc5288990ef7L, 0x44e30fa80004ccL, 0xc744adc6d8ef85L, + 0xafcd931912df70L, 0xf62a9d1572a6d8L }, + { 0x47158a03219f27L, 0x76fb27ead73136L, 0x41bb2adcc2d614L, + 0x8858cb9de1ec21L, 0xab402c45f15866L, 0x6675d5bbc82bbfL, + 0x4ee9dd6f1b28d3L, 0x875884fe373c17L } + }, + { + { 0x17806dd2a67d36L, 0xaa23a8632c9ec1L, 0xd914126fc1ee55L, + 0xbf8f7bd653701bL, 0x9b0111aea71367L, 0x61fd4aba98e417L, + 0xeb45298561c5a5L, 0x2187b0ae7af394L }, + { 0x71f12db1616ddeL, 0x061760907da7b4L, 0x414d37602ddb04L, + 0x1100be7286fb58L, 0xd7cf88d6f0d95bL, 0x8539d23746d703L, + 0xdccc9d64e23d73L, 0xaeef1d2ec89680L } + }, + { + { 0x82ccf1a336508dL, 0xa128c1f5bad150L, 0x551d8c029a188dL, + 0xef13dd4771404fL, 0xdd67696c37b993L, 0x428c0e20dddad2L, + 0x222278d038c94cL, 0x1a24a51078e3f2L }, + { 0xd297fe6edb0db9L, 0x00988d28251a87L, 0xbb946f8bfaa0d7L, + 0x380f7b9df45ea0L, 0x8526415afccf5eL, 0x909bfbfe9ec7bcL, + 0x2ed7093124755cL, 0x436802889404e2L } + }, + { + { 0x21b9fa036d9ef1L, 0xfd64b7ce433526L, 0xd9d7eb76544849L, + 0x201620cd5b54b3L, 0x25fab3dbb61159L, 0x90d4eb0c53e0d3L, + 0xba098319e74772L, 0x8749658ec1681cL }, + { 0xa354349fec316bL, 0x639a9b1a743ea2L, 0x2e514ca37c50e6L, + 0x9f4a4fddbaf6c5L, 0x0df87ef6f511c9L, 0xadd4cef0c00d95L, + 0x401c0ebaa1433fL, 0x3c3a59ebb38af9L } + }, + { + { 0x8706245f0e7dcaL, 0xad238cd3fb29caL, 0x03304439b7d8f0L, + 0xfdcd6e6154f495L, 0xc67e24a7d4ad09L, 0x1b209e85438390L, + 0xf893b81b0c211eL, 0x1aa86f07e11e36L }, + { 0x2cca3ffedea8b1L, 0x7eedd073b306cdL, 0x78e37bc12ee222L, + 0x257870bbc42a1dL, 0x5fb2bb91fbd397L, 0x470247009d6c60L, + 0x11748a320bdc36L, 0x3ff24dc04280e8L } + }, + { + { 0x0eb1c679839b52L, 0x5bcca27acfbd32L, 0xb506c1674898e3L, + 0x37d662e2489e5eL, 0x8dc0731f694887L, 0x571149ef43f1dcL, + 0x6430a3766d63dcL, 0x0d2640eb50dd70L }, + { 0x2b561493b2675bL, 0x1b4806588c604fL, 0x55c86a8aafbabcL, + 0xa7b9447608aabaL, 0xa42f63504cad8cL, 0x0f72b1dcee7788L, + 0x1d68374755d99aL, 0xd7cdd8f5be2531L } + }, +}, +{ + { + { 0x67873bdbcdfee1L, 0xa5a0c0afcd0a3fL, 0x59389f93cfa3d4L, + 0x14e945ce1c865cL, 0x62d2f8e1d588ccL, 0xfd02f8a8e228b4L, + 0x208f791b42b649L, 0x0e0dff1ab397adL }, + { 0x30ac3d90bc6eb1L, 0xf14f16a5f313bbL, 0x70fa447e2a0ad2L, + 0x6e406855a0db84L, 0xd52282be32e1e7L, 0x315a02a15ca330L, + 0x9a57a70867c2feL, 0x55f07650054923L } + }, + { + { 0x2d729f6c0cf08fL, 0x6b80138ebaf57fL, 0x6285bcc0200c25L, + 0xee845192cd2ac7L, 0x28fce4d922778aL, 0x761325ccd1011cL, + 0xd01f2475100e47L, 0xc7a1665c60d8e1L }, + { 0x950966d7ceb064L, 0x0a88e8578420dbL, 0x44f2cfce096f29L, + 0x9d9325f640f1d2L, 0x6a4a81fd2426f1L, 0x3ed6b189c905acL, + 0xba3c0e2008854dL, 0x1df0bd6a0d321bL } + }, + { + { 0x0117ad63feb1e7L, 0xa058ba2f1ae02fL, 0x5eee5aa31b3f06L, + 0x540d9d4afacd4dL, 0x38992f41571d91L, 0xef2738ebf2c7deL, + 0x28bfcab92a798dL, 0x37c7c5d2286733L }, + { 0xb99936e6470df0L, 0x3d762d58af6a42L, 0xa8c357ac74eec5L, + 0x9917bebf13afbcL, 0x28f0941f2dc073L, 0x306abf36ce7df7L, + 0xa3c5f6fd6973c8L, 0x640209b3677632L } + }, + { + { 0xee872a2e23aef7L, 0xb497b6feb9b08eL, 0xfb94d973f33c63L, + 0x9ea1ff42b32315L, 0x537b49249a4166L, 0x89c7fe6ab4f8beL, + 0xf68007fdad8f0fL, 0xe56ef0b71b8474L }, + { 0x478b2e83f333f9L, 0x144e718b2607f5L, 0x13aa605a4c7ab5L, + 0xfc1fc991d0730dL, 0xe7a04375ab3ea1L, 0xc59986a306d8d3L, + 0x24f6111702a8b1L, 0x7741394e040ad2L } + }, + { + { 0x34c6a2560723a7L, 0x8aabd0df4ea691L, 0x9d676a55d7497fL, + 0x12c09577d91fa4L, 0x581c7a86479284L, 0xa54f3daf4fd449L, + 0x2f89f3c4ef44cfL, 0xfc266b5c9ec97cL }, + { 0xfcd3fbe88b142aL, 0x9f3109f4bd69c1L, 0x08839c0b5f5a6aL, + 0x63ca8502e68303L, 0x2f0628dbba0a74L, 0x743cccf5d56b54L, + 0xbd4b06613e09fdL, 0x7a8415bde2ba3eL } + }, + { + { 0x2234a3bc076ab2L, 0xd6953e54977a98L, 0xc12215831ebe2eL, + 0x632145fbad78e2L, 0xd7ba78aa5c4b08L, 0x6f4ea71998e32aL, + 0x25900d23485a63L, 0x97ac6286a5176fL }, + { 0x5df91181093f7bL, 0x2bf9829c844563L, 0x525d99d6272449L, + 0x4281cb5b5c8a18L, 0x35df2780544a08L, 0xf4c3d2dbaeb8f4L, + 0xc7ff3175230447L, 0x6b4d7645d2fbffL } + }, + { + { 0x4837f802b0c9cbL, 0xb65f8168ce8418L, 0xdf66ea99fc1428L, + 0x9788ee804ea7e8L, 0x9eae9008334e3cL, 0xbc91058d6ba1b6L, + 0x634aba1d7064b6L, 0x12d9bb3397b368L }, + { 0x0645c85c413aa8L, 0xb09dea6ac6b5e3L, 0x29a620d289a50bL, + 0x104db3bbbcceb1L, 0x42e479287b3309L, 0xdfc373eec97f01L, + 0xe953f94b93f84eL, 0x3274b7f052dfbfL } + }, + { + { 0x9d5670a1bd6fa9L, 0xec42fc9db6c4d4L, 0xaecd4ed1b42845L, + 0x4eed90e1b03549L, 0xeb3225cbbab1faL, 0x5345e1d28a2816L, + 0x3741cfa0b77d2aL, 0x712b19f7ea8caaL }, + { 0x42e6844661853eL, 0x4cf4126e4a6e5dL, 0x196a9cfc3649f6L, + 0x06621bcf21b6b1L, 0x887021c32e29eaL, 0x5703aeb8c5680fL, + 0x974be24660f6d7L, 0xaf09badc71864eL } + }, +}, +{ + { + { 0x3483535a81b6d3L, 0x19e7301ca037dcL, 0x748cab763ddfebL, + 0xe5d87f66f01a38L, 0xbba4a5c2795cd6L, 0x411c5d4615c36cL, + 0xff48efc706f412L, 0x205bafc4b519dfL }, + { 0xfcaa5be5227110L, 0x7832f463ad0af0L, 0x34ef2c42642b1bL, + 0x7bbef7b072f822L, 0x93cb0a8923a616L, 0x5df02366d91ba7L, + 0x5da94f142f7d21L, 0x3478298a14e891L } + }, + { + { 0xad79a0fc831d39L, 0x24d19484803c44L, 0x4f8a86486aeeb2L, + 0x0ca284b926f6b9L, 0x501829c1acd7cdL, 0x9f6038b3d12c52L, + 0x77223abf371ef5L, 0x2e0351613bf4deL }, + { 0x7a5a4f2b4468ccL, 0xdcea921470ae46L, 0xf23b7e811be696L, + 0xe59ad0d720d6fbL, 0x9eacac22983469L, 0x4dd4110c4397eeL, + 0x4ef85bdcbe2675L, 0xe4999f7aa7c74bL } + }, + { + { 0x031838c8ea1e98L, 0x539b38304d96a2L, 0x5fbdef0163956eL, + 0x6bd4d35ce3f52aL, 0xe538c2355e897fL, 0x6078d3a472dd3fL, + 0x590241eca9f452L, 0x2bc8495fd7fc07L }, + { 0x23d0c89ead4c8cL, 0x1ea55a9601c66eL, 0x41493c94f5b833L, + 0xc49a300aa5a978L, 0xc98bdc90c69594L, 0x4e44cedccbdc8cL, + 0xb0d4e916adccbfL, 0xd56e36b32c37aeL } + }, + { + { 0x052bd405b93152L, 0x688b1d44f1dbfaL, 0xe77ba1abe5cc5fL, + 0x11f8a38a6ac543L, 0x3355fd6e4bb988L, 0xdf29c5af8dffb4L, + 0x751f58981f20eeL, 0x22a0f74da9b7fbL }, + { 0xec8f2bc6397b49L, 0xff59fc93639201L, 0xb7f130aa048264L, + 0xe156a63afdc4ccL, 0x0fd7c34b13acafL, 0x87698d40cb4999L, + 0x6d6ecae7f26f24L, 0xae51fad0f296e2L } + }, + { + { 0xd0ad5ebdd0f58dL, 0x6ec6a2c5c67880L, 0xe1ce0349af1e0fL, + 0x08014853996d32L, 0x59af51e5e69d20L, 0x0ef743aaa48ecfL, + 0x8d3d2ea7dafcb0L, 0x4ac4fad89189b6L }, + { 0x92d91c2eae97f1L, 0xef5eca262b4662L, 0x440b213b38b10aL, + 0xec90187fc661daL, 0x85f3f25f64cf8dL, 0xcee53ca457ad1bL, + 0x8deed4bf517672L, 0x7706fb34761828L } + }, + { + { 0x1577d9117494feL, 0x52d29be2fd7239L, 0x9a0eef00186d37L, + 0x241d0f527fe108L, 0x42824bae6fb59fL, 0xb8d33df0d48c25L, + 0xfffdb0a47af4b0L, 0x534c601073b0b6L }, + { 0xe6df35951c033bL, 0x3e1002b86c0f94L, 0xa7cb55548fb9b6L, + 0x999818ba7bbff8L, 0xe4ba3d684d8bf2L, 0x53dbb326358f0aL, + 0xeebc1e2f2568e8L, 0xc6917ebb3e0f68L } + }, + { + { 0xbe1bbfc19f8d13L, 0xc3951b62d4795cL, 0x9371c49ed535a9L, + 0x77c389f68cebeaL, 0xfc1a947a141d0eL, 0x4b48d7ade44f8bL, + 0x3db1f058580a26L, 0xeed1466258b5fcL }, + { 0x5daa4a19854b21L, 0x5bfa46f1ab1eadL, 0xc152e3559957ebL, + 0xdc84277ea48adaL, 0x68709cffc169b5L, 0xde50ce3720e617L, + 0xe42f262dd9a832L, 0xddffd4d2d6ce29L } + }, + { + { 0xd5ba5578fa0a56L, 0x0d7d0f1fafaf4cL, 0x7666e4138b63edL, + 0x04e65135d87f02L, 0xdca8866c958f32L, 0xaa8486d3ce2686L, + 0xe3785caf1cbcd3L, 0x8a9b11403c8335L }, + { 0x5c1dca22e0ef60L, 0x775af5b7d3fb20L, 0xe690ffc2b373a8L, + 0x30fe15d28330e6L, 0x8a1022bdd0f393L, 0x6bd7364966a828L, + 0x8d4b154949208aL, 0xfb38c6bb9d9828L } + }, +}, +{ + { + { 0x6d197640340ac2L, 0x969f473ecab5ffL, 0xead46f7c458e42L, + 0x168646a1d00eedL, 0xf70c878e0ce0cfL, 0xa7291d38d8d15aL, + 0x92cf916fdd10ccL, 0x6d3613424f86d5L }, + { 0xba50d172d5c4b4L, 0xe0af5024626f15L, 0x76f3809d76098aL, + 0x433dc27d6caaa8L, 0x72dc67a70d97a7L, 0x935b360f5c7355L, + 0xdbaac93179bb31L, 0x76738487ed1a33L } + }, + { + { 0x8d1ca668f9fa0dL, 0x4ed95d8a02f2bfL, 0xd19fc79f630d7bL, + 0x0448ec4f46fa51L, 0xb371dd8623bf3fL, 0xe94fabcd650e94L, + 0x3af3fcacd90a70L, 0x0f720c403ce3b7L }, + { 0x590814cd636c3bL, 0xcf6928d4469945L, 0x5843aaf484a4c6L, + 0xb5a4c1af9b4722L, 0x25116b36cfb2f9L, 0xf248cf032c2640L, + 0x8cd059e27412a1L, 0x866d536862fc5dL } + }, + { + { 0x156e62f6de4a2eL, 0x0365af7aafcc78L, 0x65c861819e925eL, + 0x4db5c01f8b2191L, 0x1fd26d1ad564faL, 0x16bbc5319c8610L, + 0x0718eef815f262L, 0x8684f4727f83d1L }, + { 0xa30fd28b0f48dbL, 0x6fef5066ab8278L, 0xd164e771a652dfL, + 0x5a486f3c6ebc8cL, 0xb68b498dc3132bL, 0x264b6efd73323fL, + 0xc261eb669b2262L, 0xd17015f2a35748L } + }, + { + { 0x4241f657c4bb1dL, 0x5671702f5187c4L, 0x8a9449f3973753L, + 0x272f772cc0c0cdL, 0x1b7efee58e280cL, 0x7b323494b5ee9cL, + 0xf23af4731142a5L, 0x80c0e1dd62cc9eL }, + { 0xcbc05bf675ffe3L, 0x66215cf258ce3cL, 0xc5d223928c9110L, + 0x30e12a32a69bc2L, 0x5ef5e8076a9f48L, 0x77964ed2329d5fL, + 0xdf81ba58a72cf2L, 0x38ea70d6e1b365L } + }, + { + { 0x1b186802f75c80L, 0x0c153a0698665aL, 0x6f5a7fe522e8ddL, + 0x96738668ddfc27L, 0x7e421d50d3bdceL, 0x2d737cf25001b2L, + 0x568840f0e8490cL, 0xea2610be30c8daL }, + { 0xe7b1bc09561fd4L, 0xeda786c26decb0L, 0x22369906a76160L, + 0x371c71478a3da3L, 0x1db8fce2a2d9bfL, 0x59d7b843292f92L, + 0x8097af95a665f9L, 0x7cb4662542b7a9L } + }, + { + { 0xa5c53aec6b0c2fL, 0xc4b87327312d84L, 0xfc374cbc732736L, + 0xa8d78fe9310cc0L, 0xd980e8665d1752L, 0xa62692d6004727L, + 0x5d079280146220L, 0xbd1fedb860fea5L }, + { 0xcbc4f8ab35d111L, 0x5ba8cdf3e32f77L, 0xd5b71adb614b93L, + 0x7b3a2df2f8808dL, 0x09b89c26ef2721L, 0x55a505447c3030L, + 0x21044312986ae6L, 0x427a0112367d4cL } + }, + { + { 0xe9fe256c1942d8L, 0x9e7377d96e3546L, 0x43e734cb0c1744L, + 0x5f46821211fbcaL, 0x44f83dc32b6203L, 0x84513086ad1d96L, + 0x54dd5192fbb455L, 0xc2a18222f10089L }, + { 0x01055a21855bfaL, 0x9e6d7b477078b4L, 0x3f8df6d30cea0eL, + 0x81c215032973f7L, 0x17dd761c0b3d40L, 0x040424c50d0abeL, + 0x5599413783deabL, 0xde9271e8f3146fL } + }, + { + { 0x5edfd25af4a11dL, 0x3a3c5307846783L, 0xb20086873edd31L, + 0x74e00ecfe0eef8L, 0xba65d2f3dd78c7L, 0xab1364371999f1L, + 0xfa9be5dde9a7e8L, 0xeb146ce87a8609L }, + { 0x76afd6565353e9L, 0xfa7023dd51ba1cL, 0x7a09f2237ede4fL, + 0xca085760ba7a1bL, 0xd973882b99950aL, 0xe894266ea5057aL, + 0xd01c4217f55e49L, 0x69cfb9c5555679L } + }, +}, +{ + { + { 0x67867e7c5d631aL, 0x1de88c55bcf47bL, 0x8366d06afd1352L, + 0xd7dbdef6e20337L, 0xb0f9e2f1253ec7L, 0x1be984510ad240L, + 0x63ec533f4a6118L, 0xd5e4c5b96ce633L }, + { 0x1d0b6c34df4a25L, 0xef9486a5a1b554L, 0x2f0e59e47b6ef3L, + 0x4d8042f2ff84d7L, 0x3e74aa3da359c9L, 0x1baa16fd21c160L, + 0xb4cff210191cbaL, 0x50032d8ebc6472L } + }, + { + { 0xb6833e01fc1b13L, 0x8a8b7ba1a5ad8fL, 0xc0cafa2622b820L, + 0xc6663af738ed20L, 0xd8944868b18f97L, 0xcf0c1f9774fbe4L, + 0xeedd4355be814fL, 0xd81c02db57e543L }, + { 0x5e32afc310bad8L, 0x065bc819b813d1L, 0x8efc5fc3142795L, + 0x5006514732d59cL, 0x91e39df2b5a3ceL, 0x2ad4477faf4204L, + 0x1a96b184d9bd4fL, 0xc3fee95a4d9c07L } + }, + { + { 0xfac7df06b4ba61L, 0xa6ed551061aaefL, 0x35aa2d6133f609L, + 0x420cfba20ed13dL, 0x861c63eea03d0cL, 0x75f0c56f936d6eL, + 0xa25f68f3d9a3d5L, 0xba0b7fecd9f66eL }, + { 0x292e1354680772L, 0x6f6a2dba73f405L, 0xca6add924ea9e4L, + 0x81cfd61268daaaL, 0x7a4cb6ce6f147aL, 0x8ec3454bded8f5L, + 0xc8a893b11d61cbL, 0x2256ffc7656022L } + }, + { + { 0x6b33271575cb78L, 0x560d305adcd23eL, 0xeedbd3ad6d834bL, + 0x614a64a5a31e27L, 0xe40b47647ee0c8L, 0x8ef4ff68bd7c2cL, + 0xa5297fc0b77727L, 0x8759208baf88adL }, + { 0x86cfe64918df68L, 0x9d60a73cdd882eL, 0x546b642b953014L, + 0xbaceae38bbef55L, 0xdf58e43f1c3467L, 0x99a83fee9f9babL, + 0xcd52cbf57a4a8bL, 0xf744e968ae36ecL } + }, + { + { 0xb945869a607124L, 0x810dbe9440e6f6L, 0x9911e60738e381L, + 0x51df68c343b80bL, 0xe424336f7a3f39L, 0x2d32acb989015cL, + 0xa69b14931019e8L, 0x8a31a38ec12f93L }, + { 0x0d0d36997c916aL, 0xdc95f3b8885372L, 0xcf1a2613549040L, + 0x60f6f5eabe95a2L, 0xa909e9fe141325L, 0x7d598f2355c865L, + 0x70c6442931a9c9L, 0x2354a85b423850L } + }, + { + { 0x4cdd22497f9619L, 0x4776fffc22162eL, 0xee5ec330cd31c2L, + 0x7c04c10f209bb8L, 0x35bbfde579e211L, 0x0e3832515cdfc2L, + 0x657e6d3e26ffa7L, 0xc66a7c3c65c604L }, + { 0x322acd7b45e567L, 0x1589cf0296db9bL, 0x1fd0bd3ba1db73L, + 0xe8826109337a40L, 0xf505a50b3035c7L, 0x4d5af066ed08d7L, + 0xb3c376b5eda400L, 0x9c7b7001944748L } + }, + { + { 0xd76832570c3716L, 0xda62af0dd540e0L, 0x76b155d6580feaL, + 0x4f42acc32b5464L, 0x881bb603f5b72bL, 0x09c130ee68b9baL, + 0x37ede3b5c50342L, 0xce61a9cfd15e7dL }, + { 0xfff1d8572605d0L, 0x62ac2d3062abc2L, 0xa85e02efbe43ddL, + 0x859d2baa947020L, 0x2ebc8a9111c20bL, 0x7f590a7a656f66L, + 0x0e1384316b21a6L, 0x29b30c500c7db6L } + }, + { + { 0x61e55e2906b8deL, 0x6a97e96949974dL, 0x24b52b526eef67L, + 0x512f5361aa595aL, 0x81cc7b83c48fcbL, 0xa64af2328115adL, + 0x9edf6f93d44b8eL, 0x68d7f7c1fe22e3L }, + { 0x2b2116a520d151L, 0x66a0b7d6aa3efbL, 0x48ae70a9b0f791L, + 0xcf12174037db88L, 0x36868cd317d9f3L, 0xb57305922fc344L, + 0xbaa852646a5d23L, 0xad6569137fc10dL } + }, +}, +{ + { + { 0xcf8e5f512c78d5L, 0xeb94d98805cdbdL, 0xad1dcdf2ab50b5L, + 0xf33c136f33cd31L, 0x0d6226b10aeff5L, 0xf7ff493f2f8fc5L, + 0x7e520d4df57165L, 0x41fbae505271a7L }, + { 0x72c898776480baL, 0x260835925f4523L, 0xed36b8d49f5f01L, + 0x3bc1dcef3d49ebL, 0x30c1c1a4940322L, 0x78c1cda7e0f731L, + 0x51f2dc86d05a31L, 0x57b0aa807f3522L } + }, + { + { 0x7ab628e71f88bcL, 0xcf585f38018f21L, 0xdbbe3a413d64f6L, + 0x0f86df1ec493a5L, 0x8355e6c7725de9L, 0x3954ffee00fe1eL, + 0xbb8978f9924e32L, 0x1c192987812714L }, + { 0x7c4ce3eaabca8bL, 0xf861eb59bf7019L, 0x31a84fc682e541L, + 0x2307ca9acd1b92L, 0x6f8b6ce4bf2842L, 0xde252accb9f9a9L, + 0x7f0611d93c46d1L, 0x8e2bd80751dc98L } + }, + { + { 0xf2fd8fbe27d54bL, 0x2a1e37ec248071L, 0x2fcc888ab8f49aL, + 0x42c62a3c18a9e5L, 0xe30290870b2446L, 0x90277fac5ac55dL, + 0x8d97d56d6dde41L, 0xf4cf8a95db04feL }, + { 0x3e280f5d30d077L, 0x2c903073cb3293L, 0xe0be2ac24eb0ddL, + 0xa2d1a498bcb4f0L, 0x16db466cd0cd45L, 0x3b28aa79a80232L, + 0xdd7e52f17b008eL, 0x20685f2868e4daL } + }, + { + { 0x0a68c147c7a486L, 0xd8ef234c429633L, 0x470667bffe7506L, + 0x55a13c88828d51L, 0x5f327412e44befL, 0x537d92a5929f92L, + 0x0a01d5b31c5cd5L, 0xb77aa7867eb3d7L }, + { 0x36ec45f8b82e4dL, 0x6821da0b37b199L, 0x8af37aad7fa94eL, + 0xf0206421085010L, 0x9b886787e56851L, 0x35f394452948ceL, + 0x125c2baafc1361L, 0x8a57d0e453e332L } + }, + { + { 0xefe99488043664L, 0xb8b8509db1aa55L, 0x1a2e5a9332523fL, + 0x5e255dd1045c0fL, 0xe68dd8a7ae7180L, 0x55f1cf345bf532L, + 0xe00722ee63a716L, 0xd1c21386116bacL }, + { 0x626221f1c6d1f4L, 0x240b8303773278L, 0xe393a0d88def16L, + 0x229266eca0495cL, 0x7b5c6c9d3e4608L, 0xdc559cb7927190L, + 0x06afe42c7b3c57L, 0x8a2ad0bb439c9bL } + }, + { + { 0xd7360fbffc3e2fL, 0xf721317fbd2e95L, 0x8cacbab5748e69L, + 0x7c89f279054bb9L, 0xcbe50faaa86881L, 0x7aa05d375206e4L, + 0x1ea01bcc752c66L, 0x5968cde1f2c2bcL }, + { 0x487c55f09a853eL, 0x82cbef1e09204bL, 0xad5c492abd8670L, + 0x7175963f12dcb3L, 0x7a85762bf6aa06L, 0x02e5697f8d5237L, + 0xccf7d1937c6157L, 0x3b14ca6c2fd59cL } + }, + { + { 0x5e610d81b9f77fL, 0x85876d0051b02fL, 0x5d81c63b8020ddL, + 0xd0b4116d6ce614L, 0x91810e5aa8bf0cL, 0xf27f91fcbf8c66L, + 0x2e5dc5f38480aeL, 0x0a13ffebec7633L }, + { 0x61ff6492bf6af8L, 0xe6aef2d641f827L, 0xad5708a5de5f04L, + 0xe5c3a80cdfee20L, 0x88466e268fcfa2L, 0x8e5bb3ad6e1d7bL, + 0xa514f06ed236b8L, 0x51c9c7ba5f5274L } + }, + { + { 0xa19d228f9bc3d8L, 0xf89c3f03381069L, 0xfee890e5c3f379L, + 0x3d3ef3d32fb857L, 0x39988495b418ddL, 0x6786f73c46e89aL, + 0x79691a59e0f12fL, 0x76916bf3bc022bL }, + { 0xea073b62cd8a0aL, 0x1fbedd4102fdbcL, 0x1888b14cb9d015L, + 0x98f2cfd76655f7L, 0xb9b591059f0494L, 0xa3dbbe1e6986a3L, + 0xef016a5eaf2b04L, 0xf671ba7cd2d876L } + }, +}, +{ + { + { 0x1dae3bf1ae05e9L, 0x6a029961f21fefL, 0x95df2b97aec3c6L, + 0x9abbc5ad83189bL, 0xaf994af2d13140L, 0xc3f884686aa406L, + 0xcd77e5075284c5L, 0x1c1e13d2a9a4d7L }, + { 0x7f8815d744b89dL, 0xb1891332ba673eL, 0x55ea93cd594570L, + 0x19c8a18d61b041L, 0x938ebaa8d2c580L, 0x9b4344d05ba078L, + 0x622da438eaf9b7L, 0x809b8079fea368L } + }, + { + { 0x3780e51c33b7a2L, 0xd7a205c387b1c8L, 0x79515f84be60e4L, + 0xde02a8b1e18277L, 0x4645c96f0d9150L, 0x45f8acbe0b3fd1L, + 0x5d532ba9b53ac3L, 0x7984dcdb0557c9L }, + { 0x5ae5ca68a92f01L, 0xd2fbb3c9d569caL, 0x668cc570c297c1L, + 0xa4829436295e89L, 0xf646bc1a33ad40L, 0x066aaa4c3f425dL, + 0x23434cdd005de2L, 0x5aca9e9db35af4L } + }, + { + { 0x2bca35c6877c56L, 0xab864b4f0ddd7dL, 0x5f6aa74404f46cL, + 0x72be164539c279L, 0x1b1d73ee0283cfL, 0xe550f46ad583d9L, + 0x4ac6518e739ad1L, 0x6b6def78d42100L }, + { 0x4d36b8cfa8468dL, 0x2cb37735a3d7b8L, 0x577f86f5016281L, + 0xdb6fe5f9124733L, 0xacb6d2ae29e039L, 0x2ab8330580b8a1L, + 0x130a4ac643b2d0L, 0xa7996e35e6884eL } + }, + { + { 0x6fb627760a0aa8L, 0xe046843cbe04f0L, 0xc01d120e6ad443L, + 0xa42a05cabef2fcL, 0x6b793f112ff09cL, 0x5734ea8a3e5854L, + 0xe482b36775f0adL, 0x2f4f60df864a34L }, + { 0xf521c5884f2449L, 0x58734a99186a71L, 0x157f5d5ac5eaccL, + 0x858d9a4248ee61L, 0x0727e6d48149c3L, 0xd5c3eaaac9ec50L, + 0xa63a64a20ee9b5L, 0x3f0dfc487be9deL } + }, + { + { 0x836349db13e3f4L, 0xebdd0263e9316dL, 0x3fd61e8324fd6cL, + 0x85dddfa0964f41L, 0x06e72de52add1bL, 0xb752cff8c4a9e2L, + 0x53b0894fdf09f7L, 0xd5220ab0bc24fdL }, + { 0x8442b35fb1981aL, 0xa733a373edd701L, 0x42b60c3d0ef089L, + 0xa1b16ec46e7bcaL, 0xc0df179a09aaf4L, 0xcd4f187638f3a1L, + 0x9af64f79eab1c2L, 0x86fed79d1d78e3L } + }, + { + { 0x42c8d86fe29980L, 0x6657b816575660L, 0x82d52c680f92caL, + 0x8587af102d42beL, 0xb5151316e8bdf0L, 0x706e2d9c333495L, + 0xd53601a9673064L, 0x27b1fbb8219099L }, + { 0x3f0929d705f7c8L, 0xff40b10f3d6e6fL, 0x673c703026af5cL, + 0x2c1dce4e25a422L, 0x5348bd73dad8b6L, 0xc39b6b6be2c329L, + 0x47854ffb921084L, 0xb347b8bb391f20L } + }, + { + { 0x79fc841eb9b774L, 0xf32da25b4b6c1dL, 0xcbba76bfe492cbL, + 0x76c51fcd623903L, 0x114cf6fcf0705aL, 0x6b720497815dafL, + 0x630b362473382eL, 0xbf40c3a9704db5L }, + { 0xa8a9ddcc5456ebL, 0x2b4472a72f2dc1L, 0x9874444d6d6ef3L, + 0x27e8d85a0ba5edL, 0x5d225b4194849fL, 0xe852cd6ebaa40dL, + 0xb669c248d4bf3fL, 0xa8601eb2343991L } + }, + { + { 0x8a0485459502d3L, 0xcab27eee269a7bL, 0x41793074875adaL, + 0x179e685e2405f9L, 0x0d7b6987b28963L, 0x80c9db8422a43eL, + 0xf5ff318a0f43eeL, 0x7a928054ba7aa7L }, + { 0xa5c79fe0c0834eL, 0x837ca0d1f849ecL, 0xfe0d7fa628ab7bL, + 0x94bcb956edd19aL, 0xa18bc932226fbfL, 0x2795379aad54a3L, + 0xceeacf8371129eL, 0x65ca57fa588be5L } + }, +}, +{ + { + { 0x7a578b52caa330L, 0x7c21944d8ca34aL, 0x6c0fbbb6447282L, + 0xa8a9957f90b2e5L, 0xbbe10666586b71L, 0x716a90249138a2L, + 0x2fa6034e7ed66dL, 0x56f77ed2b9916aL }, + { 0x69f1e26bddefb3L, 0xa4978098c08420L, 0xc3377eb09bc184L, + 0x796ce0cbe6dadeL, 0x3be0625d103bbbL, 0x01be27c992685cL, + 0xc0e25597755f9fL, 0x165c40d1c0dbfaL } + }, + { + { 0xc63a397659c761L, 0x10a0e5b630fbadL, 0xf21e8a6655ac56L, + 0xe8580fac1181e2L, 0xbfc2d9c0a84b5cL, 0x2cdbaff7afd5d1L, + 0x95f1182f61e85aL, 0x1173e96719eaf4L }, + { 0xc06d55ec6de8b9L, 0x1b4c8ebafcbcaaL, 0x52af5cbbc2bbcdL, + 0x564fab877bcd10L, 0xfd53a18ae85a6eL, 0x225785994c712fL, + 0x29b11d71352121L, 0xab1cb76c40491aL } + }, + { + { 0xb4e8ca8ce32eb4L, 0x7e484acb250b49L, 0x062c6f7a3e31a2L, + 0x497fd83625d1fcL, 0x98f821c362dda7L, 0xcae1f8f6be3111L, + 0x9077e955d4fa42L, 0xa589971a65855aL }, + { 0xda6321d28832a9L, 0xf9ef5dc3936e9eL, 0xa37f117c9797efL, + 0x0eb3c80db581beL, 0x207c5c4baa0002L, 0xc0401b5f38faa0L, + 0xceee523d0f1e6eL, 0x8d27a5fd1f0045L } + }, + { + { 0x9411063cf0af29L, 0x304385789a6693L, 0x9a9fb8f640145eL, + 0x7d82fe954832ebL, 0xf2789e1898c520L, 0x448b402f948dc0L, + 0xeca8fdf68996ddL, 0x22227e9a149b2fL }, + { 0x63509ff8e62d6aL, 0xe98d81c8c9c57fL, 0xd3874071fe3bedL, + 0xf1db013539538fL, 0xb04092e48418ceL, 0xbbf8e76d6d9d4dL, + 0x2ea9cda2cec5aeL, 0x8414b3e5078fa9L } + }, + { + { 0x5ad1cdbd68a073L, 0xd4cedafc18b591L, 0x78267078e4c1c9L, + 0x9b8d9209ca302aL, 0x3101bd2326115bL, 0x6f154b54c2717aL, + 0x618c31b263e84bL, 0x12c4138bbd6942L }, + { 0xf9ead2580da426L, 0xe748e9947d9680L, 0x9b396a38a4210eL, + 0xfaf03ddf4b8f72L, 0xbd94a5266159e7L, 0x5e730491d4c7cbL, + 0x31d1f9a7910f38L, 0x4fd10ca08d6dd1L } + }, + { + { 0x4f510ac9f2331eL, 0xee872dc7e3dcc2L, 0x4a11a32a0a0c73L, + 0x27e5803aa5a630L, 0xe5ae5037af4a8aL, 0x2dcdeba9fffeb0L, + 0x8c27748719d91fL, 0xd3b5b62b9cc61cL }, + { 0x998ac90cca7939L, 0xc22b59864514e5L, 0x950aaa1b35738aL, + 0x4b208bbdab0264L, 0x6677931a557d2eL, 0x2c696d8f7c17d3L, + 0x1672d4a3e15c51L, 0x95fab663db0e82L } + }, + { + { 0x3d427346ff205eL, 0x7f187d90ea9fbeL, 0xbd9367f466b2afL, + 0x188e53203daf2fL, 0xefe132927b54d8L, 0x14faf85ef70435L, + 0xa5061281ec95c4L, 0xad01705c22cba7L }, + { 0x7d2dfa66197333L, 0xedd7f078b4f6edL, 0xe0cb68575df105L, + 0x47c9ddb80f76bcL, 0x49ab5319073c54L, 0x845255ae607f44L, + 0x0b4ed9fcc74b7cL, 0xcfb52d50f5c3a6L } + }, + { + { 0x545c7c6c278776L, 0x92a39ae98c30f0L, 0x8aa8c01d2f4680L, + 0xa5409ed6b7f840L, 0x0c450acdcb24e7L, 0x5da6fb2c5770d9L, + 0x5b8e8be8658333L, 0xb26bf4a67ea4adL }, + { 0x2e30c81c7d91faL, 0x6e50a490eeb69fL, 0x9458c2bee4bc26L, + 0x419acf233be250L, 0x79d6f8187881abL, 0x694565d403b1beL, + 0x34b3990234fe1dL, 0x60997d72132b38L } + }, +}, +{ + { + { 0x00a974126975dcL, 0x42161c46cf94e7L, 0xcc9fe4bc64ed99L, + 0x020019a4680570L, 0x885595a698da0dL, 0x008444b77dd962L, + 0xbf3c22da4fea0eL, 0xc4630482c81245L }, + { 0xcb248c5793ab18L, 0x4dc7a20eb4320bL, 0x9a0906f1572b7dL, + 0xd5b3019f9ac20fL, 0x79b1bf534520a3L, 0x788dfe869b5322L, + 0x9a05298455b7e2L, 0x2f4aecb016bca9L } + }, + { + { 0x414d3798745618L, 0x64ba22eb7c983cL, 0x9a5d19f9f9d532L, + 0x81a00d844a80c8L, 0xb9e24f5cae98d6L, 0x6c3769caca965aL, + 0x50d6081f6e4e6dL, 0x0d9698054422a6L }, + { 0xbd7e7925cdd790L, 0xcff65da6a35219L, 0x40dc3638b60ebeL, + 0x84bee7492a50dcL, 0x57d4be415ad65eL, 0xc54256b1a6d1d3L, + 0x141c64945717ccL, 0x05eb609cd1c736L } + }, + { + { 0xfd52eab1e3c7ecL, 0xa4a5eca9f24895L, 0xaaa2a8d79fdb83L, + 0xd105e6072bdfdaL, 0x59e6ae2681d97eL, 0xfedf8e08e8077fL, + 0xb06d0ad629e462L, 0x8c7c2d096fa863L }, + { 0x5eecc4cee8fc91L, 0x5e83ab29e61174L, 0x1fd8925b28c02dL, + 0x93be5382072864L, 0xda0c88624c984eL, 0xdcf9f0ca008286L, + 0x1ecb5a6a58ba75L, 0x1d9b890c2e3c83L } + }, + { + { 0x19e866eeeee062L, 0x31c1c7f4f7b387L, 0x9be60181c06652L, + 0xc00a93a2b68bbbL, 0x54c65d69d52b2bL, 0x4591416e8b744aL, + 0x641bcca9a64ab6L, 0xf22bcb1ab08098L }, + { 0x3c0db8ff1f726cL, 0x4f5739e9d2e6a6L, 0x5cb669b45c9530L, + 0x861b04e7b472d0L, 0x3e30515894da77L, 0x3344685c9ac39bL, + 0x9e1730573bdd29L, 0x9cac12c808dc85L } + }, + { + { 0xf152b865e27087L, 0x267bd8590a580eL, 0xba79cec8baafc1L, + 0x6140ab19442686L, 0xa67090c5b31693L, 0x50a103a28b4117L, + 0x7722e610ddc08fL, 0x5d19d43e6569b2L }, + { 0x70e0c525962bf6L, 0x808e316fb5fb02L, 0x3fb80da5b667beL, + 0x8aa366efcfacecL, 0xcb0b3e7134280eL, 0x0bf1de4cd7d944L, + 0x0cd23bed092df5L, 0xc9a6a79a153a0cL } + }, + { + { 0x1c69ad02d5a4b7L, 0x4bb28d0d9e6f4aL, 0x815308ca984fc6L, + 0x40929c79037ca5L, 0x0ea2b491bd0357L, 0xec17e5b42aad4eL, + 0x1f32ade18e7235L, 0xbc60b05a96a9d3L }, + { 0x3b0229ae20f707L, 0xd63505056bdfadL, 0xac2d922d8b2e1eL, + 0x92b2998235c748L, 0x6002c3ad766f97L, 0x99198001a2a862L, + 0x2af7567b58b684L, 0xd8fe707aaafce5L } + }, + { + { 0x54487ab5df7a4bL, 0x51cccdec57ccc2L, 0x23943277510b53L, + 0x3a09f02f555de3L, 0xa696aec1be484dL, 0x56f459f37817a2L, + 0x8d8f61c623dcb4L, 0xc52223c5335656L }, + { 0xf634111b49914aL, 0xbf8e1ab8e4f9bbL, 0x2f59578f4dba02L, + 0x2a94199e004319L, 0x87931f0654d005L, 0x7df57d96fa0814L, + 0xc8da316a154031L, 0x2a44ac041f658bL } + }, + { + { 0xfb5f4f89e34ac6L, 0x0a1b10b97790f2L, 0x58fe4e74b8a06cL, + 0x10c1710955f27cL, 0x77b798ad5ebe19L, 0xaf1c35b1f1c2dcL, + 0xc25b8e6a1f8d69L, 0x49cf751f76bf23L }, + { 0x15cb2db436f7b7L, 0x186d7c27e74d1aL, 0x60731dec00a415L, + 0xea1e15615f0772L, 0xf02d591714463fL, 0x26a0c6451adeb1L, + 0x20174cdcc5229eL, 0xb817e50efd512aL } + }, +}, +}; + +static const ge448_precomp base_i[16] = { + { + { 0x26a82bc70cc05eL, 0x80e18b00938e26L, 0xf72ab66511433bL, + 0xa3d3a46412ae1aL, 0x0f1767ea6de324L, 0x36da9e14657047L, + 0xed221d15a622bfL, 0x4f1970c66bed0dL }, + { 0x08795bf230fa14L, 0x132c4ed7c8ad98L, 0x1ce67c39c4fdbdL, + 0x05a0c2d73ad3ffL, 0xa3984087789c1eL, 0xc7624bea73736cL, + 0x248876203756c9L, 0x693f46716eb6bcL } + }, + { + { 0x28173286ff2f8fL, 0xb769465da85757L, 0xf7f6271fd6e862L, + 0x4a3fcfe8daa9cbL, 0xda82c7e2ba077aL, 0x943332241b8b8cL, + 0x6455bd64316cb6L, 0x0865886b9108afL }, + { 0x22ac13588ed6fcL, 0x9a68fed02dafb8L, 0x1bdb6767f0bffaL, + 0xec4e1d58bb3a33L, 0x56c3b9fce43c82L, 0xa6449a4a8d9523L, + 0xf706cbda7ad43aL, 0xe005a8dbd5125cL } + }, + { + { 0xa99d1092030034L, 0x2d8cefc6f950d0L, 0x7a920c3c96f07bL, + 0x958812808bc0d5L, 0x62ada756d761e8L, 0x0def80cbcf7285L, + 0x0e2ba7601eedb5L, 0x7a9f9335a48dcbL }, + { 0xb4731472f435ebL, 0x5512881f225443L, 0xee59d2b33c5840L, + 0xb698017127d7a4L, 0xb18fced86551f7L, 0x0ade260ca1823aL, + 0xd3b9109ce4fd58L, 0xadfd751a2517edL } + }, + { + { 0xdf9567ceb5eaf7L, 0x110a6b478ac7d7L, 0x2d335014706e0bL, + 0x0df9c7b0b5a209L, 0xba4223d568e684L, 0xd78af2d8c3719bL, + 0x77467b9a5291b6L, 0x079748e5c89befL }, + { 0xe20d3fadac377fL, 0x34e866972b5c09L, 0xd8687a3c40bbb7L, + 0x7b3946fd2f84c9L, 0xd00e40ca78f50eL, 0xb87594417e7179L, + 0x9c7373bcb23583L, 0x7ddeda3c90fd69L } + }, + { + { 0x3d0def76ab686bL, 0x1a467ec49f7c79L, 0x3e53f4fc8989edL, + 0x101e344430a0d9L, 0xa3ae7318ad44eeL, 0xaefa6cdae1d134L, + 0xaa8cd7d824ad4dL, 0xef1650ced584fcL }, + { 0xa74df674f4754fL, 0xf52cea8ef3fb8bL, 0x47c32d42971140L, + 0x391c15da256fbbL, 0xc165faba605671L, 0xf2518c687993b9L, + 0x2daf7acbd5a84dL, 0x1560b6298f12aeL } + }, + { + { 0xef4da0254dc10aL, 0x63118655940db8L, 0xe20b14982f2948L, + 0x67b93775581dbaL, 0x422ee7104f5029L, 0x5d440db5122d34L, + 0xb1e56d71a4c640L, 0xbf12abbc2408eeL }, + { 0x0cc9f86016af01L, 0x88366abf3d8cabL, 0x85dda13a2efe12L, + 0x390df605d00674L, 0xf18f5806d187f7L, 0x28c900ff0c5d20L, + 0xad308123e01733L, 0x42d35b554bf2fdL } + }, + { + { 0x009135f2ffb1f1L, 0x099fc7e8f9c605L, 0xcc67da626bfa5aL, + 0xc186d12344552bL, 0xb5232501b339e1L, 0x70a544fc9708c5L, + 0x06baaec1e928e7L, 0x0baedd2ef0f50fL }, + { 0x535d6d8bf479e5L, 0x156e536e4ec3e9L, 0x3165741ddb9be2L, + 0x988af7159fd736L, 0x13d8a782e33dddL, 0x54604214e69002L, + 0x34d56e0804a268L, 0xc59b84f0e52a4cL } + }, + { + { 0x525d45f24729d9L, 0x5768aba8712327L, 0xa25e43b43035dbL, + 0x15a1ee8927ef21L, 0xa785d216056112L, 0x45e2fbfd508af9L, + 0xb6f721a37ba969L, 0x30d6d8c216d8d3L }, + { 0x3065e0852074c3L, 0xfa40b4a2a0684eL, 0x851325a763f955L, + 0xd4ef19c9f25900L, 0x799c869f665756L, 0x7b052223312990L, + 0xc986c2b28db802L, 0xf48fb8f28ade0aL } + }, + { + { 0x1e461731649b68L, 0xa96e5d65beb9dcL, 0x765ddff481935dL, + 0x6cf132c9f3bf2aL, 0x9f6c5c97c35658L, 0x99cd1394696e60L, + 0x99fa9249c0d5e4L, 0x1acd0638845a95L }, + { 0x0b065413636087L, 0xea20e78ea17b7fL, 0x20afc5f6161967L, + 0xfd6c8a2dc81028L, 0x4ef1357e32c8fdL, 0x8aa400400e4a88L, + 0xd6fcaef48cb82fL, 0x7ba7c6db3cd4faL } + }, + { + { 0xf843473d19c7abL, 0x968e76dc655c4dL, 0x52c87d9c4b9c2fL, + 0x65f641ae4aa082L, 0x491a39733c3603L, 0xa606ffe5810098L, + 0x09920e68bf8ad4L, 0x691a0c86db7882L }, + { 0x5205883a4d3ef5L, 0xee839b7acf2efeL, 0x4b78e2ac00ca66L, + 0xbe3f071f9fcb91L, 0x61e66c9bf6943aL, 0xe9b4e57061b79dL, + 0x8d1b01b56c06bdL, 0x0dfa315df76ae5L } + }, + { + { 0x803df65f1fd093L, 0x1cd6523489b77eL, 0x2cd2e15c20e295L, + 0xcd490be9b912d1L, 0xdd9a2ff2e886d2L, 0xa3c836dfe9d72aL, + 0xfcad5f2298e0c1L, 0xed126e24bcf067L }, + { 0x1e339533dc81bcL, 0xbea4d76ece6a08L, 0x1d15de3991b252L, + 0x74cc5cfe6daf97L, 0x5ad343f0826493L, 0x2d38a471064049L, + 0xf7f47b9ffcfa4dL, 0xef14490418066cL } + }, + { + { 0x4e7f86b9bb55abL, 0x310d7853f496a3L, 0xbd682fc0dec42cL, + 0xbde047a411d32aL, 0xea639b4c5a5ea2L, 0x5052078ba08fa1L, + 0xc968b2307729f2L, 0x567b5a623d3e28L }, + { 0x171e825977fbf7L, 0x0319c70be990aaL, 0x8f65023e12cd69L, + 0x1fb9b19f5015e6L, 0x0083f603568a7cL, 0xba3d30b1f3c5acL, + 0xe7b509d3d7a988L, 0x2318b99cd0f6b6L } + }, + { + { 0x54d3b8793ab2cfL, 0x366abead2d8306L, 0x66e8eb6d7a4977L, + 0xa61888cae0072eL, 0x9eeeef5dbc3315L, 0x93f09db163e7f5L, + 0xee9095959ade9aL, 0xaf7f578ce59be0L }, + { 0x24bfd8d5ece59eL, 0x8aa698b3689523L, 0xa9a65de2de92cfL, + 0xec11dbca6ad300L, 0x217f3fa09f88caL, 0xf6c33e3b4d6af7L, + 0xcd3bfa21d86d2dL, 0x1497f835f13f25L } + }, + { + { 0xa579568cd03d1dL, 0xd717cdae158af6L, 0x59eda97389a19fL, + 0xb32c370099e99cL, 0xa2dba91dabb591L, 0x6d697d577c2c97L, + 0x5423fc2d43fa6dL, 0x56ea8a50b382bfL }, + { 0x4a987bad80c11aL, 0xe4cde217d590a5L, 0x3dd8860f97e559L, + 0xff45e2543b593cL, 0x00eb4535343cb5L, 0x06b9b997bbfbddL, + 0x4da36b716aea24L, 0x247651757a624eL } + }, + { + { 0x32207d03474e0dL, 0x3ffbf04b41cc73L, 0x5c4dc45319eb39L, + 0xfee29be758b463L, 0xcc8a381c30c7a7L, 0x147f4e49fe0e53L, + 0x05b2e26e35a2deL, 0x4362f0292f3666L }, + { 0x0476d0c8474b85L, 0x9d8c65fccaf108L, 0xf58d4041d54b6aL, + 0x3ee6862f38e4b0L, 0x7c7c9d53b44f54L, 0x36a3fd80fb0db5L, + 0xfcd94ba18a8ac8L, 0xc1b1d568f35c05L } + }, + { + { 0x16539fc1bdd30dL, 0x1356e538df4afbL, 0xc0545d85a1aedbL, + 0xeb2037a489396bL, 0x897fcbd5660894L, 0x02a58a9b7d104aL, + 0x57fa24cc96b980L, 0xf6448e35bd8946L }, + { 0xee727418805c83L, 0x10fa274992cfc6L, 0x95141939e66b21L, + 0xe0ffa44bd08009L, 0x174332220da22bL, 0x4891ff359e6831L, + 0x407ed73a7d687bL, 0x2fb4e0751d99cfL } + }, +}; +#else + +/* Reduce scalar mod the order of the curve. + * Scalar Will be 114 bytes. + * + * b [in] Scalar to reduce. + */ +void sc448_reduce(uint8_t* b) +{ + uint32_t d[16]; + uint64_t t[33]; + uint64_t c; + uint32_t o; + + /* Load from bytes */ + t[ 0] = (((int32_t)((b[ 0] ) >> 0)) << 0) + | (((int32_t)((b[ 1] ) >> 0)) << 8) + | (((int32_t)((b[ 2] ) >> 0)) << 16) + | ((((int32_t)((b[ 3] & 0xf )) >> 0)) << 24); + t[ 1] = (((int32_t)((b[ 3] ) >> 4)) << 0) + | (((int32_t)((b[ 4] ) >> 0)) << 4) + | (((int32_t)((b[ 5] ) >> 0)) << 12) + | (((int32_t)((b[ 6] ) >> 0)) << 20); + t[ 2] = (((int32_t)((b[ 7] ) >> 0)) << 0) + | (((int32_t)((b[ 8] ) >> 0)) << 8) + | (((int32_t)((b[ 9] ) >> 0)) << 16) + | ((((int32_t)((b[10] & 0xf )) >> 0)) << 24); + t[ 3] = (((int32_t)((b[10] ) >> 4)) << 0) + | (((int32_t)((b[11] ) >> 0)) << 4) + | (((int32_t)((b[12] ) >> 0)) << 12) + | (((int32_t)((b[13] ) >> 0)) << 20); + t[ 4] = (((int32_t)((b[14] ) >> 0)) << 0) + | (((int32_t)((b[15] ) >> 0)) << 8) + | (((int32_t)((b[16] ) >> 0)) << 16) + | ((((int32_t)((b[17] & 0xf )) >> 0)) << 24); + t[ 5] = (((int32_t)((b[17] ) >> 4)) << 0) + | (((int32_t)((b[18] ) >> 0)) << 4) + | (((int32_t)((b[19] ) >> 0)) << 12) + | (((int32_t)((b[20] ) >> 0)) << 20); + t[ 6] = (((int32_t)((b[21] ) >> 0)) << 0) + | (((int32_t)((b[22] ) >> 0)) << 8) + | (((int32_t)((b[23] ) >> 0)) << 16) + | ((((int32_t)((b[24] & 0xf )) >> 0)) << 24); + t[ 7] = (((int32_t)((b[24] ) >> 4)) << 0) + | (((int32_t)((b[25] ) >> 0)) << 4) + | (((int32_t)((b[26] ) >> 0)) << 12) + | (((int32_t)((b[27] ) >> 0)) << 20); + t[ 8] = (((int32_t)((b[28] ) >> 0)) << 0) + | (((int32_t)((b[29] ) >> 0)) << 8) + | (((int32_t)((b[30] ) >> 0)) << 16) + | ((((int32_t)((b[31] & 0xf )) >> 0)) << 24); + t[ 9] = (((int32_t)((b[31] ) >> 4)) << 0) + | (((int32_t)((b[32] ) >> 0)) << 4) + | (((int32_t)((b[33] ) >> 0)) << 12) + | (((int32_t)((b[34] ) >> 0)) << 20); + t[10] = (((int32_t)((b[35] ) >> 0)) << 0) + | (((int32_t)((b[36] ) >> 0)) << 8) + | (((int32_t)((b[37] ) >> 0)) << 16) + | ((((int32_t)((b[38] & 0xf )) >> 0)) << 24); + t[11] = (((int32_t)((b[38] ) >> 4)) << 0) + | (((int32_t)((b[39] ) >> 0)) << 4) + | (((int32_t)((b[40] ) >> 0)) << 12) + | (((int32_t)((b[41] ) >> 0)) << 20); + t[12] = (((int32_t)((b[42] ) >> 0)) << 0) + | (((int32_t)((b[43] ) >> 0)) << 8) + | (((int32_t)((b[44] ) >> 0)) << 16) + | ((((int32_t)((b[45] & 0xf )) >> 0)) << 24); + t[13] = (((int32_t)((b[45] ) >> 4)) << 0) + | (((int32_t)((b[46] ) >> 0)) << 4) + | (((int32_t)((b[47] ) >> 0)) << 12) + | (((int32_t)((b[48] ) >> 0)) << 20); + t[14] = (((int32_t)((b[49] ) >> 0)) << 0) + | (((int32_t)((b[50] ) >> 0)) << 8) + | (((int32_t)((b[51] ) >> 0)) << 16) + | ((((int32_t)((b[52] & 0xf )) >> 0)) << 24); + t[15] = (((int32_t)((b[52] ) >> 4)) << 0) + | (((int32_t)((b[53] ) >> 0)) << 4) + | (((int32_t)((b[54] ) >> 0)) << 12) + | (((int32_t)((b[55] ) >> 0)) << 20); + t[16] = (((int32_t)((b[56] ) >> 0)) << 0) + | (((int32_t)((b[57] ) >> 0)) << 8) + | (((int32_t)((b[58] ) >> 0)) << 16) + | ((((int32_t)((b[59] & 0xf )) >> 0)) << 24); + t[17] = (((int32_t)((b[59] ) >> 4)) << 0) + | (((int32_t)((b[60] ) >> 0)) << 4) + | (((int32_t)((b[61] ) >> 0)) << 12) + | (((int32_t)((b[62] ) >> 0)) << 20); + t[18] = (((int32_t)((b[63] ) >> 0)) << 0) + | (((int32_t)((b[64] ) >> 0)) << 8) + | (((int32_t)((b[65] ) >> 0)) << 16) + | ((((int32_t)((b[66] & 0xf )) >> 0)) << 24); + t[19] = (((int32_t)((b[66] ) >> 4)) << 0) + | (((int32_t)((b[67] ) >> 0)) << 4) + | (((int32_t)((b[68] ) >> 0)) << 12) + | (((int32_t)((b[69] ) >> 0)) << 20); + t[20] = (((int32_t)((b[70] ) >> 0)) << 0) + | (((int32_t)((b[71] ) >> 0)) << 8) + | (((int32_t)((b[72] ) >> 0)) << 16) + | ((((int32_t)((b[73] & 0xf )) >> 0)) << 24); + t[21] = (((int32_t)((b[73] ) >> 4)) << 0) + | (((int32_t)((b[74] ) >> 0)) << 4) + | (((int32_t)((b[75] ) >> 0)) << 12) + | (((int32_t)((b[76] ) >> 0)) << 20); + t[22] = (((int32_t)((b[77] ) >> 0)) << 0) + | (((int32_t)((b[78] ) >> 0)) << 8) + | (((int32_t)((b[79] ) >> 0)) << 16) + | ((((int32_t)((b[80] & 0xf )) >> 0)) << 24); + t[23] = (((int32_t)((b[80] ) >> 4)) << 0) + | (((int32_t)((b[81] ) >> 0)) << 4) + | (((int32_t)((b[82] ) >> 0)) << 12) + | (((int32_t)((b[83] ) >> 0)) << 20); + t[24] = (((int32_t)((b[84] ) >> 0)) << 0) + | (((int32_t)((b[85] ) >> 0)) << 8) + | (((int32_t)((b[86] ) >> 0)) << 16) + | ((((int32_t)((b[87] & 0xf )) >> 0)) << 24); + t[25] = (((int32_t)((b[87] ) >> 4)) << 0) + | (((int32_t)((b[88] ) >> 0)) << 4) + | (((int32_t)((b[89] ) >> 0)) << 12) + | (((int32_t)((b[90] ) >> 0)) << 20); + t[26] = (((int32_t)((b[91] ) >> 0)) << 0) + | (((int32_t)((b[92] ) >> 0)) << 8) + | (((int32_t)((b[93] ) >> 0)) << 16) + | ((((int32_t)((b[94] & 0xf )) >> 0)) << 24); + t[27] = (((int32_t)((b[94] ) >> 4)) << 0) + | (((int32_t)((b[95] ) >> 0)) << 4) + | (((int32_t)((b[96] ) >> 0)) << 12) + | (((int32_t)((b[97] ) >> 0)) << 20); + t[28] = (((int32_t)((b[98] ) >> 0)) << 0) + | (((int32_t)((b[99] ) >> 0)) << 8) + | (((int32_t)((b[100] ) >> 0)) << 16) + | ((((int32_t)((b[101] & 0xf )) >> 0)) << 24); + t[29] = (((int32_t)((b[101] ) >> 4)) << 0) + | (((int32_t)((b[102] ) >> 0)) << 4) + | (((int32_t)((b[103] ) >> 0)) << 12) + | (((int32_t)((b[104] ) >> 0)) << 20); + t[30] = (((int32_t)((b[105] ) >> 0)) << 0) + | (((int32_t)((b[106] ) >> 0)) << 8) + | (((int32_t)((b[107] ) >> 0)) << 16) + | ((((int32_t)((b[108] & 0xf )) >> 0)) << 24); + t[31] = (((int32_t)((b[108] ) >> 4)) << 0) + | (((int32_t)((b[109] ) >> 0)) << 4) + | (((int32_t)((b[110] ) >> 0)) << 12) + | (((int32_t)((b[111] ) >> 0)) << 20); + t[32] = (((int32_t)((b[112] ) >> 0)) << 0) + | (((int32_t)((b[113] ) >> 0)) << 8); + + /* Mod curve order */ + /* 2^446 - 0x8335dc163bb124b65129c96fde933d8d723a70aadc873d6d54a7bb0d */ + /* Mod top half of extra words */ + t[ 8] += (int64_t)0x129eec34 * t[24]; + t[ 9] += (int64_t)0x21cf5b54 * t[24]; + t[10] += (int64_t)0x29c2ab70 * t[24]; + t[11] += (int64_t)0x0f635c8c * t[24]; + t[12] += (int64_t)0x25bf7a4c * t[24]; + t[13] += (int64_t)0x2d944a70 * t[24]; + t[14] += (int64_t)0x18eec490 * t[24]; + t[15] += (int64_t)0x20cd7704 * t[24]; + t[ 9] += (int64_t)0x129eec34 * t[25]; + t[10] += (int64_t)0x21cf5b54 * t[25]; + t[11] += (int64_t)0x29c2ab70 * t[25]; + t[12] += (int64_t)0x0f635c8c * t[25]; + t[13] += (int64_t)0x25bf7a4c * t[25]; + t[14] += (int64_t)0x2d944a70 * t[25]; + t[15] += (int64_t)0x18eec490 * t[25]; + t[16] += (int64_t)0x20cd7704 * t[25]; + t[10] += (int64_t)0x129eec34 * t[26]; + t[11] += (int64_t)0x21cf5b54 * t[26]; + t[12] += (int64_t)0x29c2ab70 * t[26]; + t[13] += (int64_t)0x0f635c8c * t[26]; + t[14] += (int64_t)0x25bf7a4c * t[26]; + t[15] += (int64_t)0x2d944a70 * t[26]; + t[16] += (int64_t)0x18eec490 * t[26]; + t[17] += (int64_t)0x20cd7704 * t[26]; + t[11] += (int64_t)0x129eec34 * t[27]; + t[12] += (int64_t)0x21cf5b54 * t[27]; + t[13] += (int64_t)0x29c2ab70 * t[27]; + t[14] += (int64_t)0x0f635c8c * t[27]; + t[15] += (int64_t)0x25bf7a4c * t[27]; + t[16] += (int64_t)0x2d944a70 * t[27]; + t[17] += (int64_t)0x18eec490 * t[27]; + t[18] += (int64_t)0x20cd7704 * t[27]; + t[12] += (int64_t)0x129eec34 * t[28]; + t[13] += (int64_t)0x21cf5b54 * t[28]; + t[14] += (int64_t)0x29c2ab70 * t[28]; + t[15] += (int64_t)0x0f635c8c * t[28]; + t[16] += (int64_t)0x25bf7a4c * t[28]; + t[17] += (int64_t)0x2d944a70 * t[28]; + t[18] += (int64_t)0x18eec490 * t[28]; + t[19] += (int64_t)0x20cd7704 * t[28]; + t[13] += (int64_t)0x129eec34 * t[29]; + t[14] += (int64_t)0x21cf5b54 * t[29]; + t[15] += (int64_t)0x29c2ab70 * t[29]; + t[16] += (int64_t)0x0f635c8c * t[29]; + t[17] += (int64_t)0x25bf7a4c * t[29]; + t[18] += (int64_t)0x2d944a70 * t[29]; + t[19] += (int64_t)0x18eec490 * t[29]; + t[20] += (int64_t)0x20cd7704 * t[29]; + t[14] += (int64_t)0x129eec34 * t[30]; + t[15] += (int64_t)0x21cf5b54 * t[30]; + t[16] += (int64_t)0x29c2ab70 * t[30]; + t[17] += (int64_t)0x0f635c8c * t[30]; + t[18] += (int64_t)0x25bf7a4c * t[30]; + t[19] += (int64_t)0x2d944a70 * t[30]; + t[20] += (int64_t)0x18eec490 * t[30]; + t[21] += (int64_t)0x20cd7704 * t[30]; + t[15] += (int64_t)0x129eec34 * t[31]; + t[16] += (int64_t)0x21cf5b54 * t[31]; + t[17] += (int64_t)0x29c2ab70 * t[31]; + t[18] += (int64_t)0x0f635c8c * t[31]; + t[19] += (int64_t)0x25bf7a4c * t[31]; + t[20] += (int64_t)0x2d944a70 * t[31]; + t[21] += (int64_t)0x18eec490 * t[31]; + t[22] += (int64_t)0x20cd7704 * t[31]; + t[16] += (int64_t)0x129eec34 * t[32]; + t[17] += (int64_t)0x21cf5b54 * t[32]; + t[18] += (int64_t)0x29c2ab70 * t[32]; + t[19] += (int64_t)0x0f635c8c * t[32]; + t[20] += (int64_t)0x25bf7a4c * t[32]; + t[21] += (int64_t)0x2d944a70 * t[32]; + t[22] += (int64_t)0x18eec490 * t[32]; + t[23] += (int64_t)0x20cd7704 * t[32]; + t[24] = 0; + /* Propagate carries */ + c = t[ 8] >> 28; t[ 9] += c; t[ 8] = t[ 8] & 0xfffffff; + c = t[ 9] >> 28; t[10] += c; t[ 9] = t[ 9] & 0xfffffff; + c = t[10] >> 28; t[11] += c; t[10] = t[10] & 0xfffffff; + c = t[11] >> 28; t[12] += c; t[11] = t[11] & 0xfffffff; + c = t[12] >> 28; t[13] += c; t[12] = t[12] & 0xfffffff; + c = t[13] >> 28; t[14] += c; t[13] = t[13] & 0xfffffff; + c = t[14] >> 28; t[15] += c; t[14] = t[14] & 0xfffffff; + c = t[15] >> 28; t[16] += c; t[15] = t[15] & 0xfffffff; + c = t[16] >> 28; t[17] += c; t[16] = t[16] & 0xfffffff; + c = t[17] >> 28; t[18] += c; t[17] = t[17] & 0xfffffff; + c = t[18] >> 28; t[19] += c; t[18] = t[18] & 0xfffffff; + c = t[19] >> 28; t[20] += c; t[19] = t[19] & 0xfffffff; + c = t[20] >> 28; t[21] += c; t[20] = t[20] & 0xfffffff; + c = t[21] >> 28; t[22] += c; t[21] = t[21] & 0xfffffff; + c = t[22] >> 28; t[23] += c; t[22] = t[22] & 0xfffffff; + c = t[23] >> 28; t[24] += c; t[23] = t[23] & 0xfffffff; + /* Mod bottom half of extra words */ + t[ 0] += (int64_t)0x129eec34 * t[16]; + t[ 1] += (int64_t)0x21cf5b54 * t[16]; + t[ 2] += (int64_t)0x29c2ab70 * t[16]; + t[ 3] += (int64_t)0x0f635c8c * t[16]; + t[ 4] += (int64_t)0x25bf7a4c * t[16]; + t[ 5] += (int64_t)0x2d944a70 * t[16]; + t[ 6] += (int64_t)0x18eec490 * t[16]; + t[ 7] += (int64_t)0x20cd7704 * t[16]; + t[ 1] += (int64_t)0x129eec34 * t[17]; + t[ 2] += (int64_t)0x21cf5b54 * t[17]; + t[ 3] += (int64_t)0x29c2ab70 * t[17]; + t[ 4] += (int64_t)0x0f635c8c * t[17]; + t[ 5] += (int64_t)0x25bf7a4c * t[17]; + t[ 6] += (int64_t)0x2d944a70 * t[17]; + t[ 7] += (int64_t)0x18eec490 * t[17]; + t[ 8] += (int64_t)0x20cd7704 * t[17]; + t[ 2] += (int64_t)0x129eec34 * t[18]; + t[ 3] += (int64_t)0x21cf5b54 * t[18]; + t[ 4] += (int64_t)0x29c2ab70 * t[18]; + t[ 5] += (int64_t)0x0f635c8c * t[18]; + t[ 6] += (int64_t)0x25bf7a4c * t[18]; + t[ 7] += (int64_t)0x2d944a70 * t[18]; + t[ 8] += (int64_t)0x18eec490 * t[18]; + t[ 9] += (int64_t)0x20cd7704 * t[18]; + t[ 3] += (int64_t)0x129eec34 * t[19]; + t[ 4] += (int64_t)0x21cf5b54 * t[19]; + t[ 5] += (int64_t)0x29c2ab70 * t[19]; + t[ 6] += (int64_t)0x0f635c8c * t[19]; + t[ 7] += (int64_t)0x25bf7a4c * t[19]; + t[ 8] += (int64_t)0x2d944a70 * t[19]; + t[ 9] += (int64_t)0x18eec490 * t[19]; + t[10] += (int64_t)0x20cd7704 * t[19]; + t[ 4] += (int64_t)0x129eec34 * t[20]; + t[ 5] += (int64_t)0x21cf5b54 * t[20]; + t[ 6] += (int64_t)0x29c2ab70 * t[20]; + t[ 7] += (int64_t)0x0f635c8c * t[20]; + t[ 8] += (int64_t)0x25bf7a4c * t[20]; + t[ 9] += (int64_t)0x2d944a70 * t[20]; + t[10] += (int64_t)0x18eec490 * t[20]; + t[11] += (int64_t)0x20cd7704 * t[20]; + t[ 5] += (int64_t)0x129eec34 * t[21]; + t[ 6] += (int64_t)0x21cf5b54 * t[21]; + t[ 7] += (int64_t)0x29c2ab70 * t[21]; + t[ 8] += (int64_t)0x0f635c8c * t[21]; + t[ 9] += (int64_t)0x25bf7a4c * t[21]; + t[10] += (int64_t)0x2d944a70 * t[21]; + t[11] += (int64_t)0x18eec490 * t[21]; + t[12] += (int64_t)0x20cd7704 * t[21]; + t[ 6] += (int64_t)0x129eec34 * t[22]; + t[ 7] += (int64_t)0x21cf5b54 * t[22]; + t[ 8] += (int64_t)0x29c2ab70 * t[22]; + t[ 9] += (int64_t)0x0f635c8c * t[22]; + t[10] += (int64_t)0x25bf7a4c * t[22]; + t[11] += (int64_t)0x2d944a70 * t[22]; + t[12] += (int64_t)0x18eec490 * t[22]; + t[13] += (int64_t)0x20cd7704 * t[22]; + t[ 7] += (int64_t)0x129eec34 * t[23]; + t[ 8] += (int64_t)0x21cf5b54 * t[23]; + t[ 9] += (int64_t)0x29c2ab70 * t[23]; + t[10] += (int64_t)0x0f635c8c * t[23]; + t[11] += (int64_t)0x25bf7a4c * t[23]; + t[12] += (int64_t)0x2d944a70 * t[23]; + t[13] += (int64_t)0x18eec490 * t[23]; + t[14] += (int64_t)0x20cd7704 * t[23]; + t[ 8] += (int64_t)0x129eec34 * t[24]; + t[ 9] += (int64_t)0x21cf5b54 * t[24]; + t[10] += (int64_t)0x29c2ab70 * t[24]; + t[11] += (int64_t)0x0f635c8c * t[24]; + t[12] += (int64_t)0x25bf7a4c * t[24]; + t[13] += (int64_t)0x2d944a70 * t[24]; + t[14] += (int64_t)0x18eec490 * t[24]; + t[15] += (int64_t)0x20cd7704 * t[24]; + t[16] = 0; + /* Propagate carries */ + c = t[ 0] >> 28; t[ 1] += c; t[ 0] = t[ 0] & 0xfffffff; + c = t[ 1] >> 28; t[ 2] += c; t[ 1] = t[ 1] & 0xfffffff; + c = t[ 2] >> 28; t[ 3] += c; t[ 2] = t[ 2] & 0xfffffff; + c = t[ 3] >> 28; t[ 4] += c; t[ 3] = t[ 3] & 0xfffffff; + c = t[ 4] >> 28; t[ 5] += c; t[ 4] = t[ 4] & 0xfffffff; + c = t[ 5] >> 28; t[ 6] += c; t[ 5] = t[ 5] & 0xfffffff; + c = t[ 6] >> 28; t[ 7] += c; t[ 6] = t[ 6] & 0xfffffff; + c = t[ 7] >> 28; t[ 8] += c; t[ 7] = t[ 7] & 0xfffffff; + c = t[ 8] >> 28; t[ 9] += c; t[ 8] = t[ 8] & 0xfffffff; + c = t[ 9] >> 28; t[10] += c; t[ 9] = t[ 9] & 0xfffffff; + c = t[10] >> 28; t[11] += c; t[10] = t[10] & 0xfffffff; + c = t[11] >> 28; t[12] += c; t[11] = t[11] & 0xfffffff; + c = t[12] >> 28; t[13] += c; t[12] = t[12] & 0xfffffff; + c = t[13] >> 28; t[14] += c; t[13] = t[13] & 0xfffffff; + c = t[14] >> 28; t[15] += c; t[14] = t[14] & 0xfffffff; + c = t[15] >> 28; t[16] += c; t[15] = t[15] & 0xfffffff; + t[ 0] += (int64_t)0x129eec34 * t[16]; + t[ 1] += (int64_t)0x21cf5b54 * t[16]; + t[ 2] += (int64_t)0x29c2ab70 * t[16]; + t[ 3] += (int64_t)0x0f635c8c * t[16]; + t[ 4] += (int64_t)0x25bf7a4c * t[16]; + t[ 5] += (int64_t)0x2d944a70 * t[16]; + t[ 6] += (int64_t)0x18eec490 * t[16]; + t[ 7] += (int64_t)0x20cd7704 * t[16]; + /* Propagate carries */ + c = t[ 0] >> 28; t[ 1] += c; d[ 0] = (int32_t)(t[ 0] & 0xfffffff); + c = t[ 1] >> 28; t[ 2] += c; d[ 1] = (int32_t)(t[ 1] & 0xfffffff); + c = t[ 2] >> 28; t[ 3] += c; d[ 2] = (int32_t)(t[ 2] & 0xfffffff); + c = t[ 3] >> 28; t[ 4] += c; d[ 3] = (int32_t)(t[ 3] & 0xfffffff); + c = t[ 4] >> 28; t[ 5] += c; d[ 4] = (int32_t)(t[ 4] & 0xfffffff); + c = t[ 5] >> 28; t[ 6] += c; d[ 5] = (int32_t)(t[ 5] & 0xfffffff); + c = t[ 6] >> 28; t[ 7] += c; d[ 6] = (int32_t)(t[ 6] & 0xfffffff); + c = t[ 7] >> 28; t[ 8] += c; d[ 7] = (int32_t)(t[ 7] & 0xfffffff); + c = t[ 8] >> 28; t[ 9] += c; d[ 8] = (int32_t)(t[ 8] & 0xfffffff); + c = t[ 9] >> 28; t[10] += c; d[ 9] = (int32_t)(t[ 9] & 0xfffffff); + c = t[10] >> 28; t[11] += c; d[10] = (int32_t)(t[10] & 0xfffffff); + c = t[11] >> 28; t[12] += c; d[11] = (int32_t)(t[11] & 0xfffffff); + c = t[12] >> 28; t[13] += c; d[12] = (int32_t)(t[12] & 0xfffffff); + c = t[13] >> 28; t[14] += c; d[13] = (int32_t)(t[13] & 0xfffffff); + c = t[14] >> 28; t[15] += c; d[14] = (int32_t)(t[14] & 0xfffffff); + d[15] = t[15]; + /* Mod bits over 28 in last word */ + o = d[15] >> 26; d[15] &= 0x3ffffff; + d[ 0] += 0x4a7bb0d * o; + d[ 1] += 0x873d6d5 * o; + d[ 2] += 0xa70aadc * o; + d[ 3] += 0x3d8d723 * o; + d[ 4] += 0x96fde93 * o; + d[ 5] += 0xb65129c * o; + d[ 6] += 0x63bb124 * o; + d[ 7] += 0x8335dc1 * o; + /* Propagate carries */ + o = d[ 0] >> 28; d[ 1] += o; d[ 0] = d[ 0] & 0xfffffff; + o = d[ 1] >> 28; d[ 2] += o; d[ 1] = d[ 1] & 0xfffffff; + o = d[ 2] >> 28; d[ 3] += o; d[ 2] = d[ 2] & 0xfffffff; + o = d[ 3] >> 28; d[ 4] += o; d[ 3] = d[ 3] & 0xfffffff; + o = d[ 4] >> 28; d[ 5] += o; d[ 4] = d[ 4] & 0xfffffff; + o = d[ 5] >> 28; d[ 6] += o; d[ 5] = d[ 5] & 0xfffffff; + o = d[ 6] >> 28; d[ 7] += o; d[ 6] = d[ 6] & 0xfffffff; + o = d[ 7] >> 28; d[ 8] += o; d[ 7] = d[ 7] & 0xfffffff; + o = d[ 8] >> 28; d[ 9] += o; d[ 8] = d[ 8] & 0xfffffff; + o = d[ 9] >> 28; d[10] += o; d[ 9] = d[ 9] & 0xfffffff; + o = d[10] >> 28; d[11] += o; d[10] = d[10] & 0xfffffff; + o = d[11] >> 28; d[12] += o; d[11] = d[11] & 0xfffffff; + o = d[12] >> 28; d[13] += o; d[12] = d[12] & 0xfffffff; + o = d[13] >> 28; d[14] += o; d[13] = d[13] & 0xfffffff; + o = d[14] >> 28; d[15] += o; d[14] = d[14] & 0xfffffff; + + /* Convert to bytes */ + b[ 0] = (d[0 ] >> 0); + b[ 1] = (d[0 ] >> 8); + b[ 2] = (d[0 ] >> 16); + b[ 3] = (d[0 ] >> 24) + ((d[1 ] >> 0) << 4); + b[ 4] = (d[1 ] >> 4); + b[ 5] = (d[1 ] >> 12); + b[ 6] = (d[1 ] >> 20); + b[ 7] = (d[2 ] >> 0); + b[ 8] = (d[2 ] >> 8); + b[ 9] = (d[2 ] >> 16); + b[10] = (d[2 ] >> 24) + ((d[3 ] >> 0) << 4); + b[11] = (d[3 ] >> 4); + b[12] = (d[3 ] >> 12); + b[13] = (d[3 ] >> 20); + b[14] = (d[4 ] >> 0); + b[15] = (d[4 ] >> 8); + b[16] = (d[4 ] >> 16); + b[17] = (d[4 ] >> 24) + ((d[5 ] >> 0) << 4); + b[18] = (d[5 ] >> 4); + b[19] = (d[5 ] >> 12); + b[20] = (d[5 ] >> 20); + b[21] = (d[6 ] >> 0); + b[22] = (d[6 ] >> 8); + b[23] = (d[6 ] >> 16); + b[24] = (d[6 ] >> 24) + ((d[7 ] >> 0) << 4); + b[25] = (d[7 ] >> 4); + b[26] = (d[7 ] >> 12); + b[27] = (d[7 ] >> 20); + b[28] = (d[8 ] >> 0); + b[29] = (d[8 ] >> 8); + b[30] = (d[8 ] >> 16); + b[31] = (d[8 ] >> 24) + ((d[9 ] >> 0) << 4); + b[32] = (d[9 ] >> 4); + b[33] = (d[9 ] >> 12); + b[34] = (d[9 ] >> 20); + b[35] = (d[10] >> 0); + b[36] = (d[10] >> 8); + b[37] = (d[10] >> 16); + b[38] = (d[10] >> 24) + ((d[11] >> 0) << 4); + b[39] = (d[11] >> 4); + b[40] = (d[11] >> 12); + b[41] = (d[11] >> 20); + b[42] = (d[12] >> 0); + b[43] = (d[12] >> 8); + b[44] = (d[12] >> 16); + b[45] = (d[12] >> 24) + ((d[13] >> 0) << 4); + b[46] = (d[13] >> 4); + b[47] = (d[13] >> 12); + b[48] = (d[13] >> 20); + b[49] = (d[14] >> 0); + b[50] = (d[14] >> 8); + b[51] = (d[14] >> 16); + b[52] = (d[14] >> 24) + ((d[15] >> 0) << 4); + b[53] = (d[15] >> 4); + b[54] = (d[15] >> 12); + b[55] = (d[15] >> 20); + b[56] = 0; +} + +/* Multiply a by b and add d. r = (a * b + d) mod order + * + * r [in] Scalar to hold result. + * a [in] Scalar to multiply. + * b [in] Scalar to multiply. + * d [in] Scalar to add to multiplicative result. + */ +void sc448_muladd(uint8_t* r, const uint8_t* a, const uint8_t* b, + const uint8_t* d) +{ + uint32_t ad[16], bd[16], dd[16], rd[16]; + uint64_t t[32]; + uint64_t c; + uint32_t o; + + /* Load from bytes */ + ad[ 0] = (((int32_t)((a[ 0] ) >> 0)) << 0) + | (((int32_t)((a[ 1] ) >> 0)) << 8) + | (((int32_t)((a[ 2] ) >> 0)) << 16) + | ((((int32_t)((a[ 3] & 0xf )) >> 0)) << 24); + ad[ 1] = (((int32_t)((a[ 3] ) >> 4)) << 0) + | (((int32_t)((a[ 4] ) >> 0)) << 4) + | (((int32_t)((a[ 5] ) >> 0)) << 12) + | (((int32_t)((a[ 6] ) >> 0)) << 20); + ad[ 2] = (((int32_t)((a[ 7] ) >> 0)) << 0) + | (((int32_t)((a[ 8] ) >> 0)) << 8) + | (((int32_t)((a[ 9] ) >> 0)) << 16) + | ((((int32_t)((a[10] & 0xf )) >> 0)) << 24); + ad[ 3] = (((int32_t)((a[10] ) >> 4)) << 0) + | (((int32_t)((a[11] ) >> 0)) << 4) + | (((int32_t)((a[12] ) >> 0)) << 12) + | (((int32_t)((a[13] ) >> 0)) << 20); + ad[ 4] = (((int32_t)((a[14] ) >> 0)) << 0) + | (((int32_t)((a[15] ) >> 0)) << 8) + | (((int32_t)((a[16] ) >> 0)) << 16) + | ((((int32_t)((a[17] & 0xf )) >> 0)) << 24); + ad[ 5] = (((int32_t)((a[17] ) >> 4)) << 0) + | (((int32_t)((a[18] ) >> 0)) << 4) + | (((int32_t)((a[19] ) >> 0)) << 12) + | (((int32_t)((a[20] ) >> 0)) << 20); + ad[ 6] = (((int32_t)((a[21] ) >> 0)) << 0) + | (((int32_t)((a[22] ) >> 0)) << 8) + | (((int32_t)((a[23] ) >> 0)) << 16) + | ((((int32_t)((a[24] & 0xf )) >> 0)) << 24); + ad[ 7] = (((int32_t)((a[24] ) >> 4)) << 0) + | (((int32_t)((a[25] ) >> 0)) << 4) + | (((int32_t)((a[26] ) >> 0)) << 12) + | (((int32_t)((a[27] ) >> 0)) << 20); + ad[ 8] = (((int32_t)((a[28] ) >> 0)) << 0) + | (((int32_t)((a[29] ) >> 0)) << 8) + | (((int32_t)((a[30] ) >> 0)) << 16) + | ((((int32_t)((a[31] & 0xf )) >> 0)) << 24); + ad[ 9] = (((int32_t)((a[31] ) >> 4)) << 0) + | (((int32_t)((a[32] ) >> 0)) << 4) + | (((int32_t)((a[33] ) >> 0)) << 12) + | (((int32_t)((a[34] ) >> 0)) << 20); + ad[10] = (((int32_t)((a[35] ) >> 0)) << 0) + | (((int32_t)((a[36] ) >> 0)) << 8) + | (((int32_t)((a[37] ) >> 0)) << 16) + | ((((int32_t)((a[38] & 0xf )) >> 0)) << 24); + ad[11] = (((int32_t)((a[38] ) >> 4)) << 0) + | (((int32_t)((a[39] ) >> 0)) << 4) + | (((int32_t)((a[40] ) >> 0)) << 12) + | (((int32_t)((a[41] ) >> 0)) << 20); + ad[12] = (((int32_t)((a[42] ) >> 0)) << 0) + | (((int32_t)((a[43] ) >> 0)) << 8) + | (((int32_t)((a[44] ) >> 0)) << 16) + | ((((int32_t)((a[45] & 0xf )) >> 0)) << 24); + ad[13] = (((int32_t)((a[45] ) >> 4)) << 0) + | (((int32_t)((a[46] ) >> 0)) << 4) + | (((int32_t)((a[47] ) >> 0)) << 12) + | (((int32_t)((a[48] ) >> 0)) << 20); + ad[14] = (((int32_t)((a[49] ) >> 0)) << 0) + | (((int32_t)((a[50] ) >> 0)) << 8) + | (((int32_t)((a[51] ) >> 0)) << 16) + | ((((int32_t)((a[52] & 0xf )) >> 0)) << 24); + ad[15] = (((int32_t)((a[52] ) >> 4)) << 0) + | (((int32_t)((a[53] ) >> 0)) << 4) + | (((int32_t)((a[54] ) >> 0)) << 12) + | (((int32_t)((a[55] ) >> 0)) << 20); + /* Load from bytes */ + bd[ 0] = (((int32_t)((b[ 0] ) >> 0)) << 0) + | (((int32_t)((b[ 1] ) >> 0)) << 8) + | (((int32_t)((b[ 2] ) >> 0)) << 16) + | ((((int32_t)((b[ 3] & 0xf )) >> 0)) << 24); + bd[ 1] = (((int32_t)((b[ 3] ) >> 4)) << 0) + | (((int32_t)((b[ 4] ) >> 0)) << 4) + | (((int32_t)((b[ 5] ) >> 0)) << 12) + | (((int32_t)((b[ 6] ) >> 0)) << 20); + bd[ 2] = (((int32_t)((b[ 7] ) >> 0)) << 0) + | (((int32_t)((b[ 8] ) >> 0)) << 8) + | (((int32_t)((b[ 9] ) >> 0)) << 16) + | ((((int32_t)((b[10] & 0xf )) >> 0)) << 24); + bd[ 3] = (((int32_t)((b[10] ) >> 4)) << 0) + | (((int32_t)((b[11] ) >> 0)) << 4) + | (((int32_t)((b[12] ) >> 0)) << 12) + | (((int32_t)((b[13] ) >> 0)) << 20); + bd[ 4] = (((int32_t)((b[14] ) >> 0)) << 0) + | (((int32_t)((b[15] ) >> 0)) << 8) + | (((int32_t)((b[16] ) >> 0)) << 16) + | ((((int32_t)((b[17] & 0xf )) >> 0)) << 24); + bd[ 5] = (((int32_t)((b[17] ) >> 4)) << 0) + | (((int32_t)((b[18] ) >> 0)) << 4) + | (((int32_t)((b[19] ) >> 0)) << 12) + | (((int32_t)((b[20] ) >> 0)) << 20); + bd[ 6] = (((int32_t)((b[21] ) >> 0)) << 0) + | (((int32_t)((b[22] ) >> 0)) << 8) + | (((int32_t)((b[23] ) >> 0)) << 16) + | ((((int32_t)((b[24] & 0xf )) >> 0)) << 24); + bd[ 7] = (((int32_t)((b[24] ) >> 4)) << 0) + | (((int32_t)((b[25] ) >> 0)) << 4) + | (((int32_t)((b[26] ) >> 0)) << 12) + | (((int32_t)((b[27] ) >> 0)) << 20); + bd[ 8] = (((int32_t)((b[28] ) >> 0)) << 0) + | (((int32_t)((b[29] ) >> 0)) << 8) + | (((int32_t)((b[30] ) >> 0)) << 16) + | ((((int32_t)((b[31] & 0xf )) >> 0)) << 24); + bd[ 9] = (((int32_t)((b[31] ) >> 4)) << 0) + | (((int32_t)((b[32] ) >> 0)) << 4) + | (((int32_t)((b[33] ) >> 0)) << 12) + | (((int32_t)((b[34] ) >> 0)) << 20); + bd[10] = (((int32_t)((b[35] ) >> 0)) << 0) + | (((int32_t)((b[36] ) >> 0)) << 8) + | (((int32_t)((b[37] ) >> 0)) << 16) + | ((((int32_t)((b[38] & 0xf )) >> 0)) << 24); + bd[11] = (((int32_t)((b[38] ) >> 4)) << 0) + | (((int32_t)((b[39] ) >> 0)) << 4) + | (((int32_t)((b[40] ) >> 0)) << 12) + | (((int32_t)((b[41] ) >> 0)) << 20); + bd[12] = (((int32_t)((b[42] ) >> 0)) << 0) + | (((int32_t)((b[43] ) >> 0)) << 8) + | (((int32_t)((b[44] ) >> 0)) << 16) + | ((((int32_t)((b[45] & 0xf )) >> 0)) << 24); + bd[13] = (((int32_t)((b[45] ) >> 4)) << 0) + | (((int32_t)((b[46] ) >> 0)) << 4) + | (((int32_t)((b[47] ) >> 0)) << 12) + | (((int32_t)((b[48] ) >> 0)) << 20); + bd[14] = (((int32_t)((b[49] ) >> 0)) << 0) + | (((int32_t)((b[50] ) >> 0)) << 8) + | (((int32_t)((b[51] ) >> 0)) << 16) + | ((((int32_t)((b[52] & 0xf )) >> 0)) << 24); + bd[15] = (((int32_t)((b[52] ) >> 4)) << 0) + | (((int32_t)((b[53] ) >> 0)) << 4) + | (((int32_t)((b[54] ) >> 0)) << 12) + | (((int32_t)((b[55] ) >> 0)) << 20); + /* Load from bytes */ + dd[ 0] = (((int32_t)((d[ 0] ) >> 0)) << 0) + | (((int32_t)((d[ 1] ) >> 0)) << 8) + | (((int32_t)((d[ 2] ) >> 0)) << 16) + | ((((int32_t)((d[ 3] & 0xf )) >> 0)) << 24); + dd[ 1] = (((int32_t)((d[ 3] ) >> 4)) << 0) + | (((int32_t)((d[ 4] ) >> 0)) << 4) + | (((int32_t)((d[ 5] ) >> 0)) << 12) + | (((int32_t)((d[ 6] ) >> 0)) << 20); + dd[ 2] = (((int32_t)((d[ 7] ) >> 0)) << 0) + | (((int32_t)((d[ 8] ) >> 0)) << 8) + | (((int32_t)((d[ 9] ) >> 0)) << 16) + | ((((int32_t)((d[10] & 0xf )) >> 0)) << 24); + dd[ 3] = (((int32_t)((d[10] ) >> 4)) << 0) + | (((int32_t)((d[11] ) >> 0)) << 4) + | (((int32_t)((d[12] ) >> 0)) << 12) + | (((int32_t)((d[13] ) >> 0)) << 20); + dd[ 4] = (((int32_t)((d[14] ) >> 0)) << 0) + | (((int32_t)((d[15] ) >> 0)) << 8) + | (((int32_t)((d[16] ) >> 0)) << 16) + | ((((int32_t)((d[17] & 0xf )) >> 0)) << 24); + dd[ 5] = (((int32_t)((d[17] ) >> 4)) << 0) + | (((int32_t)((d[18] ) >> 0)) << 4) + | (((int32_t)((d[19] ) >> 0)) << 12) + | (((int32_t)((d[20] ) >> 0)) << 20); + dd[ 6] = (((int32_t)((d[21] ) >> 0)) << 0) + | (((int32_t)((d[22] ) >> 0)) << 8) + | (((int32_t)((d[23] ) >> 0)) << 16) + | ((((int32_t)((d[24] & 0xf )) >> 0)) << 24); + dd[ 7] = (((int32_t)((d[24] ) >> 4)) << 0) + | (((int32_t)((d[25] ) >> 0)) << 4) + | (((int32_t)((d[26] ) >> 0)) << 12) + | (((int32_t)((d[27] ) >> 0)) << 20); + dd[ 8] = (((int32_t)((d[28] ) >> 0)) << 0) + | (((int32_t)((d[29] ) >> 0)) << 8) + | (((int32_t)((d[30] ) >> 0)) << 16) + | ((((int32_t)((d[31] & 0xf )) >> 0)) << 24); + dd[ 9] = (((int32_t)((d[31] ) >> 4)) << 0) + | (((int32_t)((d[32] ) >> 0)) << 4) + | (((int32_t)((d[33] ) >> 0)) << 12) + | (((int32_t)((d[34] ) >> 0)) << 20); + dd[10] = (((int32_t)((d[35] ) >> 0)) << 0) + | (((int32_t)((d[36] ) >> 0)) << 8) + | (((int32_t)((d[37] ) >> 0)) << 16) + | ((((int32_t)((d[38] & 0xf )) >> 0)) << 24); + dd[11] = (((int32_t)((d[38] ) >> 4)) << 0) + | (((int32_t)((d[39] ) >> 0)) << 4) + | (((int32_t)((d[40] ) >> 0)) << 12) + | (((int32_t)((d[41] ) >> 0)) << 20); + dd[12] = (((int32_t)((d[42] ) >> 0)) << 0) + | (((int32_t)((d[43] ) >> 0)) << 8) + | (((int32_t)((d[44] ) >> 0)) << 16) + | ((((int32_t)((d[45] & 0xf )) >> 0)) << 24); + dd[13] = (((int32_t)((d[45] ) >> 4)) << 0) + | (((int32_t)((d[46] ) >> 0)) << 4) + | (((int32_t)((d[47] ) >> 0)) << 12) + | (((int32_t)((d[48] ) >> 0)) << 20); + dd[14] = (((int32_t)((d[49] ) >> 0)) << 0) + | (((int32_t)((d[50] ) >> 0)) << 8) + | (((int32_t)((d[51] ) >> 0)) << 16) + | ((((int32_t)((d[52] & 0xf )) >> 0)) << 24); + dd[15] = (((int32_t)((d[52] ) >> 4)) << 0) + | (((int32_t)((d[53] ) >> 0)) << 4) + | (((int32_t)((d[54] ) >> 0)) << 12) + | (((int32_t)((d[55] ) >> 0)) << 20); + + /* a * b + d */ + t[ 0] = dd[ 0] + (int64_t)ad[ 0] * bd[ 0]; + t[ 1] = dd[ 1] + (int64_t)ad[ 0] * bd[ 1] + + (int64_t)ad[ 1] * bd[ 0]; + t[ 2] = dd[ 2] + (int64_t)ad[ 0] * bd[ 2] + + (int64_t)ad[ 1] * bd[ 1] + + (int64_t)ad[ 2] * bd[ 0]; + t[ 3] = dd[ 3] + (int64_t)ad[ 0] * bd[ 3] + + (int64_t)ad[ 1] * bd[ 2] + + (int64_t)ad[ 2] * bd[ 1] + + (int64_t)ad[ 3] * bd[ 0]; + t[ 4] = dd[ 4] + (int64_t)ad[ 0] * bd[ 4] + + (int64_t)ad[ 1] * bd[ 3] + + (int64_t)ad[ 2] * bd[ 2] + + (int64_t)ad[ 3] * bd[ 1] + + (int64_t)ad[ 4] * bd[ 0]; + t[ 5] = dd[ 5] + (int64_t)ad[ 0] * bd[ 5] + + (int64_t)ad[ 1] * bd[ 4] + + (int64_t)ad[ 2] * bd[ 3] + + (int64_t)ad[ 3] * bd[ 2] + + (int64_t)ad[ 4] * bd[ 1] + + (int64_t)ad[ 5] * bd[ 0]; + t[ 6] = dd[ 6] + (int64_t)ad[ 0] * bd[ 6] + + (int64_t)ad[ 1] * bd[ 5] + + (int64_t)ad[ 2] * bd[ 4] + + (int64_t)ad[ 3] * bd[ 3] + + (int64_t)ad[ 4] * bd[ 2] + + (int64_t)ad[ 5] * bd[ 1] + + (int64_t)ad[ 6] * bd[ 0]; + t[ 7] = dd[ 7] + (int64_t)ad[ 0] * bd[ 7] + + (int64_t)ad[ 1] * bd[ 6] + + (int64_t)ad[ 2] * bd[ 5] + + (int64_t)ad[ 3] * bd[ 4] + + (int64_t)ad[ 4] * bd[ 3] + + (int64_t)ad[ 5] * bd[ 2] + + (int64_t)ad[ 6] * bd[ 1] + + (int64_t)ad[ 7] * bd[ 0]; + t[ 8] = dd[ 8] + (int64_t)ad[ 0] * bd[ 8] + + (int64_t)ad[ 1] * bd[ 7] + + (int64_t)ad[ 2] * bd[ 6] + + (int64_t)ad[ 3] * bd[ 5] + + (int64_t)ad[ 4] * bd[ 4] + + (int64_t)ad[ 5] * bd[ 3] + + (int64_t)ad[ 6] * bd[ 2] + + (int64_t)ad[ 7] * bd[ 1] + + (int64_t)ad[ 8] * bd[ 0]; + t[ 9] = dd[ 9] + (int64_t)ad[ 0] * bd[ 9] + + (int64_t)ad[ 1] * bd[ 8] + + (int64_t)ad[ 2] * bd[ 7] + + (int64_t)ad[ 3] * bd[ 6] + + (int64_t)ad[ 4] * bd[ 5] + + (int64_t)ad[ 5] * bd[ 4] + + (int64_t)ad[ 6] * bd[ 3] + + (int64_t)ad[ 7] * bd[ 2] + + (int64_t)ad[ 8] * bd[ 1] + + (int64_t)ad[ 9] * bd[ 0]; + t[10] = dd[10] + (int64_t)ad[ 0] * bd[10] + + (int64_t)ad[ 1] * bd[ 9] + + (int64_t)ad[ 2] * bd[ 8] + + (int64_t)ad[ 3] * bd[ 7] + + (int64_t)ad[ 4] * bd[ 6] + + (int64_t)ad[ 5] * bd[ 5] + + (int64_t)ad[ 6] * bd[ 4] + + (int64_t)ad[ 7] * bd[ 3] + + (int64_t)ad[ 8] * bd[ 2] + + (int64_t)ad[ 9] * bd[ 1] + + (int64_t)ad[10] * bd[ 0]; + t[11] = dd[11] + (int64_t)ad[ 0] * bd[11] + + (int64_t)ad[ 1] * bd[10] + + (int64_t)ad[ 2] * bd[ 9] + + (int64_t)ad[ 3] * bd[ 8] + + (int64_t)ad[ 4] * bd[ 7] + + (int64_t)ad[ 5] * bd[ 6] + + (int64_t)ad[ 6] * bd[ 5] + + (int64_t)ad[ 7] * bd[ 4] + + (int64_t)ad[ 8] * bd[ 3] + + (int64_t)ad[ 9] * bd[ 2] + + (int64_t)ad[10] * bd[ 1] + + (int64_t)ad[11] * bd[ 0]; + t[12] = dd[12] + (int64_t)ad[ 0] * bd[12] + + (int64_t)ad[ 1] * bd[11] + + (int64_t)ad[ 2] * bd[10] + + (int64_t)ad[ 3] * bd[ 9] + + (int64_t)ad[ 4] * bd[ 8] + + (int64_t)ad[ 5] * bd[ 7] + + (int64_t)ad[ 6] * bd[ 6] + + (int64_t)ad[ 7] * bd[ 5] + + (int64_t)ad[ 8] * bd[ 4] + + (int64_t)ad[ 9] * bd[ 3] + + (int64_t)ad[10] * bd[ 2] + + (int64_t)ad[11] * bd[ 1] + + (int64_t)ad[12] * bd[ 0]; + t[13] = dd[13] + (int64_t)ad[ 0] * bd[13] + + (int64_t)ad[ 1] * bd[12] + + (int64_t)ad[ 2] * bd[11] + + (int64_t)ad[ 3] * bd[10] + + (int64_t)ad[ 4] * bd[ 9] + + (int64_t)ad[ 5] * bd[ 8] + + (int64_t)ad[ 6] * bd[ 7] + + (int64_t)ad[ 7] * bd[ 6] + + (int64_t)ad[ 8] * bd[ 5] + + (int64_t)ad[ 9] * bd[ 4] + + (int64_t)ad[10] * bd[ 3] + + (int64_t)ad[11] * bd[ 2] + + (int64_t)ad[12] * bd[ 1] + + (int64_t)ad[13] * bd[ 0]; + t[14] = dd[14] + (int64_t)ad[ 0] * bd[14] + + (int64_t)ad[ 1] * bd[13] + + (int64_t)ad[ 2] * bd[12] + + (int64_t)ad[ 3] * bd[11] + + (int64_t)ad[ 4] * bd[10] + + (int64_t)ad[ 5] * bd[ 9] + + (int64_t)ad[ 6] * bd[ 8] + + (int64_t)ad[ 7] * bd[ 7] + + (int64_t)ad[ 8] * bd[ 6] + + (int64_t)ad[ 9] * bd[ 5] + + (int64_t)ad[10] * bd[ 4] + + (int64_t)ad[11] * bd[ 3] + + (int64_t)ad[12] * bd[ 2] + + (int64_t)ad[13] * bd[ 1] + + (int64_t)ad[14] * bd[ 0]; + t[15] = dd[15] + (int64_t)ad[ 0] * bd[15] + + (int64_t)ad[ 1] * bd[14] + + (int64_t)ad[ 2] * bd[13] + + (int64_t)ad[ 3] * bd[12] + + (int64_t)ad[ 4] * bd[11] + + (int64_t)ad[ 5] * bd[10] + + (int64_t)ad[ 6] * bd[ 9] + + (int64_t)ad[ 7] * bd[ 8] + + (int64_t)ad[ 8] * bd[ 7] + + (int64_t)ad[ 9] * bd[ 6] + + (int64_t)ad[10] * bd[ 5] + + (int64_t)ad[11] * bd[ 4] + + (int64_t)ad[12] * bd[ 3] + + (int64_t)ad[13] * bd[ 2] + + (int64_t)ad[14] * bd[ 1] + + (int64_t)ad[15] * bd[ 0]; + t[16] = (int64_t)ad[ 1] * bd[15] + + (int64_t)ad[ 2] * bd[14] + + (int64_t)ad[ 3] * bd[13] + + (int64_t)ad[ 4] * bd[12] + + (int64_t)ad[ 5] * bd[11] + + (int64_t)ad[ 6] * bd[10] + + (int64_t)ad[ 7] * bd[ 9] + + (int64_t)ad[ 8] * bd[ 8] + + (int64_t)ad[ 9] * bd[ 7] + + (int64_t)ad[10] * bd[ 6] + + (int64_t)ad[11] * bd[ 5] + + (int64_t)ad[12] * bd[ 4] + + (int64_t)ad[13] * bd[ 3] + + (int64_t)ad[14] * bd[ 2] + + (int64_t)ad[15] * bd[ 1]; + t[17] = (int64_t)ad[ 2] * bd[15] + + (int64_t)ad[ 3] * bd[14] + + (int64_t)ad[ 4] * bd[13] + + (int64_t)ad[ 5] * bd[12] + + (int64_t)ad[ 6] * bd[11] + + (int64_t)ad[ 7] * bd[10] + + (int64_t)ad[ 8] * bd[ 9] + + (int64_t)ad[ 9] * bd[ 8] + + (int64_t)ad[10] * bd[ 7] + + (int64_t)ad[11] * bd[ 6] + + (int64_t)ad[12] * bd[ 5] + + (int64_t)ad[13] * bd[ 4] + + (int64_t)ad[14] * bd[ 3] + + (int64_t)ad[15] * bd[ 2]; + t[18] = (int64_t)ad[ 3] * bd[15] + + (int64_t)ad[ 4] * bd[14] + + (int64_t)ad[ 5] * bd[13] + + (int64_t)ad[ 6] * bd[12] + + (int64_t)ad[ 7] * bd[11] + + (int64_t)ad[ 8] * bd[10] + + (int64_t)ad[ 9] * bd[ 9] + + (int64_t)ad[10] * bd[ 8] + + (int64_t)ad[11] * bd[ 7] + + (int64_t)ad[12] * bd[ 6] + + (int64_t)ad[13] * bd[ 5] + + (int64_t)ad[14] * bd[ 4] + + (int64_t)ad[15] * bd[ 3]; + t[19] = (int64_t)ad[ 4] * bd[15] + + (int64_t)ad[ 5] * bd[14] + + (int64_t)ad[ 6] * bd[13] + + (int64_t)ad[ 7] * bd[12] + + (int64_t)ad[ 8] * bd[11] + + (int64_t)ad[ 9] * bd[10] + + (int64_t)ad[10] * bd[ 9] + + (int64_t)ad[11] * bd[ 8] + + (int64_t)ad[12] * bd[ 7] + + (int64_t)ad[13] * bd[ 6] + + (int64_t)ad[14] * bd[ 5] + + (int64_t)ad[15] * bd[ 4]; + t[20] = (int64_t)ad[ 5] * bd[15] + + (int64_t)ad[ 6] * bd[14] + + (int64_t)ad[ 7] * bd[13] + + (int64_t)ad[ 8] * bd[12] + + (int64_t)ad[ 9] * bd[11] + + (int64_t)ad[10] * bd[10] + + (int64_t)ad[11] * bd[ 9] + + (int64_t)ad[12] * bd[ 8] + + (int64_t)ad[13] * bd[ 7] + + (int64_t)ad[14] * bd[ 6] + + (int64_t)ad[15] * bd[ 5]; + t[21] = (int64_t)ad[ 6] * bd[15] + + (int64_t)ad[ 7] * bd[14] + + (int64_t)ad[ 8] * bd[13] + + (int64_t)ad[ 9] * bd[12] + + (int64_t)ad[10] * bd[11] + + (int64_t)ad[11] * bd[10] + + (int64_t)ad[12] * bd[ 9] + + (int64_t)ad[13] * bd[ 8] + + (int64_t)ad[14] * bd[ 7] + + (int64_t)ad[15] * bd[ 6]; + t[22] = (int64_t)ad[ 7] * bd[15] + + (int64_t)ad[ 8] * bd[14] + + (int64_t)ad[ 9] * bd[13] + + (int64_t)ad[10] * bd[12] + + (int64_t)ad[11] * bd[11] + + (int64_t)ad[12] * bd[10] + + (int64_t)ad[13] * bd[ 9] + + (int64_t)ad[14] * bd[ 8] + + (int64_t)ad[15] * bd[ 7]; + t[23] = (int64_t)ad[ 8] * bd[15] + + (int64_t)ad[ 9] * bd[14] + + (int64_t)ad[10] * bd[13] + + (int64_t)ad[11] * bd[12] + + (int64_t)ad[12] * bd[11] + + (int64_t)ad[13] * bd[10] + + (int64_t)ad[14] * bd[ 9] + + (int64_t)ad[15] * bd[ 8]; + t[24] = (int64_t)ad[ 9] * bd[15] + + (int64_t)ad[10] * bd[14] + + (int64_t)ad[11] * bd[13] + + (int64_t)ad[12] * bd[12] + + (int64_t)ad[13] * bd[11] + + (int64_t)ad[14] * bd[10] + + (int64_t)ad[15] * bd[ 9]; + t[25] = (int64_t)ad[10] * bd[15] + + (int64_t)ad[11] * bd[14] + + (int64_t)ad[12] * bd[13] + + (int64_t)ad[13] * bd[12] + + (int64_t)ad[14] * bd[11] + + (int64_t)ad[15] * bd[10]; + t[26] = (int64_t)ad[11] * bd[15] + + (int64_t)ad[12] * bd[14] + + (int64_t)ad[13] * bd[13] + + (int64_t)ad[14] * bd[12] + + (int64_t)ad[15] * bd[11]; + t[27] = (int64_t)ad[12] * bd[15] + + (int64_t)ad[13] * bd[14] + + (int64_t)ad[14] * bd[13] + + (int64_t)ad[15] * bd[12]; + t[28] = (int64_t)ad[13] * bd[15] + + (int64_t)ad[14] * bd[14] + + (int64_t)ad[15] * bd[13]; + t[29] = (int64_t)ad[14] * bd[15] + + (int64_t)ad[15] * bd[14]; + t[30] = (int64_t)ad[15] * bd[15]; + t[31] = 0; + + /* Mod curve order */ + /* 2^446 - 0x8335dc163bb124b65129c96fde933d8d723a70aadc873d6d54a7bb0d */ + /* Propagate carries */ + c = t[ 0] >> 28; t[ 1] += c; t[ 0] = t[ 0] & 0xfffffff; + c = t[ 1] >> 28; t[ 2] += c; t[ 1] = t[ 1] & 0xfffffff; + c = t[ 2] >> 28; t[ 3] += c; t[ 2] = t[ 2] & 0xfffffff; + c = t[ 3] >> 28; t[ 4] += c; t[ 3] = t[ 3] & 0xfffffff; + c = t[ 4] >> 28; t[ 5] += c; t[ 4] = t[ 4] & 0xfffffff; + c = t[ 5] >> 28; t[ 6] += c; t[ 5] = t[ 5] & 0xfffffff; + c = t[ 6] >> 28; t[ 7] += c; t[ 6] = t[ 6] & 0xfffffff; + c = t[ 7] >> 28; t[ 8] += c; t[ 7] = t[ 7] & 0xfffffff; + c = t[ 8] >> 28; t[ 9] += c; t[ 8] = t[ 8] & 0xfffffff; + c = t[ 9] >> 28; t[10] += c; t[ 9] = t[ 9] & 0xfffffff; + c = t[10] >> 28; t[11] += c; t[10] = t[10] & 0xfffffff; + c = t[11] >> 28; t[12] += c; t[11] = t[11] & 0xfffffff; + c = t[12] >> 28; t[13] += c; t[12] = t[12] & 0xfffffff; + c = t[13] >> 28; t[14] += c; t[13] = t[13] & 0xfffffff; + c = t[14] >> 28; t[15] += c; t[14] = t[14] & 0xfffffff; + c = t[15] >> 28; t[16] += c; t[15] = t[15] & 0xfffffff; + c = t[16] >> 28; t[17] += c; t[16] = t[16] & 0xfffffff; + c = t[17] >> 28; t[18] += c; t[17] = t[17] & 0xfffffff; + c = t[18] >> 28; t[19] += c; t[18] = t[18] & 0xfffffff; + c = t[19] >> 28; t[20] += c; t[19] = t[19] & 0xfffffff; + c = t[20] >> 28; t[21] += c; t[20] = t[20] & 0xfffffff; + c = t[21] >> 28; t[22] += c; t[21] = t[21] & 0xfffffff; + c = t[22] >> 28; t[23] += c; t[22] = t[22] & 0xfffffff; + c = t[23] >> 28; t[24] += c; t[23] = t[23] & 0xfffffff; + c = t[24] >> 28; t[25] += c; t[24] = t[24] & 0xfffffff; + c = t[25] >> 28; t[26] += c; t[25] = t[25] & 0xfffffff; + c = t[26] >> 28; t[27] += c; t[26] = t[26] & 0xfffffff; + c = t[27] >> 28; t[28] += c; t[27] = t[27] & 0xfffffff; + c = t[28] >> 28; t[29] += c; t[28] = t[28] & 0xfffffff; + c = t[29] >> 28; t[30] += c; t[29] = t[29] & 0xfffffff; + c = t[30] >> 28; t[31] += c; t[30] = t[30] & 0xfffffff; + /* Mod top half of extra words */ + t[ 8] += (int64_t)0x129eec34 * t[24]; + t[ 9] += (int64_t)0x21cf5b54 * t[24]; + t[10] += (int64_t)0x29c2ab70 * t[24]; + t[11] += (int64_t)0x0f635c8c * t[24]; + t[12] += (int64_t)0x25bf7a4c * t[24]; + t[13] += (int64_t)0x2d944a70 * t[24]; + t[14] += (int64_t)0x18eec490 * t[24]; + t[15] += (int64_t)0x20cd7704 * t[24]; + t[ 9] += (int64_t)0x129eec34 * t[25]; + t[10] += (int64_t)0x21cf5b54 * t[25]; + t[11] += (int64_t)0x29c2ab70 * t[25]; + t[12] += (int64_t)0x0f635c8c * t[25]; + t[13] += (int64_t)0x25bf7a4c * t[25]; + t[14] += (int64_t)0x2d944a70 * t[25]; + t[15] += (int64_t)0x18eec490 * t[25]; + t[16] += (int64_t)0x20cd7704 * t[25]; + t[10] += (int64_t)0x129eec34 * t[26]; + t[11] += (int64_t)0x21cf5b54 * t[26]; + t[12] += (int64_t)0x29c2ab70 * t[26]; + t[13] += (int64_t)0x0f635c8c * t[26]; + t[14] += (int64_t)0x25bf7a4c * t[26]; + t[15] += (int64_t)0x2d944a70 * t[26]; + t[16] += (int64_t)0x18eec490 * t[26]; + t[17] += (int64_t)0x20cd7704 * t[26]; + t[11] += (int64_t)0x129eec34 * t[27]; + t[12] += (int64_t)0x21cf5b54 * t[27]; + t[13] += (int64_t)0x29c2ab70 * t[27]; + t[14] += (int64_t)0x0f635c8c * t[27]; + t[15] += (int64_t)0x25bf7a4c * t[27]; + t[16] += (int64_t)0x2d944a70 * t[27]; + t[17] += (int64_t)0x18eec490 * t[27]; + t[18] += (int64_t)0x20cd7704 * t[27]; + t[12] += (int64_t)0x129eec34 * t[28]; + t[13] += (int64_t)0x21cf5b54 * t[28]; + t[14] += (int64_t)0x29c2ab70 * t[28]; + t[15] += (int64_t)0x0f635c8c * t[28]; + t[16] += (int64_t)0x25bf7a4c * t[28]; + t[17] += (int64_t)0x2d944a70 * t[28]; + t[18] += (int64_t)0x18eec490 * t[28]; + t[19] += (int64_t)0x20cd7704 * t[28]; + t[13] += (int64_t)0x129eec34 * t[29]; + t[14] += (int64_t)0x21cf5b54 * t[29]; + t[15] += (int64_t)0x29c2ab70 * t[29]; + t[16] += (int64_t)0x0f635c8c * t[29]; + t[17] += (int64_t)0x25bf7a4c * t[29]; + t[18] += (int64_t)0x2d944a70 * t[29]; + t[19] += (int64_t)0x18eec490 * t[29]; + t[20] += (int64_t)0x20cd7704 * t[29]; + t[14] += (int64_t)0x129eec34 * t[30]; + t[15] += (int64_t)0x21cf5b54 * t[30]; + t[16] += (int64_t)0x29c2ab70 * t[30]; + t[17] += (int64_t)0x0f635c8c * t[30]; + t[18] += (int64_t)0x25bf7a4c * t[30]; + t[19] += (int64_t)0x2d944a70 * t[30]; + t[20] += (int64_t)0x18eec490 * t[30]; + t[21] += (int64_t)0x20cd7704 * t[30]; + t[15] += (int64_t)0x129eec34 * t[31]; + t[16] += (int64_t)0x21cf5b54 * t[31]; + t[17] += (int64_t)0x29c2ab70 * t[31]; + t[18] += (int64_t)0x0f635c8c * t[31]; + t[19] += (int64_t)0x25bf7a4c * t[31]; + t[20] += (int64_t)0x2d944a70 * t[31]; + t[21] += (int64_t)0x18eec490 * t[31]; + t[22] += (int64_t)0x20cd7704 * t[31]; + /* Propagate carries */ + c = t[ 8] >> 28; t[ 9] += c; t[ 8] = t[ 8] & 0xfffffff; + c = t[ 9] >> 28; t[10] += c; t[ 9] = t[ 9] & 0xfffffff; + c = t[10] >> 28; t[11] += c; t[10] = t[10] & 0xfffffff; + c = t[11] >> 28; t[12] += c; t[11] = t[11] & 0xfffffff; + c = t[12] >> 28; t[13] += c; t[12] = t[12] & 0xfffffff; + c = t[13] >> 28; t[14] += c; t[13] = t[13] & 0xfffffff; + c = t[14] >> 28; t[15] += c; t[14] = t[14] & 0xfffffff; + c = t[15] >> 28; t[16] += c; t[15] = t[15] & 0xfffffff; + c = t[16] >> 28; t[17] += c; t[16] = t[16] & 0xfffffff; + c = t[17] >> 28; t[18] += c; t[17] = t[17] & 0xfffffff; + c = t[18] >> 28; t[19] += c; t[18] = t[18] & 0xfffffff; + c = t[19] >> 28; t[20] += c; t[19] = t[19] & 0xfffffff; + c = t[20] >> 28; t[21] += c; t[20] = t[20] & 0xfffffff; + c = t[21] >> 28; t[22] += c; t[21] = t[21] & 0xfffffff; + c = t[22] >> 28; t[23] += c; t[22] = t[22] & 0xfffffff; + /* Mod bottom half of extra words */ + t[ 0] += (int64_t)0x129eec34 * t[16]; + t[ 1] += (int64_t)0x21cf5b54 * t[16]; + t[ 2] += (int64_t)0x29c2ab70 * t[16]; + t[ 3] += (int64_t)0x0f635c8c * t[16]; + t[ 4] += (int64_t)0x25bf7a4c * t[16]; + t[ 5] += (int64_t)0x2d944a70 * t[16]; + t[ 6] += (int64_t)0x18eec490 * t[16]; + t[ 7] += (int64_t)0x20cd7704 * t[16]; + t[ 1] += (int64_t)0x129eec34 * t[17]; + t[ 2] += (int64_t)0x21cf5b54 * t[17]; + t[ 3] += (int64_t)0x29c2ab70 * t[17]; + t[ 4] += (int64_t)0x0f635c8c * t[17]; + t[ 5] += (int64_t)0x25bf7a4c * t[17]; + t[ 6] += (int64_t)0x2d944a70 * t[17]; + t[ 7] += (int64_t)0x18eec490 * t[17]; + t[ 8] += (int64_t)0x20cd7704 * t[17]; + t[ 2] += (int64_t)0x129eec34 * t[18]; + t[ 3] += (int64_t)0x21cf5b54 * t[18]; + t[ 4] += (int64_t)0x29c2ab70 * t[18]; + t[ 5] += (int64_t)0x0f635c8c * t[18]; + t[ 6] += (int64_t)0x25bf7a4c * t[18]; + t[ 7] += (int64_t)0x2d944a70 * t[18]; + t[ 8] += (int64_t)0x18eec490 * t[18]; + t[ 9] += (int64_t)0x20cd7704 * t[18]; + t[ 3] += (int64_t)0x129eec34 * t[19]; + t[ 4] += (int64_t)0x21cf5b54 * t[19]; + t[ 5] += (int64_t)0x29c2ab70 * t[19]; + t[ 6] += (int64_t)0x0f635c8c * t[19]; + t[ 7] += (int64_t)0x25bf7a4c * t[19]; + t[ 8] += (int64_t)0x2d944a70 * t[19]; + t[ 9] += (int64_t)0x18eec490 * t[19]; + t[10] += (int64_t)0x20cd7704 * t[19]; + t[ 4] += (int64_t)0x129eec34 * t[20]; + t[ 5] += (int64_t)0x21cf5b54 * t[20]; + t[ 6] += (int64_t)0x29c2ab70 * t[20]; + t[ 7] += (int64_t)0x0f635c8c * t[20]; + t[ 8] += (int64_t)0x25bf7a4c * t[20]; + t[ 9] += (int64_t)0x2d944a70 * t[20]; + t[10] += (int64_t)0x18eec490 * t[20]; + t[11] += (int64_t)0x20cd7704 * t[20]; + t[ 5] += (int64_t)0x129eec34 * t[21]; + t[ 6] += (int64_t)0x21cf5b54 * t[21]; + t[ 7] += (int64_t)0x29c2ab70 * t[21]; + t[ 8] += (int64_t)0x0f635c8c * t[21]; + t[ 9] += (int64_t)0x25bf7a4c * t[21]; + t[10] += (int64_t)0x2d944a70 * t[21]; + t[11] += (int64_t)0x18eec490 * t[21]; + t[12] += (int64_t)0x20cd7704 * t[21]; + t[ 6] += (int64_t)0x129eec34 * t[22]; + t[ 7] += (int64_t)0x21cf5b54 * t[22]; + t[ 8] += (int64_t)0x29c2ab70 * t[22]; + t[ 9] += (int64_t)0x0f635c8c * t[22]; + t[10] += (int64_t)0x25bf7a4c * t[22]; + t[11] += (int64_t)0x2d944a70 * t[22]; + t[12] += (int64_t)0x18eec490 * t[22]; + t[13] += (int64_t)0x20cd7704 * t[22]; + t[ 7] += (int64_t)0x129eec34 * t[23]; + t[ 8] += (int64_t)0x21cf5b54 * t[23]; + t[ 9] += (int64_t)0x29c2ab70 * t[23]; + t[10] += (int64_t)0x0f635c8c * t[23]; + t[11] += (int64_t)0x25bf7a4c * t[23]; + t[12] += (int64_t)0x2d944a70 * t[23]; + t[13] += (int64_t)0x18eec490 * t[23]; + t[14] += (int64_t)0x20cd7704 * t[23]; + /* Propagate carries */ + c = t[ 0] >> 28; t[ 1] += c; rd[ 0] = (int32_t)(t[ 0] & 0xfffffff); + c = t[ 1] >> 28; t[ 2] += c; rd[ 1] = (int32_t)(t[ 1] & 0xfffffff); + c = t[ 2] >> 28; t[ 3] += c; rd[ 2] = (int32_t)(t[ 2] & 0xfffffff); + c = t[ 3] >> 28; t[ 4] += c; rd[ 3] = (int32_t)(t[ 3] & 0xfffffff); + c = t[ 4] >> 28; t[ 5] += c; rd[ 4] = (int32_t)(t[ 4] & 0xfffffff); + c = t[ 5] >> 28; t[ 6] += c; rd[ 5] = (int32_t)(t[ 5] & 0xfffffff); + c = t[ 6] >> 28; t[ 7] += c; rd[ 6] = (int32_t)(t[ 6] & 0xfffffff); + c = t[ 7] >> 28; t[ 8] += c; rd[ 7] = (int32_t)(t[ 7] & 0xfffffff); + c = t[ 8] >> 28; t[ 9] += c; rd[ 8] = (int32_t)(t[ 8] & 0xfffffff); + c = t[ 9] >> 28; t[10] += c; rd[ 9] = (int32_t)(t[ 9] & 0xfffffff); + c = t[10] >> 28; t[11] += c; rd[10] = (int32_t)(t[10] & 0xfffffff); + c = t[11] >> 28; t[12] += c; rd[11] = (int32_t)(t[11] & 0xfffffff); + c = t[12] >> 28; t[13] += c; rd[12] = (int32_t)(t[12] & 0xfffffff); + c = t[13] >> 28; t[14] += c; rd[13] = (int32_t)(t[13] & 0xfffffff); + c = t[14] >> 28; t[15] += c; rd[14] = (int32_t)(t[14] & 0xfffffff); + rd[15] = t[15]; + /* Mod bits over 28 in last word */ + o = rd[15] >> 26; rd[15] &= 0x3ffffff; + rd[ 0] += 0x4a7bb0d * o; + rd[ 1] += 0x873d6d5 * o; + rd[ 2] += 0xa70aadc * o; + rd[ 3] += 0x3d8d723 * o; + rd[ 4] += 0x96fde93 * o; + rd[ 5] += 0xb65129c * o; + rd[ 6] += 0x63bb124 * o; + rd[ 7] += 0x8335dc1 * o; + /* Propagate carries */ + o = rd[ 0] >> 28; rd[ 1] += o; rd[ 0] = rd[ 0] & 0xfffffff; + o = rd[ 1] >> 28; rd[ 2] += o; rd[ 1] = rd[ 1] & 0xfffffff; + o = rd[ 2] >> 28; rd[ 3] += o; rd[ 2] = rd[ 2] & 0xfffffff; + o = rd[ 3] >> 28; rd[ 4] += o; rd[ 3] = rd[ 3] & 0xfffffff; + o = rd[ 4] >> 28; rd[ 5] += o; rd[ 4] = rd[ 4] & 0xfffffff; + o = rd[ 5] >> 28; rd[ 6] += o; rd[ 5] = rd[ 5] & 0xfffffff; + o = rd[ 6] >> 28; rd[ 7] += o; rd[ 6] = rd[ 6] & 0xfffffff; + o = rd[ 7] >> 28; rd[ 8] += o; rd[ 7] = rd[ 7] & 0xfffffff; + o = rd[ 8] >> 28; rd[ 9] += o; rd[ 8] = rd[ 8] & 0xfffffff; + o = rd[ 9] >> 28; rd[10] += o; rd[ 9] = rd[ 9] & 0xfffffff; + o = rd[10] >> 28; rd[11] += o; rd[10] = rd[10] & 0xfffffff; + o = rd[11] >> 28; rd[12] += o; rd[11] = rd[11] & 0xfffffff; + o = rd[12] >> 28; rd[13] += o; rd[12] = rd[12] & 0xfffffff; + o = rd[13] >> 28; rd[14] += o; rd[13] = rd[13] & 0xfffffff; + o = rd[14] >> 28; rd[15] += o; rd[14] = rd[14] & 0xfffffff; + + /* Convert to bytes */ + r[ 0] = (rd[0 ] >> 0); + r[ 1] = (rd[0 ] >> 8); + r[ 2] = (rd[0 ] >> 16); + r[ 3] = (rd[0 ] >> 24) + ((rd[1 ] >> 0) << 4); + r[ 4] = (rd[1 ] >> 4); + r[ 5] = (rd[1 ] >> 12); + r[ 6] = (rd[1 ] >> 20); + r[ 7] = (rd[2 ] >> 0); + r[ 8] = (rd[2 ] >> 8); + r[ 9] = (rd[2 ] >> 16); + r[10] = (rd[2 ] >> 24) + ((rd[3 ] >> 0) << 4); + r[11] = (rd[3 ] >> 4); + r[12] = (rd[3 ] >> 12); + r[13] = (rd[3 ] >> 20); + r[14] = (rd[4 ] >> 0); + r[15] = (rd[4 ] >> 8); + r[16] = (rd[4 ] >> 16); + r[17] = (rd[4 ] >> 24) + ((rd[5 ] >> 0) << 4); + r[18] = (rd[5 ] >> 4); + r[19] = (rd[5 ] >> 12); + r[20] = (rd[5 ] >> 20); + r[21] = (rd[6 ] >> 0); + r[22] = (rd[6 ] >> 8); + r[23] = (rd[6 ] >> 16); + r[24] = (rd[6 ] >> 24) + ((rd[7 ] >> 0) << 4); + r[25] = (rd[7 ] >> 4); + r[26] = (rd[7 ] >> 12); + r[27] = (rd[7 ] >> 20); + r[28] = (rd[8 ] >> 0); + r[29] = (rd[8 ] >> 8); + r[30] = (rd[8 ] >> 16); + r[31] = (rd[8 ] >> 24) + ((rd[9 ] >> 0) << 4); + r[32] = (rd[9 ] >> 4); + r[33] = (rd[9 ] >> 12); + r[34] = (rd[9 ] >> 20); + r[35] = (rd[10] >> 0); + r[36] = (rd[10] >> 8); + r[37] = (rd[10] >> 16); + r[38] = (rd[10] >> 24) + ((rd[11] >> 0) << 4); + r[39] = (rd[11] >> 4); + r[40] = (rd[11] >> 12); + r[41] = (rd[11] >> 20); + r[42] = (rd[12] >> 0); + r[43] = (rd[12] >> 8); + r[44] = (rd[12] >> 16); + r[45] = (rd[12] >> 24) + ((rd[13] >> 0) << 4); + r[46] = (rd[13] >> 4); + r[47] = (rd[13] >> 12); + r[48] = (rd[13] >> 20); + r[49] = (rd[14] >> 0); + r[50] = (rd[14] >> 8); + r[51] = (rd[14] >> 16); + r[52] = (rd[14] >> 24) + ((rd[15] >> 0) << 4); + r[53] = (rd[15] >> 4); + r[54] = (rd[15] >> 12); + r[55] = (rd[15] >> 20); + r[56] = 0; +} + +/* Precomputed multiples of the base point. */ +static const ge448_precomp base[58][8] = { +{ + { + { 0x70cc05e, 0x26a82bc, 0x0938e26, 0x80e18b0, 0x511433b, 0xf72ab66, + 0x412ae1a, 0xa3d3a46, 0xa6de324, 0x0f1767e, 0x4657047, 0x36da9e1, + 0x5a622bf, 0xed221d1, 0x66bed0d, 0x4f1970c }, + { 0x230fa14, 0x08795bf, 0x7c8ad98, 0x132c4ed, 0x9c4fdbd, 0x1ce67c3, + 0x73ad3ff, 0x05a0c2d, 0x7789c1e, 0xa398408, 0xa73736c, 0xc7624be, + 0x03756c9, 0x2488762, 0x16eb6bc, 0x693f467 } + }, + { + { 0x5555555, 0x5555555, 0x5555555, 0x5555555, 0x5555555, 0x5555555, + 0x5555555, 0x5555555, 0xaaaaaa9, 0xaaaaaaa, 0xaaaaaaa, 0xaaaaaaa, + 0xaaaaaaa, 0xaaaaaaa, 0xaaaaaaa, 0xaaaaaaa }, + { 0xa9386ed, 0xeafbcde, 0xda06bda, 0xb2bed1c, 0x098bbbc, 0x833a2a3, + 0x80d6565, 0x8ad8c4b, 0x7e36d72, 0x884dd7b, 0xed7a035, 0xc2b0036, + 0x6205086, 0x8db359d, 0x34ad704, 0xae05e96 } + }, + { + { 0x6ff2f8f, 0x2817328, 0xda85757, 0xb769465, 0xfd6e862, 0xf7f6271, + 0x8daa9cb, 0x4a3fcfe, 0x2ba077a, 0xda82c7e, 0x41b8b8c, 0x9433322, + 0x4316cb6, 0x6455bd6, 0xb9108af, 0x0865886 }, + { 0x88ed6fc, 0x22ac135, 0x02dafb8, 0x9a68fed, 0x7f0bffa, 0x1bdb676, + 0x8bb3a33, 0xec4e1d5, 0xce43c82, 0x56c3b9f, 0xa8d9523, 0xa6449a4, + 0xa7ad43a, 0xf706cbd, 0xbd5125c, 0xe005a8d } + }, + { + { 0x8ba7f30, 0xce42ac4, 0x9e120e2, 0xe179894, 0x8ba21ae, 0xf1515dd, + 0x301b7bd, 0x70c74cc, 0x3fda4be, 0x0891c69, 0xa09cf4e, 0x29ea255, + 0x17226f9, 0x2c1419a, 0xc6c0cce, 0x49dcbc5 }, + { 0xde51839, 0xe236f86, 0xd4f5b32, 0x44285d0, 0x472b5d4, 0x7ea1ca9, + 0x1c0d8f9, 0x7b8a5bc, 0x90dc322, 0x57d845c, 0x7c02f04, 0x1b979cb, + 0x3a5de02, 0x27164b3, 0x4accde5, 0xd49077e } + }, + { + { 0x2030034, 0xa99d109, 0x6f950d0, 0x2d8cefc, 0xc96f07b, 0x7a920c3, + 0x08bc0d5, 0x9588128, 0x6d761e8, 0x62ada75, 0xbcf7285, 0x0def80c, + 0x01eedb5, 0x0e2ba76, 0x5a48dcb, 0x7a9f933 }, + { 0x2f435eb, 0xb473147, 0xf225443, 0x5512881, 0x33c5840, 0xee59d2b, + 0x127d7a4, 0xb698017, 0x86551f7, 0xb18fced, 0xca1823a, 0x0ade260, + 0xce4fd58, 0xd3b9109, 0xa2517ed, 0xadfd751 } + }, + { + { 0xabef79c, 0x7fd7652, 0x443a878, 0x6c20a07, 0x12a7109, 0x5c1840d, + 0x876451c, 0x4a06e4a, 0xad95f65, 0x3bed0b4, 0x3fb0260, 0x25d2e67, + 0xaebd971, 0x2e00349, 0x4498b72, 0x54523e0 }, + { 0x07c7bcc, 0xea5d1da, 0x38ea98c, 0xcce7769, 0x61d2b3e, 0x80284e8, + 0x6e1ff1b, 0x48de76b, 0x9c58522, 0x7b12186, 0x2765a1a, 0xbfd053a, + 0x056c667, 0x2d743ec, 0xd8ab61c, 0x3f99b9c } + }, + { + { 0xeb5eaf7, 0xdf9567c, 0x78ac7d7, 0x110a6b4, 0x4706e0b, 0x2d33501, + 0x0b5a209, 0x0df9c7b, 0x568e684, 0xba4223d, 0x8c3719b, 0xd78af2d, + 0xa5291b6, 0x77467b9, 0x5c89bef, 0x079748e }, + { 0xdac377f, 0xe20d3fa, 0x72b5c09, 0x34e8669, 0xc40bbb7, 0xd8687a3, + 0xd2f84c9, 0x7b3946f, 0xa78f50e, 0xd00e40c, 0x17e7179, 0xb875944, + 0xcb23583, 0x9c7373b, 0xc90fd69, 0x7ddeda3 } + }, + { + { 0x153bde0, 0x2538a67, 0x406b696, 0x223aca9, 0x1ad713e, 0xf9080dc, + 0xd816a64, 0x6c4cb47, 0x5dc8b97, 0xbc28568, 0xc08e2d7, 0xd97b037, + 0x5d0e66b, 0x5b63fb4, 0x520e8a3, 0xd1f1bc5 }, + { 0xe69e09b, 0x4eb873c, 0xbc8ee45, 0x1663164, 0xba8d89f, 0x08f7003, + 0x386ad82, 0x4b98ead, 0xbd94c7b, 0xa4b93b7, 0xc6b38b3, 0x46ba408, + 0xf3574ff, 0xdae87d1, 0xe9bea9b, 0xc7564f4 } + }, +}, +{ + { + { 0x5bfac1c, 0x2e4fdb2, 0xf5f3bca, 0xf0d79aa, 0x20fb7cc, 0xe756b0d, + 0xb39609a, 0xe3696be, 0x5a5ab58, 0xa019fc3, 0x3b281dd, 0xa2b2485, + 0x61ac0a2, 0xe3e2be7, 0xeb56730, 0xf19c34f }, + { 0xa30241e, 0x2d25ce8, 0xb73d7a1, 0xf5661ea, 0xdaac9f4, 0x4611ed0, + 0x4ced72c, 0xd544234, 0xe92e985, 0xce78f52, 0x4da4aad, 0x6fe5dd4, + 0x1d363ce, 0xfcaddc6, 0xc9111bf, 0x3beb69c } + }, + { + { 0x940ebc9, 0xd2e7660, 0xb17bbe0, 0xe032018, 0x75c0575, 0xad49391, + 0x21c7f34, 0xdd0b147, 0x3e147e0, 0x52c2ba4, 0x0ee8973, 0x7dd03c6, + 0xecf2754, 0x5472e8d, 0xd6482bb, 0x17a1cd1 }, + { 0x8128b3f, 0xdd43b84, 0xea7dd25, 0xf0cae34, 0xff07df2, 0x81ca99f, + 0x92ebbdc, 0x1c89597, 0x72155e6, 0x45c7a68, 0x39ddd08, 0x907a50e, + 0xbb2d89b, 0xbe398c2, 0x1b3b536, 0x38063f9 } + }, + { + { 0xf843b23, 0x149fafb, 0xac7f22a, 0x00ab582, 0xf2f4d4c, 0xa3b981b, + 0x4341a22, 0x2ce1a65, 0x7c03b63, 0x68a4074, 0x12f2cf8, 0x63206a2, + 0x5149741, 0xc9961d3, 0xbc7099e, 0xfb85430 }, + { 0x90a9e59, 0x9c91072, 0x06de367, 0x734e94a, 0xdb99214, 0x5cf3cbe, + 0x45b1fb9, 0xc6bce32, 0xdd7be0d, 0x1a82abe, 0xede7d1c, 0xf74976a, + 0x21503bd, 0x7025b7c, 0x0d096ab, 0xf789491 } + }, + { + { 0x555a41b, 0x6bd48bb, 0x67de206, 0xfbdd0d0, 0xdd6dfd1, 0x98bc477, + 0x3e40b8a, 0x1d0693b, 0xda32ae4, 0x6e15563, 0xfcebaa2, 0x0194a20, + 0x0980a93, 0xda11615, 0x0109cec, 0x8e11920 }, + { 0xffb9726, 0x8ea0552, 0x047e44b, 0xeba50a4, 0x60ddf76, 0xc050d24, + 0xac690e0, 0xe009204, 0x9b18edc, 0x47b8639, 0xc77f23f, 0x2f5b76a, + 0x0792905, 0x4296c24, 0x06f6dc7, 0x73f6b4a } + }, + { + { 0x3b10cad, 0xb6ef9ea, 0xf7c8fce, 0x312843d, 0x8bedf86, 0x5bdcd52, + 0xf6dd823, 0x2889059, 0x08bfde0, 0x04578e9, 0x123e2e5, 0x3245df3, + 0x7ee9e3a, 0xbf461d5, 0x6f94ceb, 0xddec2d4 }, + { 0x145768f, 0x21b43b9, 0xdae962a, 0xe79a8f9, 0xcbb043f, 0xff1972b, + 0x239649b, 0xe3dcf6d, 0xc533b85, 0xed592bd, 0xdbe22d0, 0x14ff94f, + 0xf1d8e22, 0x6c4eb87, 0xd18cf6d, 0xd8d4c71 } + }, + { + { 0x8d96345, 0xcda666c, 0x836cd21, 0x9ecaa25, 0x984606e, 0x6e885bd, + 0x804f054, 0x1dd5fef, 0x6959ae4, 0x9dfff6b, 0xc9b55cc, 0x99b9cf8, + 0x62b9b80, 0xb4716b0, 0x554b128, 0x13ec87c }, + { 0x75aacc2, 0xe696d1f, 0x87fc5ff, 0xf78c993, 0x3809d42, 0x76c0947, + 0xb618fa8, 0x99ce62d, 0x2f53341, 0x35e3e02, 0x0db6c5e, 0x62fc1ac, + 0x00d8b47, 0xa1fb8e6, 0x58f0d1e, 0x0bc1070 } + }, + { + { 0x16da513, 0x1f45269, 0xf5cf341, 0x1f2fc04, 0x64d23e0, 0xae92086, + 0xda8a113, 0x4e33082, 0x1cfc085, 0x2688ec6, 0x6e5327f, 0x6f2e8de, + 0xb4e48a8, 0x2070db3, 0x3240ade, 0xd662697 }, + { 0xfbd997b, 0xa6b317f, 0x49e26bd, 0x9fa1b56, 0x8cba0f3, 0xcbf0d25, + 0x17b4745, 0x4a7791b, 0x5c9e190, 0x25f555b, 0x923ec4c, 0x7cd3940, + 0xe98f1b6, 0x16f4c6a, 0xbcd4e0f, 0x7962116 } + }, + { + { 0x02491e3, 0x8d58fa3, 0x7ab3898, 0x7cf76c6, 0x647ebc7, 0xbc2f657, + 0xd25f5a3, 0x5f4bfe0, 0xd69505d, 0x503f478, 0x3fb6645, 0x4a889fc, + 0xfa86b18, 0x33e1bc1, 0x5508dd8, 0xabb234f }, + { 0x9a05b48, 0x5348e1b, 0x64dc858, 0x57ac5f1, 0xec8a2d3, 0x21f4d38, + 0xa3a3e9d, 0x5ec6d3c, 0x560a0b8, 0xcd4062e, 0x3433f59, 0x49b74f7, + 0xcab14e3, 0xefd9d87, 0xeb964f5, 0x858ce7f } + }, +}, +{ + { + { 0xeb731b4, 0x7577254, 0x4e2397e, 0x9fff1fb, 0xc821715, 0x749b145, + 0x2e65e67, 0x40619fe, 0x2e618d8, 0x57b8281, 0x707b83e, 0x063186c, + 0x31b24a2, 0xcfc80cb, 0xac75169, 0xcca6185 }, + { 0xb255818, 0x6539f44, 0x0368bce, 0x5895da0, 0x17c7482, 0x841a309, + 0xb1a9c9e, 0x85469e1, 0xe4f7d9d, 0x05664c0, 0x7b35cc0, 0x8a06318, + 0xa0e9b0a, 0x214763a, 0x4b26ac2, 0x1bd872c } + }, + { + { 0xa93762b, 0x3578f97, 0x72d52bc, 0x434f69a, 0x22cb565, 0xddcca40, + 0xff20544, 0xa7d1e41, 0x8a66588, 0x823475d, 0x99d7baf, 0x9fc97c7, + 0x660e421, 0x15542f1, 0x843faf6, 0xa7d1f60 }, + { 0x4063ccc, 0xbbfaab5, 0xa49855a, 0x3ad9bad, 0x5bddbfe, 0xffd5f1c, + 0xae87e59, 0x0e419c2, 0xf89956b, 0xdce6ed6, 0xccd8951, 0xf047c21, + 0xa83c991, 0x6ed4a1b, 0x2d28e0a, 0x85af86e } + }, + { + { 0x9ed48a8, 0x04433c4, 0x0bc375d, 0xeffa858, 0xfa6e3b5, 0xfb0e1b2, + 0xa1aadda, 0x51483a2, 0xf8b2ea8, 0x733448d, 0xf639f0c, 0xaa0513c, + 0xa23bf84, 0x6bc61a3, 0xdc2430d, 0x3e64f68 }, + { 0xc5876b1, 0x51bf502, 0x1c0dd2a, 0x6b83375, 0x342914f, 0xe597be1, + 0xf8e632c, 0x43d5ab0, 0xd62587b, 0x2696715, 0xed34f24, 0xe87d20a, + 0xe18baf7, 0x25b7e14, 0xe22e084, 0xf5eb753 } + }, + { + { 0x24d8295, 0x51da717, 0x18d1340, 0xd478e43, 0x2cf7f66, 0xacf94f4, + 0x3760711, 0x230d7d1, 0x5abc626, 0x078a66a, 0x6b5f6da, 0xd78b0bd, + 0x96d1d0b, 0x23a9713, 0x4bd960f, 0x87623d6 }, + { 0x77db53f, 0x0841a99, 0xf4d03ee, 0x23c1a53, 0x1f95df1, 0x2f62c2e, + 0x116f4e7, 0xd1e2ec1, 0x34811a9, 0x896d2fe, 0xec8096e, 0xad65e2b, + 0xb1744a6, 0x09d36f9, 0xff5ddf7, 0x564bac7 } + }, + { + { 0xc3f77cb, 0x48b41e2, 0x0968938, 0x5227673, 0xfd9b452, 0xff1b899, + 0x2e03908, 0x67cf3bf, 0x248a6fb, 0x3731d90, 0x256598f, 0xd800a05, + 0xbdc8530, 0x347d2f2, 0x7ad08a1, 0xc72a300 }, + { 0x1d65f73, 0x5e5be74, 0x4206ead, 0x183d4ae, 0xade4013, 0xcb50c1c, + 0x3102483, 0x39db43d, 0x70d6325, 0x0eb49fa, 0xc1f02b9, 0xa18f6a2, + 0xdbf5e66, 0x3e6fe30, 0x3a82aa5, 0xac4eeb9 } + }, + { + { 0x3613d47, 0x295affd, 0xb56f343, 0x7b7e68a, 0x92b173b, 0x9806296, + 0xbad35fb, 0x937061e, 0x5c21eea, 0x2501978, 0x787a746, 0xe92721b, + 0x3651631, 0x463c46c, 0xc6f2d5a, 0x6da4b5d }, + { 0x6e6d18c, 0xcb67cc1, 0x0010588, 0x1b30d52, 0xdb1d1e8, 0x1bb6ea6, + 0xad11474, 0x9c6308a, 0x3d19b1c, 0xc316741, 0xbe4fb79, 0xf2e84d7, + 0xe050f77, 0xeccb873, 0xcc2bf86, 0xf7c8d80 } + }, + { + { 0x7ab20e5, 0x16fe2e1, 0xecf3a92, 0x274dead, 0x0972f67, 0x9f43487, + 0x4605751, 0x9a65a45, 0xb8980b2, 0x9351f07, 0x0eb08a5, 0x412962b, + 0x733f440, 0xb8c9bfd, 0x1ca250f, 0xac2cd64 }, + { 0x2ba7d26, 0x68cdd0f, 0x4e0beea, 0xd3d2a4a, 0x9f4a258, 0x50135c1, + 0xf0d02e4, 0xb475e53, 0x589283a, 0x432d8c6, 0xa0a2b6c, 0x29141bf, + 0x13704bc, 0xd7379ec, 0x52459bf, 0x831562c } + }, + { + { 0xeeec506, 0x676b366, 0x45da557, 0xdd6cad5, 0x77057d2, 0x9de39cb, + 0xdf05bf1, 0x388c5fe, 0xdfb1f03, 0x6e55650, 0x52126c9, 0xdbceffa, + 0x3a4a220, 0xe4d187b, 0xeb27020, 0xac914f9 }, + { 0xd2e5f30, 0x3f4ab98, 0xdd94451, 0x6ae97da, 0x0d80981, 0x64af695, + 0xf2aa2ce, 0x36b4b90, 0x18fcf59, 0x6adcd7a, 0xc116c81, 0x3ddfe6d, + 0x549b9e3, 0x661072b, 0xec4584d, 0xd9e3134 } + }, +}, +{ + { + { 0xa1e400c, 0x6e46707, 0x551e806, 0xcdc990b, 0x3a07724, 0xfa51251, + 0x1b3e4f5, 0x500553f, 0xef4dac3, 0x67e8b58, 0x2cb4cc7, 0x958349f, + 0x7f9143c, 0x948b4ed, 0x2b7822b, 0xe646d09 }, + { 0x2bc3c26, 0xd185dd5, 0xc837fc9, 0x34ba16e, 0x5a788b7, 0x516d4ba, + 0x56142b0, 0x72f2de7, 0xf445b3d, 0x5846f61, 0xf4631a1, 0xdaec5c9, + 0x169ea9b, 0xa10b18d, 0xaf6751b, 0x85d2998 } + }, + { + { 0x43ddf31, 0xda0cac4, 0x1860911, 0x0966e17, 0x3cba600, 0x9c3a717, + 0x571f895, 0x5781880, 0x737ac21, 0x5e2a927, 0x6c253fb, 0x8a46148, + 0x95ee626, 0xe801cf5, 0x5f84fc0, 0x271166a }, + { 0xba856bd, 0x306937f, 0xbe80a43, 0x80cb179, 0xffb5980, 0x70393b2, + 0x660fc64, 0xa8e4a1c, 0xc0d5c98, 0x5078abf, 0xfbd31ff, 0x62ba530, + 0x9e51b88, 0xda60844, 0x355ae15, 0xdb6ecb0 } + }, + { + { 0x23c5d49, 0xbcbb6ea, 0x87959bc, 0x08906ba, 0x0991665, 0x61cc088, + 0xd90d13c, 0x21d6b41, 0xd03afe9, 0x0c27ac1, 0x5cfea52, 0x159995f, + 0xbdfe220, 0x4057e20, 0xcbdf058, 0xdd1b349 }, + { 0x2e37159, 0x0cd6626, 0x3eb0d17, 0x8cea8e4, 0x5bce7f0, 0x553af08, + 0x5b6511d, 0xb94cb5f, 0x50e0330, 0x7b8d3a5, 0x57ab7e7, 0x4159110, + 0x6aa886f, 0x320820e, 0xc5b6b81, 0x130d4d6 } + }, + { + { 0xc7bb2ed, 0x2f98059, 0xa49bdfb, 0x33ebf4c, 0xb0a675b, 0x04c72a1, + 0xadb6c14, 0x94f9ea4, 0xcf728c0, 0x03376d8, 0x4c6eb6a, 0x5c059d3, + 0xeb8da48, 0x0178408, 0x2956817, 0x8bf607b }, + { 0xceb3d28, 0x7ad2822, 0x37ae653, 0xd07a403, 0xc1e46b2, 0xbc68739, + 0x9154ba9, 0x15d7cca, 0xa26617d, 0x6b97103, 0xb2e0d28, 0xa610314, + 0xfd4d363, 0x52a08ba, 0xc7dc2af, 0x80c2638 } + }, + { + { 0x3187140, 0x0cde7ef, 0x4b70acd, 0x93b92ca, 0x7a79cdc, 0x5696e50, + 0x8eaab66, 0x73cc972, 0x8f1b0c7, 0x6b8c5b6, 0x4f7e0b1, 0xb39a318, + 0x376108a, 0x72cfb0d, 0x98536a7, 0x0c53efc }, + { 0x24c2f1e, 0x03b52a8, 0x6399b78, 0x717132e, 0x349a85d, 0x31ebd25, + 0x1a200d4, 0x265ee81, 0x407d7ad, 0x0b1aad2, 0x94d2962, 0x9a9ebc8, + 0x41171d9, 0x994e6cd, 0x6c8fa83, 0x09178d8 } + }, + { + { 0xa2593a1, 0x7d1d238, 0xb38fb19, 0x863e93a, 0xe7712a9, 0xd23a4cc, + 0x27efcd5, 0x7477b13, 0x1392f6c, 0x3ba69ff, 0xf7bb5a5, 0x63e0c32, + 0x026effd, 0x20412c0, 0xef424ab, 0xd3ee8e4 }, + { 0x64e5174, 0x14c0b2d, 0xe58c47b, 0x2a611f2, 0xc1e8635, 0xaa58a06, + 0xcf17034, 0x1870c3e, 0x83f1bf3, 0xb0d5e34, 0x16c7eb3, 0xb19905c, + 0x6efa4ca, 0xbf85d62, 0x180f92b, 0xfd16b2f } + }, + { + { 0x3adcb48, 0xc0431af, 0xba90496, 0xc9a7a8d, 0x3895294, 0xd765a16, + 0x551de70, 0xb02a41a, 0x749b8a1, 0xb71b261, 0xc6f3e47, 0x0dfa89e, + 0x0f5d9ce, 0x392c0d8, 0x31aee3c, 0x43c59d8 }, + { 0x4d76f49, 0x94bfb6d, 0x27d68a5, 0xe8f5b82, 0x630fd08, 0x78ae1d9, + 0xce1bdae, 0x1379029, 0x66715dc, 0x9689da0, 0xd3278c7, 0x5d4cb24, + 0x9e84fbc, 0x77c9833, 0xea1048c, 0xc8478dc } + }, + { + { 0x770d2ba, 0xe4b8f31, 0x42ea095, 0x744f652, 0x036f138, 0xd06e090, + 0x3b078ca, 0xd3a3d5b, 0x78b8417, 0xc7ae541, 0xc738fd7, 0xad6c5d4, + 0x4676454, 0x6178984, 0x5d9a392, 0xfbf3423 }, + { 0xfff772f, 0x8e451a7, 0x5ffbead, 0x8605bb7, 0x930d59f, 0x6f75cc1, + 0x8f3f460, 0xd4f4755, 0x6700c8a, 0xefd2d79, 0x2406421, 0xceb462a, + 0x9dfe8f1, 0x8ed0f97, 0xd1d7600, 0x0280bf1 } + }, +}, +{ + { + { 0xdd9a54d, 0x761c219, 0x86a39c0, 0x1127fcb, 0x4c9bedd, 0x7d0e4f0, + 0x4d976b6, 0x27c017a, 0xda042cf, 0x800c973, 0x2593f11, 0xe7419af, + 0xae67960, 0xbd49448, 0x744fd85, 0xd3b60b7 }, + { 0x61676fe, 0x5e74ed9, 0x39af627, 0x7383ef3, 0x5e62df7, 0x34407e0, + 0x8bf3196, 0xb053461, 0x583b407, 0xd6b7184, 0x55011be, 0xe3d0685, + 0x2124b52, 0x94083d0, 0xf780aaf, 0xa908324 } + }, + { + { 0x73ec9c3, 0xb27af1a, 0x70fa725, 0xb66ad9f, 0x8cf73e4, 0x07724f5, + 0x9949358, 0xc3fcd57, 0xda0cc01, 0x06efb79, 0x10597c9, 0x1e977d2, + 0x703e8d6, 0xcd732be, 0x6d0b69e, 0x6fd29bf }, + { 0x667128e, 0xca658ac, 0xc7872b3, 0xca0036a, 0x5355837, 0xc969858, + 0x075cf1c, 0x59f3be8, 0x3809a11, 0x9f1b9b0, 0x9733871, 0x6881ced, + 0xe902a5f, 0x8cda0fb, 0x4e3871e, 0x4d8c69b } + }, + { + { 0xddee82f, 0x5c3bd07, 0x2f9723b, 0xe52dd31, 0x74f1be8, 0xcf87611, + 0x35f8657, 0xd9ecbd8, 0xfbfea17, 0x4f77393, 0xd78fe2c, 0xec9579f, + 0x0fb0450, 0x320de92, 0x95d9c47, 0xbfc9b8d }, + { 0x5e1b4c3, 0x818bd42, 0x40e2c78, 0x0e0c41c, 0xbccb0d0, 0x0f7ce9a, + 0x5ef81fb, 0xc7e9fa4, 0x73574ad, 0x2561d6f, 0xd2efb0b, 0xa2d8d99, + 0xe96cd0a, 0xcf8f316, 0x4964807, 0x088f0f1 } + }, + { + { 0x45d5a19, 0x0a84989, 0x6c2131f, 0x47ab39c, 0xf3fc35d, 0x5c02824, + 0x9ee8127, 0x3be77c8, 0xc90b80a, 0xa8491b7, 0xa28aa93, 0x5397631, + 0x6c0b344, 0x54d6e81, 0x876d0e4, 0x22878be }, + { 0x6db3bf6, 0xeecb8a4, 0x54577a3, 0x340f295, 0x9a00f85, 0xa779868, + 0x4bb9147, 0x98465d7, 0xda3c736, 0x9532d7d, 0x7504b20, 0x6d574f1, + 0xd86e435, 0x6e356f4, 0x4533887, 0x70c2e8d } + }, + { + { 0xd293980, 0xdce5a0a, 0x069010e, 0x32d7210, 0x06deaaa, 0x64af59f, + 0x59239e4, 0xd6b43c4, 0x9199c29, 0x74bf255, 0x11e1e2b, 0x3efff41, + 0xcb0f8d8, 0x1aa7b5e, 0x989e395, 0x9baa22b }, + { 0x7b33ac1, 0xf78db80, 0x54ce80a, 0x05a3b43, 0x7bc8e12, 0x371defc, + 0x1224610, 0x63305a0, 0x6d697ef, 0x028b1ae, 0x1cd8051, 0x7aba39c, + 0x28ee4b4, 0x76ed7a9, 0x7f99901, 0x31bd02a } + }, + { + { 0xf075566, 0xf9dab7a, 0xf56f18b, 0x84e29a5, 0xf64e56d, 0x3a4c45a, + 0x6a7302d, 0xcf3644a, 0x156b658, 0xfb40808, 0xf96be52, 0xf33ef9c, + 0xcaa2f08, 0xfe92038, 0xb261894, 0xcfaf2e3 }, + { 0x224ce3f, 0xf2a0dbc, 0x592eb27, 0xed05009, 0x95889d0, 0x501743f, + 0x77c95c2, 0xa88a478, 0xdd63da9, 0x86755fb, 0xc7ee828, 0x9024acf, + 0xf38113b, 0x634b020, 0x6056e64, 0x3c5aacc } + }, + { + { 0xa2ef760, 0xe03ff3a, 0xb1c3bac, 0x3b95767, 0x940d754, 0x51ce6aa, + 0x47a9a3d, 0x7cbac3f, 0x34f8d1a, 0xa864ac4, 0x80dbd47, 0x1eff3f2, + 0x7ebd5ca, 0xd8ab660, 0x05b07ed, 0xc4df5c4 }, + { 0xa4f095b, 0x3dc92df, 0x7cdbd9a, 0x5ae36a5, 0x7891e04, 0x7ff2973, + 0x0a5fe7b, 0x37c0313, 0xaa6e35e, 0x210d7b0, 0xbf200d8, 0x6edfb53, + 0x84afb85, 0x787b68d, 0x72c6de3, 0x9b5c49b } + }, + { + { 0x4010f4e, 0x5185716, 0x0536ebe, 0xe0b144b, 0x887d663, 0xacabb14, + 0xedf584f, 0xac1caed, 0xaf175a3, 0xb43fb8f, 0xf992a3c, 0x310b6d5, + 0x85178a4, 0xf2c4aa2, 0x8bd56bf, 0x69c9969 }, + { 0xa4d972e, 0x73d6372, 0x9583803, 0x3d5bb2e, 0xd891581, 0x7bf7d18, + 0x568a34a, 0xa5ce5d7, 0x1f45c81, 0x670b433, 0x1f96910, 0x97265a7, + 0xb07c1ea, 0xdb14eb3, 0xfed447c, 0xdf008ea } + }, +}, +{ + { + { 0x00c2f10, 0x0379f5a, 0xd350285, 0xb320b4f, 0x8efdd7d, 0x74e560e, + 0xf46a140, 0xf2f017e, 0x0f34624, 0x2ced1a6, 0xca08ec9, 0x7c4b4e3, + 0x5d8bc6b, 0xdffc2a1, 0x527b007, 0xcc8f3f3 }, + { 0x861fe83, 0x59f8ac4, 0xd03144c, 0x8d48d2c, 0xbfa6dce, 0xa8457d2, + 0x677c136, 0xd7ed333, 0xc228e18, 0xcb8e219, 0x16ab1e4, 0x5f70bc9, + 0x3780370, 0x2ae3a3d, 0x88f17ad, 0x9f33654 } + }, + { + { 0x960e4bb, 0xeab0710, 0xab9cfd3, 0xc668a78, 0xb0ef946, 0x2e85553, + 0x8df5df3, 0xa43c4b9, 0x3cb3646, 0x0ecd559, 0x18dbe71, 0x6f543c4, + 0xf59818b, 0xee7edaa, 0x90911c1, 0xc44e8d2 }, + { 0x269b509, 0xafb38b1, 0x52afe2c, 0x9e2737c, 0xccfa664, 0x5b2ef02, + 0xe1cc58b, 0x1e0aeac, 0x5ea134e, 0x37a57e9, 0x83b9fc2, 0xc9c465a, + 0x6e3ecca, 0x4b9e8c7, 0x9bdbab5, 0xca07dbe } + }, + { + { 0xb0d7807, 0xd297f3c, 0xf59ce61, 0xee441a5, 0xb2db844, 0x728553b, + 0x640e9e0, 0x90f87e5, 0xcb76dff, 0xaa72cbf, 0x4012d57, 0x065c686, + 0x9678b44, 0xd5ee88f, 0x2177603, 0x3d74b85 }, + { 0x748b68e, 0x3f9c947, 0x8f44d44, 0x03856d9, 0x462426c, 0xde34b84, + 0x845ab29, 0xc16d1bb, 0xd2e18de, 0x9df6217, 0xb154643, 0xec6d219, + 0x2ee0f8f, 0x22a8ec3, 0x91c5175, 0x632ad38 } + }, + { + { 0x6869267, 0x19d9d23, 0xfe5532a, 0x628df94, 0x6dc9a01, 0x458d76c, + 0x2cc39c8, 0x405fe6c, 0xf3a04ba, 0x7dddc67, 0x12500c7, 0xfee6303, + 0xa50e9de, 0x580b6f0, 0x6090604, 0xfb5918a }, + { 0x3af6b2d, 0xd715925, 0x1c7d1ec, 0x83d62d6, 0x85858c4, 0x94398c1, + 0x14bfb64, 0x94643dc, 0xaf7db80, 0x758fa38, 0xa8a1557, 0xe2d7d93, + 0x3562af1, 0xa569e85, 0x84346aa, 0xd226bdd } + }, + { + { 0xd0ccd20, 0xc2d0a5e, 0x5dbc0cf, 0xeb9adb8, 0x26d7e88, 0xe0a29ee, + 0x84a8e98, 0x8bb39f8, 0x37396ea, 0x511f1c1, 0xc8b2fb3, 0xbc9ec5a, + 0x090e5bc, 0x299d81c, 0x4cdd587, 0xe1dfe34 }, + { 0x5e465b7, 0x80f61f4, 0x1bad59e, 0x5699c53, 0xb79ff92, 0x85e92e4, + 0x9db244c, 0x1e64fce, 0xa22097d, 0x3748574, 0xefff24e, 0xe2aa6b9, + 0x0a10bc6, 0xb951be7, 0x9067a1c, 0x6685326 } + }, + { + { 0xa6114d3, 0xf716ddf, 0x037ec1f, 0x9e515f5, 0x44944a6, 0x7734541, + 0xaba97cc, 0x1540c4c, 0x8b54bb7, 0xe41e548, 0xcae37bc, 0x4363156, + 0xf3d2ce8, 0xc384eaf, 0x4c58ba4, 0x72a4f45 }, + { 0xdcaf3fc, 0x0ceb530, 0x78dcdbb, 0x72d5365, 0xc6320fa, 0x9b44084, + 0xeb74c70, 0x6262d34, 0x608e6dc, 0x8abac85, 0x10dd38d, 0x82a5264, + 0xa819b8d, 0xbc39911, 0x03ad0d9, 0xbda15fe } + }, + { + { 0xf9dc60b, 0xadbf587, 0x7d846d2, 0xf9d814f, 0xb77bde0, 0xccdd241, + 0x2242f50, 0x89cb6d7, 0xe6360a8, 0x95c0e3e, 0xdf49713, 0x7c7dd5a, + 0x57d5814, 0x68e0e49, 0x0c16571, 0x3aa097d }, + { 0x267d03a, 0xb56b672, 0x8c44af4, 0x4f55708, 0xf3252a5, 0x67c49e7, + 0xc94a469, 0x871d6cf, 0x01fbfaa, 0x57ae998, 0x48a5d8e, 0x5c0e48f, + 0x5e240b9, 0xe9bf9c8, 0x99d41ca, 0xa410189 } + }, + { + { 0xb2889b4, 0x6beb0c7, 0x9455370, 0x78b7f89, 0x47ca364, 0xd434214, + 0x9f21e5b, 0xdd9d2da, 0x0a7e4aa, 0xa0c7c18, 0xda1660c, 0x022c0d4, + 0x5a57002, 0xe1f5c16, 0x518f68f, 0x51c7c9e }, + { 0x2586502, 0x6d521b6, 0x183ec1b, 0xa0f2cb3, 0xcaa5e16, 0x578b4e0, + 0x764997f, 0x7bd4fbd, 0x64b1804, 0x7ec56c3, 0x0ee08e4, 0xb75a254, + 0xdc19080, 0x6bf74a6, 0x97d6e59, 0x6ec793d } + }, +}, +{ + { + { 0x0a4beb9, 0x16789d6, 0x9b9c801, 0x512b2cd, 0x8c7bb9c, 0xf8b6d10, + 0x9ebdc8c, 0xd85651e, 0x9ba971a, 0xc945082, 0x7e1cf78, 0x852d9ea, + 0x0af01e2, 0x6a45e35, 0x6151dcf, 0xe6cdadf }, + { 0x2b8c01b, 0xc454bb4, 0x3d54cd2, 0x59e0c49, 0x454d608, 0x8e1e686, + 0xd8c6103, 0x0dbae4b, 0x6c18b18, 0xa5603a1, 0x3369093, 0x227a6b2, + 0x5f3de1c, 0xf1e8929, 0x8ab63c5, 0x42f0b58 } + }, + { + { 0x5b596d8, 0xf1974cc, 0x44719f0, 0xee8093f, 0xf6f5b54, 0x40ba933, + 0x2f3d654, 0xd6e5365, 0x26d73b8, 0x9aeb835, 0x0776382, 0x50ed535, + 0xad43875, 0x3be47d6, 0xc786e48, 0x21d56df }, + { 0xb73bb39, 0x8a75e18, 0xf265a78, 0x9eba84c, 0x2e772e7, 0x7c02a4d, + 0x4c1ecd2, 0xf7df6d4, 0x6cef71b, 0xa8d9ea0, 0xcae3b68, 0x86e8f91, + 0x99efefa, 0x2fd1411, 0x214e6f6, 0x0b36ab2 } + }, + { + { 0xbdce61c, 0xd79065c, 0xdecb229, 0xcb562ff, 0x4600849, 0xef5d3d1, + 0x1d23ac8, 0x348b31b, 0x15c36b8, 0xb2ea699, 0x4822836, 0x268683d, + 0xc6f0b7d, 0x083edbe, 0x1a7821c, 0xaf4f39d }, + { 0x4e64841, 0x23be6e8, 0x65bf791, 0xe9e2463, 0x02bfd7c, 0xa3208ac, + 0xd01357d, 0x231989c, 0x6422ab4, 0x79b8aad, 0x91b8564, 0x57d2b7e, + 0x8c04421, 0x28ebbcc, 0x7d09c05, 0xdc787d8 } + }, + { + { 0x6c7bed5, 0xeb99f62, 0x39cd0e8, 0x326b15f, 0xd860615, 0xd9d53dc, + 0x1bf4205, 0xdf636e7, 0x0752209, 0x1eaa0bf, 0x4744abb, 0x17ce69a, + 0xf3ea2fb, 0x474572d, 0x224a7f3, 0xc4f6f73 }, + { 0x63081b4, 0x7ed86ad, 0x4a20afb, 0xcd4cdc7, 0xb301b2e, 0x7563831, + 0xe038699, 0x5b4d2b1, 0x802a15f, 0xa15d1fa, 0x13e9172, 0x6687aaf, + 0xba6da90, 0x3eccd36, 0x7474e83, 0x34e829d } + }, + { + { 0x19c9b27, 0x4cea19b, 0x5f52523, 0xa14c37a, 0x726625c, 0x248b16d, + 0x6cabc21, 0x8c40f9f, 0x32a5c65, 0x918470c, 0x2a98d5b, 0x314056b, + 0x34a0714, 0x6c974cf, 0x4f6314a, 0x0c8f8a9 }, + { 0x70bccfd, 0x4844557, 0x740c9fd, 0xf5835db, 0xa21407c, 0x12e59b5, + 0xdb1689d, 0xbe338e0, 0xdd5e915, 0x5a50ce9, 0xef99f39, 0xb1780e9, + 0xee4d833, 0x1262b55, 0x89c5340, 0x4be3f22 } + }, + { + { 0x6c4b858, 0xbb99b90, 0x550ca53, 0xa7724d1, 0x826962e, 0x7d31f5a, + 0xa5804da, 0xf239322, 0x0275048, 0x3e11320, 0x3ee4cb6, 0xcbb1bb8, + 0x1331191, 0xdb86525, 0x7d1d903, 0xb7caf9e }, + { 0x77d7a9d, 0x06e3b05, 0xb3bbbf5, 0x7a132b0, 0x7c50575, 0xd61fbc5, + 0xaf4b646, 0x393f712, 0xcb7efe9, 0xef77972, 0x5ea4995, 0x20e6d5d, + 0xfbbe4c6, 0x0ac23d4, 0xc807f2a, 0x8456617 } + }, + { + { 0x5396143, 0x4995fb3, 0xb99dc46, 0xa8b4bd1, 0x4150064, 0x2293e8e, + 0x22a3545, 0x2f77d49, 0xb2192c4, 0xe866b03, 0x5e0aa38, 0x58b01f0, + 0x2ed246b, 0xe406b23, 0xed60974, 0x447edb3 }, + { 0x8869703, 0xf541b33, 0x383420a, 0x6959fe0, 0x4be4e48, 0xd6b39db, + 0xb5714ef, 0x048f3b4, 0x5d9e4b8, 0x68b4968, 0x2177963, 0xbda8e6c, + 0xc4211fe, 0x5094e35, 0x2d46d1a, 0xea591c3 } + }, + { + { 0x2fef780, 0x3a768ff, 0x32970c6, 0x4218d28, 0xec6da17, 0xce598e4, + 0xfbb126a, 0xf675645, 0x0427617, 0xb04c23f, 0xe4fce74, 0xc9f93fb, + 0x3c91b00, 0x44a414b, 0x1d3b3cc, 0x4d982f3 }, + { 0xb24cce0, 0xb1d40e8, 0x133e73d, 0x5a21c07, 0x0bb589d, 0x6e9358e, + 0x2399844, 0x39cfb17, 0x166080e, 0x83f7647, 0x450b468, 0xcfe7bf8, + 0x1e8434f, 0x2a288f7, 0x21a81e3, 0xd39f1e5 } + }, +}, +{ + { + { 0x528af6f, 0x78c6f13, 0x94b74d9, 0x0001fe2, 0x01aab44, 0xae77425, + 0xef0039c, 0x7cbe937, 0x0fa2a67, 0xaf3e4f0, 0xda1378e, 0xe28175f, + 0x8ccd90e, 0x72adeed, 0x00af22f, 0x16a8ce1 }, + { 0xcbf63dd, 0x69fae17, 0x9e39e26, 0x6786172, 0xf827a18, 0xe92b3d5, + 0x8403682, 0x4d75e41, 0x9056a79, 0x01a4fd9, 0x20008f5, 0x89efb2d, + 0xb78ff15, 0xa2f6918, 0xa3437f5, 0xf41c870 } + }, + { + { 0x7be353c, 0xc840ae5, 0x3fb2691, 0x465a5eb, 0x7eba833, 0x34a89f0, + 0x013346e, 0xf620896, 0xe875df2, 0x563b5f0, 0xfbc44ce, 0x5f7fc8b, + 0xcfedf9d, 0x22fcb5a, 0x7dc691b, 0x7cf68d4 }, + { 0x76a103f, 0x37f7c2d, 0xfd87b7d, 0x728a128, 0xccf2132, 0x7db2ad8, + 0xb100e63, 0xa4c13fe, 0x7b511d5, 0xcd28a51, 0x721ca5c, 0xb910280, + 0xd84bd52, 0xec1305f, 0x2729791, 0xb964642 } + }, + { + { 0x5bc7462, 0x83fccdf, 0xd6f012f, 0x01f3dda, 0x3a6a87c, 0x57f1171, + 0xff403ac, 0xedb47ce, 0xbaab073, 0x6c184e5, 0x6f0d6a1, 0x5b17c7d, + 0x3ef2c91, 0x45a4c4f, 0x86a8f41, 0x26c3f7e }, + { 0xb646514, 0x81a6db0, 0xca8b9ae, 0xf84059f, 0x9f02305, 0xd73dab6, + 0xc4b7c6c, 0x0de3fae, 0x696df2f, 0x18abb88, 0x75d7740, 0x45dd1b9, + 0x9ee35bc, 0x3aeccc6, 0xb029f88, 0x478252e } + }, + { + { 0x8b2ce15, 0x66bf85b, 0x335709d, 0x1175425, 0x8123874, 0x00169ef, + 0x9b89868, 0xfd3c18c, 0x775204e, 0xb3612f9, 0xc2cd510, 0x4b8d09d, + 0x14559ad, 0xafa12e6, 0x9657493, 0x1ddaa88 }, + { 0x1e77a08, 0x87d700b, 0x14d2e71, 0xaf4cf2f, 0xbf90c94, 0xe00835d, + 0x6dc8429, 0xb16a6ec, 0xf8a4d92, 0x02a7210, 0x3d0c48d, 0x5a5ab40, + 0xb5b9bea, 0x0052b3a, 0xe138f89, 0x6242739 } + }, + { + { 0x16b2819, 0x7c215d3, 0xfeb9d7a, 0xdacb65e, 0xd833423, 0xc3c569e, + 0x886a058, 0xbc08435, 0x7e5cb61, 0x132c4db, 0x9422aff, 0x6373a27, + 0xfca9fc4, 0x43b9d7e, 0xdbe465f, 0xe3319a5 }, + { 0x0b39da7, 0x51d3687, 0x4b75492, 0xcb6d798, 0xeadd87a, 0x77eb272, + 0xe0d3f6c, 0xf2fb47d, 0xf9f791c, 0x807fd86, 0x975e885, 0xf01086b, + 0xb6a3604, 0xf9314b5, 0x67be852, 0x8cd4538 } + }, + { + { 0x858f79b, 0x7c1e6b3, 0x938caf9, 0xf0477c4, 0x3e88c44, 0xb311bbf, + 0x1e3a3c1, 0x9234c09, 0x95a1d4d, 0x531af2b, 0xb8d1c64, 0xf3cc969, + 0xb51e78d, 0x6f3c328, 0x34e8881, 0x5a1bd6c }, + { 0x3a9336f, 0x2e31239, 0x5ced897, 0x020f0cc, 0x5fab121, 0x4b45d7b, + 0x1841210, 0x8068b1c, 0x8349170, 0x1bd85fc, 0x0f97fe5, 0xfe816d8, + 0x14b84fc, 0x1089818, 0xb93cd48, 0x1d4fabb } + }, + { + { 0xaef599e, 0x1f11d45, 0xb09c58a, 0x8d91243, 0xd08c3c3, 0xd2eec7b, + 0x3b02793, 0x5a6039b, 0x8fb2c00, 0xb27fed5, 0xe8acf5e, 0xb5de44d, + 0x6e6c698, 0x2c3e0cd, 0x777180d, 0x2f96ed4 }, + { 0x96d0e36, 0x67de8bf, 0xc9b6d65, 0xd36a2b6, 0x637d59c, 0x8df5d37, + 0xc8d9878, 0x951899f, 0xb13fcf8, 0x0fa090d, 0x1f5c7b4, 0xa527081, + 0x513a37a, 0x56a6560, 0x14dc1fe, 0xc6f5530 } + }, + { + { 0x94945d6, 0x7f6def7, 0x8cc8832, 0x2f52fe3, 0xa812ff5, 0x0228ad9, + 0xbb8478a, 0xcd282e5, 0xbe91b07, 0xa0bc9af, 0x11165e2, 0x0360cdc, + 0x7b857e4, 0xb5240fd, 0xfa36b08, 0x67f1665 }, + { 0xad2c93f, 0x84ce588, 0xe8ff4c0, 0x94db722, 0x489c8a3, 0xad2edbb, + 0x7e5f278, 0x6b2d5b8, 0xd1d0798, 0x0265e58, 0x4c5589e, 0xd2c9f26, + 0x4e4074d, 0xde81f09, 0x303089f, 0xc539595 } + }, +}, +{ + { + { 0x83e882c, 0x183492f, 0xb5e6c12, 0x4d58203, 0xefec20b, 0x1ac96c3, + 0xe1cd15e, 0xabd5a5b, 0xcbbb14b, 0x7e1e242, 0xd0543b3, 0x9f03f45, + 0xd678158, 0xc94bc47, 0xa446cad, 0x7917be0 }, + { 0x9b37394, 0x53f2be2, 0x064cc76, 0x0cb0a6c, 0xfba3da3, 0x3a857bc, + 0x80fcb49, 0xac86bc5, 0x30ab146, 0x9d5336e, 0x5bc1270, 0xafb093d, + 0xe5c3b6e, 0x996689d, 0xea076ba, 0x55189fa } + }, + { + { 0x646ce03, 0x99ef986, 0x30e6100, 0xa155f81, 0x29b6b07, 0x75bef17, + 0x1de077b, 0xc46f08e, 0x7ed0526, 0xf52fdc5, 0x61a299a, 0xe09d989, + 0x7b8e93a, 0x9527329, 0x0acd185, 0x11255b5 }, + { 0x4a6acdd, 0x57919db, 0x4451d74, 0x708a578, 0x283f7b3, 0x5b0bd01, + 0xc3d9260, 0xe82f40c, 0x82bbdc2, 0x2ab96ec, 0xc164d87, 0x921f680, + 0xc17a6a9, 0xf0f7883, 0x382a001, 0xc366478 } + }, + { + { 0x2e40791, 0x5c9aa07, 0xa0776bf, 0xf0b72d6, 0xeaa50dc, 0x445f9b2, + 0x6bda47f, 0xa929fa9, 0x3bbfc49, 0x539dc71, 0x006a78b, 0x4f16dd0, + 0xeef39c7, 0x331ba3d, 0xc34157c, 0xbfa0a24 }, + { 0x6a3b482, 0x0220beb, 0x6c43885, 0x3164d4d, 0xacdea23, 0xa03bb5d, + 0x9d8f450, 0xd6b8b5a, 0xbd208fe, 0xd218e65, 0x35c476f, 0x43948ed, + 0x0a2ed2b, 0x29a0dd8, 0x25295b7, 0xa6ccf33 } + }, + { + { 0xac38939, 0xf68f15f, 0xf8010c1, 0xb3dd5a2, 0xa35f141, 0xf7ac290, + 0x7388574, 0xdc8f3b2, 0xe95fed2, 0x7ec3de1, 0x257ac7d, 0xc625451, + 0x664e55a, 0x66fc33e, 0x4832ba5, 0xd3968d3 }, + { 0xc026448, 0x980291b, 0x24da4a5, 0xfcb2125, 0x827a360, 0xbca7df4, + 0x85ca63b, 0xfcc395c, 0x8e9f733, 0xcf566ec, 0xd465f70, 0x835ee9b, + 0x372f916, 0xe66d111, 0x04d9211, 0xc066cf9 } + }, + { + { 0x8b48818, 0xb9763a3, 0x4288f96, 0xa6d23cc, 0xed3a229, 0xe27fcf5, + 0xabaff00, 0x6aebf9c, 0x8131cd1, 0xf337503, 0xffabd58, 0x13ad41d, + 0x861c83b, 0x1bee6af, 0x9c142e7, 0x274fe96 }, + { 0x9b84b5b, 0x70ebcc9, 0x8191cfc, 0xe1a57d7, 0xcbf00b8, 0x46ccd06, + 0xefe402d, 0xc233e8e, 0xbeebeb3, 0xb4ab215, 0xbd14e7b, 0xb7424ea, + 0xa679578, 0x351259a, 0x471d684, 0x6d6d01e } + }, + { + { 0x815ae38, 0x755c465, 0x611db56, 0xadc3e85, 0x188dd50, 0x633999b, + 0xc12d907, 0xfdf7509, 0x238b6af, 0x25bcfde, 0x397f5e7, 0x50d705d, + 0x944c974, 0xb65f60b, 0x27ac325, 0x8867fc3 }, + { 0x3763eff, 0x2edc441, 0x341fb63, 0x892c0b3, 0xb3a7f28, 0xb34b83a, + 0x15c2f18, 0x9aa106d, 0x1bb2277, 0x720bbc6, 0x5cfaefd, 0x637f72a, + 0xf43e565, 0xf57db6e, 0xb58e772, 0xceb7c67 } + }, + { + { 0x6ecc1de, 0x2793da5, 0x38f31b2, 0x4e10974, 0x8781267, 0x4229b4f, + 0xdec04a1, 0xe5d2272, 0xec17cff, 0x6abb463, 0x0cbb048, 0x28aaa7e, + 0xd22ef85, 0x41dc081, 0x5e63d0f, 0xcbc361e }, + { 0xad5dbaa, 0xb78aafc, 0xfc1edc3, 0x0111505, 0x92c7bfa, 0x63ed66d, + 0xe468919, 0x2982284, 0xb8c0d8c, 0x30f1f21, 0x2685093, 0xf056747, + 0xf03dd0f, 0x0e085b6, 0x5581e66, 0xa8c8db8 } + }, + { + { 0x264ad0c, 0x42009a6, 0x593bef4, 0x13bf2b8, 0x5d4e8b1, 0x1d11190, + 0xef7bddc, 0xfe3e940, 0x624e62c, 0xa012275, 0x1d6d3cc, 0xcb65924, + 0xedb7ab6, 0xc7bcc70, 0xb750b1c, 0xff9fafb }, + { 0x7fea84b, 0xf65df29, 0x90b0e02, 0x17c84a8, 0x301e821, 0xa92a859, + 0xfb480d1, 0xbee8cb2, 0x59c604e, 0x7010b8c, 0xe803c43, 0x47bf3f4, + 0x47b3fff, 0xd645142, 0x9f0da13, 0xc4c5dcb } + }, +}, +{ + { + { 0xb5253b3, 0x8af700c, 0x206957a, 0x31ca605, 0x3eafdcd, 0x2574439, + 0xd3ae15e, 0x2ba5ae1, 0x5b82579, 0x710b738, 0x112b95a, 0x145ab57, + 0x38c55c5, 0x4b133a0, 0x2a16fef, 0xf7559c9 }, + { 0xd9ba896, 0x70c3e68, 0xc33d07a, 0x475dd32, 0x3a41e40, 0xe084e47, + 0xfd2e706, 0xddc9382, 0x79510bd, 0x34b7275, 0xa5f901e, 0x5e78a69, + 0xdcfb823, 0x429dfd7, 0x014f0a3, 0x1d9dc18 } + }, + { + { 0xaf403d7, 0x364fcdf, 0xb7d7b34, 0xd9ea4ff, 0xcbb1dac, 0x21a3426, + 0x143b4f5, 0xfa51052, 0x6df2409, 0x2bca073, 0x8ad7285, 0x7e6985a, + 0x4aaa27f, 0x3a1a9d0, 0x9fc0c6c, 0x1a815e1 }, + { 0xbb65bb3, 0xfab6147, 0x33ced0b, 0xa36dc0d, 0x2062d78, 0x26a8859, + 0x28a5fb7, 0x3438617, 0x4ebb1ad, 0xe82da25, 0xd05aa11, 0x70f5071, + 0xadaac48, 0x0b7f847, 0x93cb269, 0xeb812bc } + }, + { + { 0xf7caccc, 0xcb317cc, 0xcf85098, 0xd3410d9, 0x7f078d7, 0xca68c8d, + 0xb782efc, 0xfe9e812, 0x5f544b5, 0x32e7c0f, 0x3a7b7f2, 0x44fe95a, + 0xe91327b, 0xf4f1543, 0x76645ed, 0x27d118d }, + { 0xd7abc2c, 0x690547c, 0xb53c8af, 0xf64680f, 0x79ea989, 0xbe0cbe0, + 0xa91af28, 0x6cf0cce, 0x9daa2f9, 0xa3b85a2, 0x91faed0, 0xd4b663c, + 0xa8b20ba, 0x782c7b7, 0xb8d98ce, 0xf494faf } + }, + { + { 0x002f55a, 0x080c0d7, 0x2d6d9dd, 0xf4f8f14, 0x382f025, 0xb326229, + 0xad28c20, 0x58fd0b5, 0x8d06a15, 0x704b992, 0x7fbd8e4, 0xf4545d9, + 0xed55581, 0xc32fa63, 0x01ac0fd, 0x3ab7936 }, + { 0x6099fd1, 0x13ece52, 0x9c79178, 0x776dba8, 0xce26c45, 0x8d28212, + 0x60d739c, 0x09fddaf, 0xa84826e, 0xf9931ed, 0xb29439e, 0x6e73d90, + 0x9095e61, 0x94cfefc, 0x802f474, 0x3050d16 } + }, + { + { 0x9f6394b, 0x0898f8f, 0x88b0e91, 0x48b8cea, 0x4c1b362, 0x4bc9925, + 0x827d9ec, 0xe3fccb4, 0xd950d6a, 0x5d4cf9a, 0x39b5b38, 0xa16f1ef, + 0x620f288, 0x3c76d1d, 0xe119390, 0x9fdd059 }, + { 0xfb5edf8, 0x7b5de9e, 0x769d14e, 0x3e290b9, 0x6bd10b5, 0x4df3a91, + 0x82f8f7b, 0xae99bca, 0xc9524af, 0x5481d5d, 0x69504f1, 0xf112e4f, + 0x51931ec, 0xb048f09, 0x18f51b1, 0xbff876a } + }, + { + { 0x46c1c37, 0x932e2a7, 0x9aea4c1, 0x903ad52, 0x8f161f2, 0x717ac91, + 0xf425e2a, 0xa57d197, 0x7f39e0e, 0xae89dac, 0xbaa2a58, 0x91655c0, + 0x54836dd, 0xe3dc286, 0xa9ec9e6, 0xb5f0baa }, + { 0xbdbda04, 0xf7c4662, 0x51059c0, 0xbe5393b, 0xdd95b0f, 0xb16d552, + 0x1b3bd96, 0xde495b3, 0xc0206c5, 0xb2a6e02, 0x014d3a9, 0x045cc09, + 0x2a2f490, 0xf66a315, 0xc5dea05, 0x208c108 } + }, + { + { 0x65237ea, 0x6e38b68, 0x9f27fc6, 0x93a1303, 0xa95068a, 0x9a6d510, + 0xe7c9e54, 0x6fbf216, 0x571ac1d, 0x7824290, 0x91c2a0c, 0x8cb23ba, + 0xc7e434d, 0x611202e, 0x76058b4, 0x8f901bf }, + { 0x0849588, 0xef0ac05, 0xdd31804, 0xe0d2dde, 0xeb2ca81, 0xaf5417c, + 0x5d1a509, 0x420ac06, 0x9683bb6, 0x46e345e, 0xf613f7f, 0x6daf635, + 0x48a9576, 0xc9e8291, 0x176d147, 0x5f9f1d1 } + }, + { + { 0x77e9709, 0xd24ae1d, 0x0047b8a, 0x77751dc, 0xc6a1593, 0xe325334, + 0x671f86a, 0x9baf962, 0xc29a15e, 0x425af6a, 0x2796e33, 0x3108600, + 0xfc253a5, 0xb6ea78c, 0xafae0ea, 0x4c733e0 }, + { 0x97c99b9, 0x4b7443a, 0x50203a6, 0xc14e9e4, 0x52680ba, 0xd1bb515, + 0xd55533a, 0xa56a3ef, 0x169e1a0, 0xa66e38c, 0xeed7da0, 0xb3e4df9, + 0xddce3d9, 0x022c937, 0xf6e36b4, 0x8552089 } + }, +}, +{ + { + { 0xf5cc82e, 0x8e4bf95, 0xc3ed6c9, 0x2ad80c3, 0xc9045e1, 0xf2e5b2c, + 0x59b06d4, 0x42c9065, 0x7b43b84, 0xc1f7379, 0x72d7992, 0x1710dbf, + 0x767b41c, 0xe98cf47, 0x7bfb9e9, 0xe713fce }, + { 0x9fa5134, 0x9f54ae9, 0xde40d0e, 0x3002fd8, 0x9311334, 0xdc282b7, + 0xbfeb360, 0x5519810, 0x0f96ffe, 0x31539c7, 0xd27777b, 0x04eacc0, + 0x8ff5053, 0x5982410, 0x32b67ad, 0x5982366 } + }, + { + { 0x6bea5c2, 0x6eb4554, 0xd509a33, 0x82cfae0, 0x394bb59, 0x6a69bd8, + 0x5770ee1, 0x1880d8d, 0x7dacf9e, 0x6351844, 0xf02b891, 0x5b1ecc5, + 0xb6c9a5a, 0xeb7d900, 0x8897da8, 0xdab8a76 }, + { 0x98851a6, 0x28c7be5, 0x4d73c3b, 0x0101d4f, 0x5084996, 0x3c2569c, + 0x280bde0, 0xb9bc911, 0xcd0d4f9, 0x513a22a, 0x2a15f3b, 0xdf2986d, + 0x2aa4943, 0x231c28f, 0x0333870, 0x29623ad } + }, + { + { 0x4084416, 0x2ceb178, 0x49516cd, 0x924cf1c, 0x4be856f, 0x76536c0, + 0x47a265b, 0x11b59cd, 0x4999494, 0x720dc84, 0x007b795, 0x910f794, + 0x2d3df83, 0x8434e14, 0xbd478d3, 0x8f53878 }, + { 0xaeb9c2f, 0xd9b072e, 0xfd8a29f, 0x16f87ea, 0x2fd0de1, 0x8c42f9b, + 0x0e816ef, 0x916721e, 0x18bde37, 0x2ecb470, 0x2375da2, 0xcde3b7a, + 0xef94281, 0x30d0657, 0x5cd7af8, 0x5105456 } + }, + { + { 0x4bdced3, 0x7230b33, 0x0838569, 0x0c6a3e1, 0xe3493b8, 0xf19c9ec, + 0x0d97c57, 0xf275927, 0x0c862eb, 0xf14181e, 0x32c72bc, 0xfd3bac1, + 0xf3be362, 0x620563f, 0x47283b7, 0x672ccaf }, + { 0x2b7bf16, 0x191e3fa, 0x520dad7, 0xf838633, 0x3629d87, 0xd3dde55, + 0xaf86ebe, 0x14d8836, 0x221b2ce, 0x3db7dfb, 0x0aed72a, 0x3872abb, + 0x8c665b7, 0xb60de52, 0x44982cb, 0x89c2596 } + }, + { + { 0x4dbba25, 0x799a2de, 0xa42715e, 0xd818aae, 0xf55c362, 0xbc88f4d, + 0x713c9ae, 0x142a163, 0xfbfb33f, 0x411e8ee, 0x6bb684a, 0x34b4629, + 0xdc81817, 0x4344bec, 0x17f9d46, 0xcc9573d }, + { 0xff38a7d, 0xf85f8bc, 0x0caf117, 0xa14bf73, 0x4ba6429, 0x126874f, + 0xaa5db97, 0xcc9bf22, 0x6aba827, 0x62b56df, 0x9c9772a, 0xfee1cb8, + 0x177e541, 0xe36838f, 0xadd438f, 0x698815d } + }, + { + { 0x38ed1ad, 0xc9fd894, 0x7b6a601, 0x73cd79d, 0x05e8d20, 0x2210e62, + 0x3592af5, 0x72384ac, 0x763d07e, 0x5ccc079, 0xa5f79eb, 0x2f31a4a, + 0x2945a95, 0x693f4ed, 0x8056fdc, 0xc712017 }, + { 0xdf4b09a, 0x361ecd2, 0xb7d929a, 0xa5644ea, 0x3fabe9a, 0x34abc0b, + 0xe942a8c, 0x1a2473c, 0x6454bc3, 0xe00c924, 0xdff7366, 0xab324bc, + 0x21b8f99, 0xe1412f1, 0xe33551e, 0x970b572 } + }, + { + { 0xbd0a6b5, 0x6ca4cac, 0x921d654, 0x5584787, 0xc809bda, 0x18e5253, + 0xf0cbe5e, 0x01b32c3, 0x0f987dd, 0xb9aa754, 0x6dfa4db, 0x628f4bb, + 0x891890b, 0x0255f0b, 0x874e590, 0x25b7df4 }, + { 0x8ed5f95, 0xbded318, 0xca93023, 0x9dc428d, 0xbccf520, 0xc68f25a, + 0xe616e6c, 0xc4f3764, 0xa1d9993, 0xd9a57f1, 0x533431b, 0xd1964a5, + 0x02ab6d0, 0x06cd77f, 0x03e52e0, 0xa660791 } + }, + { + { 0x5f72700, 0xab08864, 0x0a1a44e, 0xf77b2ff, 0xc2a24b5, 0x43ebdd8, + 0x4f564d7, 0xa6d6711, 0xf414160, 0x495df63, 0x76f6de6, 0xf5bacd7, + 0x7c2b43d, 0x3011aff, 0x3241928, 0xbb1e64c }, + { 0x5034073, 0xf70c572, 0x68f1e97, 0x891c62a, 0xb22e374, 0xed8eb2e, + 0x7dbcc2f, 0xd3a53e9, 0xdc8f220, 0x1d06281, 0xace4393, 0x9eef48f, + 0xd2abecd, 0x96014f5, 0x2653ceb, 0x1da7e09 } + }, +}, +{ + { + { 0xd00bc94, 0x7593318, 0xc7262a2, 0x586f3c6, 0x958ad31, 0xea68f52, + 0xd4e8bed, 0x6707fcc, 0xcb3f9ce, 0xb7e35d6, 0xf4b1be8, 0x2cbb6f7, + 0x7b41aee, 0xa535268, 0xf7b39b8, 0x1d77845 }, + { 0xeaf9554, 0xb1f3995, 0xfe9e7d4, 0x3250f70, 0xa00c23c, 0x62e5d1b, + 0xc10e3bf, 0x5e422f5, 0xc25cec4, 0x7a18039, 0x7cc4d5b, 0xb4e66a1, + 0x36d0e0c, 0xad7c5f6, 0xa4cf347, 0x9f40b12 } + }, + { + { 0x51e3696, 0x697f882, 0xab0a648, 0xc89bc40, 0x9785804, 0x8f261a5, + 0xb51a2bd, 0x4c7f900, 0x8a2dfcf, 0xd00e7af, 0xb642aeb, 0xf9c534d, + 0xb63df0e, 0xea2a79f, 0xf2f64a4, 0x392a69a }, + { 0xc331b6c, 0x0c0f01c, 0x6a5edb5, 0x414bf2e, 0x5068391, 0xfe5ed81, + 0x62fbc34, 0x0a8078d, 0x54bca98, 0x78a4382, 0x3d727c7, 0xf7a49ae, + 0xab4dffe, 0x96c1de1, 0x3b9440a, 0x45901f7 } + }, + { + { 0xacfe46e, 0x3f1189f, 0x4467443, 0xdca6f46, 0x2eb5bcf, 0xac38542, + 0x906bf72, 0xb02dce9, 0xfe1d454, 0xdd8cdac, 0x65f7218, 0xc26f04c, + 0x6ea145d, 0xb474859, 0x5bdb315, 0xc53dc6b }, + { 0x9ad7197, 0xbe5be74, 0x18b5ecc, 0x627e919, 0x9ea405d, 0x57c889c, + 0x1a5360b, 0x2e5650c, 0x1b30b27, 0x42290df, 0x5242687, 0x4a07157, + 0xd379133, 0x553ed1f, 0x01db019, 0xb9d7a07 } + }, + { + { 0x56597dc, 0xcfe551c, 0x925ebd6, 0x81af92a, 0xf4e8d57, 0x83efe16, + 0x1f640d3, 0x61bb431, 0x78b414a, 0xf80440f, 0x6c9e3b4, 0x72f3c63, + 0x6a03c66, 0xb55f43a, 0xe417037, 0x47a9ded }, + { 0xdbb612b, 0x1a7e287, 0xdbb9220, 0x895c3c7, 0x6c04764, 0xd50c86e, + 0x53cf7ca, 0xed52698, 0xf74af55, 0xc78d799, 0xb969ff2, 0xb2ba0f2, + 0x1c6530b, 0x06d4815, 0x165a575, 0x764a1fe } + }, + { + { 0xc1b5ece, 0x4383a3b, 0x54ff148, 0x0563c88, 0x5af796e, 0x9a45279, + 0x88e9953, 0xffba7c0, 0xb6a3001, 0xfe9fb5e, 0x25b6b19, 0x7950988, + 0xd81be5e, 0x67c899a, 0x2f9d29b, 0xc89ac8d }, + { 0x29ab8f7, 0x7c76ba3, 0x6e40f74, 0xb2a18c9, 0x3864d9b, 0x1b5056e, + 0x9b582b8, 0xdfa503d, 0x7c9c68e, 0xfb03519, 0x6b3c22b, 0xdc50131, + 0xa6c96ff, 0x38ab231, 0x8cb1c10, 0x4ea527c } + }, + { + { 0xc05b4ed, 0xd632f20, 0xb2a032d, 0xe0199fa, 0x26812d7, 0x3732956, + 0x013df13, 0x2aed855, 0x39f96ac, 0x92ca24b, 0xbb9751a, 0x620273d, + 0xf7437a1, 0x5d0d21e, 0x077de56, 0x9de2a43 }, + { 0x11a4674, 0x0569b12, 0x89c3989, 0xfc3923e, 0x2c5c770, 0x3d12704, + 0x84e8c37, 0x0072b90, 0xac39f9a, 0x7178d4d, 0x778d345, 0x5f8292f, + 0x77c7307, 0x9e5bf0f, 0xc3a20f5, 0x7691610 } + }, + { + { 0x705fe96, 0x7c4ead5, 0xc8e464c, 0x377ec35, 0x7689954, 0x3e5b990, + 0xa2d31ea, 0xc0f6949, 0xc580671, 0x839d395, 0xb215b09, 0x2f347a6, + 0x683df83, 0xfdcfa33, 0x6af39a8, 0x6e12cc2 }, + { 0x13a3bd2, 0xae46ec8, 0x59366f8, 0x03a7d3b, 0xb87aed4, 0xe2029d5, + 0xfe1b83d, 0xbdc4e43, 0xdb8a1a8, 0x768437c, 0xea0dd7f, 0xe47acc3, + 0x62a0af4, 0x550e0cc, 0x1a20962, 0xcaf2cbc } + }, + { + { 0xf28a78f, 0x5a784f7, 0x07e9724, 0x952a9b5, 0x1bab7a3, 0x8ac5e41, + 0xb7bc1e1, 0x1251e3f, 0xdc15e22, 0xe360f82, 0x95213f5, 0x3ac72da, + 0x4dcd47b, 0x65ee9ba, 0x3af5952, 0xdfeab7b }, + { 0x26fd3c6, 0x34c5c80, 0xf3ac7ee, 0xd977b08, 0x7dba2f6, 0x003bd01, + 0xac98c8d, 0xcfc5cf8, 0x0e46922, 0x05eb604, 0xfaa9352, 0xc248b17, + 0x395c7a7, 0xfa41c0f, 0xb71ee44, 0x29931d4 } + }, +}, +{ + { + { 0x07861c5, 0xac087bb, 0x5ae8240, 0x3bd37db, 0xf94518f, 0x94c68ec, + 0xff88a5b, 0xd32a378, 0x9b441d1, 0x42c8aaf, 0xfc07f12, 0x089db70, + 0xd3d4455, 0x211c386, 0x546b158, 0x1db9af7 }, + { 0x51bc927, 0xdfd1b65, 0x0733df4, 0x69c0493, 0x2aeb586, 0xdc72cd4, + 0x823aa13, 0xeebdace, 0x56ad643, 0x51b3b3c, 0xd4e0426, 0xb983a99, + 0x69c4ecc, 0xa1e5b6c, 0x45e6668, 0x37cd382 } + }, + { + { 0x9f73aea, 0x158ce6d, 0x14ff475, 0x36a7749, 0xdc0b018, 0x0d4e424, + 0x3946f09, 0xc2c4448, 0xfacda62, 0x7a7de3f, 0xb486709, 0x49a19e6, + 0xdb61da7, 0x65094d8, 0x8f5ee87, 0x09edfd9 }, + { 0xb37226d, 0xe460fcf, 0x69bf470, 0x3b9d039, 0x247ca22, 0x3d4d511, + 0xc782cb1, 0xc7248d6, 0x00ad293, 0x91189a0, 0xe8abe75, 0x1244942, + 0xbf52cdb, 0x9f88d12, 0xbbbcadf, 0x368463e } + }, + { + { 0x8074f45, 0x419e4b3, 0x0771c83, 0xd3f8e2e, 0x2e68d34, 0xd2743b4, + 0xb116a00, 0xc68b7db, 0xd84cc37, 0xfad2cf7, 0xb7a0f4d, 0xcfd27c0, + 0x190e587, 0x3b9e23f, 0x751ca9e, 0x7bab499 }, + { 0xa8f12ee, 0x3270861, 0x31b36d5, 0xee1f38d, 0xe4c0eed, 0x748bb31, + 0x110ebad, 0x9be5c9b, 0xc8b6cb6, 0x728660b, 0x93d914a, 0x7bc9df7, + 0xc88c859, 0x73a4f2c, 0xb4e7f0e, 0xbe4a2fd } + }, + { + { 0xa450e77, 0xe566ff8, 0x6a13aba, 0xb0b4006, 0xcd7dc90, 0x483a510, + 0x5fa9ccc, 0xb1a2013, 0xa80e67c, 0xeb0b631, 0x020801a, 0x7c34e1f, + 0xf4e447c, 0x0257dc8, 0x74c6f0f, 0x7abe7d1 }, + { 0xb19a576, 0xf115a3a, 0x064ca0e, 0x8f0474a, 0x351f99b, 0x999bb6b, + 0x773edc3, 0x855254b, 0x427d717, 0x49f6c2f, 0x2e0cef2, 0x9f68253, + 0x2ee34f5, 0x1fe126c, 0x80150f7, 0x1ec2cae } + }, + { + { 0xc005b7a, 0x862c5af, 0xec4ef17, 0x61adea7, 0x007b446, 0xf885fd3, + 0x9b0e30e, 0x25c129d, 0xfeec7e0, 0xbc10f25, 0xdf79ee1, 0x3901ac4, + 0xfe9e19f, 0xad49db7, 0x360d050, 0xc8624d9 }, + { 0xbf3260b, 0xc74a576, 0x8c010c2, 0xbde8024, 0x09b6977, 0xf155329, + 0xd52dcf8, 0x6a5a82e, 0x29b9dfc, 0x4fbf59d, 0xc7b730c, 0x337d049, + 0x3a89cd4, 0xb3deac6, 0xad2f2eb, 0x1e07595 } + }, + { + { 0x3b7c84e, 0xa0b0a4d, 0x8cf2b00, 0xf132c37, 0xeaaa8ec, 0x192814b, + 0x7b4b5df, 0xe7929f9, 0x42d0ab7, 0xf08a68e, 0x7b60cdd, 0x814afb1, + 0x7d9c160, 0x78c348c, 0x44db217, 0xf8a9488 }, + { 0xeaa2578, 0xcdefd88, 0xbd0e260, 0xf717f56, 0x1694d02, 0x7754e13, + 0x181dbd8, 0x1254c14, 0x6e5f312, 0x0dacdd2, 0xcef87bf, 0xb8abdfb, + 0xe74e2ea, 0xb985972, 0x002b424, 0x1717621 } + }, + { + { 0x162df70, 0x92cc75e, 0x18ee849, 0x1e20c06, 0x26aa590, 0xc036b46, + 0x4da5155, 0x31be67e, 0xf7213b0, 0x04911b5, 0xbb2e72e, 0x39261d7, + 0x5c015a3, 0x9e84466, 0x298ae67, 0x2f59fc0 }, + { 0x1701fcc, 0xa3ea7ba, 0x0ebd651, 0x87a5fa9, 0x301d7b1, 0xa607ed4, + 0x3b2e271, 0xbd4ec5f, 0xdc4180f, 0x732a1a2, 0xfeaa8c1, 0xbe15d82, + 0x66f2f3f, 0x1036702, 0x9e79ce8, 0xccfd397 } + }, + { + { 0x70a54ad, 0x82ab835, 0xe3bec75, 0x5c1dee8, 0x54b556b, 0xf583ff4, + 0xf461e60, 0x9220199, 0x87fc4e7, 0xdf61ca8, 0x0776dad, 0x6641fd2, + 0x8edd061, 0x00c6edd, 0x55f7e87, 0xaf9b142 }, + { 0x9bbe3ec, 0x73f15e4, 0xf8bc1fa, 0xdd3b788, 0x1b8ff86, 0xb24cc07, + 0x41be58b, 0x6c260d2, 0x6b10ada, 0xec1c4e3, 0x7fdb985, 0xf6b4209, + 0xd47c212, 0x0d0ac85, 0x07d78d1, 0x967191c } + }, +}, +{ + { + { 0x843d0f3, 0x3b11638, 0xf27f10e, 0x4b89297, 0x863ba2a, 0x477236e, + 0xadd280c, 0x1949622, 0x04da757, 0x7cd5235, 0x79e4ff7, 0xe0e99d2, + 0x537da41, 0xb4ef894, 0x5a24ff1, 0xc55dde4 }, + { 0xb587521, 0x18d8e21, 0x3777833, 0x8010b5d, 0xd3a54c8, 0x4af522d, + 0x4c0ac13, 0x7cd476b, 0x4099f67, 0x4587e61, 0x605ee64, 0x494d0ed, + 0xcc80903, 0x3218ba2, 0x0b2e169, 0x5ff56aa } + }, + { + { 0x3a06c69, 0x51ec94e, 0x5e65c52, 0xa26d7be, 0xd44ee96, 0x156f113, + 0xbf5b9b4, 0x70f0968, 0x5f5332d, 0x9b7e469, 0x6703829, 0x36c295f, + 0xd04f492, 0x1522690, 0x728043b, 0xcf35ca4 }, + { 0x190a7c3, 0xf9ca3e1, 0xf971b07, 0x53d2413, 0x9c48b49, 0xae59652, + 0xfefff5c, 0x74672b8, 0xa7643b0, 0x0a3018b, 0x3e9b0a8, 0x51919e8, + 0xc932fb5, 0x89ad33d, 0x643e687, 0x52a4419 } + }, + { + { 0xd2d0acd, 0x7778990, 0x487fdf1, 0x3bdbcce, 0x2b03dd2, 0xdc413ca, + 0x9a2b7d0, 0x278755b, 0x35ddd7f, 0x4ebb8b5, 0xbcbdb92, 0x0465152, + 0x671d051, 0x34f22d6, 0x87192b9, 0x1ba04c7 }, + { 0x83560c1, 0xb1693f4, 0x7d174e9, 0xe08a593, 0x64dc9af, 0x47ffdc4, + 0xce8126c, 0x1123596, 0x1124628, 0x632d95f, 0xfee7c76, 0x66287ab, + 0xc552332, 0xb40fe60, 0xe304e1e, 0x3f11729 } + }, + { + { 0x5030a8c, 0x97a6ea0, 0x09c27b2, 0x6924198, 0xac9dd5d, 0x3308501, + 0xbe73fdc, 0x9fed7fa, 0x0535286, 0xea55544, 0x6c9b832, 0xc7c07ab, + 0xc51b967, 0x178c882, 0x86ee075, 0x6fa0c69 }, + { 0xb8b5c4a, 0xbaa4a15, 0x3130c0a, 0xf83c0ea, 0x2800331, 0xcf8624b, + 0x7ccbcb8, 0xade85cd, 0xf08445d, 0x971d7f6, 0x6a546dc, 0xfd480b7, + 0xc93761c, 0xdc15a38, 0x9d04631, 0xc4c495c } + }, + { + { 0x9470efe, 0x5f4cee8, 0x88d93ad, 0x9fe8961, 0xf4e49ce, 0x24783b3, + 0x52ffb3e, 0x1bc7ed7, 0x6d81e17, 0xa3abe6a, 0x7a333c3, 0xd6bb8b4, + 0x10a3527, 0x3485c0b, 0x31a9d10, 0x7cddc9c }, + { 0xc38ca37, 0x0c78112, 0xdd2f8d8, 0x10e249d, 0xc511911, 0x72c88cc, + 0x29a6c84, 0x4d75b5a, 0xa227b1e, 0xc74b267, 0xf8e35ad, 0x698390c, + 0xe98d230, 0x8f27edf, 0x6bdc7f4, 0xec922f2 } + }, + { + { 0xfc32e11, 0xac34023, 0x47200d1, 0xe0ae2f5, 0xbd98c82, 0xa7c7492, + 0x7b02154, 0x3910b68, 0xe28ab6d, 0x6fdd06c, 0xd98b012, 0xd3a7e49, + 0x9f54207, 0x4c1c82b, 0x45c176f, 0xef5bbe6 }, + { 0xd3e71eb, 0x3d17960, 0x080e70c, 0x90d7e84, 0xbff5d9e, 0x83e6438, + 0x535d85c, 0x1877e1f, 0xfbb69cc, 0x931ed6e, 0x1247848, 0xcf96265, + 0x750da4e, 0x76d618b, 0x717fbf6, 0xc076708 } + }, + { + { 0xeec5126, 0x80a5ac5, 0x3379c80, 0x6d05dd1, 0x2336d32, 0x514b089, + 0x6725137, 0x586c006, 0x574f954, 0xab2365a, 0xac7d356, 0x3c89ea0, + 0x27460ba, 0xf1f2edd, 0xab9870f, 0xf200ddb }, + { 0xa35e885, 0xc8f1b2c, 0xe6e7550, 0x5d22f86, 0x9554615, 0x24b9a40, + 0x616314f, 0xcb41107, 0xc976a11, 0xca752f0, 0xa08291a, 0x3e2f839, + 0xf2c420e, 0x0cff22f, 0x82b9747, 0xafd603e } + }, + { + { 0x810a3da, 0xaddeddc, 0xd3a87bf, 0x78b6c2d, 0xde3a04c, 0xbc7020b, + 0x9b6d045, 0x47ab973, 0x0959358, 0x3b046d6, 0x509ee3e, 0x0f953e7, + 0x69fc61b, 0x803dc86, 0x893c8d4, 0xcceaec0 }, + { 0xb048a45, 0x21f8c40, 0xfcaea8a, 0xb535073, 0x90e360b, 0xe712c35, + 0x8403338, 0x5d0f3f4, 0x7207f2d, 0xe0ea26c, 0xffd9e05, 0x20f6b57, + 0x4788b00, 0xb97d68e, 0x1889cce, 0xb121554 } + }, +}, +{ + { + { 0x464238e, 0x0079817, 0x0d381ca, 0x2110302, 0xd9f01b5, 0x1cc4c6e, + 0x5a131b1, 0x5e35dc5, 0x06944eb, 0xb61848d, 0x29631a3, 0x83792a0, + 0xafca0dd, 0xbe1017f, 0x782fcbb, 0x70aaa01 }, + { 0x99945e7, 0xc63b7a0, 0xc4486c1, 0xe9164ec, 0x885f2c1, 0xb133e35, + 0xc99ae02, 0x186f0d3, 0x2bf53e6, 0x2fca492, 0x48a02bc, 0xf922aa2, + 0x0dd3dca, 0x4fe6490, 0xf6a8207, 0xe8c313f } + }, + { + { 0x97caf1e, 0xc5b3583, 0x922a4b6, 0xa001922, 0xdf07c95, 0x67e36be, + 0xb2f4f34, 0xabaa0ae, 0xdedc333, 0x66dc926, 0x38ec5b3, 0x82021c4, + 0x00ab176, 0x82b4f26, 0x69c45af, 0x1b7c22e }, + { 0x0924ad9, 0x07b0dbe, 0xa407dde, 0xe030936, 0x26ccd06, 0x66e1ce9, + 0xe3505a9, 0xb50c108, 0xda98f51, 0x8b921e1, 0x20cf7c7, 0x449ca1a, + 0xe67d079, 0xadb80c7, 0x834372d, 0x205aa54 } + }, + { + { 0x19bf847, 0x1482b48, 0x5906f0f, 0xd6c16ab, 0x23ad060, 0x323fb17, + 0xc832be7, 0x0346389, 0x2ee45bf, 0xe71b2d8, 0xfb22276, 0x761c37d, + 0x5d70be2, 0xa9b3334, 0x5a0627a, 0x81a0656 }, + { 0x99a6282, 0x3377503, 0xd0436f0, 0xafc8d2e, 0xc53342f, 0x22f71d3, + 0x8939ad3, 0x66ca56d, 0x30e09ba, 0x15a9192, 0xa6de890, 0x261091e, + 0xe78f2d5, 0x609d700, 0x8eaaf78, 0x8aa52ee } + }, + { + { 0xce76258, 0xa398788, 0x494b975, 0x3031d07, 0x043dfe2, 0x4a6d652, + 0xb4401ec, 0xdb1a849, 0xce8bbcc, 0xf81ebbb, 0x16efe9e, 0x937dd47, + 0xef85ecc, 0x9c19350, 0x214273b, 0x260d932 }, + { 0x77bf1a3, 0x1d7e21e, 0xa544eb7, 0x199d689, 0x94ced50, 0x9da5941, + 0x8a0aeaa, 0x71a60be, 0x26d3b51, 0x183a0ae, 0x8df9728, 0x49f176a, + 0x3230674, 0x744376e, 0xe25541c, 0xb2cb21a } + }, + { + { 0x9a0071f, 0x7a72158, 0xe7d2a6b, 0xe19dd29, 0x55113f0, 0x3deb34e, + 0xede573b, 0xef1f8eb, 0x5665e37, 0xa8f7ff9, 0xf2d7777, 0xa2c21ea, + 0x91e2e39, 0x1387afa, 0x7db68f6, 0x04057b9 }, + { 0x1c241f7, 0x8b9d5ae, 0x8e75993, 0x689588a, 0x5c0e2d4, 0x79585b4, + 0x7b64974, 0xba1ef16, 0x1c08a75, 0x72685bc, 0xd572edd, 0xf0a5814, + 0x5ab0e70, 0x71464a3, 0x339aea7, 0xc93c92b } + }, + { + { 0x5b8a87d, 0x1917e2a, 0x3a82756, 0xea5db76, 0x6420e2b, 0x5bba2fb, + 0x019372a, 0x5cc0501, 0xccc5efd, 0xb1ef8be, 0xf49c57d, 0xaf06393, + 0x87a0bc4, 0x3ab1adf, 0x34fe6b6, 0x2ee4cca }, + { 0x6b8ba9b, 0xd160668, 0x7efec13, 0xef137d9, 0x50abb76, 0x7b60465, + 0xf753a00, 0xb40ec2b, 0xeaf8f1d, 0x696ed22, 0xd8ba3d8, 0x398c91f, + 0x37db313, 0x11f2034, 0xfe5079e, 0xe1ec33b } + }, + { + { 0xbdc81f0, 0x8a10c00, 0x6fe8e05, 0x5f39256, 0x14a368e, 0xa595dab, + 0x38cec6b, 0x32b3181, 0x1b00d00, 0xd77afde, 0x4d9923d, 0x3c97928, + 0x76e13dd, 0x78f0e7a, 0xbf75675, 0x5ee8e59 }, + { 0x91b130c, 0x49ec893, 0xa47a441, 0x9416182, 0x76e2ce8, 0x54555b5, + 0x349c40b, 0xcbdd2fd, 0x9392bbe, 0x10ae737, 0x2e2dab0, 0x270b111, + 0xaf293f4, 0x5cb7712, 0xd6095c6, 0xfc22a33 } + }, + { + { 0x0f15878, 0xdcb5bbd, 0xb6bba48, 0xbcf27ad, 0x7b70eba, 0x979913e, + 0x158578a, 0x4c0f34b, 0x6ed6088, 0x53f59a7, 0x75b0fc2, 0x19b3b2c, + 0x0153f3c, 0xad628dc, 0xcec1607, 0x5195a2b }, + { 0xdfe0f7a, 0x95f8b84, 0x152920b, 0x935c6b0, 0x4da1056, 0x25f9e31, + 0xb28c229, 0x4910a94, 0x8ee4d6e, 0x54b03b4, 0x694e3ed, 0xc991fc3, + 0xdbe5709, 0x68c4c26, 0x63d7657, 0xc9cfce4 } + }, +}, +{ + { + { 0xf52a44e, 0x21c9227, 0xe85bfbd, 0x7f105a2, 0x6268fc2, 0x887781f, + 0xa2d7e35, 0x56ee808, 0x2d3930f, 0x14f9de5, 0xdcb561a, 0x4a4e356, + 0x7f95598, 0x8736226, 0x5f34151, 0x211c342 }, + { 0x0eaf9cb, 0x8fcb75b, 0x3d60ce2, 0xcc9edf9, 0xa5fe627, 0x54412c9, + 0x842dd09, 0x6036a72, 0xa6c6099, 0x71ce668, 0x5386764, 0x02b30d7, + 0x6f18e23, 0xb69bed3, 0xd1de9f4, 0x124c9b1 } + }, + { + { 0xe69b531, 0xe8f8d95, 0xaff1049, 0xe1e115e, 0xeddea0c, 0x9087cd1, + 0x7449916, 0x8ed55a5, 0x7808404, 0x8009f54, 0x17fea55, 0x990f216, + 0xfe8ecf9, 0x68ba624, 0x56d1f47, 0x8ac2950 }, + { 0x529dfb0, 0x3257887, 0x244c080, 0xc4a613f, 0x28672fa, 0xabb1ac0, + 0x31eb291, 0xb2915c5, 0x8fababa, 0x6e368ca, 0x1fde498, 0x6b8c259, + 0xf2a548c, 0x67724a1, 0xf90409b, 0x6b3b7e8 } + }, + { + { 0xfae20aa, 0x5415003, 0x85df5ce, 0x95858a9, 0x0ac6bee, 0x42bc987, + 0x39ea1a9, 0x8d843c5, 0xb571043, 0x5de200c, 0x1741a33, 0x084fcd5, + 0x0009d1c, 0xe1ca20c, 0xe957e6d, 0x0271d28 }, + { 0x9e3be55, 0x84cbf80, 0x1c578c6, 0xc804dda, 0x409a93a, 0xea85489, + 0x972021d, 0x64a450a, 0xe681312, 0xc6a2161, 0x65bc111, 0x280bff9, + 0x0f8526f, 0xd358a4b, 0x953a3ab, 0xd967be8 } + }, + { + { 0x7dd066c, 0x4c5e615, 0x634c8d4, 0x37afd33, 0x42d8b87, 0xa3ac88a, + 0x938b607, 0x9681e9b, 0x37fe4c8, 0x7a286ab, 0x2494245, 0xdeee574, + 0x6af75a8, 0x184b9d3, 0x3670c04, 0x20f696a }, + { 0xa39e8b9, 0x1340adf, 0x0850b2e, 0x03c1929, 0x2c0e1ef, 0x435ebd4, + 0x142ee9b, 0x49de18b, 0x3f116f2, 0xb440b27, 0x2214463, 0xd94e9fa, + 0x6311543, 0x1b0ddd3, 0x991ba3c, 0x1ae042a } + }, + { + { 0x5bb47aa, 0xbc322f8, 0x54a5845, 0x9e25625, 0x21115f3, 0x96b65ae, + 0xbb5757b, 0x46fbed4, 0x4c42dce, 0x18aec4f, 0x8d801f0, 0xc59caf6, + 0x1205521, 0x9189463, 0x89feb7a, 0x66bd8e0 }, + { 0xc529ee7, 0x39ebe95, 0x8eadb99, 0x28d8992, 0x6927544, 0x6058c78, + 0xd3808ec, 0x877e7a5, 0x1c52eaf, 0x8f65111, 0xae221cd, 0xfb59812, + 0xf890391, 0x22289c6, 0x4966e92, 0xa97695b } + }, + { + { 0x6ff10f0, 0xf0a9122, 0xa2a65c8, 0x49a931b, 0xb1d3cb0, 0x3fcebbc, + 0xca9685f, 0x70eb79b, 0xab38cb6, 0x82520b5, 0x76304c3, 0xccf991b, + 0xaf8b07c, 0x575aab1, 0x5ed5efb, 0xec8166a }, + { 0xc8689b1, 0xddc5698, 0xb2e78d7, 0x227c949, 0x8e07d91, 0x6132321, + 0x22cfd62, 0x658a11d, 0x004dd5f, 0x908fb44, 0x90d21b1, 0xe3d14f0, + 0xa6a1639, 0x6f3db9d, 0x333a525, 0x09d86c0 } + }, + { + { 0x6f043f7, 0xd83eaf0, 0xb52d5f6, 0x88ab648, 0x57144d7, 0x67c664d, + 0xeafc8b5, 0x55d7644, 0xcceb291, 0x1c89f20, 0x831ac47, 0x51aec7b, + 0x6148854, 0x51172fa, 0xf6d7bfe, 0x8fabf7e }, + { 0x477ee27, 0x5910316, 0x20fe61e, 0x5f299dd, 0x42826ab, 0x48079a8, + 0x22591fa, 0xf4a83ba, 0x55482ec, 0x8fac660, 0x6b65b3b, 0x48fd5f1, + 0x9fd9e19, 0x4288a7c, 0x9377894, 0x27db819 } + }, + { + { 0x7fd9dd6, 0x2936ee4, 0x9ec87c6, 0xcce5f0e, 0xdb6e3b4, 0x15a50e3, + 0xad701c8, 0x61df105, 0x1dff1f7, 0x3601add, 0xe8a16e1, 0xb761e06, + 0x1af3f91, 0x4341e02, 0x933fa3f, 0x9156a4a }, + { 0x54bc01d, 0x9dc46ae, 0x64eb910, 0x605577a, 0x5a59a99, 0x22b99f8, + 0x0a229d8, 0xab2dbaf, 0x6599364, 0xa8bfb65, 0xe94ebf0, 0x39ed4a5, + 0x0dbb23e, 0x7b46a1e, 0x8751422, 0x117b195 } + }, +}, +{ + { + { 0x423bddf, 0xd19e8fd, 0x387ef59, 0x9d77042, 0x849590a, 0x315cbdd, + 0x7866c1e, 0xfdc637c, 0x03515a6, 0x72be83d, 0x0376780, 0xd44a4a0, + 0x19e0c2b, 0x3b96131, 0x7b1a689, 0x023aca3 }, + { 0x82282ea, 0xf5f3687, 0x8a8b5c7, 0x4471089, 0x17a3066, 0xcd2f00a, + 0x81ed681, 0x754e112, 0x0bfcefd, 0x9c6c70c, 0x3b6f29b, 0xd6aced0, + 0x2817a2a, 0xe443d56, 0xe7c0012, 0xe590ef4 } + }, + { + { 0x3e62e2a, 0xc2f9676, 0xb2daa26, 0x661816e, 0xdd5f512, 0x3515fd2, + 0x56b6e75, 0xdc36e27, 0x74cc658, 0x0bdde46, 0x00e7644, 0x1029086, + 0x1694a09, 0xfdf0045, 0xceac169, 0x454bcb6 }, + { 0x6481eb6, 0xf4c92ab, 0x09750e7, 0x8b77afa, 0x6362d6d, 0xe6f4231, + 0xf53a3ae, 0x0d45dee, 0xd7dcf98, 0xdac7aac, 0x125ec4a, 0x628cb7f, + 0xaec0320, 0x41e8a20, 0xea2e35b, 0x7418c7e } + }, + { + { 0xdf40519, 0x4d649ab, 0x3525833, 0x8cb22d4, 0x7a5333f, 0x15f6d13, + 0x72c23ee, 0x8c3991b, 0x0cd44a3, 0x248b9a5, 0xccc1a75, 0x6b4c4e0, + 0x15c99a9, 0x3221efb, 0x0a9c504, 0x236d504 }, + { 0xd559100, 0x401c7fb, 0x07c524d, 0xcf0e075, 0x34a9275, 0x39647c0, + 0xf7e8683, 0x2355422, 0xb3ae670, 0x3e0a16e, 0xad61b7f, 0x1c83bcb, + 0x9ca6cbe, 0x491bcb1, 0x5e29458, 0xe668dc4 } + }, + { + { 0x219379e, 0xe44c65b, 0xbb607ee, 0x211381b, 0xb7bc6db, 0xd4c7428, + 0xb76a2e8, 0xba62a03, 0x8bb0b31, 0xe1729c9, 0xc6bbc10, 0x3caeb50, + 0xb0187aa, 0x6c66727, 0xfb90dcf, 0xbf9d2f0 }, + { 0x1184dc6, 0xec69350, 0x2698eb5, 0xd58d2a3, 0xa316b07, 0xb366d8d, + 0x251c017, 0xe1e39bb, 0xadb157f, 0xbe44ba9, 0x8a8b06c, 0xbaa9a9a, + 0x6e473e1, 0xd0f4635, 0x1d681c6, 0xd25a8f6 } + }, + { + { 0xcb102c7, 0xba39d5f, 0xd8aa1eb, 0x66eba21, 0x697fbf4, 0xcc2591a, + 0x2317f54, 0x5adb579, 0xf76c6f9, 0xa01ae71, 0x5042705, 0x2c525de, + 0x4f4479f, 0xc8f4272, 0xe6d7a5b, 0x26ab54a }, + { 0xdc28106, 0xda217b5, 0xeb2ae6a, 0xc7cadea, 0x53ea3b2, 0x0b16094, + 0xcc6111b, 0xcddcc1c, 0xa7a7beb, 0x5c47aff, 0x0e52dab, 0xf9931bd, + 0xc6dcf96, 0x5231835, 0xf27ea4e, 0x7095bde } + }, + { + { 0xc33b4e2, 0xee8adae, 0x63ceb44, 0x3006651, 0x880b086, 0xf1476fb, + 0x9569ce8, 0x0703328, 0x238b595, 0x2cabf9a, 0x26c8158, 0x85017bc, + 0x68d5144, 0x420b5b5, 0xf9c696f, 0xa9f5f1e }, + { 0xc8fec5a, 0x1409c3a, 0x28e9579, 0x541516f, 0x0e1f446, 0x06573f7, + 0x2311b96, 0x3e3c706, 0x3c2ffd8, 0x0033f1a, 0xca6711c, 0x8e808fc, + 0x07aef98, 0x716752d, 0x92525b3, 0x5e53e9a } + }, + { + { 0x5a1c29f, 0xce98a42, 0x3ca6dc9, 0xaa70348, 0xedfa48b, 0xe77d822, + 0x068abca, 0xd2e3455, 0x482cfca, 0xb456e81, 0x7fbfb08, 0xc5aa981, + 0x8243194, 0x8979f25, 0x2cd043d, 0x727f217 }, + { 0xaa53923, 0x7cca616, 0xe9bcb72, 0x387c5ae, 0x37580bb, 0x0173fd4, + 0x75fc0d9, 0xdd7795b, 0x345deae, 0x47d1c37, 0xb0d1c03, 0x2eb5d7f, + 0x958f002, 0xf7a1b92, 0x8f61b67, 0x7365cf4 } + }, + { + { 0x562a5ed, 0x4b22c3b, 0x5c7cd07, 0x711216f, 0x9ba0648, 0x51f72c4, + 0x0de9e6f, 0xc10d093, 0xfda63ba, 0xaca479b, 0xaf532b0, 0x4722a55, + 0x7236f39, 0x8d59eb7, 0x4465c34, 0x5cad874 }, + { 0x722b0c1, 0xa2119e5, 0xf343ea4, 0xb670264, 0xc19f387, 0x6910f02, + 0x0381fba, 0xcfec5bc, 0x52c0a1d, 0x5f5de0d, 0x6378cb6, 0x4e474d5, + 0x27e2ba3, 0x2fc8027, 0x159b541, 0xa215da3 } + }, +}, +{ + { + { 0x8499895, 0xed53585, 0x65c998d, 0xa0aefd5, 0x2d5a561, 0x210d850, + 0xa2cd9d6, 0xc2cc23c, 0xc4d297e, 0x2371d46, 0xd18d441, 0x88b2143, + 0x043993d, 0xbebdad9, 0xad5f28d, 0x6ba91e7 }, + { 0x3a731f4, 0xc2bb3f1, 0x5d0d5c3, 0xd35cfac, 0x35ac427, 0x9950998, + 0x5458adb, 0x8938bb5, 0xab26f3b, 0x0bd738c, 0xa28cd8d, 0x56db3d5, + 0xa1d8b4b, 0x87eb95f, 0xe7f3b4b, 0xd6700ef } + }, + { + { 0xea1e57b, 0x962c920, 0x6dded6d, 0xd3be37e, 0x2c96a73, 0xf499b62, + 0x6c99752, 0x3eaf7b4, 0x025590b, 0xa310c89, 0x721db23, 0x535aa4a, + 0x19714a0, 0x56ab578, 0xd4048c1, 0xeecb4fa }, + { 0x470c466, 0x7b79ec4, 0x1383cee, 0xc4e8f2e, 0x5750c45, 0x0f5d776, + 0x725527d, 0xa3b3bc3, 0x6d00cce, 0x2f5deb6, 0x95a8d81, 0x5d5a0f4, + 0xe02b824, 0x50a442e, 0x2a11628, 0xafb0446 } + }, + { + { 0x0c613de, 0x72b67bc, 0xe6f0b24, 0x0150d4b, 0x8ed289d, 0x847854e, + 0xa320f88, 0xe08292f, 0x29c6160, 0xd5b6da3, 0x4fb9d06, 0x2a48e2d, + 0x2de087c, 0x55d9e41, 0x4f02100, 0x65683b5 }, + { 0xa8886c6, 0x4dc8c2e, 0x20d6114, 0xe966dd2, 0xa57af97, 0x99745eb, + 0xb854725, 0x23a9a71, 0x621a047, 0x8effe05, 0x049a4be, 0xf16d284, + 0x5b0660f, 0x95828c2, 0x56e96b0, 0xd5b69ba } + }, + { + { 0x4ffa0b8, 0x0b5b424, 0x096cc5e, 0x0585b45, 0xf505d37, 0x413e1ae, + 0x0c7ab8d, 0xe5652a3, 0x2990120, 0xab32fb7, 0x3f09368, 0x6b8b16e, + 0xefe128e, 0xbf9fadb, 0x14b7671, 0x85f366b }, + { 0x090608d, 0xcb2f294, 0xac3045f, 0x25e2769, 0x6131904, 0x069c4f0, + 0x329a779, 0x1c57cf1, 0xb7cace7, 0x72fe0d5, 0x0897a45, 0x04d9f43, + 0x359a645, 0xbaf32f6, 0xfa7485a, 0x0fa854f } + }, + { + { 0x5f56f60, 0xae3533c, 0x0ad9360, 0x9773bbb, 0x38fbe6b, 0x769b34a, + 0xffb0c00, 0xb5ba8e9, 0x75472e4, 0xa939318, 0xce5f30f, 0x12cac92, + 0xa9e7dbc, 0x514fc06, 0x58b4734, 0xd7ca865 }, + { 0x65a730b, 0xd101ff3, 0xabe70e9, 0x92da451, 0xef7bf4b, 0xfb5f94a, + 0x1d56c7b, 0x8c3ef4c, 0x8435c10, 0xb085766, 0xe7ed4cc, 0x7fbbbda, + 0x24f372f, 0x1da6eaf, 0x59b8ae3, 0x0ab2c1f } + }, + { + { 0xf10a4b9, 0x63a1a78, 0x0c7e510, 0xbb5278d, 0xf874142, 0x97b224e, + 0xb2517b1, 0x0a9ff52, 0xc5cd920, 0x1b5a485, 0xa1823b9, 0x1a8e2eb, + 0x0e914a8, 0x2b088c0, 0xcf13432, 0xe5ec3ad }, + { 0x6e7e253, 0x0d6ab3e, 0x6f18458, 0x9f0f5cd, 0xf459a6d, 0x839a744, + 0x1eb15f7, 0xb4b4f94, 0xc72cb14, 0xe0313ac, 0xb20472d, 0x58ee933, + 0x872543e, 0x5f73d7a, 0x501f067, 0xb1700c5 } + }, + { + { 0x085f67f, 0xb70428e, 0x43cabe5, 0x5441d51, 0xe0a6055, 0x4d0e8c2, + 0x0882e4f, 0x8d39a08, 0xc1cb39d, 0x615bb32, 0xf7a1642, 0x113f18d, + 0x250681f, 0xbab8cf5, 0x677b72a, 0x3017ba2 }, + { 0x5a3a876, 0xcd2b6e9, 0x2035a69, 0x0476501, 0xefa2ea0, 0x31d6440, + 0x56874d5, 0xde8f8d1, 0x0199d4a, 0xcbc71cd, 0xe7f2170, 0xc546b61, + 0x112c4c3, 0x4e57e4e, 0xd1622ba, 0x58955a8 } + }, + { + { 0x04e2f6f, 0x0064cd7, 0xe0edd38, 0xe9d458d, 0x7e0a5c8, 0xeb1a597, + 0x01fc0a8, 0xe322ece, 0x1032a19, 0x8b9d166, 0xa89de94, 0x3e7b539, + 0x001c754, 0xfa30262, 0xdb588f6, 0xe33de4d }, + { 0x954eb94, 0x4dafbdb, 0x0584c1b, 0xbb43648, 0x5dbe29b, 0x622c93e, + 0xf57b931, 0x968f9e3, 0x0f6453b, 0x98f03be, 0x08f696c, 0xb0ecc7f, + 0xa505335, 0x5af55f4, 0xfb3fa9b, 0x028533e } + }, +}, +{ + { + { 0x27e8d86, 0x3bc8e68, 0x63f105a, 0x4e43b30, 0x4981250, 0x5301b7d, + 0x9f72fa8, 0x8b0a75e, 0x357348c, 0x88f59db, 0xec4208e, 0x5f0ebb1, + 0xc043d3b, 0x4712561, 0xc806b97, 0x9e5ded0 }, + { 0x2121d09, 0xf9bd0a6, 0xe337cd1, 0x1759ecb, 0xe945542, 0xd1acc0e, + 0xbd2f63a, 0x3683feb, 0xda5dfe9, 0x44f1bcc, 0x707f22f, 0xa3606c9, + 0x2d96ca5, 0x45ef064, 0x9022df9, 0xfc3107d } + }, + { + { 0x44be755, 0xe81320b, 0x5c7c761, 0xdf213d5, 0xb4e5db9, 0xf43d2d5, + 0x8dedcd2, 0x3bcfd82, 0xd37a9ec, 0xdf368a6, 0xf475a77, 0xfef20ae, + 0x162c064, 0x22f5894, 0x0142a7d, 0x956bc66 }, + { 0x7daec78, 0xaaa10e2, 0xb6e9a78, 0x3cb9b72, 0xe383f72, 0xa740bad, + 0x7759007, 0xc31b401, 0xa7afc50, 0xdada964, 0xfd3d11f, 0x6bf062c, + 0x5db3679, 0x9470d53, 0x03abf13, 0x3394473 } + }, + { + { 0x46e5d7f, 0x533f440, 0x49048c8, 0xd1793e3, 0x1929b94, 0x59e1150, + 0x8364134, 0xcddbbcb, 0x582774f, 0x795c794, 0xe03081a, 0x114dfc4, + 0xef54042, 0x541ef68, 0x23f18cd, 0x159295b }, + { 0x48a2c8c, 0xfb7e2ba, 0xbb6d116, 0xe2d4572, 0xd750b53, 0x7bb0b22, + 0xd142ee8, 0xc58888c, 0x90c9e2d, 0xd11537a, 0xd02eb9e, 0x77d5858, + 0xd444a79, 0x1fa4c75, 0xd58a68d, 0xf19b2d3 } + }, + { + { 0xeb8b90f, 0x37e5b73, 0x3f2a963, 0x3737f7a, 0x9de35e0, 0x87913fa, + 0x8731edd, 0xec7f992, 0x219491e, 0x6e6259e, 0x4de236c, 0xb2148a0, + 0xfdd309b, 0x89700e8, 0x9f0bf80, 0x9ce51e4 }, + { 0x301f17b, 0xe7ec421, 0x3bc5f4f, 0xa4b570a, 0x1285ee2, 0xc2b1b2a, + 0xc53db73, 0x5e86bc8, 0xf24fa90, 0xb65fcea, 0x08ab024, 0x9e74c56, + 0xf9ed877, 0x5c8003d, 0x4a2cbbc, 0xa632e9e } + }, + { + { 0xc91c8b5, 0x32a4546, 0xc969363, 0xc122b5a, 0x3648b3a, 0xbbbec5e, + 0x25143b0, 0xd5a365e, 0x54157ce, 0xcf3e464, 0xf9bab64, 0x9712f04, + 0x04b4008, 0xc12d43a, 0x2edf1c7, 0x51932d7 }, + { 0xb2f8470, 0xaef1655, 0x6c24ace, 0xaa8e3f3, 0x6b4e761, 0x7da75da, + 0xb90bca2, 0xd371827, 0x0afb45c, 0x84db450, 0xef46b5d, 0xae12045, + 0xd962f98, 0x91639a5, 0x72f2ac0, 0x669cbe6 } + }, + { + { 0x83a4356, 0x851bb31, 0x9a1bf15, 0x7d436bf, 0x120b378, 0x46a3f0e, + 0x3f5b357, 0x9302abc, 0x93fef53, 0x1e06726, 0x5fd2ee9, 0xb12f4a9, + 0x7de9433, 0x94a884c, 0xa6f2874, 0x2645234 }, + { 0xcdb8dfa, 0x6fb56f5, 0x9e0ee4e, 0x4a17dfc, 0x83ab01e, 0xe269d83, + 0xb77c10f, 0xda932da, 0x0321243, 0x463af0c, 0x16fc8a3, 0xbe1d682, + 0x48b39e3, 0x2eae3ea, 0x3b03e7b, 0x9423021 } + }, + { + { 0xb22f28a, 0xaeb507c, 0x49a6b44, 0xa77458b, 0xc03dc17, 0x232ed5a, + 0x9c61ac6, 0x79dfc16, 0xcd71b93, 0x7c48be9, 0xc429cd9, 0x983d68a, + 0x98ae2c8, 0x7709c47, 0xa5df075, 0xe4765c0 }, + { 0x3367f33, 0x23c4deb, 0x37d72a7, 0xbdf2b7e, 0x0af2d26, 0xbaab5c7, + 0xfd026ab, 0xd609f7f, 0x541b039, 0x23b72b2, 0x83be852, 0x8d06bac, + 0xcb23d1c, 0x911d4a9, 0xfb0dbd7, 0xeae815c } + }, + { + { 0x2c33481, 0x487c35c, 0xb6136db, 0xffab636, 0xa3d3aa4, 0xccd4dae, + 0xc3704e0, 0x87149bb, 0xc0e8396, 0x9de8119, 0x58e7ca6, 0xd49357a, + 0x1562d75, 0x6878918, 0x5ab1fad, 0xc745381 }, + { 0x02c9b91, 0x0f15798, 0xb1ddde5, 0x7ffc3f0, 0x6aae50d, 0xa01d5e0, + 0xe279873, 0x6a97e65, 0xb5b1b41, 0x4bcf42f, 0x32f5982, 0x1c6410f, + 0x50701c8, 0xd4f7600, 0x873b90d, 0xff02663 } + }, +}, +{ + { + { 0xe5b2de2, 0xdc53ea2, 0x38acecb, 0x94b352d, 0x0d9d5e5, 0x37d960b, + 0x90bd997, 0xabd868f, 0x35a7376, 0x781668f, 0x10118bf, 0x043d597, + 0xf57928a, 0xd4da719, 0x983e46c, 0x01942f6 }, + { 0x728bd76, 0xab97fc8, 0x4b5c1c5, 0x825956b, 0xc82a104, 0x202809f, + 0xc8e3132, 0xdb63e9c, 0xc2181af, 0xa41c701, 0x43e066a, 0xd280180, + 0x24044ce, 0xc734e41, 0x505193c, 0x4d9ab23 } + }, + { + { 0xf9f0c3f, 0x0bcd42a, 0xb94a218, 0xda21a46, 0x0ffc788, 0xe55243c, + 0x47a5551, 0x318aae6, 0x79af9cb, 0x8c2938b, 0xec1dce5, 0x5d15232, + 0x8ad2e5c, 0x3d310ba, 0x94f792a, 0xd3d9724 }, + { 0x12a9553, 0xdeb4ca1, 0xeb54d9d, 0x2f1ed04, 0x69fb7a1, 0xaa9c9cf, + 0x54dcd3a, 0xeb73c3a, 0xf5f201f, 0xee3eddc, 0xba7d234, 0x35f9e1c, + 0xd2e242f, 0x1d1d04c, 0x0df7515, 0x48df9d8 } + }, + { + { 0xa81dd9a, 0x4ecc77d, 0x03aa015, 0xa6ac4bb, 0xbbc4fed, 0x7645842, + 0x9d6cf52, 0x9ae34cd, 0x5917e0b, 0xf8ff033, 0xc2cc175, 0x7c9da37, + 0xaaacfbe, 0x1e74dcc, 0x7999af8, 0xa8f2df0 }, + { 0x102a466, 0xd06c4ea, 0xae190dd, 0x2156e87, 0xec4a863, 0xc95db8a, + 0x244a6fe, 0x49edffd, 0x904f81e, 0x110fae6, 0xa1cd104, 0xbaa3e50, + 0x0478b65, 0x5bd38a2, 0xdaefbcc, 0x2b57d05 } + }, + { + { 0x86f4534, 0x1ce92ba, 0x414f5e3, 0xb2a8592, 0x9979436, 0xdd7a4c6, + 0x3f0add7, 0x7599aff, 0xe2d4f64, 0xe0ce4d3, 0x401a29f, 0x74475cc, + 0xa2377d9, 0xaef6541, 0x3f917b6, 0x54048f5 }, + { 0x05312ec, 0x1b86b22, 0x31493cb, 0x779ba22, 0xaac9320, 0xc718369, + 0x617fce4, 0xeab01a8, 0xf7187fa, 0x17b1f10, 0xa1aca46, 0xe68eda0, + 0x2586342, 0x61033fe, 0x0b6ca43, 0xfc14e79 } + }, + { + { 0x13d2491, 0x9f22319, 0x7997202, 0x66bdb53, 0x4617f34, 0x0bafb0c, + 0xf3bb7b3, 0x5917831, 0xb45bddb, 0x6feb2a6, 0x0202c19, 0x08662b3, + 0x05852f6, 0x0bc2b57, 0x91818c2, 0x2c00fd4 }, + { 0xda37dac, 0xca7672c, 0x5a30865, 0xfe4c04c, 0x322e92a, 0x5f1399f, + 0x25b1beb, 0xe7d67ea, 0xdce7f68, 0xe08b014, 0xf2f2b3c, 0x24df52a, + 0x750ecd1, 0x2028b23, 0xc810a45, 0x9b25d4b } + }, + { + { 0x7a9d799, 0xa35b715, 0x01f9c99, 0x6da1eb3, 0xe363ba8, 0x33ef91c, + 0xce140da, 0x21c0e2e, 0x158cd84, 0xb0b11bf, 0x93da438, 0x6a87442, + 0x3db585b, 0x924f10d, 0x10c6159, 0xf5ddd73 }, + { 0x6a74c21, 0xb72dcb8, 0xcc8f79f, 0x6d14198, 0x9c5a8d6, 0x99f4b6c, + 0x90e135c, 0x0639688, 0x83f6385, 0x330edb8, 0x9079675, 0xe1a5a6b, + 0xb8f5fe0, 0x6e37fa8, 0x61dca1e, 0x60e2fd9 } + }, + { + { 0x66c395e, 0xc6cb403, 0xb51d0f1, 0x03b21a7, 0xe693181, 0xbc478a5, + 0xc6cff33, 0x0017c2f, 0x39d8d1e, 0x740a5b8, 0x4d9ec6d, 0x3968d66, + 0xb0ef1b0, 0xfd53738, 0x1ed0a04, 0x73ca8fd }, + { 0x75ab371, 0x4ace938, 0xddad7e9, 0xd602936, 0x750bcc2, 0x1f5424a, + 0x68c7a17, 0xfe09b36, 0x58341ec, 0x165f7de, 0x6ce61e5, 0x95b825a, + 0x66c83c4, 0x9d31e19, 0xcc5887b, 0x65b3e08 } + }, + { + { 0x21482d1, 0xd37e932, 0x08b6380, 0x9af6597, 0x7d61e4b, 0x279426a, + 0x80997ad, 0x80dd0ec, 0xd5b76d4, 0x7239b0d, 0xe76c098, 0x92e6c73, + 0xeab3e1d, 0xeeb2321, 0xeb1a910, 0xa69c4a7 }, + { 0x833d9ae, 0x46d6aa7, 0x572b0fe, 0x3ee6957, 0xcdb3d97, 0x44ccbed, + 0xcbea01b, 0x342f29d, 0x8926876, 0x0d518c5, 0x5585d2c, 0xaaabae7, + 0xe008f58, 0xc548c77, 0x21fab2c, 0x819e2fa } + }, +}, +{ + { + { 0xc16e981, 0x468e149, 0x9ddbb7c, 0x286c790, 0xdb7a38a, 0x2a92d47, + 0x8a27cb2, 0xde614e6, 0xe5b0ab6, 0x8dc8822, 0xcf48565, 0x38441ae, + 0x089435b, 0x11ed5c9, 0x82d0d31, 0x2389286 }, + { 0x72f2f31, 0xc6698d4, 0x56d76af, 0x295242c, 0xeba563b, 0x4099205, + 0x3ab7384, 0xae7de5a, 0xd0ed86c, 0xccdf127, 0x965c3c3, 0xb9b6d5b, + 0x2c31ad7, 0xe351a8f, 0xac12f13, 0xa761dd8 } + }, + { + { 0xf171ab7, 0xda115dd, 0x401f93d, 0x2de17b1, 0x40964b4, 0x95019ca, + 0x65ba3c3, 0x169d1f4, 0x0090d08, 0x534a007, 0x82bf410, 0x805c5e2, + 0x65f8d90, 0x15dfe11, 0xca72456, 0x827a416 }, + { 0x33a36c4, 0x5af8884, 0xd8ee604, 0x8bfa54c, 0x9ce290f, 0x08fd141, + 0x287b3a6, 0x2db5e8c, 0x03cdad2, 0xe5be981, 0xbf810b9, 0x155b874, + 0x670f473, 0x2ae42de, 0x7f74657, 0x2218584 } + }, + { + { 0x23ffa43, 0x54b2a50, 0xa24d919, 0xcf87b16, 0x63524e8, 0x1ff5402, + 0x56d1e54, 0x73c94e0, 0x3899fb5, 0x7651552, 0x18723bf, 0x13a7214, + 0x3561517, 0x39afbdd, 0x9f2862e, 0x49b790a }, + { 0x527d2ce, 0xc8c1f4f, 0x7609bb7, 0x1997aec, 0x02a3400, 0x583ad80, + 0x4f79706, 0xac2374e, 0x21b7183, 0xbf1f9a8, 0x6600fe0, 0x06158ab, + 0xbd56751, 0xfcc9b2e, 0xddaaec7, 0xe1de5ac } + }, + { + { 0x788fdab, 0x230baa1, 0x7d04597, 0xf30860a, 0x99f4caa, 0xa2c7ece, + 0x6ad065e, 0xbd39f10, 0x3bef7bd, 0xfd92f5d, 0x96d2203, 0x6069fad, + 0xc4d9e0d, 0xbff38ca, 0x1fda313, 0x419a017 }, + { 0x572f035, 0x5d77fd8, 0xb282b40, 0x5af99f2, 0x23facff, 0x7257d3b, + 0x58c90af, 0xf2ee223, 0x9b6a52a, 0xcc2687d, 0x302430e, 0x140892c, + 0x3ec4f38, 0xa934d5e, 0x3bd18be, 0xc087d7c } + }, + { + { 0xa2c5ed7, 0x7e94138, 0x53610bf, 0xbc8ceef, 0xd86f803, 0xe89356b, + 0x5a55330, 0x9a3a380, 0x11ad648, 0xe894aba, 0xba95918, 0x2e68fba, + 0xfcad344, 0x643e2ba, 0x61640aa, 0x0dd0256 }, + { 0xe25cbdd, 0xc02e479, 0x13a1b3f, 0xd78c4d8, 0xcca9692, 0xa6dae8f, + 0xe5de8a0, 0x3dd91e9, 0x764ea36, 0x78ae0ce, 0x85dbc5e, 0xb4ad999, + 0xe82a169, 0x967ff23, 0xbaee1fc, 0xaeb26ec } + }, + { + { 0x9a6f90c, 0x8c50255, 0x0ea374a, 0x56e7abe, 0x56413b2, 0x675c722, + 0x946753f, 0xd3fc17e, 0xe235f7c, 0x28c4e1f, 0xb028eb0, 0xe209bcd, + 0x489fe88, 0x7d0f93a, 0x063706a, 0xb966a2e }, + { 0x4a30319, 0xb6c228c, 0xca6d674, 0x6868efe, 0x057311a, 0x0610a70, + 0xbad7f89, 0x0808112, 0x1dd6181, 0x2a2462c, 0xb58e88a, 0x52ed9fe, + 0x33821a2, 0xbbff16f, 0x17f882a, 0xda53e96 } + }, + { + { 0x8c30e5d, 0xb6ffca3, 0x5c905f5, 0xa90f991, 0xd753e88, 0x72fb200, + 0x7256c6a, 0xe509d4c, 0xd866500, 0x369e552, 0x33cf8ae, 0xee4b7e0, + 0xefcf6eb, 0x280d954, 0xd557f0e, 0x5b275d3 }, + { 0xb5cecf8, 0xeb17211, 0xbdb2f8d, 0xd6ad50f, 0x35e04b7, 0x2478c7b, + 0xac73bd3, 0x97e7143, 0x4817e24, 0x09d6ede, 0x2c405e1, 0x68fea71, + 0x05f67a1, 0x34adbc9, 0x73edf99, 0xd20ab70 } + }, + { + { 0x569f191, 0xe116a96, 0x4d6e29a, 0xb3f0bce, 0xf51dbab, 0x30b9e1a, + 0x346d276, 0x1dd36f3, 0x0749a27, 0x8315103, 0xab47f70, 0x242f148, + 0x5585681, 0xe8a5bcf, 0x5ed79ba, 0x8b80184 }, + { 0x3894ad1, 0xa4042fd, 0x2b88bc6, 0x82f781d, 0xbe4c397, 0x2d34cac, + 0xdd99c9f, 0x8731aea, 0xef1d382, 0x0f95498, 0xdd0bbc9, 0xcaba2e1, + 0x54064e8, 0x78889e9, 0x61a8ab9, 0x8cd9c97 } + }, +}, +{ + { + { 0xfa0459e, 0xf31f53f, 0x315cd6b, 0xf8742a1, 0xae64e97, 0xabe2f50, + 0x9b9da48, 0xbd78741, 0x51e526e, 0x4521a33, 0xe10ba45, 0xfa05935, + 0xe8f903c, 0x5c947e1, 0x5a754ee, 0x0aa47d1 }, + { 0xd814825, 0xb2849ef, 0x5c9968d, 0x9c2a5d2, 0x04e634c, 0x24dbb26, + 0xdb38194, 0x33f3a4c, 0xc8a2b6b, 0xe04f609, 0xabbbfdb, 0xcaefd8e, + 0x404498b, 0x683119a, 0x8b21cbd, 0x24ab7a9 } + }, + { + { 0x21fa2dd, 0x6f13269, 0xc10a4bc, 0xd79e61c, 0x4bd6d46, 0xac4b3ce, + 0xbd3f37b, 0x52459b6, 0xa396966, 0xce0f0a3, 0xa1ed488, 0x050d1d5, + 0xe0b17fa, 0x1b9c403, 0x04a2e66, 0xee1abd0 }, + { 0x5cf3e3b, 0x97065c3, 0xbe33441, 0x6513d5f, 0x79047ae, 0xcd34634, + 0xfd22df1, 0x45cbb1c, 0x967b17c, 0x7a173ae, 0x2223cda, 0x75f5ba7, + 0xefe0a73, 0xe3d12db, 0xfd7adcf, 0x3b7f94d } + }, + { + { 0xf1e9b7d, 0xd596a13, 0x6734e0c, 0x04f5bdd, 0x8be163a, 0x18b694f, + 0xd959fa3, 0x15620c7, 0x53d2a3b, 0x65fc2c5, 0xc4d36f2, 0xd44a364, + 0x268ceab, 0xc8b421f, 0xbfe2bd4, 0x564139a }, + { 0x19d4633, 0xb524610, 0x6346934, 0x5ab3f88, 0x9819422, 0x96691fe, + 0x8b39b82, 0xdfdec89, 0x97cfb27, 0x84b1c79, 0x4d6d004, 0xe59a98d, + 0x12c350f, 0x5e5d0c6, 0xd415774, 0xb431220 } + }, + { + { 0x6aae0a2, 0x3d0ca73, 0x48c2d8c, 0x7b1991f, 0x5cdae72, 0x00ae856, + 0xbd55128, 0xdbb6ca0, 0x45c82bf, 0x3c2ab2a, 0x79545ca, 0xea5a559, + 0xd5927d0, 0xeba9a26, 0x83257fc, 0xb52e401 }, + { 0xca9650a, 0x55ed517, 0xe3ebff2, 0xbdaa081, 0x9f8831b, 0x8cf7ce4, + 0x6e3b8d3, 0x1d0b5bd, 0xd8fc869, 0xa314a9f, 0xb892bab, 0x07f2079, + 0xa0cc9d9, 0xb700dbf, 0x6dc0a39, 0x7105a08 } + }, + { + { 0x8c7d901, 0x0c7e05d, 0xaf3182b, 0xa7ff681, 0xf9a0d06, 0xb88e3ca, + 0xc343b7f, 0xfe20a12, 0x03251f9, 0x9f02577, 0xc40c5eb, 0xf225ded, + 0xb208ea7, 0x50e0cec, 0xe6eeb65, 0x5b250f0 }, + { 0x4806b6e, 0x807a153, 0xfa94139, 0xded120a, 0x49366fb, 0x237ddc7, + 0x5a34bcb, 0xdd3674e, 0x9c4a61d, 0xef6cdff, 0xb2fb896, 0x036194b, + 0x9528cd9, 0x3865953, 0x6936a52, 0x0723c59 } + }, + { + { 0xe17719d, 0x1f84cd5, 0xc73b394, 0x545939b, 0x83e84e7, 0xefbf3c5, + 0xf77fd66, 0x6cc46f1, 0x1383ab8, 0xa629f59, 0xcd35cd2, 0x9177ffa, + 0x9dd411b, 0x039187f, 0x7b7eea8, 0xa9cf1cf }, + { 0xac47e5d, 0xa3b105a, 0xd0a9da4, 0xa755bea, 0x73da15e, 0x50cfbae, + 0x60b628c, 0x9456cbc, 0x9b7a910, 0x7ffc362, 0xcd6d6a4, 0x30b5924, + 0x0b04ab6, 0x198629f, 0x624dea9, 0xc74609c } + }, + { + { 0xaf12fa6, 0x27d4d77, 0x690aeb2, 0xdd8a216, 0xfe24417, 0xe48fc02, + 0x720e17e, 0x1970403, 0xce37b42, 0x95013fd, 0xde4bd9b, 0x06817d2, + 0x63d0ba2, 0xc5863e7, 0xa556f5d, 0xa1bafc0 }, + { 0x410a78a, 0xf28ec7b, 0x0a01a63, 0x0dcac42, 0xb5bce11, 0xfcd3fa4, + 0xd278b89, 0x054d7e5, 0x5ce49e3, 0x5195db8, 0x2c73d96, 0x4c0b167, + 0x20a1bdb, 0xd943077, 0x59c77a7, 0x66fa8b3 } + }, + { + { 0xd7462fe, 0xb9e93ae, 0x18dde4f, 0xbfe54b2, 0x3dbb08e, 0xaabb528, + 0x0e5fc45, 0x8c36702, 0x8e69be3, 0x3502888, 0xc12a11d, 0x6d2efc1, + 0xf265e30, 0xfce5ceb, 0x5742c7e, 0x58c8bb3 }, + { 0xccf7fa0, 0x32e89dc, 0xdd020a4, 0xa811f33, 0x5129fe5, 0xa10d620, + 0xe4ed29b, 0x3841c88, 0xd8b1ea6, 0xf3303a9, 0x1781f58, 0xa9a0cad, + 0x8f3ef0b, 0x4502b38, 0x74c6d35, 0x2b7587e } + }, +}, +{ + { + { 0x23ae7cd, 0xc6eaea1, 0x73c0caa, 0xa1884d4, 0xef1ea88, 0x901e76f, + 0xa14269d, 0xdb9935c, 0x947f1de, 0xe8b2486, 0xa657588, 0x4ad56f4, + 0x2913fb1, 0xe768054, 0x37600da, 0x2abff5d }, + { 0xa81a797, 0xa814813, 0x46acb69, 0x63e76a4, 0x4ab8277, 0xb103839, + 0x9d8e759, 0x587de34, 0xddf62df, 0xdfaeb8d, 0x9239d49, 0x24fe1cf, + 0xe130d1c, 0x7de7409, 0x581d070, 0x3ecfef9 } + }, + { + { 0xf87c72d, 0x8d177a0, 0x8c6d1de, 0xae7e581, 0x8cece85, 0x0077b5f, + 0x32d2187, 0x3824838, 0x6db2bd2, 0x49d8b15, 0xc8d85b9, 0xe9e5513, + 0xe05c53f, 0x63c410c, 0xd86f752, 0xceaf2fb }, + { 0x93806c5, 0x0b432fe, 0x3d06c75, 0x18eb15d, 0x12cfc02, 0xcaad826, + 0x1e2d045, 0x581e040, 0x95edcfd, 0xd573cb5, 0xdbc66e3, 0xce71948, + 0xacc14ea, 0xcf68721, 0x6cac4dc, 0xf68bea2 } + }, + { + { 0xcb74da2, 0xd8576af, 0xc433f46, 0x8771c29, 0xe2f5b8e, 0x7315af6, + 0xba33928, 0xc195481, 0x2fb1f94, 0xb77dcc2, 0xa610f75, 0xcb3e57c, + 0x53907df, 0xeb2a927, 0x23eff95, 0x916f149 }, + { 0xb6cd291, 0xbb378e4, 0x2f13ce1, 0xa2a5e2b, 0xbcd00b0, 0xa8a0e60, + 0x682b75a, 0x5902741, 0x3f65a77, 0xa0882c9, 0xc93cfff, 0x2069f75, + 0x70c0cb9, 0x1ede405, 0x0d526c4, 0x13840c9 } + }, + { + { 0x03ced48, 0xdc2caaa, 0xa0315be, 0x2079219, 0x3b1f642, 0xca49356, + 0xb0665f2, 0x0202dc7, 0xb7a5238, 0xe5d6bbd, 0x26eab32, 0x36fbd5e, + 0xf5819b4, 0xb3988f1, 0x4aa4d69, 0x5b15dc8 }, + { 0x54e5c24, 0xa52feed, 0xe91a797, 0x927471b, 0xd57f677, 0xd119bfd, + 0x78e4c4f, 0xde38f7b, 0xb150bc3, 0xa7af516, 0x26b76c2, 0x403b21e, + 0x92300dc, 0x589067d, 0x066802a, 0x04e406a } + }, + { + { 0xa9ca9bb, 0x28e7d09, 0xfccf4a0, 0xaa84fd5, 0x635b7ed, 0xdbe9fb8, + 0xd56fc7c, 0x9ede3f5, 0xb01cb29, 0xa4b5031, 0x7f93703, 0x584299d, + 0xb6fe825, 0xbd28868, 0x8b9c2d9, 0x1d385d4 }, + { 0x822be80, 0x6606f4a, 0x626d0fd, 0xb5a0165, 0x14568ad, 0x9920a20, + 0x1c6d174, 0x7d430f4, 0xe02e9e9, 0xc243e16, 0xa6bd649, 0x367f1d2, + 0x71b8c36, 0x6939100, 0x4de2984, 0x2ede131 } + }, + { + { 0x5beec32, 0xdc78187, 0xa525ff4, 0x1fff0cc, 0x676df34, 0x6e86425, + 0x3f638e1, 0x2b4e8a6, 0x9b1e59f, 0xc4991d2, 0x1589717, 0x399d001, + 0xbe041cd, 0x406464e, 0x9e65bb0, 0x901cb3d }, + { 0xfb42307, 0xf5f4572, 0xf1b7307, 0xf81b3b0, 0xf2094d1, 0x8fb695c, + 0xdb56f7b, 0x7db4792, 0x5a794e0, 0x36836d5, 0x09bc879, 0x2da477b, + 0x1887c40, 0x1cdfadb, 0xf2699b6, 0x65dc6c2 } + }, + { + { 0x4737972, 0x36f9f21, 0x7a387b0, 0x48f0c8b, 0x39a1d24, 0xa156ed3, + 0x0fed268, 0x375293a, 0x7ff75cb, 0xf679f48, 0x1cc9e62, 0xd15a00f, + 0x22c3877, 0x92a7dc7, 0x6fb0ed4, 0xe987063 }, + { 0x16f5f3c, 0xfd8e59c, 0xaeeb48e, 0x375732e, 0xca1ab42, 0x2dd9213, + 0x9ffccea, 0xcb06209, 0xb23edfd, 0xfc611f6, 0x99b060e, 0x2716349, + 0x820de8a, 0xb938b5d, 0xeb49a32, 0x138f6e7 } + }, + { + { 0xe485f70, 0x7feda63, 0xeb27b2c, 0x646380a, 0xc4511c7, 0xcf8fe32, + 0xff9406a, 0x2c68e1e, 0x20b6020, 0xa9f2fd9, 0x3b3e465, 0x1c98fc6, + 0x93e53aa, 0xb8dac35, 0xa750e96, 0x2fb47b6 }, + { 0x1950bb3, 0xea373ef, 0x4ac7aec, 0x8156694, 0xb55b931, 0x8d6b3c2, + 0xb62ef7d, 0x5d13f2d, 0xab9182b, 0x4647f2a, 0x33bf07c, 0x8f56c5a, + 0xb35a221, 0xc5ab284, 0x5a46a6b, 0x0747ab7 } + }, +}, +{ + { + { 0x86b85c5, 0x5b9236c, 0xc482448, 0x5967a0d, 0x7df6ae0, 0x397c955, + 0x5378f2b, 0xf83ee1c, 0x6e05dd1, 0xf82df65, 0x19d7c8b, 0x4c424f6, + 0xa6d5f2a, 0xa612550, 0x63c3ebf, 0xfe8482a }, + { 0x0142c82, 0xcb8d403, 0x3679e6c, 0x08b0662, 0x3eca5ee, 0x3ea5146, + 0x1370500, 0x089eb3b, 0x5a0d306, 0xcbfb19c, 0x42a65bb, 0x2f68588, + 0xe51e119, 0xe3e1db5, 0x110895e, 0x2c150e7 } + }, + { + { 0xf6d4c4c, 0xf323488, 0x63b87e2, 0x5fc931f, 0x35c759f, 0x8867da0, + 0x9746d4c, 0xb6f1eff, 0x990be0a, 0x8a8172d, 0x5c407b4, 0x1113eee, + 0x378ed8a, 0xd80dacf, 0x3fa7fd1, 0x99b57cf }, + { 0x5176405, 0xf5bb6d9, 0x92e83b5, 0x6b8963a, 0x8a7ef8d, 0xac55b6b, + 0x6c1fbf0, 0xe73fa12, 0x60148df, 0xdb37560, 0xf3f1fba, 0x72f1a98, + 0xea550f2, 0x1f71d0a, 0x9544a87, 0xc3ea4f0 } + }, + { + { 0x4322bf3, 0x5b09da2, 0x61264e1, 0x2a573d5, 0x803acc4, 0x93cb2e1, + 0xe502fc6, 0x397b4fb, 0x39e0ebc, 0xddfb212, 0xbbcbc57, 0xeccd8f5, + 0x4663788, 0x49d3bed, 0x1218df9, 0x37192aa }, + { 0x2ffa3c6, 0x8a05bc9, 0x23ebf4d, 0xc38c281, 0xfe343a8, 0xc80d547, + 0x6c63516, 0xa8d5a5b, 0x8d8fa6b, 0xc5d8ce1, 0x24a87c0, 0xeb5e872, + 0x75bfa23, 0x9806e9e, 0x689469a, 0x11f0889 } + }, + { + { 0x8e75666, 0x81005f6, 0xd349505, 0xb84d861, 0x9f321ea, 0xe083282, + 0xcfa33a1, 0xb751d7a, 0x067c550, 0x793cf6f, 0x1027e56, 0x073a6b2, + 0x66a6012, 0x53f40ee, 0xc210fa9, 0x70bfaa8 }, + { 0xe4b5998, 0x1518e39, 0x24b8d9c, 0x8f0b530, 0xafdf923, 0xd91c281, + 0x24e3f69, 0xc5cfb28, 0x870871f, 0x63a529a, 0x2128dad, 0x3d3e887, + 0xcb30cce, 0xed658dc, 0xafb7bae, 0xf9373b9 } + }, + { + { 0xde58ed2, 0x22d4dbe, 0x03f8789, 0x4fefc1d, 0x344817f, 0x6b0a1fe, + 0xa56b0b2, 0x96bef40, 0xda249fa, 0x32684ee, 0x524a91b, 0x8298864, + 0x0c736a1, 0xa958baf, 0xef2f3e5, 0xd033a7d }, + { 0x43f4d6a, 0x5be3edc, 0x9c89abb, 0x326a39d, 0x55d997a, 0x90c44f7, + 0x6e966c2, 0x2058106, 0x6548038, 0xdbae490, 0xd473fc1, 0xac7bc97, + 0x4b2603a, 0xb34488b, 0x5e9bb98, 0x27aea27 } + }, + { + { 0x1b88773, 0xa59e728, 0x0c241f6, 0xe2f05d4, 0x4e75749, 0xa56229e, + 0x1b10705, 0x8f00c0b, 0x19394d3, 0x8559946, 0xaaf5e32, 0x0d7e352, + 0x787b8ea, 0x526c462, 0xa179d48, 0x89297d9 }, + { 0xef43892, 0xeff17e6, 0x221f841, 0x17091eb, 0x4a4b848, 0x82f5eb3, + 0x8eb7b76, 0x6bea477, 0x76c536c, 0x21f2271, 0x96c81bb, 0xd9ef2c8, + 0x54bf4d3, 0x7c27546, 0xd7c28c8, 0x9dd4662 } + }, + { + { 0x20e1a6b, 0xe7fff00, 0xa08d467, 0x26a35c6, 0x3248c91, 0xb3c773d, + 0xba7d935, 0xa646615, 0xb0d26fa, 0xa91f453, 0x60c6d32, 0xdcf9c34, + 0x9e3e3dc, 0x6366861, 0xf30f3e2, 0x3012813 }, + { 0xc2fc61a, 0xac6623d, 0x2bfd2ff, 0x108dc25, 0x231d6ea, 0xd7f5c0d, + 0xad1107e, 0xa904f9a, 0x0d1e9c8, 0x46941c2, 0xc810cf2, 0xe5b6451, + 0x4f511d1, 0xaba8e67, 0x08373fe, 0x5b4b94f } + }, + { + { 0x849c230, 0x002d4e2, 0xd8ba391, 0x9bed0ef, 0x828e319, 0x745e0c0, + 0xca58de2, 0xcd40907, 0x1abaa4a, 0x2c87ab1, 0xdb64391, 0x3c17a97, + 0x86c72d2, 0x36b184e, 0x485f7aa, 0xb03d202 }, + { 0xde24aba, 0x2b6b79b, 0x2325fb2, 0xdcb7854, 0x66ebae2, 0xf5d1db9, + 0x903840a, 0x35a4d5b, 0x190e9da, 0x7afeb09, 0x35c1792, 0x1818f6a, + 0x3faa269, 0x90091fa, 0x2570235, 0xc4ccff6 } + }, +}, +{ + { + { 0xec85940, 0xa177619, 0x7ef7eee, 0xfca24db, 0x7a90c11, 0xb2450f3, + 0xdbf4f85, 0x29d256d, 0x51316c3, 0x920c8d0, 0x04474da, 0x2f7f7ba, + 0x2ec9a0b, 0x308117f, 0xd0d2085, 0xd0a231a }, + { 0x7ab641d, 0xf3288fc, 0x9f4fa32, 0xc68bade, 0xbbf8253, 0x768f014, + 0xc0a33f0, 0x5eff260, 0x6bb93ce, 0xc71b453, 0x680697f, 0xa71d045, + 0xce72bc3, 0xb62444c, 0xd1379f3, 0x11f03e8 } + }, + { + { 0xc16df92, 0x1f54789, 0xe3ed142, 0x874c642, 0xfa2a9f1, 0x6699f60, + 0x3fecfc1, 0xbd1b8d3, 0x8a3d953, 0x59682d5, 0x4a36b81, 0xf17c021, + 0x181a666, 0xeb9621d, 0x3cf1ad8, 0x7c2c3ab }, + { 0xe529f7c, 0xe6888c3, 0xb355315, 0x197b66a, 0x83e31ac, 0x63b558a, + 0x891c68e, 0x4aa7bc5, 0x592e360, 0xc17d989, 0x1363666, 0xc750a29, + 0x4909ac0, 0x0d53470, 0x4594a10, 0xd6d0272 } + }, + { + { 0x3fbb635, 0x35c541b, 0x5982afa, 0x50016d0, 0x96b0ca0, 0x58ebce4, + 0x577ea56, 0xb940027, 0xe38480f, 0xf29d305, 0xebd6a2c, 0x43705b0, + 0xe90c639, 0x0e4acda, 0xf56e05e, 0xbe94a29 }, + { 0x30659ad, 0xc61f4a0, 0xc402211, 0x39074ad, 0x51b621d, 0xfe0d8d5, + 0xd1d5222, 0x2d02e8d, 0x46c2683, 0x05ece3c, 0xc689d41, 0xf70705a, + 0x4d837bf, 0xe3caf44, 0x75ba6d0, 0xfda0584 } + }, + { + { 0xcb7d458, 0x1098163, 0xf5ba834, 0x12b645f, 0x28af72c, 0x70a3181, + 0xf32e5dd, 0x5f4727e, 0x10a21b4, 0x7cbae15, 0x6785389, 0xa80bf80, + 0xb8f93b7, 0x9827402, 0x08349da, 0xe385f82 }, + { 0x9589f6e, 0x2d05461, 0xe7c0191, 0x6aa5b26, 0xbd5574d, 0xe79ae12, + 0x4148e61, 0x5d13f91, 0x13716ff, 0x7b2be0f, 0x80bb81f, 0x82b0fe6, + 0x3e2569c, 0x697633c, 0x873f8b3, 0x6c1f083 } + }, + { + { 0x0be1674, 0x6e26d85, 0xab8044f, 0xe4e47f6, 0x82fc434, 0xfdf46e8, + 0xc89cadc, 0x639ae2c, 0x4b85bdc, 0x2244a52, 0xb7cf4ea, 0xb1e4790, + 0x7e0bb8f, 0x51dce03, 0x2716cee, 0xdd14335 }, + { 0x8e8841d, 0x1c049b4, 0xb97c621, 0x6bf26dc, 0xba01178, 0x21d6255, + 0x8e4f0e4, 0x477258a, 0x68f8ef1, 0xf5e437e, 0x8b03e1e, 0xd118fbc, + 0xe1c91b3, 0x3d6bc51, 0xd5b6907, 0xa259486 } + }, + { + { 0x7b6f5dc, 0x4159cfc, 0x493694a, 0x05a52b3, 0x83b8883, 0xeeb511c, + 0x2b06400, 0x19d79e4, 0x738f37e, 0x8e503a2, 0x5a94ad9, 0xa30e579, + 0x262618d, 0x3981c75, 0x2dcba19, 0x06b6c69 }, + { 0x4d1b051, 0xd7242ee, 0x3b350c4, 0x6274ccb, 0xf540019, 0x66df0bb, + 0x5ae12d5, 0x4d66be6, 0x1049cba, 0xcea2960, 0x8df84b3, 0x4047339, + 0x75a31c8, 0x7d6c96b, 0x874174c, 0xbb80159 } + }, + { + { 0x59f1aa4, 0xf0f7be0, 0xdcff451, 0x798f39a, 0x8014e1e, 0x96763ff, + 0x09cc5ec, 0x03987a8, 0x893650a, 0x4919656, 0x75e24df, 0x92e8eef, + 0xe89d639, 0x54e97cd, 0x7682cc0, 0x8081d06 }, + { 0xa8ceb71, 0xb9ef41a, 0xa4d7aaa, 0xb8173a4, 0xc54ee10, 0x93d81b1, + 0x70a445a, 0xabe1805, 0x64d569d, 0xac0ff97, 0x3e570be, 0x86946b2, + 0x4180641, 0x8e11dd2, 0x99f67dc, 0x3d0b33c } + }, + { + { 0x48bf5a4, 0x2c9637e, 0xccaf112, 0x9fdec19, 0x5c42023, 0xe5cde9d, + 0x878f0cc, 0x9869620, 0x1fe6eba, 0xcf970a2, 0x54e678b, 0x1df5ec8, + 0x28d00dd, 0x4667f01, 0xb0b3fa8, 0xfa7260d }, + { 0xb34239b, 0x6bd2895, 0x2d2a50d, 0x04c8bc5, 0x6cb23e2, 0x14e55ef, + 0x3a278d5, 0x6440c27, 0x2193046, 0xf4b12e3, 0x5dd4c08, 0x46adf64, + 0x4656e8c, 0x70e2998, 0xe4acd44, 0xe7b36ea } + }, +}, +{ + { + { 0x16cf664, 0xea64a57, 0x26fd357, 0x8497ee4, 0x814e851, 0x44d94b4, + 0x5a6a2cf, 0xf4aac22, 0x80c301f, 0x947b309, 0x7865383, 0xf390ba1, + 0xd1773d3, 0x16c4fc6, 0x6227220, 0x61b9814 }, + { 0x1dd0270, 0x07dd03a, 0x0f160df, 0x290ca82, 0x44ba955, 0x8f22054, + 0x0b6f1b3, 0x4e85e45, 0xad78089, 0xfd73ce9, 0x2f2cb0e, 0x67c1270, + 0xee33a61, 0xa7de0d7, 0x6553261, 0x6a811cc } + }, + { + { 0x2d0a427, 0x5ef0574, 0x220a341, 0xe8d2e95, 0x8044886, 0xdd28cbf, + 0xa1aa58b, 0xdad7b4b, 0x8ec901b, 0xb28f373, 0x5bbe3db, 0x1841a93, + 0xa075fee, 0x8fd7cd1, 0xc0d3cdd, 0x93b603f }, + { 0x5edd859, 0xca54fd5, 0x64ed687, 0xa4cb05f, 0xed1a3d7, 0x3138668, + 0xee32be5, 0x1224fda, 0xc80aeb3, 0xf1f532b, 0xe8d4d69, 0xa4f65d0, + 0x5905fe5, 0xc697a01, 0x6690ce4, 0x514da7a } + }, + { + { 0x3de4a55, 0xc7b9af8, 0xb318d93, 0xc79bad7, 0xf5b1c83, 0x1808071, + 0xb965b16, 0x92112ef, 0x7bb740a, 0x655ab38, 0x384ff87, 0x53dbc8b, + 0x72dc6f2, 0xd153c28, 0x99c7819, 0x2ec20e1 }, + { 0x3b854b5, 0x65e46ea, 0xc711db5, 0x272d5ae, 0x26e19e8, 0xfd1bb53, + 0x3dc0665, 0x33280b8, 0xb8f1c4a, 0x95b986e, 0xa685c4a, 0xa671fc4, + 0x83bdbbf, 0xa03cbd5, 0xab77544, 0xd329402 } + }, + { + { 0x8e62b35, 0x40fa651, 0xf9e55a6, 0x3913b11, 0x5270a41, 0x4e8089b, + 0x80d1886, 0x565f52a, 0x512749b, 0x93b5f05, 0x141c547, 0x35c869c, + 0xf86717f, 0x9a44a1a, 0x9c2b2cb, 0x2b9984b }, + { 0x4952322, 0x61fb607, 0x7af1464, 0x2d4072f, 0x600eb30, 0x9b2fa8c, + 0xf10668e, 0x6071fb7, 0x90634ca, 0x27cc24d, 0x471d32b, 0x3875bc2, + 0xa11210c, 0x678590b, 0xfcc5a9a, 0x352b447 } + }, + { + { 0x5fa3200, 0x795d541, 0xa92949f, 0xadaa557, 0x3cc88c4, 0x42fff06, + 0x71b68a5, 0x26d6831, 0xe67ad8c, 0x3286549, 0x86396b2, 0x5bf6363, + 0xe12c8ea, 0x41229b6, 0x748952e, 0x05320c9 }, + { 0x900b460, 0xae36b63, 0xf2b6aff, 0x9354ff2, 0x065ee0c, 0x10b810b, + 0xcc8bb38, 0x4d6925f, 0x7a22f14, 0x31c03fd, 0x57544e8, 0x76b7f44, + 0xc0eed26, 0x3a9123c, 0xe0cd1cc, 0x77acd67 } + }, + { + { 0x07ec527, 0x2e90530, 0x62937cf, 0x32388ef, 0xe229188, 0xa445389, + 0x33bcebe, 0xa44b68e, 0x4c4e701, 0x5a8722e, 0xcf07e41, 0xfd066e8, + 0x95fab62, 0xa3c1a4f, 0xe542f24, 0xb4d6a1b }, + { 0xaf6c9b5, 0xe6a92e4, 0xc83d61d, 0x9452484, 0x0062276, 0x422b55b, + 0x5279688, 0x261973a, 0x3999fb2, 0xde8be26, 0x7b029ca, 0x64e9628, + 0x06897d4, 0xd8edfaa, 0x6955511, 0x408319c } + }, + { + { 0x50a5632, 0xff6baed, 0x5c5885a, 0x922b7d0, 0x1b45864, 0xdf0f3b3, + 0xc04340e, 0x27e49c0, 0x122c447, 0x618c566, 0xeafee7e, 0x7863a38, + 0xb828cb0, 0x7143aff, 0xf9d054e, 0x51fcf4c }, + { 0x27f5e09, 0xc4a4b31, 0x90be2bd, 0x021f47a, 0x7ab956d, 0x1a06019, + 0x86ea86b, 0xe77fa15, 0xd550ef3, 0x9ccde87, 0x6532654, 0x7dee53a, + 0xe826387, 0x8b4f060, 0xad077b5, 0xda38637 } + }, + { + { 0x0e9fac8, 0xbc901b3, 0x6fb2a2a, 0xfa08204, 0x5e04efc, 0x92f68ab, + 0x9ac12d0, 0x184a30a, 0xb25d479, 0x1aa11aa, 0x0f03161, 0x8bc5f4c, + 0xcfc8817, 0x7e3a083, 0x597f93f, 0x84d9355 }, + { 0x239abc6, 0xc014478, 0x8d37b04, 0xb226b09, 0xf575789, 0xb056942, + 0xba745eb, 0x816b95a, 0xb98ddb6, 0x2a49d39, 0x291af81, 0xc41ca26, + 0xab26347, 0xb3afe99, 0x604b638, 0x59c31bc } + }, +}, +{ + { + { 0xc42befd, 0xa16a8b9, 0x2052f00, 0x731c9c9, 0x1f5dfa0, 0x1ad49b4, + 0xbffce36, 0x7a289e3, 0x0c79cf1, 0x868fac0, 0x86721ab, 0x6d6d284, + 0xe726c94, 0x590f928, 0x51f3841, 0x0e802cb }, + { 0x0b694bc, 0x6a6a57a, 0x8120fb8, 0xb9bb0cd, 0x9c05826, 0xad96ac7, + 0x7768df0, 0x294da8c, 0xb56c6c6, 0xfe32311, 0xae8d050, 0x291c2c6, + 0xe7db4c9, 0x1c765e7, 0xd65f9f7, 0xe058298 } + }, + { + { 0x7e8d345, 0x4bfa85b, 0xde1dfc8, 0xa04ef95, 0x324ace3, 0xb5f7f21, + 0x574b14a, 0x4b350a1, 0xf8e5c8d, 0x11436bf, 0x7642369, 0x1c789f9, + 0xfb623ce, 0xeb5e335, 0x442d562, 0x9deacd2 }, + { 0x531ee71, 0x4ff989f, 0xaacb52a, 0x43e2c49, 0x85bfadc, 0xa763198, + 0xd0161a0, 0x08b6d5c, 0x541f197, 0x010e3fa, 0x3279a16, 0x83a589e, + 0x6309f9b, 0xf099137, 0xf1cea10, 0x07c093b } + }, + { + { 0x33d2192, 0x1ce3f0f, 0xc37ce73, 0x07b559a, 0x207be27, 0xaa2ad38, + 0x7ed93de, 0x84f053b, 0x3b98a4b, 0xbc5c797, 0x63aa9b9, 0xc923461, + 0x231a10c, 0x807cc16, 0xa061209, 0x8ffdf57 }, + { 0x497070f, 0xa9ca741, 0xd113b3a, 0xf608ec9, 0x8d0384d, 0x5132726, + 0xf5ec307, 0x96686ac, 0x71c4665, 0x437bbbd, 0x7c379ca, 0xdef09d5, + 0x621747c, 0xf8be033, 0x8ae8047, 0x2775b37 } + }, + { + { 0xb2c4fc2, 0x4009798, 0x203772e, 0x148d7d1, 0xf8423fb, 0x9d9392d, + 0xaf8cef4, 0xa5bd72e, 0x4380b53, 0x579d58d, 0x8c39d24, 0x2ff88f1, + 0x5706466, 0x9ca2fbc, 0x1e56af2, 0xb42987d }, + { 0x5d94ea8, 0xcc2556e, 0x5369d76, 0x4e5c2b3, 0x2a94f9c, 0x5de3574, + 0x5cb4145, 0x8d068c9, 0x51bfcbf, 0x4d553ff, 0x8a23fce, 0x3ab7164, + 0xd0fa7f3, 0xc9cb3a9, 0xed9ced1, 0xf81209b } + }, + { + { 0xe5b66f5, 0xde7356e, 0xe8a25e0, 0x7b2bf1a, 0x2c9b725, 0x09a444a, + 0x4906c55, 0xfd8a2f4, 0x82514f3, 0x409cc80, 0x28999a9, 0x47e0099, + 0x6a312f4, 0x0a582a6, 0xf6723de, 0xf7946f8 }, + { 0x92d8aff, 0xa55f6ba, 0xa544b1c, 0xb62c3c8, 0x5c16a94, 0xa1d1411, + 0x2ad5e71, 0xc378319, 0x06b1dd6, 0x13d7847, 0xee7ff55, 0x99005f8, + 0x8a1e7d8, 0xfb5ea3f, 0xb4cac39, 0xdc7f53c } + }, + { + { 0x36e3794, 0x482abaf, 0xc74684f, 0xc23e9e5, 0xf1629be, 0x4544cf6, + 0x2f40374, 0xd8a8ee5, 0xf433bdb, 0x2eea87f, 0xae9990e, 0x489a99c, + 0x54b23b6, 0xefc131e, 0x8600270, 0x25fe699 }, + { 0xc059a7e, 0x03d2d9e, 0x6979c3c, 0xa6445b5, 0x9bfbcea, 0x491a10c, + 0xe937af1, 0x15b5974, 0x797c7fc, 0x4be8002, 0xfedcfee, 0xbed8a49, + 0xa9e0691, 0x35751ce, 0x9ef5982, 0xe9a9fa3 } + }, + { + { 0x3065de7, 0xeffeaca, 0xac4d4e2, 0x841d544, 0xcaf199f, 0x8144679, + 0x443967a, 0x98cf4f9, 0xf33183c, 0x8cd57f4, 0xc1b15eb, 0x390832a, + 0xa53b500, 0xc4b1fea, 0xdff24b5, 0xd762a10 }, + { 0xb0ee2a9, 0xccd3eed, 0x362d485, 0xa6dd4a9, 0xf1d047a, 0xeb4ff26, + 0x23860fc, 0xc0771fd, 0x4b64114, 0xdbb4e39, 0x4d29b29, 0x2ff3f24, + 0x387b365, 0x9cac005, 0xde5994a, 0x05b7aa6 } + }, + { + { 0xc03dd63, 0x5e71752, 0xbc74687, 0xad10fe9, 0x54c76ab, 0x51a5b0c, + 0x1f586d4, 0x763fd50, 0x816048b, 0xc7bd5ce, 0x3f744dc, 0x8fc83d2, + 0x109df9a, 0x0561802, 0xccf0e43, 0x18fb01f }, + { 0x038ab23, 0xe4606fc, 0xa664c98, 0x5878f1f, 0x5da7356, 0x3aedbbd, + 0x516746a, 0x3c578f5, 0x1a17210, 0x259477f, 0x028248f, 0xc7a869d, + 0x48cbf95, 0x6517a61, 0x3d04d47, 0xbc5f91d } + }, +}, +{ + { + { 0x083ca53, 0x15fd9a9, 0x2697ca6, 0x1161da0, 0x56b676c, 0xf516af3, + 0x75eec13, 0x8a420d5, 0x1a9526b, 0x72d6742, 0x76b463f, 0x8d8c29e, + 0x8815627, 0x38a4f58, 0xe0650f9, 0xf7e528b }, + { 0x382edca, 0x2cfa78e, 0xc4ad83c, 0x638d183, 0xe4a0119, 0x96d3b9d, + 0xa7c1101, 0x5769ccb, 0x2b8d04a, 0xc3b3b79, 0x4951bde, 0x96212f6, + 0x481161e, 0xad7905a, 0x41c5edf, 0x8fd6762 } + }, + { + { 0x39d6cde, 0xf7b0635, 0x115a84a, 0x69d0549, 0xcbd9fe4, 0x4a976c6, + 0x950ff96, 0xc92953f, 0x654d127, 0x1d7f0fe, 0xda0f75d, 0x7293870, + 0xcf2277f, 0x7bb3652, 0x834484f, 0x64798c9 }, + { 0xac3a76c, 0xb94d8bf, 0x7ff776b, 0xf5721a9, 0x2722e31, 0x23a6e9f, + 0x9a5c034, 0xe9da996, 0x456ebc3, 0xb9bbf83, 0x96956a4, 0x239f58a, + 0x18b7f00, 0x8b75beb, 0xa51cb97, 0x6c2b5b8 } + }, + { + { 0x7eb41f3, 0x78b1c62, 0x17c4352, 0x0638fcf, 0x0c5709c, 0x939edd8, + 0xedc906c, 0x0a8dfc3, 0xefb01ed, 0x3942f47, 0x49986fe, 0x4c82757, + 0x4dffa57, 0x792545c, 0x6c3ff26, 0xeee6883 }, + { 0x12b1218, 0x824d08e, 0x902457f, 0x515a478, 0xbae55b3, 0xc70cc9c, + 0xbcef9d4, 0x1240737, 0x2f9db7f, 0xf22e616, 0x91f8da2, 0x98c4f02, + 0xafaaa67, 0xa89219c, 0xe7d27e2, 0xf35fd87 } + }, + { + { 0x01b80d0, 0x19b0cd7, 0xf9aebd1, 0x3d7e29d, 0x0477cbc, 0xd39c9ca, + 0x5ff0d3d, 0xac0f615, 0x520fd01, 0x8a51993, 0xb22d6fb, 0x508ff54, + 0x318d3ab, 0x8786c47, 0x4a683f8, 0x4312c46 }, + { 0x95359f6, 0x73b1d39, 0x963011e, 0x0d94fa5, 0x9bfe83e, 0x5723af2, + 0x6841df3, 0xafa9001, 0xb7c498a, 0x791e92a, 0x7ea4253, 0xbc931ad, + 0xb783c06, 0x438e016, 0x2ca662b, 0x1347db2 } + }, + { + { 0xfbaa861, 0x41df37d, 0x329e4de, 0x98ecb23, 0x507e018, 0xdaf1560, + 0xb088e32, 0xa902269, 0xe4cab2f, 0xad898a5, 0x02c1e1b, 0xd84e9ed, + 0x8488af3, 0xc20a5d5, 0x6cc77c6, 0xc7165af }, + { 0xdeb7461, 0x8526f3a, 0x4a2d332, 0x03577b1, 0xe4760b5, 0x28e469d, + 0xb276266, 0x442c7f9, 0xf9c90fa, 0x90d5c77, 0x3e211bd, 0x7aa8716, + 0x5decfd6, 0x56d8ff0, 0xee23e6e, 0xa204b56 } + }, + { + { 0x4aceafc, 0x2e4374e, 0x6fcd5e5, 0x978743b, 0xc4855ca, 0xa0f6345, + 0xe98074b, 0x9bc7e4f, 0xc33d08a, 0x3835d57, 0x6f00566, 0xeec7c8b, + 0x1acf55c, 0x71628a2, 0x97fb19e, 0x5da3750 }, + { 0x01a7125, 0x6904a8e, 0xe6e3780, 0xad33c85, 0xc19f94a, 0x1702928, + 0x7c04b3d, 0xb424ff2, 0x19e2ba3, 0xb212e39, 0xc9af4c9, 0x4cca8e8, + 0xfd9bf0e, 0x98ab7ae, 0x9799db5, 0x21d245d } + }, + { + { 0xec08806, 0x6b034dc, 0xb40f2d9, 0xfd763f2, 0x29cb906, 0x5e16de0, + 0x8a0e16a, 0x02b7014, 0xe071e12, 0x463c8ee, 0x25ad509, 0x6447281, + 0xdc0e07a, 0x9ee6f2d, 0x68d4d97, 0x188895c }, + { 0xb27f971, 0x092fff3, 0xc9b7722, 0xb3c159f, 0x3cae42d, 0xe27d8ff, + 0xe87071d, 0xf8a5ed6, 0x607ebd2, 0x318388f, 0x53486f1, 0x924967b, + 0x7c46e1f, 0x7730494, 0xf21d196, 0xf279c60 } + }, + { + { 0x84f3201, 0xef2bc03, 0x1f94c51, 0xf8750c7, 0x986ec65, 0xbaa4f5a, + 0x2732a33, 0x6f8a5de, 0x299e365, 0x0f13d80, 0xe85261f, 0x2709530, + 0xf527d56, 0x097d922, 0xbe1f3f8, 0x4969687 }, + { 0x3e1708d, 0x9f3f504, 0x4aa4be4, 0xac67b87, 0x320a87e, 0x75fb042, + 0x6e2cad6, 0xa361ad3, 0x203e9f6, 0xcb01470, 0xc9b76c6, 0xe3807b7, + 0xb907c09, 0xf086833, 0x7e85a01, 0xe9bed3c } + }, +}, +{ + { + { 0x91780c7, 0xa7ea989, 0xd2476b6, 0x04e4ecc, 0xc494b68, 0x0af9f58, + 0xdee64fd, 0xe0f269f, 0x021bd26, 0x85a61f6, 0xb5d284b, 0xc265c35, + 0x3775afd, 0x58755ea, 0x2ecf2c6, 0x617f174 }, + { 0x5ec556a, 0x50109e2, 0xfd57e39, 0x235366b, 0x44b6b2e, 0x7b3c976, + 0xb2b7b9c, 0xf7f9e82, 0x0ec6409, 0xb6196ab, 0x0a20d9e, 0x88f1d16, + 0x586f761, 0xe3be3b4, 0xe26395d, 0x9983c26 } + }, + { + { 0x6909ee2, 0x1d7605c, 0x995ec8a, 0xfc4d970, 0xcf2b361, 0x2d82e9d, + 0x1225f55, 0x07f0ef6, 0xaee9c55, 0xa240c13, 0x5627b54, 0xd449d1e, + 0x3a44575, 0x07164a7, 0xbd4bd71, 0x61a15fd }, + { 0xd3a9fe4, 0x30696b9, 0x7e7e326, 0x68308c7, 0xce0b8c8, 0x3ac222b, + 0x304db8e, 0x83ee319, 0x5e5db0b, 0xeca503b, 0xb1c6539, 0x78a8dce, + 0x2d256bc, 0x4a8b05e, 0xbd9fd57, 0xa1c3cb8 } + }, + { + { 0xd95aa96, 0x5685531, 0x6bd51ff, 0xc6f1174, 0xc9c2343, 0xb38308a, + 0x2921841, 0x52ee64a, 0x78f3b01, 0x60809c4, 0xae403ac, 0xe297a99, + 0xcb09a5b, 0x7edc18f, 0x81ac92a, 0x4808bcb }, + { 0x34dc89a, 0x3ec1bb2, 0x4e39da5, 0x1e8b42e, 0xe526486, 0xde67d5e, + 0x76f0684, 0x2376548, 0x285a3dd, 0x0a583bd, 0xfe9b009, 0x3d8b87d, + 0x0413979, 0x45bd736, 0x38a727f, 0xb5d5f90 } + }, + { + { 0x4bde3ee, 0x7b8820f, 0x24d5170, 0xea712ef, 0xdf6ec7b, 0x517f88c, + 0x983ea9a, 0xb15cecf, 0x31a4592, 0x9eeee44, 0xebb013e, 0x786c784, + 0x1f4e15d, 0x2f06cb3, 0x4f4fda1, 0x5603fd8 }, + { 0x9e1321f, 0xf6790e9, 0x74a4c09, 0x274c66a, 0x9a41a4e, 0xa4b70b4, + 0xada5157, 0x7700bdd, 0x51be8dc, 0xe54a60d, 0x1a477e0, 0xfaf9276, + 0xb027eac, 0x6661c72, 0x280b917, 0x50e2340 } + }, + { + { 0x96ec123, 0x635f40f, 0x7a766a4, 0x4a33133, 0xb935587, 0x9ce4416, + 0x95d97e4, 0xbb6e1f5, 0x9d4197d, 0x2614723, 0x490e896, 0xabd4478, + 0x8bba895, 0xf6a1b2a, 0x5e27a45, 0x401fa40 }, + { 0x0620900, 0x7354ba5, 0x385678b, 0xc443a29, 0x53cf5fa, 0x48aba10, + 0xbbe152d, 0xd67e723, 0x2a63d68, 0x4b858e0, 0x72be4ee, 0x174e1ee, + 0x9ab8d46, 0xad0fbb3, 0xce17dd7, 0xa0fdffb } + }, + { + { 0x9c46fd8, 0xa1ea325, 0x9fb96ef, 0xeca122e, 0x6767acd, 0xf9074a2, + 0x2787082, 0x9b004a2, 0x7f3ba8e, 0x389f807, 0x0d5aabe, 0x6463de9, + 0xb090585, 0xf30ceaa, 0x5634ab8, 0x71b31e8 }, + { 0xaf02aed, 0x0dee65c, 0x20ac252, 0x506886e, 0x86b8a59, 0x0665f78, + 0xf2bb328, 0xb9b784d, 0xdc6b089, 0x46e443a, 0x66c27fd, 0x3d5de19, + 0xf0fde70, 0x0419265, 0x2b5c034, 0xed94612 } + }, + { + { 0x13b0056, 0x5a52ad2, 0xb909ee3, 0x9fbeb92, 0xbdaab08, 0xb42ba18, + 0xffc8a77, 0xec127c4, 0xfda906a, 0xc6d2985, 0x994bbe7, 0x5355547, + 0x9cdfd62, 0xa7470c0, 0xd2e675a, 0x31a3971 }, + { 0xcc8b356, 0x8d8311c, 0x01b4372, 0xabb0bf8, 0x0294566, 0x33c1cad, + 0xe07b672, 0xe2e649c, 0x2ae3284, 0x9084d88, 0x1835ce2, 0x7a90d4c, + 0x809d44c, 0xb4d1cd5, 0x9f0528f, 0x7822714 } + }, + { + { 0xbf5844b, 0xca884cf, 0x8524cf9, 0x9dd05c4, 0x36ba889, 0xdbffa19, + 0x29e7666, 0xef94fdd, 0x3eaf48f, 0x358f81b, 0x1530d56, 0x96734d5, + 0x4adf9e5, 0x378b2d1, 0x4731f61, 0x2f85046 }, + { 0x99dcb83, 0xd6ae905, 0x6199239, 0xa4f89e0, 0x8f0f958, 0x6405249, + 0xcc27707, 0x2866d99, 0xf551c0f, 0x64681a2, 0x4c37080, 0x2c7b0d0, + 0x00ac301, 0x218925b, 0x54df895, 0x8d57fb3 } + }, +}, +{ + { + { 0x809c8d7, 0xdaebde0, 0x0e95ea1, 0x58c761c, 0x00ae5e2, 0xbd99650, + 0xcd51acd, 0x6117a85, 0x7c55d56, 0xc4424d8, 0xdfbeeaf, 0xe9b1dde, + 0x0db4791, 0xda98bb5, 0x3fca108, 0xff3a5a6 }, + { 0x5ccbea1, 0x172fb8e, 0xa9f6cc9, 0x9fe12a7, 0x8967ce2, 0x1de4b0b, + 0x671dbc6, 0xc1ab60f, 0x5dedcda, 0x338385a, 0x3a043fe, 0x647a420, + 0x28ebc89, 0xe9abc64, 0x03ba3c8, 0xc357ff0 } + }, + { + { 0xde39ebd, 0x37061e7, 0x2be567a, 0xebb9135, 0xd6bb80a, 0xa9a6f6b, + 0x99f0ba2, 0x039345d, 0x98bbf47, 0x215494e, 0xa2a1ccb, 0xf2cb7a4, + 0x37f67c9, 0xf51aa10, 0x17fff71, 0xd29c85c }, + { 0x4d30b87, 0x8d4e4f2, 0x93a8309, 0x20fdf55, 0x757075c, 0x9b9f9cf, + 0xcd70101, 0x09142ad, 0x766ca55, 0x901d0ee, 0x32e418b, 0x6a5d86a, + 0xd7fcaec, 0x550ad92, 0xd91b26e, 0x64e8818 } + }, + { + { 0x47e5ee5, 0x5cea0f7, 0xbe99699, 0x8ca1d31, 0x5c136c7, 0x52db846, + 0x90e0d74, 0x8cecb38, 0xede2ad8, 0xb8efe9d, 0xf17ade8, 0x18d6ff8, + 0x2d66c20, 0xd222735, 0xf2005fd, 0xc46593e }, + { 0xf7141e1, 0xe5ebe6f, 0xe0126f2, 0xc968315, 0x1cb91b6, 0x95adc73, + 0x38a6003, 0x753b54c, 0x4230a61, 0xa614125, 0x559fece, 0x23ac6eb, + 0x3865c23, 0x9816b60, 0x543a570, 0x567014e } + }, + { + { 0xdd2b71f, 0xd46091d, 0x97d24ff, 0x3999a5d, 0x1ecff3c, 0xce2a4f1, + 0x581c6f0, 0xab2687c, 0xcba70b4, 0xa9fb2eb, 0x42093e1, 0x6fde356, + 0xaee724a, 0x00253ec, 0x2b81bdd, 0xa08ce3c }, + { 0x935a2b3, 0xa251238, 0x584f750, 0x8cae1d4, 0x988a219, 0x011469e, + 0x5a6a50e, 0x61f7ed3, 0x01fcebd, 0xe13ebaa, 0x31d8867, 0x794b976, + 0xcda32e7, 0xf25755c, 0x4564cd1, 0x368a97b } + }, + { + { 0xaa3397b, 0x0d22224, 0x38066db, 0x1dbb3e6, 0x0ce8e32, 0xfe0b5ee, + 0x7bab4dc, 0x09c17c8, 0xf188b64, 0x5cc65dd, 0x211b5fa, 0x74c4abf, + 0xab0ba86, 0xdcc17b7, 0xa535501, 0xfbdf46f }, + { 0xaca569e, 0x4775087, 0x06a1718, 0x6575f90, 0xb94de93, 0xb5c45a9, + 0x8497171, 0x0fc8006, 0x489f7ab, 0x775d965, 0xf5c0c89, 0x8775b58, + 0x1a06254, 0x05d4e20, 0xb6d73a5, 0x8cab349 } + }, + { + { 0x39465b0, 0xca78163, 0x14498fd, 0x3ef9148, 0x6255c11, 0x9ca1f34, + 0xb7f38f1, 0x389fd15, 0x354b8f3, 0xdac2089, 0xa840a70, 0x82d07fc, + 0x1dd483a, 0xf53fd73, 0x1590578, 0xa6e4eae }, + { 0x3c01b77, 0x7bf65af, 0xa75c982, 0x27542f3, 0x716cfce, 0xc5bd947, + 0x884b9e7, 0xba5fe76, 0xd55725d, 0x39bae14, 0xfae0eab, 0x982f64e, + 0x7a5293a, 0xcfae662, 0xd60f464, 0x22a25a1 } + }, + { + { 0x7dd5e16, 0x74caecc, 0xce7bca3, 0x23678a2, 0x57f1ba1, 0x4673932, + 0xa4c1697, 0x4eb9948, 0xeaba18d, 0x5d400e8, 0x9807871, 0x128d1c8, + 0xbff38a6, 0x78f9627, 0xa39d4cc, 0xf80b813 }, + { 0x31d3aad, 0x8aeefa0, 0x27db664, 0x5042199, 0x4cb6383, 0x244fc69, + 0x72192a3, 0x3190477, 0xbbfb57b, 0xcc86075, 0x4451511, 0xbae3a13, + 0xf6174f0, 0x16cf416, 0xd376813, 0xb343cc0 } + }, + { + { 0xd1824b7, 0x31ac9b9, 0xec8f61a, 0x6282260, 0xc781765, 0xbbeb9f8, + 0x2d110da, 0x06ab5c0, 0x47146b8, 0xd583e22, 0x4100d05, 0x79a1608, + 0xf0a5c95, 0x16dbbb4, 0xe331667, 0xfe2af1d }, + { 0xaf8710e, 0x26f0364, 0xeec08fe, 0x1cb8c91, 0x1d95e9f, 0x436bce6, + 0x57944a0, 0xfe9050c, 0x07b626b, 0x5f45acf, 0x9cf1276, 0x48dc93f, + 0xa05bfb7, 0x4491371, 0x4bcf785, 0x5106304 } + }, +}, +{ + { + { 0xed0b3b6, 0xac2e294, 0x671637b, 0x5c5ade6, 0x1140677, 0x2f289ce, + 0x754eb53, 0xaf446e2, 0x20421ad, 0x70911b7, 0xe0b7556, 0x4b73836, + 0x2a97827, 0xcadf104, 0x8005bc6, 0x4824e49 }, + { 0x937c28a, 0xb0eeccd, 0x0c3ee97, 0x1ce061d, 0x9f33faa, 0xcb07631, + 0xaea66dc, 0x9980bf4, 0xd111d98, 0x2bd0755, 0x7fe4de0, 0x43feaf6, + 0xb077b2f, 0xe76fb80, 0x5793b04, 0x227dc9f } + }, + { + { 0x14f49ba, 0xea24ae5, 0x11436e7, 0xbc39ea6, 0x78485d8, 0x9d7fed2, + 0xdf8b131, 0xb6ef00c, 0xfdbc7af, 0x0237b4b, 0x64ccd27, 0x08745b5, + 0xafc5a76, 0xaf8595d, 0x29f5500, 0x43657af }, + { 0x48470f8, 0x3007183, 0x640fd53, 0x51f91fd, 0xbe15512, 0x859c807, + 0xab3e9c5, 0x7d1a474, 0x81553e5, 0x5d714d9, 0x6f62310, 0x0757343, + 0x6b02a62, 0xedc5be0, 0xea47832, 0x5a4b9b7 } + }, + { + { 0xe93dbb3, 0x03e0a24, 0xcadc884, 0x25841dc, 0x8d10ad5, 0xabc1a81, + 0x2042ddd, 0x207e38a, 0xfeba8d8, 0x7fffbdb, 0xa3ec9b5, 0x74efebb, + 0x0b40a9f, 0x0bc39ca, 0x0267feb, 0x69ee9c9 }, + { 0xbc62919, 0xd402fac, 0x1cf53c6, 0xe9f8fc1, 0x7cc7d81, 0xe76fa5a, + 0x96bb19d, 0x4f2d876, 0xadc67c7, 0xd4fb7f9, 0x96702dc, 0x40621d5, + 0x438f6c5, 0x5b6a98e, 0xf1a1036, 0xa7c64de } + }, + { + { 0x9a092c7, 0x84c5e80, 0x11c22b7, 0x9e40e0a, 0xd06c99b, 0x820a091, + 0xeecca8f, 0x45fdc77, 0x5794f16, 0xfe1b8a3, 0x4ce3d6d, 0x31f7e5b, + 0x82c74c8, 0xfd5e010, 0xc1f6f7d, 0xfdabf30 }, + { 0xb9248a0, 0xbfa6017, 0x546b941, 0xe898d30, 0x207ff65, 0x878c492, + 0xb874e64, 0xbf22e8d, 0x53a547e, 0x43fdb1b, 0x5fbd464, 0xb66deda, + 0xc7ae1b5, 0x59127a6, 0x6a7515a, 0xa463646 } + }, + { + { 0xde9ab2e, 0x22c4e66, 0x0203c58, 0xfaf60c2, 0x0d5c5ed, 0xed2d7bf, + 0x4ca0f19, 0xdbc16fe, 0x465b979, 0x54e8ef6, 0xa310ef9, 0xe2d64b1, + 0x3778636, 0xa0f2c95, 0x281883b, 0xf3b4aa4 }, + { 0x9be6629, 0x4ac9af0, 0x1ca90c5, 0xba455e1, 0x856f492, 0x0147538, + 0xabd7840, 0xc80db7e, 0x6beb9cd, 0xb3526d9, 0x9d81503, 0x37657fb, + 0x193cec3, 0x8729a16, 0xd69952a, 0xd9a93fb } + }, + { + { 0x94f47c6, 0xfce0175, 0xe366d05, 0x228da21, 0xdc8baf3, 0x27ce0b2, + 0x6b4a951, 0x8cc660b, 0x384bb01, 0xf678947, 0x44d980c, 0xc629d7d, + 0xe85e81f, 0x47980e4, 0x1cd723e, 0xa2e636a }, + { 0x77fb207, 0x6b6ebae, 0x4c92891, 0x7017961, 0xb4d279c, 0x5569541, + 0x41758cb, 0xbb6b36a, 0x27a8e30, 0xecaa222, 0xb470ad9, 0x8b6746a, + 0x63e2d3d, 0x4c46017, 0xd3edaec, 0xe19c4ed } + }, + { + { 0x34718c8, 0x0b43fec, 0xf33499f, 0x553c407, 0x970d1db, 0x8272efb, + 0xa8e8d1c, 0x008c62c, 0x63eec45, 0xe4b79d7, 0xf2d71a3, 0x1fd4230, + 0xa368c36, 0x090fdaf, 0xfca7baa, 0xf62c101 }, + { 0xd2395b3, 0x1c9e6c8, 0x04c5513, 0x671ed63, 0x299a465, 0x577d933, + 0x63f9986, 0x286890e, 0xbfc979c, 0xd92a95d, 0x2b51019, 0xcebd79d, + 0x3d07251, 0xe74d88b, 0x906f9ad, 0x8b6db73 } + }, + { + { 0x7b3d90c, 0xc0c43db, 0x4304a06, 0x85d154e, 0xaf2f38e, 0xe8aceef, + 0x83d9459, 0x5e04293, 0x431afd1, 0x65e5e32, 0xa900a65, 0x9e5f050, + 0x8a26671, 0xcbaa171, 0x9c93de7, 0x33d0b24 }, + { 0xd5b6680, 0x3dcbf92, 0x20006f9, 0xc47e5ec, 0x9a51924, 0xc971129, + 0xcd0ed46, 0x665d9b8, 0xa5fcab6, 0xed2d63f, 0xcfbfc5a, 0xa817eb6, + 0xb76eb76, 0xb38169f, 0xf11160b, 0x8b93544 } + }, +}, +{ + { + { 0x693bdcd, 0x02eca52, 0x2ae01d6, 0xbbf0923, 0x8b44b3e, 0x0b0a2de, + 0xb250dff, 0xdb82449, 0x6e1c530, 0x0c42b86, 0xa64c2c4, 0xcd226dc, + 0xf046b5f, 0xcfb2bb1, 0x3fccb0d, 0x97e2fae }, + { 0x45ed156, 0xdf92907, 0xf641229, 0x224dcb9, 0x5f1f67e, 0x2126abc, + 0xe9c8a6b, 0xa7eed5a, 0x9857d9b, 0x40abedc, 0xde941c6, 0x3f9c7f6, + 0xd725ddf, 0x2158d42, 0x8c69543, 0xbdd1015 } + }, + { + { 0x8df2fbc, 0xa7dd24e, 0x13d1aee, 0x3adbcfd, 0x13b2177, 0xf6a32d1, + 0x7a9a14c, 0x89a7232, 0xdc65df9, 0xe3aef43, 0xa64d74c, 0xeaec3e3, + 0x4fec33b, 0x4d387d8, 0x21a2128, 0xaba2a05 }, + { 0x6b85e30, 0x2382c22, 0xcd2aad3, 0x4352d85, 0xd9772c4, 0xb0c6001, + 0x5f3653f, 0x7ed8263, 0x0300f47, 0x3626a6f, 0x6ca7e4e, 0x23909de, + 0xc154141, 0xb43dd81, 0x7e4bc68, 0x9a49fad } + }, + { + { 0x2428f88, 0xa3661df, 0x56e0db2, 0xbe48b02, 0xce79aa9, 0x3cd1871, + 0x23dddac, 0x90ab871, 0x71871a6, 0x9c58fb9, 0xa34910e, 0xf031f7f, + 0x81060e4, 0xb501eea, 0x791224e, 0xdb668ba }, + { 0x6a705bc, 0x240bbcb, 0x2d1865e, 0x7e76fbd, 0x2513641, 0x6e2cd02, + 0x46365c9, 0xe6c5225, 0xa5a01fb, 0xe46a8b8, 0xb67618b, 0x696fa7b, + 0x0db6792, 0x418b3b9, 0x7108b9c, 0x7204acd } + }, + { + { 0x8456b45, 0xb5a143b, 0xf53b4d9, 0x8a3ab25, 0xe13a570, 0xb112a58, + 0x81487d2, 0x613ca32, 0x3b1e7c9, 0x837d823, 0xd41e9d5, 0x592bade, + 0x5cd02f2, 0xdc1893a, 0x8972e23, 0x0879502 }, + { 0xcb76261, 0x7003c08, 0x332a5e0, 0x14bde9e, 0xcbbd78e, 0x14b2872, + 0xde238e8, 0x5594061, 0x067466c, 0xad12645, 0xf5e4952, 0xa8d0e64, + 0xc7f8d06, 0x5b44b82, 0xfb1b828, 0xb51bea8 } + }, + { + { 0x3f0dacc, 0xebad685, 0x1cbebbc, 0x5c31b8b, 0xfa5a2dc, 0x6746975, + 0x31d9faa, 0x2d95965, 0x00fc0e4, 0x343797d, 0x55fe01b, 0x38d821c, + 0x7323aa0, 0x0bfdb24, 0xf962a8e, 0x42613c4 }, + { 0xe134bc0, 0x599a211, 0x47a7084, 0x75fa4a1, 0x7f734b5, 0x6e71948, + 0x6dfca2b, 0xd5ced2d, 0x8aeabd2, 0x9fa0fdc, 0x12361da, 0x5e6b03f, + 0x5859fcf, 0xad23d31, 0x25a5fc8, 0x3120ef1 } + }, + { + { 0x8e9f638, 0x990ef62, 0x626a60c, 0xfdaa240, 0x2abddab, 0x4a3de20, + 0xd8872b2, 0xd5d10b7, 0x1ea5880, 0xa01b730, 0xa81b9d8, 0x481697f, + 0x3471ed8, 0x2984153, 0x292d37c, 0xefd73f8 }, + { 0x9994beb, 0xdda7626, 0x6a4f865, 0xa037703, 0xe5b47d5, 0xda992ec, + 0xe53edba, 0x912a427, 0x9264e45, 0x6467598, 0xaf71222, 0xd3b68c3, + 0x6dedc5f, 0x9d3436c, 0x076b2ad, 0x1e027af } + }, + { + { 0x4382f4a, 0xd56fca1, 0x8966b7b, 0x83712a4, 0xa4c9ddb, 0xd6b2cf5, + 0xf602875, 0xa66be29, 0x894f3d0, 0x70e4266, 0xb3195ca, 0x007d220, + 0x82c74d4, 0xba38d8f, 0xd975cbd, 0xdccc5fc }, + { 0xc88b38b, 0x03e1610, 0x52e0d8d, 0xeb9f9a1, 0xb646eb7, 0x6a57eca, + 0xc76b6c1, 0x161641f, 0xbd2e12b, 0xf9025ad, 0x5c0e26d, 0x87c74db, + 0xbfeca74, 0xed5cb51, 0xe34a08c, 0x603dfb6 } + }, + { + { 0xcb03307, 0xc4be728, 0xc2741cc, 0xde34c0e, 0xa74eb17, 0xe01db05, + 0x8905e4b, 0x1bfce0c, 0xd1b1826, 0xb18830a, 0xe87bbfb, 0xcacbb41, + 0xd2f1a79, 0x8696842, 0x08c83ea, 0xa80e5fb }, + { 0x3f1439c, 0xe48f163, 0xcd6987b, 0xc1d4108, 0xb751814, 0x05705c4, + 0xc1c622d, 0xa9bffd0, 0x46cd053, 0x23de4af, 0x39457c3, 0xf782f5e, + 0x5e5d243, 0x815276b, 0x6161ae3, 0x3132041 } + }, +}, +{ + { + { 0x77f2542, 0x2459661, 0x8372b25, 0x203be7e, 0xee2007b, 0xc7c9426, + 0x0621799, 0xc564138, 0xc28c3ce, 0xda56589, 0x7afc1e3, 0x13e8a7c, + 0xe352082, 0xdba81e9, 0x04435c7, 0xf430549 }, + { 0x691de4a, 0x4d26533, 0xfb777ab, 0x364408c, 0xeae7f88, 0xccdfb43, + 0xa525b11, 0xbc40f44, 0x3c60627, 0x8e112a5, 0xe17e696, 0x7f7c581, + 0x1ea774a, 0x0fd7878, 0x0b1f582, 0xd09e632 } + }, + { + { 0x70aab15, 0x44390bd, 0x889c3f2, 0x41112bc, 0xd685349, 0x6b02894, + 0x5584dfe, 0x7103001, 0x1ba7887, 0x373cb1b, 0x2a017c7, 0x53d286c, + 0x3c81fdc, 0x2ed0388, 0xfbcc6fc, 0x3bfc5e3 }, + { 0xfd6418d, 0xd38ac6f, 0xbfad89e, 0xc667e96, 0xeab4d66, 0x46f4f77, + 0x0911293, 0x194c04f, 0x68c48d5, 0x0fd09cf, 0x63cf7f4, 0x6f5b055, + 0xacd562f, 0x0c0a8c4, 0x36d965d, 0x94c1d83 } + }, + { + { 0xcaa127a, 0x94fc8f0, 0xd803690, 0xc762d5d, 0x1ebf0d3, 0x8bfdfd1, + 0x48eac50, 0xa98cdf2, 0x8b5ff10, 0x3d7365d, 0xc65b4de, 0x20dc29b, + 0x8ec7c68, 0x62ac28e, 0x90372d2, 0x7f5a132 }, + { 0x3246658, 0xf3d8a25, 0x9ac202a, 0xa4bebd3, 0x5cc1697, 0x078ede7, + 0xc8fc022, 0x5525800, 0x5fae77b, 0x302a802, 0x57917b6, 0x0180139, + 0x864bf55, 0x7c8806d, 0x12f06f1, 0x4e2d878 } + }, + { + { 0x3d66e88, 0x8d35118, 0xa91d02a, 0xfb861a1, 0x7850e5f, 0x8c27c2a, + 0xa5496f6, 0x9fd6399, 0x8080049, 0x52152ae, 0xfd1c2dc, 0x600e2ff, + 0xffe8b2e, 0xc75902a, 0xe03b175, 0x5c4d2cc }, + { 0x4f57e78, 0x8ad7c42, 0x1736f87, 0x77cf606, 0xf85038a, 0x2876012, + 0x1b97b95, 0xff32845, 0x392dfc8, 0x3cc6dd5, 0xa6f5075, 0x72f1363, + 0x71de894, 0x028ec44, 0x6f45a86, 0x7030f2f } + }, + { + { 0x9695817, 0x66400f5, 0xf20ea36, 0xeda0a7d, 0xd394992, 0x855be51, + 0x8336f62, 0x2d082c1, 0xf28c868, 0x30944dd, 0x0dc86d0, 0xfb5f853, + 0x564a0bd, 0x9562ae5, 0xb6b9b51, 0x1f7ea12 }, + { 0xd0a7148, 0x5bd74e0, 0xb91e572, 0x6c8247f, 0x47da498, 0x699aba5, + 0x1f7c814, 0xed82581, 0x62057b9, 0x434674b, 0x15c15b4, 0x8b4df5e, + 0xb110081, 0x2a97da1, 0x4c417fe, 0x2a96b0c } + }, + { + { 0x237639d, 0x4f75dfc, 0x1db7029, 0xe5ad6bc, 0xb3d28f7, 0xd43e06e, + 0xe447989, 0x89f3bb5, 0x01a1a6e, 0xc426a2c, 0x315878f, 0x33ea71c, + 0xb1b5705, 0x8a7784a, 0x77ca811, 0xa59e86e }, + { 0x36ae155, 0xddb133c, 0x0d51b42, 0x49f1d4c, 0x9d05519, 0x5508082, + 0x5291816, 0x20e23be, 0x67181ec, 0x35047ec, 0x7aad091, 0x6237dc4, + 0xe2e25a2, 0xa1d3ce1, 0x0d3db4c, 0x1de0522 } + }, + { + { 0xd9fd423, 0xe9a5e19, 0x9801e43, 0x0c2c3d0, 0x28df2da, 0x043c2dd, + 0xe1ad12a, 0x4eecab4, 0x9615aa5, 0x97e1797, 0xca7bb5e, 0xe57b879, + 0xcc92619, 0xa2a903c, 0xaa56e93, 0x5cef370 }, + { 0x7f3232c, 0xbef29fa, 0x2b7ad5c, 0x1cf35ed, 0x3b6077a, 0x35c4893, + 0x7a1d47d, 0xe065148, 0xce14572, 0xedb4673, 0x0b17629, 0xdc9e98c, + 0x9a02a5c, 0xef98ebe, 0x11d03c0, 0x1f772e3 } + }, + { + { 0x4608f72, 0xcbdbdcd, 0x5a13c6f, 0xb435223, 0x4bb3c21, 0xa6497f6, + 0x12c15c9, 0x3af2383, 0x6322d11, 0xfbbf4b3, 0xc641775, 0x520a5c6, + 0xe81e0e1, 0x18cd967, 0x3de3871, 0x980b2c6 }, + { 0x9ae44a2, 0xfa9db61, 0x176bc56, 0x0281dd2, 0x8a7f817, 0xfd03711, + 0x4129b30, 0x9c48545, 0x039626d, 0xb439648, 0xe4ada6b, 0x355050e, + 0x7f5d98c, 0xc9c16d6, 0x18c4d5e, 0xf53ccc3 } + }, +}, +{ + { + { 0x3ffb20b, 0x50ae942, 0x6865eb4, 0xa6c0b42, 0x09930f1, 0x4677f7d, + 0x4a16427, 0x742e0b6, 0xf976f9a, 0x521d18e, 0xa454749, 0x43ac9cf, + 0xc51f50d, 0xda3a91d, 0xad6f954, 0xf657029 }, + { 0x6b4f99a, 0xfe5f064, 0x63ad4ce, 0xd92a5d9, 0x2e0e081, 0xfcb5509, + 0x8d8a858, 0xadc85ab, 0x0632f0f, 0x8e9b966, 0x8d7216d, 0xe7a4f16, + 0x59c3b99, 0x00a4cc5, 0xba09dc1, 0xed6d0bd } + }, + { + { 0x1621beb, 0x7236d14, 0xbc7ca95, 0x1751fd4, 0x2f5319c, 0xaa619d1, + 0x4e9316f, 0xfc2b15b, 0x9fd4d33, 0x2d1a906, 0x8ced829, 0x28c3bac, + 0x1dd998f, 0xf2efab5, 0x3b149ed, 0x2c13330 }, + { 0xf601ac6, 0x65237c9, 0x07d6a45, 0xb54dd65, 0xfb1a4cf, 0xa1ce391, + 0x115f67e, 0x2957533, 0x465279b, 0x6456da8, 0xa993e02, 0x02890aa, + 0xb7175e4, 0x6891853, 0x0f3e59b, 0x3fda203 } + }, + { + { 0xd8c6e0b, 0xe99fe12, 0x5341c56, 0x7cb07ff, 0xdf77b24, 0xc292c7b, + 0xca29906, 0xf52dfd0, 0x772f02c, 0x4a6aa26, 0xe1bbd09, 0x26f7684, + 0xee7c2a8, 0xec56b2b, 0xad4a312, 0x67709e6 }, + { 0xc570263, 0x99c57b2, 0x2faafae, 0xeb0100b, 0xff25eca, 0x980d5d1, + 0x82cf936, 0xace35e6, 0x44679ed, 0x5a82ce5, 0x074b81e, 0x5c76a41, + 0xa00abb1, 0xf36fa43, 0x04ffb2d, 0x0642819 } + }, + { + { 0x04bdd28, 0x68f6bc8, 0xb5dc7ad, 0xc311d96, 0xed32e45, 0xff0d646, + 0xe0f712d, 0xaf3cdc6, 0xd483861, 0xd4508e9, 0x0e1c277, 0xb624be5, + 0xc5dd841, 0xc510275, 0x298dc02, 0x451c5c3 }, + { 0xdd34d6b, 0xf87d479, 0xdd06a38, 0xda7f293, 0xb699e9f, 0x575e129, + 0x215b2cc, 0x79e5fb2, 0x657e690, 0xd280028, 0xe702a71, 0x7fecd09, + 0xfa13677, 0x85160ab, 0xce65f64, 0x5de3427 } + }, + { + { 0xe8fff38, 0x84e4bf6, 0xb358b1c, 0x16f3725, 0x3b472a5, 0x360371c, + 0x52f217a, 0xe64c061, 0x0501241, 0x8e67379, 0xab2dd96, 0x88e81d6, + 0x1385604, 0xf3e218a, 0xe84184d, 0x9736caf }, + { 0xdbb93a3, 0xb55a043, 0x9301088, 0x335088f, 0xb2a4959, 0xcea7a2d, + 0xb882c33, 0x48e5d4a, 0xad46179, 0x114f09b, 0xb446576, 0x4416467, + 0x34c6c2f, 0x01cb23e, 0xa02db8a, 0xddebf04 } + }, + { + { 0x9bde8a1, 0x36d60cc, 0x676e4ad, 0x20fd2f2, 0x8936581, 0xebdcfb7, + 0xdbfc2c3, 0x245d0d5, 0xa9f82e5, 0x104c62c, 0xd654d9b, 0x7387457, + 0xae7f10e, 0xe966777, 0x1d8e582, 0xefeb16f }, + { 0x70364b5, 0x4faf4f1, 0xd612472, 0x0e1ab58, 0xfed6085, 0x11bbfe7, + 0xa59a09a, 0xb360a14, 0x722fdb6, 0x61d96e9, 0x94068bd, 0x16a12f1, + 0xf73c2be, 0x225bf07, 0xc8bd24e, 0x1e64665 } + }, + { + { 0x3698c75, 0x27a478a, 0x6202aa2, 0x778ccd3, 0x8d87f1f, 0x0149c63, + 0x784edae, 0xa660e5f, 0x82adfa8, 0xe0d4d2f, 0x1ba1f9d, 0xf512dd6, + 0x6245c58, 0x90cfed9, 0x18b53dd, 0x6c3a548 }, + { 0xbdc094f, 0x833f70c, 0xb1514e7, 0xa5f26f5, 0x1c8cf13, 0x93e7cf5, + 0x186ec43, 0x1436601, 0xe78170a, 0x81924ac, 0x8694368, 0xcc880a0, + 0x0b62cbb, 0x2dfa955, 0x96b4a2c, 0x0bc6aa4 } + }, + { + { 0x3561aa2, 0x5157a7e, 0x8645c1e, 0x525c500, 0xce7cbb3, 0x22feb4e, + 0xc89a58b, 0x36d0d25, 0xc9bde9c, 0x43131f7, 0x881f731, 0x74afdda, + 0x7c8e36a, 0x99ab87c, 0xc1d4fb2, 0xf07a476 }, + { 0xbebc606, 0x1b82056, 0xfcf089f, 0x95a1e5a, 0x2b55d5c, 0xc5bccfa, + 0x00eb0b1, 0x8fbc18e, 0x9efb483, 0x93a06fe, 0x2d74c57, 0xcafd725, + 0x3de4350, 0xc7518f0, 0xc6fd762, 0x9a719bf } + }, +}, +{ + { + { 0x2362087, 0x5ee0d83, 0x0b167e8, 0x7f2c0d7, 0x5e0e865, 0xb732789, + 0x98c4e65, 0xef5b2e8, 0x8fe9cc1, 0x222797d, 0x82d1e15, 0xfe6d73e, + 0xf62dc4b, 0xc7c0e9c, 0x937ceda, 0x962acfe }, + { 0xc1e85c7, 0xd763711, 0x2836978, 0x8f2dbbc, 0x8c44e98, 0xbadc055, + 0xa3e93f8, 0xed63eab, 0x41b55c7, 0x807e857, 0x6d1207b, 0xd51ae5e, + 0x39d541b, 0xa0ef9a6, 0xa0c56a5, 0x58855f9 } + }, + { + { 0x213091d, 0x7d88eaa, 0x45b6a0d, 0xcbdfee7, 0x4f5e077, 0x826a012, + 0x90f1e4c, 0xb04fc13, 0xaea69aa, 0x1961ac3, 0xd5bb63e, 0x3afb719, + 0x4ac7e5c, 0x2a37837, 0xc50ca45, 0x78efcc1 }, + { 0xb8abdef, 0x346e8f0, 0x88095d0, 0x27e3dbd, 0xffc6c22, 0x56d3379, + 0xfa4b291, 0x67d416c, 0x3b1b373, 0xc3baaf6, 0xdf73bae, 0x0184e1f, + 0x9167528, 0x38ae8f7, 0x35d6297, 0x7329d4c } + }, + { + { 0xf568c52, 0x45d2ac9, 0x9808593, 0x5134814, 0x31b7ed8, 0x0c92d83, + 0x0876ecd, 0x921327a, 0x052736a, 0xf752d75, 0xbc6b837, 0x7b56487, + 0xa23b4cc, 0x6b1a320, 0xec0d665, 0x1983937 }, + { 0x08554ab, 0x2c3017c, 0x366e87f, 0x40ad955, 0x8ed7f02, 0x88c4edf, + 0x3cc5e6d, 0x64a7db1, 0x2dc978b, 0x5ac91fa, 0x925d2a2, 0x016a20d, + 0xabb57b4, 0x3604dfe, 0xd7e2e85, 0xc3683ec } + }, + { + { 0x4c0c6d0, 0xc47150a, 0xe22adcf, 0x30af45e, 0x022ea4b, 0x39b5acb, + 0x77203b5, 0xfbe3185, 0x6fd9b59, 0xe5aaa34, 0xdd1c8dc, 0x0062c90, + 0x54049ac, 0xcf113f3, 0x63a31b5, 0xd8fba4d }, + { 0x1056a69, 0x73b5488, 0xd780bda, 0x3be6cbc, 0x30ba2b9, 0x5776ec2, + 0x8e8d6f7, 0xbe883cf, 0x5c2be6f, 0x64efe94, 0xf1ade8d, 0x064f704, + 0x743110e, 0x41cfd17, 0x4c20abe, 0xaac9411 } + }, + { + { 0xf1c1468, 0x91f9192, 0x4563e13, 0x8176e74, 0x0bda15d, 0xa48b5f9, + 0xda42af6, 0x2a085ae, 0x425c018, 0xfd38ab2, 0x08abafb, 0x2884ba4, + 0xcbd091d, 0x356f318, 0x817871b, 0x454e450 }, + { 0x8ada531, 0xe080e81, 0x3152ba8, 0xa40f1eb, 0x0c38eb1, 0x051049f, + 0xbd45003, 0x37e4bb3, 0x54a01e5, 0x6d09804, 0xeeb824a, 0x6de932f, + 0xdc93481, 0xccdef37, 0x93a05e8, 0x8633e07 } + }, + { + { 0x034675c, 0xbe94256, 0x08db789, 0x376c01d, 0x9af1b6b, 0x8707ee7, + 0x11bfbac, 0x633b3ef, 0xd06db60, 0x694f33f, 0xbb13407, 0x2a68bfc, + 0xda27c3a, 0x1c860c9, 0xd701ac3, 0xbca16de }, + { 0xc59ffd0, 0x2b76cfa, 0x54d718d, 0xf9a1165, 0x67f0878, 0xf86a1db, + 0xaf34e85, 0xe313e05, 0x3343159, 0xa188811, 0x0bb7ed1, 0xdbe4c3f, + 0x0c732bc, 0x73b67e8, 0xe74110e, 0xa4e1c87 } + }, + { + { 0x5c6770c, 0xce1106b, 0x5c0bcb7, 0x422c70b, 0x8195e7f, 0x32a3990, + 0x1ccd4aa, 0xa24968d, 0x720e557, 0x8f08ecf, 0x54bcc81, 0x5da10a4, + 0x6cd846e, 0x9d3c73b, 0x368d065, 0xaeb12c7 }, + { 0xcf9fd1b, 0x2110859, 0xee2bd6d, 0xd2a4801, 0xe9466ac, 0x376e556, + 0x3b5aa35, 0x767803b, 0xb8a89ba, 0x343f842, 0x6726bbf, 0x3263cc1, + 0x25871b0, 0x26caf17, 0x41b8578, 0xef66ad6 } + }, + { + { 0x638068c, 0xc9f2249, 0x1ccf9af, 0x96d282c, 0x69b435a, 0x71df30c, + 0xcb9d5c9, 0x88c943a, 0x2a8f378, 0xbf98ef1, 0x114c6ff, 0xffc1824, + 0xd52e8c7, 0xda3ad2c, 0x1afcb59, 0xf1222bc }, + { 0x0ee334a, 0x459e94b, 0x421933a, 0xd4477b8, 0xa1e401e, 0x60fb7b0, + 0x0d1e330, 0xfde6e82, 0x3233fde, 0xcecfe9b, 0x2e93523, 0x09ec466, + 0x30775b9, 0xa5ba649, 0xadf80f2, 0xcc397e5 } + }, +}, +{ + { + { 0x4ddc8a8, 0x2fe182d, 0xac056bf, 0x88d6e79, 0x0e41e4e, 0xc3ff2d1, + 0x2c3679f, 0x32ec7f9, 0x4e61051, 0x3561f09, 0x6c6250a, 0x4553f5a, + 0xdd25c5b, 0x2b765ef, 0x6a1cd7f, 0xe3a40a2 }, + { 0x5d821dd, 0xb27309b, 0xc2c17ca, 0x950fb8d, 0x8fb0d4c, 0xfeed015, + 0xf550179, 0x762c479, 0xe095840, 0x306cf44, 0xd379e66, 0x84b413a, + 0xbb2e4f1, 0xd6e5d5a, 0x94b085d, 0x8bc12b7 } + }, + { + { 0x04b5532, 0xc0d4cb8, 0xb9940a6, 0x7a31525, 0x68c69d1, 0x010e7dd, + 0x2a18c35, 0xd81f29d, 0x3f11e73, 0x08ae770, 0x6e55106, 0x5358f87, + 0xc960ef5, 0x299e8ca, 0xacfc8dc, 0x89a6fb4 }, + { 0x6dc7d4a, 0x5996a40, 0xe51b96e, 0x21e5112, 0x09a202b, 0x95b8c3d, + 0xd441f1f, 0x306ab0f, 0x98d4245, 0x2834fed, 0xd0abbde, 0xc29c387, + 0xb805c15, 0xf6a9bf1, 0xc4e458d, 0x602f4f8 } + }, + { + { 0xe5a893a, 0xf041486, 0x8934327, 0x53b891d, 0x4000758, 0x11e000d, + 0x662bad9, 0xa4ccde8, 0xb9a1b64, 0xe34d3ed, 0x84e7a6d, 0x72d9675, + 0x6627be4, 0x773da2f, 0xe835ae3, 0xa11c946 }, + { 0x650bc15, 0x02e8203, 0xe58b78d, 0x2d35936, 0xf21a3cc, 0xe9cfbe8, + 0x1049222, 0x55ad831, 0x38fff47, 0xbf99de4, 0x3831db5, 0xebbfd80, + 0xaf2af42, 0xe990636, 0xb7f5a0e, 0xc26ae52 } + }, + { + { 0xfa8f846, 0xb5d85b1, 0xb3b1455, 0x4166489, 0xd36a305, 0x768260d, + 0x4ff5645, 0xc6a8235, 0xd6e93e5, 0xd241cd8, 0xa406e74, 0xeed9aa1, + 0x5f600d9, 0x9e96ab0, 0x6eca2a1, 0xa26b8b5 }, + { 0xd705aef, 0x78321cf, 0xc0161ec, 0xc4fb6b3, 0x5199cf1, 0xdc32441, + 0xd0a5067, 0x33627d0, 0x15143ee, 0x13490cb, 0x85b4f44, 0x77e0ede, + 0x394b165, 0x904f12e, 0xefab32d, 0x90f50f5 } + }, + { + { 0xbc2de96, 0x4aa0a16, 0xaa9c12b, 0x172596a, 0x60e8a29, 0xd512e1e, + 0xf637e83, 0x77d35c1, 0xd2aae0b, 0xbb0d141, 0x8c03738, 0x8a878a5, + 0xab0e525, 0x6d24c01, 0xf760887, 0xb7d3136 }, + { 0x3f91b7c, 0xdbc3f8f, 0xa8722c0, 0xe7b4bca, 0xda0ae65, 0x3286a91, + 0x225b084, 0x8372274, 0xae1886c, 0x5884cd5, 0x3a23cf7, 0xb4e63ef, + 0xf2dd0da, 0xfe5f202, 0x653916c, 0x951fac9 } + }, + { + { 0x854fa4e, 0x05e2e8f, 0x1edaf10, 0xf411f94, 0xa0a928d, 0x26cc562, + 0x4abce65, 0x78fd34e, 0x98a32e2, 0x1d87609, 0x4c37518, 0x85dc76f, + 0x00e8021, 0xdcaeef5, 0x4e9b2a5, 0x7fcb2f8 }, + { 0xf382c06, 0x9eba91e, 0x24cae53, 0x2052e85, 0xf5c1519, 0x617336e, + 0xb4e632b, 0xf1546d5, 0xd7b8ffd, 0xa9edc81, 0x29ab68c, 0xdb2914f, + 0xdebbaba, 0xe805070, 0xc3b719e, 0x775e53b } + }, + { + { 0x065256a, 0xa40e294, 0x8fb031a, 0x9f11386, 0x059667c, 0xac03af8, + 0x0475f58, 0x432eb3a, 0x01faad0, 0x22332bf, 0xbc57a11, 0xc8132e9, + 0x3bc3f8b, 0x27d5a17, 0x930bf3e, 0x5471fc6 }, + { 0xe6bff40, 0xba28bc0, 0x555e564, 0x198d57e, 0x9c65b8f, 0x13ce831, + 0x5681b51, 0xb0a5c9d, 0xdeb9e11, 0x467588b, 0xbb4250b, 0xf1891a7, + 0xd12b433, 0x10b938b, 0x24dcda4, 0x0b8c802 } + }, + { + { 0xcf332d3, 0xc428703, 0xf2a5b98, 0x9d0053c, 0x7838a15, 0x4e4c620, + 0xfbf8a43, 0x2e92919, 0x21cd9a5, 0x39ad524, 0x1561588, 0x584ed6c, + 0x17a95c8, 0x20af305, 0xb70e1c8, 0xa223077 }, + { 0x2fa4871, 0x679cfea, 0xac633c7, 0x54f2a46, 0x4cdc5f1, 0x6030651, + 0x75a1dc7, 0xc4facda, 0x2d07d19, 0x710a288, 0x6b44992, 0xd55864e, + 0x454c5b2, 0x44d4b6c, 0x72f9981, 0x2855d28 } + }, +}, +{ + { + { 0xc7b0674, 0x4071b3e, 0xf8794d5, 0x800eb14, 0xbe6783e, 0x70573af, + 0x7785901, 0xafaa440, 0x405f32c, 0x112d2a1, 0x169b3e2, 0x3761a52, + 0x842a366, 0xe168b31, 0x9bf4734, 0x5bc322f }, + { 0x976c4a0, 0x36ef240, 0xfea4e64, 0x066f3d6, 0xa989e57, 0x0e954bd, + 0xf9466e4, 0xe36ef5e, 0xbeb9226, 0x6bb615a, 0x3d5a2ca, 0x5571e5f, + 0x4897a86, 0xa86efe2, 0x28a9f77, 0xed7e9cf } + }, + { + { 0x1f82c68, 0xdf10c97, 0x3b597e6, 0x796ba1e, 0xe718cbf, 0x1ac77ec, + 0x410eac8, 0xc8175bb, 0xbc555ef, 0x0cdf9a1, 0x7524e05, 0x6b889f1, + 0xae26d82, 0x6bf1e61, 0xd2e97d9, 0xb3f6ad5 }, + { 0xf226487, 0x94dcff9, 0xbe03dde, 0x60e6356, 0x6a3dd7d, 0xda1f93b, + 0x79ca90c, 0xf1be721, 0x1e6bce5, 0x05ed313, 0xd48af3e, 0xcf50908, + 0x61e554f, 0x3b0e85c, 0xa2778d3, 0xfe7e35b } + }, + { + { 0x75ac5a9, 0x42c5032, 0xda062c2, 0xa66a66d, 0xcaa7023, 0xa4f4f82, + 0x64b4f86, 0x489d476, 0x97311ad, 0x10b1088, 0x177b2ec, 0x55dd637, + 0x9a267b1, 0xa5ccff0, 0xff327b0, 0xf07690b }, + { 0x2250cd2, 0x39162ed, 0x8b255f1, 0x1426de0, 0x1bdd731, 0xf227afd, + 0xfa4c844, 0x78f8a36, 0x157379c, 0x267a211, 0xcc04acb, 0x3f05f92, + 0xfc69cae, 0x374496c, 0x16ebfec, 0xbf2c5d0 } + }, + { + { 0xd0518d1, 0x605418b, 0x9e1cbc6, 0x3237f80, 0x286c019, 0x37a7005, + 0xb15af0b, 0xf1fb0e0, 0xaa853c0, 0xfc3b97c, 0xe6beba2, 0x1f48bd0, + 0xe6a72f1, 0x8e5d7c5, 0x26ebf0c, 0x575e66d }, + { 0x62eae3d, 0x0994776, 0x96c9c65, 0x53f074f, 0xb81bade, 0x6cfbfdb, + 0x3fed7d1, 0x98b4efe, 0x38c3382, 0xdaa1123, 0x47b8ec6, 0xdf88b73, + 0x9504a4f, 0x9b0fe4b, 0xf30c1c3, 0x2e7df4c } + }, + { + { 0x2fc1833, 0x25380cb, 0x18d62de, 0xb8e248c, 0xd82f9db, 0x91c8f59, + 0x2444750, 0x5ec2b20, 0x66b6f74, 0x3f3a1f7, 0xdd7d14d, 0x0180aa9, + 0x2956b9c, 0xd0a342d, 0x7139873, 0x26e910e }, + { 0x139e23d, 0x2261dc4, 0xb8343dd, 0x7edb181, 0xb4038dd, 0xfcf1073, + 0xa3bfea3, 0x88870ef, 0x64a263e, 0x4e98ba9, 0x70811f5, 0x3c6e5dc, + 0xf86055d, 0x17d28f5, 0x66e4199, 0xca9c276 } + }, + { + { 0x964ef8c, 0x0b2d8bd, 0x88e2ba6, 0x5a99b85, 0x04498ce, 0x9e927b2, + 0x756eb25, 0x9ff20c5, 0x3f27736, 0x97cc27b, 0x4729583, 0xf32dd6d, + 0x0381a94, 0xbdc2658, 0xef2c06f, 0x70fef15 }, + { 0x49252cc, 0x50a6191, 0x236b4b9, 0x9eb4a14, 0x8e00f78, 0x9b1b215, + 0x6ea9c23, 0x27add36, 0xc3a8e79, 0xef61763, 0xd82ce56, 0xed4542f, + 0x0caed75, 0xa8737e7, 0xd452d76, 0xeca0ac2 } + }, + { + { 0x3d082d0, 0x20c0779, 0xc9e9f3b, 0x6e3ce64, 0x75a195f, 0xb3a4dce, + 0xbdd9f24, 0x3a3c305, 0x8688942, 0xe2545c8, 0x080f32b, 0xa463c82, + 0x42686b8, 0x4429748, 0x7213866, 0xf50e20d }, + { 0x3826e74, 0x265ac52, 0x228e8ec, 0x26fba57, 0xe6b3ed8, 0x8a1e1db, + 0xf0fe65a, 0x7c7b278, 0xc395234, 0x9a6df23, 0x0b0f114, 0x9956206, + 0xef90837, 0x440c8c4, 0x3645f65, 0x21ad22a } + }, + { + { 0xedd31b2, 0x1e023a6, 0x9ff8668, 0xf76d145, 0x17b45c8, 0x9707056, + 0x1e88e37, 0x0612078, 0x922faac, 0x85c51c8, 0x22756d9, 0x4df392e, + 0xa03c98e, 0x8907fd0, 0x52ea51c, 0x626f46a }, + { 0x486c8a2, 0xf8f766a, 0x88ed18c, 0x8c499a2, 0x3c4f0de, 0x44d2dc6, + 0x6f2a0b6, 0x47dde68, 0x4a973fd, 0x9a655f8, 0x786ac80, 0x3e7124e, + 0xe8a0574, 0x699e61c, 0x31cdd0d, 0xdf0ba9a } + }, +}, +{ + { + { 0xd73e69b, 0x76270ad, 0xc67d38a, 0x991120f, 0x9469f0c, 0x7be5830, + 0x7db40ac, 0x93aba59, 0x822fc08, 0x2b707bc, 0x69551cd, 0x4199fc0, + 0xf367324, 0x38deed4, 0x2228787, 0xca518e1 }, + { 0xd9a9277, 0x72f1bef, 0xe49ae90, 0x57d4aab, 0xdb23478, 0x13810d5, + 0x9b4b77f, 0x2a8b780, 0x1b4e004, 0xb542f4e, 0x3ec77f0, 0x4080fd0, + 0xcec6596, 0xb49e9fe, 0x3f16037, 0x20338d3 } + }, + { + { 0x53554b0, 0x4adcdae, 0xe04c4db, 0xfea4906, 0x7748233, 0x0808bec, + 0x47148d7, 0xde7477c, 0x03da38c, 0xdd9124c, 0x25ee8e9, 0x6b25031, + 0xb0d6161, 0xae67399, 0x82203b6, 0x70c4acd }, + { 0xd31dae8, 0x9683916, 0x1ac7f69, 0x3477503, 0x988e4ad, 0x9553153, + 0x53a15e1, 0xb58f411, 0x92ba2dd, 0xb65a2d4, 0xa90169c, 0x7c3efb1, + 0x6b1747d, 0x210f45e, 0xcff488d, 0x16e8d1b } + }, + { + { 0x9d703db, 0x252adf8, 0xfdfeb39, 0x259ac1d, 0x115e806, 0x7faf6af, + 0xc1aff21, 0x7aaefd6, 0x7c0113d, 0x8054210, 0xe19b4b1, 0x481f1a5, + 0xfcc8c61, 0x7c17d43, 0xbb0bbbe, 0x8b04452 }, + { 0x4cebae1, 0xe51e5f5, 0x56a414c, 0x05341ba, 0x7fb8a30, 0x0083a2c, + 0x77f4952, 0xb4663f2, 0x4bb0074, 0xce72eec, 0xa3584d1, 0x74fdd66, + 0xb02e076, 0x6b9e58e, 0x3b961f4, 0x5be45d5 } + }, + { + { 0x1ab2e0b, 0xc7474f3, 0xf4bf454, 0x2838ccb, 0xf3c3eac, 0x634392e, + 0x137602b, 0x440e40a, 0xd1ae8e3, 0xeea67e9, 0x77e221e, 0xafdf93a, + 0x2719a10, 0x3c9f3da, 0x32c8256, 0x466ecef }, + { 0xf9c432f, 0x1061c19, 0xb1c7d98, 0xa1332d9, 0xa425c2c, 0xbc735f2, + 0x4b1bccb, 0x1429cdf, 0x6bbb5f9, 0x77b42a1, 0x5955ae4, 0x30078e3, + 0x21cc315, 0x8acd777, 0xe86fa99, 0xaa90d5f } + }, + { + { 0x721115a, 0xfcfd460, 0x08269b8, 0x6a7de3e, 0x96dd47e, 0xe5964a6, + 0x8dca975, 0x6717cd5, 0x98b149e, 0x7ea4ebe, 0xb7b8057, 0x6f894d5, + 0x7f30e31, 0xbd6f960, 0x23df092, 0x61ca453 }, + { 0x9d782f3, 0x32241f9, 0x2abfae2, 0x55173b0, 0xd15bbbd, 0x0abe0ed, + 0xb438abb, 0xb6d3c0a, 0x9ffa20b, 0x62fb467, 0xd31560a, 0x30926b5, + 0x2a0aa6d, 0x44bf27c, 0x1a4cb97, 0xf747313 } + }, + { + { 0xb0535de, 0xa2f6c0d, 0xc855166, 0xcb02ae1, 0xb3422f0, 0xc699e6b, + 0x281ba8a, 0x774febe, 0xffabcc7, 0x1d9d24f, 0xfe12ba5, 0x0b31ba1, + 0x13d0af7, 0x4c86803, 0x2f47160, 0x90640d3 }, + { 0x5876603, 0xa0c4bf4, 0x950ab08, 0x717f6fa, 0xa710de8, 0xf12bb53, + 0x6a88f50, 0xc500c61, 0x2645351, 0x0070f99, 0x2446893, 0x57aab5d, + 0xb68f657, 0xd553fa8, 0x693c55d, 0xe8537c1 } + }, + { + { 0x7fc7684, 0x58e86eb, 0xbfc73a9, 0xdf330f7, 0xcc11936, 0x41e337d, + 0x6e35759, 0x36d9200, 0x3500d8b, 0x0132703, 0x9483354, 0xfa68405, + 0x667851b, 0xc8f2980, 0x18296b0, 0x538ec89 }, + { 0xcff55f9, 0xa2a2c4f, 0x60d20bd, 0xb260d4d, 0xd9cc59f, 0x3ed576f, + 0xd514fcc, 0x4ed8c64, 0xc22b315, 0x37ebfb2, 0x94c212c, 0xca67a36, + 0x3a1795e, 0x4f8e08c, 0x4e7261f, 0x498f926 } + }, + { + { 0xc59b3d4, 0xfea7382, 0x3f2925f, 0xb9942ed, 0x8ea77e8, 0xe4b00dc, + 0x3cab02e, 0x74a18ec, 0xef16d0b, 0xbbbb752, 0xffab032, 0x639da4f, + 0x3aa30f0, 0xc371a4a, 0xcaa175b, 0x8e26b22 }, + { 0x7e2b62e, 0x94e4156, 0x25a794c, 0x7cceea6, 0x479f015, 0x931d2f4, + 0x90b25b2, 0x946183d, 0x68a2807, 0x1504e97, 0xfa49ddd, 0xa7577d3, + 0xdd48699, 0x24fc87e, 0x3d7d99c, 0x9edefd6 } + }, +}, +{ + { + { 0x0f0b450, 0x0508b34, 0xc36f7f4, 0xe0069a5, 0x2a5a761, 0x2655664, + 0x848e04d, 0x0193fd8, 0x73fe2e7, 0xc108cf5, 0xfd787d4, 0x05eb0ec, + 0xff28985, 0x1555ccb, 0x651b995, 0xb5af09f }, + { 0xe1134be, 0x167d72c, 0x57c669a, 0xd6d98bf, 0x6dd76fa, 0x40fb716, + 0x2a41b31, 0xeabbf20, 0x09b75b0, 0x300ff0e, 0xd9a0c1e, 0x32b6fad, + 0x65a80e0, 0x8051883, 0x32110fe, 0x8bef693 } + }, + { + { 0xbef47d4, 0x637802f, 0x2d16eaa, 0xfac114b, 0x0415644, 0x7b3f3ab, + 0x2dd895b, 0x17ab8d1, 0x87195f3, 0x271b7fe, 0xa71f65f, 0xa3f867e, + 0xc80583a, 0x39ba40c, 0x56e1fcc, 0x6db0672 }, + { 0x06662a8, 0x4feab4e, 0xc74bd46, 0xc857415, 0x732b126, 0x18032ed, + 0x7a099ea, 0x87c8aea, 0x36fe0a8, 0xb4a7535, 0x27673f6, 0x33a98da, + 0x2b8e549, 0x3e40c02, 0x9a4c587, 0x2def1af } + }, + { + { 0xa8c9ad9, 0x9618b68, 0x49defda, 0xd70b4aa, 0x5f788ef, 0xae8b138, + 0xdd523f4, 0x87c3542, 0x5c5b004, 0xe42c705, 0xfa7df57, 0x6303360, + 0x5f6d068, 0x33e27a7, 0x8ff331a, 0x9b3268e }, + { 0x23ee0c3, 0x845cc96, 0xac80084, 0x003af70, 0x530c41d, 0x6a9f931, + 0xbb127f0, 0xa1d7051, 0xca36245, 0x642ce05, 0x0323ee9, 0xc34205b, + 0xb7b3513, 0x7cc8912, 0x076cbdb, 0x6252cc8 } + }, + { + { 0x7089522, 0x10e68a0, 0x58fc658, 0x36c1361, 0x74723a4, 0x490397d, + 0x519d56c, 0x42692c0, 0xf1ff235, 0x69d251b, 0xc2cbf37, 0xe689d03, + 0x825b7f4, 0xf04ceba, 0x2281c2e, 0xd6b9bee }, + { 0xe0043ab, 0xc52ef3f, 0xd1d1be8, 0x351bf28, 0x0f18a5a, 0x277615f, + 0x5d6800f, 0x31f717f, 0xab922e2, 0xf5fb82d, 0x2d6ae43, 0x99aee2f, + 0xc63b982, 0x42477fe, 0xa594a01, 0x904aeb1 } + }, + { + { 0xeb39974, 0xaa82174, 0x95e6aa0, 0xbc38e61, 0x25c0675, 0x6a3df8a, + 0xffbe739, 0xf324203, 0xa3f0649, 0xfa5a0b4, 0x7a7a6b8, 0x79c8732, + 0x40ad3f5, 0xeb65ecd, 0xe4e45c5, 0x718d416 }, + { 0xe2326fd, 0x029dbf4, 0xe7942f0, 0x0c63416, 0x6f4e678, 0x6d0c728, + 0xa138601, 0x59f0b10, 0x8d92ea9, 0x8a1d978, 0xc22eca5, 0x9f8d712, + 0x7b6b96b, 0x7397044, 0xe6fb955, 0xa2d49ee } + }, + { + { 0xbf14a19, 0x249f900, 0x63a8cd2, 0xd3522da, 0x86964d2, 0x28a32f3, + 0xc1fa743, 0xacf712b, 0x0bb94d3, 0x98a9bfc, 0xbc06824, 0x318ece1, + 0x4fce7f0, 0xfc47675, 0xe4135b7, 0x19caec9 }, + { 0xc6817bb, 0x6de68a8, 0xf3b6d89, 0x7121960, 0xf5a818e, 0xa7d4261, + 0x9157455, 0x0c0ba51, 0x450d5ff, 0x78b6acf, 0x4e8649a, 0x198b493, + 0xfd05da3, 0x0941a3c, 0xdb55951, 0x264ea4a } + }, + { + { 0x46e5a31, 0xcfee91c, 0xfff7366, 0x47b6806, 0x5df849d, 0xdb14be4, + 0xac66cc7, 0x3c5e22b, 0xa5f4769, 0x7f3f284, 0x383be36, 0x4e00815, + 0x8072b0b, 0x39a9f0b, 0xc7eadd6, 0x9887cd5 }, + { 0xb659511, 0x7dd8f05, 0xd2e1cb9, 0x15c796d, 0x0d31345, 0xe5edb0c, + 0x6939c60, 0x2025df0, 0xbf15de1, 0x6314c08, 0x04c7fb5, 0x03c1548, + 0xbb5d3ed, 0x413337f, 0x477e983, 0xfc20b40 } + }, + { + { 0x5db0ef9, 0x7f96880, 0xe9c2a70, 0x05562de, 0x7dae133, 0x071e5bc, + 0x237fc4a, 0xa8cdd12, 0x4ea492b, 0x6d565e7, 0x381ee52, 0xa17cf94, + 0x9f5c546, 0x6ab8a4e, 0x40288ef, 0xbb642f3 }, + { 0x5df5c2d, 0x64e5921, 0xbb906f4, 0x43696e3, 0x74ae46c, 0x73a841a, + 0xc506b8a, 0xe264883, 0xa1be548, 0x9542e1a, 0x5e81b4a, 0x8938539, + 0xeaca6ce, 0x5642cfa, 0x806e0f9, 0xed8077b } + }, +}, +{ + { + { 0x7e13597, 0x1c776c4, 0x9e584fd, 0x0ec8b28, 0xb8b61e8, 0x0bb6043, + 0x9cd835b, 0xdcc1748, 0x39fef9a, 0x493e6ac, 0xd133e17, 0xb44eb34, + 0x71cb6f9, 0xfebcd00, 0xd20eff2, 0xe6cf543 }, + { 0x0a004c7, 0xf265cad, 0xd35cc12, 0x9b06c9d, 0xcb4ea53, 0x769f985, + 0x0993434, 0x29160a2, 0x8d939c4, 0xdf8dd10, 0x6711e2f, 0xefa177c, + 0xcd7a2cd, 0x1695790, 0x77f6642, 0x38da3d7 } + }, + { + { 0x6307b74, 0x9bfcfd9, 0xbfdabc3, 0xc26a36d, 0x4abe28e, 0x9341be0, + 0x73d1387, 0xdb20b52, 0x3d1949c, 0xf8d229c, 0xb8b3a41, 0xf1e0afe, + 0xed565d0, 0x29c60df, 0x8b43b2c, 0x6930bb5 }, + { 0xfc0718f, 0x1d76527, 0x1f67189, 0xdb98143, 0x51f32cc, 0x0c62f64, + 0x8bd35e5, 0x70a6626, 0xc1cece7, 0x1725641, 0xf96f4a4, 0x7f130a8, + 0xf06ee98, 0x72319e9, 0x67bf9b2, 0x215b738 } + }, + { + { 0x0aaddd7, 0x8d1bec2, 0xb8be4f9, 0xfb8b95b, 0xfde1026, 0xeac193e, + 0x9d5860c, 0xa5edea7, 0x44280d3, 0x4adbaea, 0x38f4798, 0xce8b670, + 0xec30dea, 0x914c107, 0x000776b, 0xbdc5cf7 }, + { 0xa206a13, 0xb6fd7d1, 0xdae986e, 0x9941eba, 0x1f1caaa, 0x76c27a8, + 0x3f108b4, 0x6967c12, 0x4aea2d0, 0x6f11528, 0x144ddac, 0x9bb4319, + 0xc8ec6fc, 0x1a4d3ea, 0xbf37420, 0xfe4b0b8 } + }, + { + { 0xec0ac6f, 0x5d9a4a1, 0xfc7c80d, 0x84b79f2, 0xc14fac3, 0x64222f7, + 0xc23b3f2, 0xdd9e039, 0xea956bb, 0x4a84abd, 0xebe09dc, 0x370dcba, + 0xe0eaf82, 0x79a9ea8, 0xaee375f, 0x4cfb60a }, + { 0x9106827, 0x6a10dbf, 0x43f305b, 0xa3ba5cf, 0xc1bb083, 0x481b885, + 0xb3117b1, 0x2f52380, 0xddd6791, 0x0066122, 0x63bace3, 0x4f8923e, + 0xecb88d4, 0x5c5f499, 0x3bac146, 0xfdc780a } + }, + { + { 0x7ba1f71, 0x34b70ae, 0x45bd184, 0x9091829, 0xe707313, 0x3b39778, + 0x6164e91, 0xdeefc5e, 0x4971f39, 0xbb55bed, 0x8dafc8b, 0x7d52339, + 0xa6adf0f, 0x82391bf, 0xe319522, 0xfd6f90a }, + { 0xf29bbc9, 0x60fdf77, 0xaaa4030, 0xeff9ed8, 0xf8c0d3f, 0x978e045, + 0xeed65cd, 0xe0502c3, 0x3cfd4c8, 0x3104d8f, 0xa639005, 0xab1be44, + 0x9eeab3f, 0xe83f431, 0x451d797, 0x01970e8 } + }, + { + { 0x3180f4b, 0xbc972f8, 0x617779d, 0xac053c0, 0x7fa149f, 0x89392c5, + 0xbcb6263, 0xdc4699b, 0xce12882, 0x0ae8b28, 0xaf1a4dc, 0xdca19a7, + 0x64e1a74, 0xd3d719f, 0xaffdd5d, 0xbb50201 }, + { 0x7ac30e9, 0x56f7310, 0x1878900, 0x65cc9c7, 0x27338a3, 0x83f5866, + 0xac5bb13, 0x122adef, 0x1bcd4d5, 0x97de200, 0xb8aa3a0, 0x6ed3985, + 0x6821f9b, 0x8680f1d, 0xdda9f98, 0xcb42028 } + }, + { + { 0x0ec2db3, 0xcdb0708, 0x3dad1a1, 0xe28c833, 0xde2da07, 0x2093e32, + 0x83b8987, 0x7317073, 0xf552b8d, 0xad17871, 0x51cf70a, 0x846da98, + 0x5c4f5e1, 0xf94a16e, 0x0f8348a, 0x8429996 }, + { 0x98db78a, 0x4bf3f68, 0x3d19b52, 0xad77fa8, 0x8b972dc, 0x6976772, + 0x5321be0, 0x7dfa35a, 0xdd344a6, 0x9881846, 0xad4e2a8, 0xe550292, + 0xbc68bf1, 0x8075217, 0x893be15, 0xdd837c4 } + }, + { + { 0xd4fab5b, 0x09c931e, 0xb77a0f1, 0xb2dcf08, 0xe0d38a6, 0x7dac5c0, + 0x0ae73af, 0xa5570b0, 0xf5aed28, 0xc7c19d3, 0x5251e92, 0x575fa6f, + 0xcdf7275, 0xb843cd6, 0x9a01287, 0xd9d3d8e }, + { 0xb3c370b, 0xf94e356, 0xfe464b0, 0xc62b99f, 0xa986057, 0x7792650, + 0xc4b1874, 0xeaa67d5, 0x0b07078, 0xba1ba4d, 0x7a03699, 0xdbf636d, + 0xedd32a3, 0x1a16c34, 0xa45cb5d, 0x6ce2495 } + }, +}, +{ + { + { 0xa684441, 0xd7c4d9a, 0x30cd42a, 0xce62af6, 0x43014c4, 0xcd2669b, + 0x6f65b24, 0xce7e711, 0x576fa19, 0x1847ce9, 0x9dd8ca6, 0x82585ac, + 0xb42e1db, 0x3009096, 0x384ab8b, 0x2b2c83e }, + { 0xb4e9a6e, 0xe171ffc, 0x7374b40, 0x9de4218, 0xdb1d616, 0x5701f9f, + 0xa3e8cbc, 0x211e122, 0x1e400bf, 0x04e8c1a, 0x0f37159, 0x0297470, + 0x3df8c28, 0x41775d1, 0x61ac2db, 0xcfaad4a } + }, + { + { 0x7dc0f49, 0x6341b4d, 0xf471a53, 0xaff6c2d, 0xfb8e91e, 0x20ec795, + 0xc3b7b62, 0x4c7a4df, 0xd374938, 0x9f33ff2, 0x3a60f2e, 0x38f8c65, + 0x2efef73, 0xc1168ac, 0xce408ee, 0x046146f }, + { 0x308b0c3, 0x9b39ac0, 0x36b8570, 0xe032d61, 0xfc4aacf, 0xee07d8d, + 0xd5a41dd, 0x0a82acb, 0x7c3d726, 0xbe0ded2, 0xb926ce9, 0xce51d60, + 0x5806c1e, 0xfa2f7f4, 0x1dec59c, 0xe367c6d } + }, + { + { 0xda2547b, 0x64511b6, 0x0761405, 0x76a349c, 0x01223ab, 0x37d6626, + 0xf4d7c48, 0x0e243c1, 0xda756a0, 0xdc9c8b4, 0xd72e7e9, 0xc7430df, + 0x27b4210, 0x0eb1308, 0xcf11cbd, 0x7a9c044 }, + { 0xe8dd150, 0x2c08ff6, 0x2932fc6, 0x18b738c, 0x04513e8, 0x07d5651, + 0xaa40a17, 0x0ca5cff, 0x01baa8f, 0xd486341, 0xb72b79e, 0xfb20faf, + 0x654020f, 0x1a051e5, 0x4e17f23, 0xe3b3317 } + }, + { + { 0x4de9428, 0x0591048, 0x5abdf97, 0x620542a, 0xa16a4d1, 0xaa0eded, + 0x6d65bb9, 0xa93f71c, 0xb8dfaf9, 0x88be135, 0x57ca8ee, 0x1d9f4e5, + 0x26781ad, 0x4c896aa, 0x6c6c49f, 0xd3fbe31 }, + { 0x2c34c3d, 0x088d852, 0xbadff1e, 0xbb6d645, 0x385450d, 0xe3080b8, + 0x50ab1f3, 0x5ccc54c, 0xac0657d, 0x4e07e6e, 0xb7ef2c0, 0xa7ba596, + 0x73a81e9, 0xcceca8a, 0x8284c35, 0xa0b804c } + }, + { + { 0xf17a6a2, 0x7c55956, 0x789cfa8, 0xb451d81, 0x2506eaa, 0xdf414e8, + 0xae96562, 0x6ef40fb, 0x0e0297e, 0x63ea283, 0x73c46fa, 0xf5df26e, + 0xaac8bce, 0xe00641c, 0x64371f3, 0xc89ed8f }, + { 0x793202e, 0xd22b08e, 0x875cb50, 0x39a9033, 0xf85ddb4, 0xe64eec0, + 0x7acf7b5, 0xdce45a7, 0xb9b802d, 0x39d1e71, 0xbd559ac, 0xafdfe7c, + 0x809eeb5, 0x17ec1f8, 0x4889b8c, 0x8c0e38a } + }, + { + { 0x17089da, 0x47eabfe, 0xec90c50, 0x2d18466, 0x5861531, 0xa511aa4, + 0x8c39b39, 0xebb3d34, 0xf1b5282, 0xa0ac4da, 0xa9dadba, 0xea26be7, + 0x554d86e, 0x8992ba8, 0xd5f2ef5, 0x7fcbdb6 }, + { 0x56863e7, 0x320e79b, 0xa7dce2d, 0xeb9d0c0, 0x784cbc6, 0xb9f4031, + 0x7ac1f81, 0x68823ee, 0x9d87497, 0xa6b6f4f, 0x57f9b6e, 0x83c67b6, + 0x0fef2a7, 0x3735747, 0x59596e2, 0xf38028f } + }, + { + { 0x7e82886, 0x9ea57ab, 0x48c44d5, 0x18221c5, 0x314a24f, 0xbf8e6cf, + 0xfd025e5, 0x70ff18e, 0x5334468, 0x08d03de, 0x7404fb7, 0x2b206d5, + 0x55e36b0, 0xb923271, 0xb88ddd9, 0xcc7604a }, + { 0x4a746f0, 0x3df5152, 0x168e3fc, 0x8fdebd8, 0x7f8c32c, 0xffc550c, + 0x148743e, 0x1dbbc17, 0xb88e18b, 0xd48af29, 0x750027c, 0x8dca11c, + 0x1832be3, 0x717f9db, 0x2b06019, 0x22923e0 } + }, + { + { 0xc1cc4d3, 0xd4e06f5, 0x2b4f03a, 0x0fa32e3, 0xc4628d0, 0x956b9af, + 0x939dad1, 0x95c39ce, 0x8a00416, 0x39d41e0, 0x6fb01aa, 0xfd7ff26, + 0x45af340, 0xc6033d5, 0x8e36584, 0x2f65542 }, + { 0x8dff960, 0x14cfb1f, 0xda81474, 0x7236ffc, 0xd452d0f, 0xc6a6788, + 0x77f6094, 0x2ad4a52, 0x07eea74, 0x369d65a, 0xd6229aa, 0x27c6c38, + 0x8863976, 0xe590e09, 0xb38b142, 0x361ca6e } + }, +}, +{ + { + { 0xdfeb7ef, 0x6803413, 0xd3f4fad, 0xb669d71, 0xc941606, 0x5df402a, + 0x8e6c5b7, 0xe5d1776, 0x92ab236, 0x131bcb3, 0xce2e0e0, 0x7f1fb31, + 0x9e98c35, 0xa2c020d, 0xf28657b, 0x33b23c0 }, + { 0x9cf7879, 0xed14e73, 0xb4357b3, 0x10d4867, 0x31e4e04, 0x127cea3, + 0xaa5f8a7, 0xc60d25f, 0x025b987, 0xfef840a, 0x66f2a0a, 0x78081d6, + 0xac36198, 0x0fa0b97, 0x134dc9f, 0xe0bb919 } + }, + { + { 0xcc32eae, 0xc1d2461, 0x0f79a37, 0x0fdbfdf, 0x1c95f02, 0x70f2bc2, + 0x372cddf, 0x7d68bec, 0x8439342, 0x44f7817, 0x4843a6c, 0xa3d5678, + 0x07f8959, 0xbadf77a, 0x73db4ca, 0xf458198 }, + { 0xd54f805, 0xe8eaaf3, 0xb84c1e7, 0x2f529d1, 0x21e535c, 0x404e32e, + 0x159b5f5, 0xabac85c, 0xb00466f, 0x4e8e594, 0xc941873, 0x40fcaab, + 0xbe407c6, 0x3b4e370, 0x5b2e58d, 0xccd5788 } + }, + { + { 0x88b74a8, 0x3ee615e, 0xeab4e69, 0xd7d6608, 0xe4ace36, 0x27cf9f1, + 0x7aebabb, 0x282359e, 0xf6d162f, 0x96e509b, 0xf1a290a, 0xad906f3, + 0x1314a58, 0xe7d6c4f, 0x218431d, 0xeecffe4 }, + { 0xe2cfed9, 0xa66e0e9, 0x71f0544, 0xb0887ec, 0xa04c5d7, 0xd34e36b, + 0xed4392d, 0x094daa5, 0xc8aa925, 0xcda83ad, 0xb979786, 0x1adef91, + 0xfddc5d6, 0x3124dcb, 0x0b70c14, 0x5cc27ed } + }, + { + { 0x0eac2d8, 0x386dbc0, 0xc50ca30, 0xa716ecb, 0x80d9f04, 0x9e3fc05, + 0xcfeaceb, 0x37dde44, 0xa3522d5, 0xd88d74d, 0x2cf239a, 0x6bb9e9f, + 0xa7cbfec, 0x9e7fb49, 0x0a5c0ef, 0xe1a75f0 }, + { 0xfb9229d, 0x6e434e7, 0xc8a79b3, 0x0ec6df5, 0xd3fb311, 0x7046380, + 0x52e20fa, 0xe957ef0, 0x9ef4614, 0x0f4fe9a, 0x54d8f2b, 0x1b37d9c, + 0x39d84a2, 0x23b2dc1, 0x724e713, 0xf62c4f6 } + }, + { + { 0x747e219, 0xbd6922c, 0x3869b7b, 0x34d1438, 0x96f2272, 0x8c875a5, + 0x3fe361e, 0xd9602c0, 0x744839f, 0x081348f, 0x61ac1f1, 0x61bd16c, + 0xd8da4e1, 0x993b727, 0x7741271, 0xbb40ba8 }, + { 0x81dcfff, 0xe6dcc98, 0x93ce616, 0x9f513f5, 0x618cd8f, 0xdc09683, + 0x26639be, 0xc3b1d10, 0xc762ee2, 0xe8f149f, 0xb244aae, 0x59f26ef, + 0x693dd96, 0x3f2de27, 0x9c3a7de, 0xd8b68f7 } + }, + { + { 0x970bd5b, 0x6fa20b9, 0x75f6179, 0x87242d7, 0x72d9308, 0xa95a6c6, + 0x37a8a58, 0x6eb2518, 0xc59562c, 0xfdea12a, 0x20f1fc3, 0x4419c1e, + 0x9d66788, 0x0c1bd99, 0x32c0547, 0x4b74288 }, + { 0xdf479ab, 0x4f38acc, 0xc52a942, 0x01f6271, 0x02ca9a7, 0xe3298f4, + 0xb718fc8, 0x533daca, 0xb093ca8, 0x133602a, 0x8f98104, 0xc04da80, + 0xaf08620, 0xd0f2e23, 0x178b164, 0x882c817 } + }, + { + { 0xec30a71, 0x28e6678, 0xf78aca1, 0xe646879, 0x88fa078, 0x868a64b, + 0xfee3433, 0x671030a, 0x87c0211, 0xb2a06bb, 0x46c406a, 0x202eca9, + 0xe4f0f59, 0x64d6284, 0x3c9f907, 0x56ae4a2 }, + { 0x1dcc100, 0x5abbb56, 0x07c7784, 0x6fef6cf, 0xdb7302d, 0xb6e25cd, + 0x42980e8, 0xa26785b, 0xfb96801, 0xe7d4043, 0x8e4282b, 0x46df55d, + 0xc602d6e, 0x9c0a5f5, 0x75dfe29, 0xf065604 } + }, + { + { 0x3dcbc90, 0x0e82a1a, 0x656feac, 0xb1ee285, 0x0d3d3b2, 0xfa4353b, + 0xdd5c5df, 0xc2e7a6e, 0x416ce53, 0x13707e1, 0x87ebc07, 0xc84ce07, + 0x8a9a834, 0xdd273ce, 0x5e8e1e7, 0x432a617 }, + { 0xbd0064a, 0xa359670, 0x6534516, 0xc899dd5, 0xdb27169, 0x666560e, + 0xa19a068, 0x1537b22, 0xeac7527, 0x3420507, 0x6fc13a7, 0x479f25e, + 0x1bc19b3, 0xc847acc, 0x0b20d45, 0xecdecf0 } + }, +}, +{ + { + { 0x4acea57, 0x6f24100, 0xda68597, 0xdace1c6, 0x50ce77f, 0xea7dd41, + 0x1585884, 0x1aecb84, 0xea4a85c, 0x92ff208, 0x88eebd2, 0xde9433c, + 0x3f4d289, 0x53cd318, 0x26539af, 0x3970858 }, + { 0xb827d87, 0x4b57599, 0x3d77638, 0xdc82ac0, 0x52f6e61, 0x6943366, + 0xad5e8a6, 0xb8fc4b0, 0xf388642, 0x1b6f7dc, 0xa74dd57, 0x6f24533, + 0x41750cf, 0xc669378, 0x28a37af, 0x06757eb } + }, + { + { 0xc133995, 0x0e70d53, 0x7c8c97d, 0x88a5e0c, 0x85f3be3, 0x4e59dbf, + 0x0e92698, 0x0f364ac, 0xef6940f, 0x3a1e79b, 0xd85d23a, 0xc8a3941, + 0x9a00e58, 0x143bb99, 0xc6f2f10, 0x61cf7d6 }, + { 0x85150fe, 0x979c994, 0x59d773f, 0xcfd0df2, 0xaab7bcd, 0xce97b9d, + 0x6afd8fc, 0xc9fff8e, 0x89a4628, 0x246befd, 0x1567090, 0xf630282, + 0x6749c58, 0x1539342, 0xa0f3fd3, 0xff47d0e } + }, + { + { 0x35f6706, 0x09b0bfd, 0x2c82e69, 0x7464581, 0x50d5fe9, 0xb60729f, + 0x95c74f1, 0xf133245, 0xbb76c89, 0x33647e3, 0x5a9afcc, 0x0126404, + 0x0f154ab, 0x46d57ee, 0x25680a4, 0x2efa555 }, + { 0x5329d90, 0x12ebfc6, 0x79800af, 0xcb37ae5, 0x6f8e310, 0x5bb5349, + 0xf1bb936, 0x9b59c63, 0xf4610e9, 0x5b49baa, 0x4f2d6ac, 0x2bbeeef, + 0x0badc67, 0x87ee21e, 0xf1ddfa0, 0x12e2aad } + }, + { + { 0xa9109ee, 0x5b4668f, 0x8a6cea2, 0xfa95133, 0x4068e16, 0xe45e6fc, + 0x0205ed8, 0x8ae9a0c, 0x679b79b, 0x2993b96, 0xed604d3, 0xc6b878f, + 0x32c77f3, 0x01d0208, 0x495a1ab, 0xd45d890 }, + { 0x29d2030, 0x99348fa, 0x61f8f7a, 0x961f9a6, 0x674f74b, 0xfd53212, + 0xb3e72bc, 0x45cee23, 0xb77e2d5, 0x3fccb86, 0x4219cb7, 0xdff0310, + 0xc056871, 0x233771d, 0x7d2c521, 0x1214e32 } + }, + { + { 0xff2a8e1, 0x9f51e15, 0x138bc70, 0x86571c5, 0x0c09d46, 0xbfc4caf, + 0xc2a0c18, 0x65e33fe, 0x426867d, 0x8214392, 0x80ae4ed, 0x51ce6c0, + 0xb110de6, 0x6cbe8d7, 0xfd22ea4, 0x7f6e947 }, + { 0xcadefc4, 0x7373a75, 0xb0c682f, 0x6fca1d2, 0xf3c7c1e, 0xcd2140d, + 0x558b7a5, 0x8653a37, 0x55eb321, 0x653e74e, 0xc31af73, 0xbe0c6b3, + 0xf4fc365, 0x3376379, 0x71add4d, 0x3570b37 } + }, + { + { 0x83c3494, 0x9061ec1, 0x677bc95, 0xaf2f28d, 0x3bf8768, 0x6fe7279, + 0x0fa86d8, 0xc5f50e3, 0xa3293ce, 0x6c03060, 0xe2355a6, 0x4d53357, + 0xe4df931, 0x43a59ea, 0x13b79c6, 0x6f48f5d }, + { 0xddc5192, 0xa4d073d, 0xa65773f, 0x6d0e318, 0x765de9e, 0x1008792, + 0x39a0375, 0xa724ed2, 0x97d7c9e, 0x510ff14, 0x5baa863, 0x251f622, + 0x648a351, 0x86464fe, 0xd50fd91, 0xf85e98f } + }, + { + { 0x86ee987, 0x29c9634, 0x10dcc9f, 0x93e8e52, 0xc910b1f, 0xa1fc4d1, + 0xfeb603e, 0x015acac, 0x0844a5f, 0xc9f25f8, 0x73f4dac, 0x50de93c, + 0x310a4aa, 0x1758783, 0x358f106, 0x544d570 }, + { 0x1dc68ca, 0x4eeec7b, 0xe00fbcb, 0x6238e6f, 0xb4e83c9, 0x34d394c, + 0x2292656, 0x764ffa2, 0xf641f2e, 0x5614cd1, 0x9e07234, 0x4252eb6, + 0x68d2ba4, 0xcbaef45, 0x8a98b17, 0x8c9c550 } + }, + { + { 0x4106140, 0xf235d9d, 0x9eb601e, 0x1bf2fc3, 0x375e0c3, 0x6fb6ca9, + 0xc0024d2, 0x4bf5492, 0xeb54cc6, 0x3d97093, 0x5c90cb5, 0xc60931f, + 0xfbe0f1a, 0xfa88808, 0xd33e7d4, 0xc22b83d }, + { 0xc0abbf5, 0x9cfec53, 0x93723df, 0x52c3f0a, 0x39b96b6, 0x0622b7e, + 0x1667270, 0x300de28, 0x9ef426a, 0x50b66c7, 0xc6eb295, 0x8849189, + 0x8914a7e, 0xeaec3a9, 0xc4c99e0, 0x7ed56b0 } + }, +}, +{ + { + { 0x687e557, 0x7926403, 0x5310017, 0xa349816, 0xd43a8fd, 0x1b06e91, + 0x6ac23cb, 0xf201db4, 0x4f48750, 0x6f172ad, 0xe74bd3e, 0x5ed8c8c, + 0xdaba648, 0x492a654, 0xa9b64ff, 0x123010b }, + { 0x6e89f93, 0xa83125b, 0x398378a, 0x3a3b0b0, 0x0aebe7c, 0x9622e0b, + 0x49512a4, 0xb9cbfdc, 0x6aaf12a, 0x13edffd, 0x9f5eafd, 0x555dff5, + 0x1212efa, 0x3cba6fe, 0xd9bb0f8, 0xd07b744 } + }, + { + { 0x9a48920, 0x45732b0, 0x13ff36d, 0xf3080fc, 0xde8f950, 0x9347395, + 0x382b897, 0x14d025a, 0x04d72ad, 0x60c5a74, 0x11a9c71, 0x30be7e5, + 0x31ac33a, 0x43ffabd, 0x35cbb14, 0x97b06f3 }, + { 0x7740de9, 0xe4ff5c5, 0xaacf81e, 0x5fed090, 0xe8b7c9d, 0x97196ee, + 0x045910b, 0x316dcd1, 0x5ad8c63, 0x7a2b2f5, 0xc5b03bb, 0x674fffd, + 0xe65953c, 0xc1cd133, 0x0a83556, 0x3c06052 } + }, + { + { 0x091c23d, 0x797c3f6, 0x39c9c05, 0x2ea2de3, 0xa31f67c, 0x5d958b4, + 0xd5f088c, 0xf97afe5, 0x0b37243, 0xbcfbd2a, 0xeca630c, 0xc43ad3e, + 0x42845e0, 0xb92a337, 0xa9a0f16, 0x970bff7 }, + { 0x5970a79, 0x8635511, 0xf205928, 0xcee332e, 0xc04c208, 0x2c58d70, + 0x3f5e5bf, 0xdbfe19a, 0x8e51c56, 0x8f8f2c8, 0x8e2da75, 0xb61f58e, + 0x624d93f, 0x4046a19, 0xe1f9538, 0x7de64db } + }, + { + { 0xc2d850e, 0xd018e1c, 0x63a723c, 0x8cdb643, 0x90a42af, 0x9a65abe, + 0x16f20cc, 0xfeece96, 0xd5cff56, 0xc906800, 0x3f0deed, 0x0acf23a, + 0x728dd3a, 0x2143061, 0xb8ce34c, 0x66276e2 }, + { 0x73cc9c7, 0x23700dc, 0x5b1778b, 0xdb44851, 0x4aab669, 0x330f41e, + 0xf5282a4, 0x2f5aabc, 0x30f9e01, 0xff837a9, 0x901cc98, 0x1a1eb2f, + 0xe69bd7f, 0xd3f4ed9, 0x8a72a7d, 0xa6b1141 } + }, + { + { 0x9ea3b43, 0x34bde80, 0x5ced6ae, 0x5ddcb70, 0x95a6cb8, 0x8257f5b, + 0xc77dcb8, 0xaac205d, 0x035b397, 0x77d740d, 0xcf7e0a6, 0xca7847f, + 0x085601b, 0x9404dd6, 0x457e4f9, 0x0a5046c }, + { 0xbc11470, 0xcaee868, 0x005c5f6, 0xb118796, 0xec79173, 0xcc04976, + 0x21f6827, 0x7f51ba7, 0x486ff7e, 0xa8e3f0c, 0xf87838c, 0x327163a, + 0x6d039fd, 0xcf2883e, 0xdb8b0e2, 0x6fb7ab6 } + }, + { + { 0x620d669, 0x8ca5bac, 0xed7caa9, 0xff707c8, 0x927909b, 0xdaefa2b, + 0x7029da3, 0x1d2f955, 0x6d131a0, 0x52a3ba4, 0x3ab1041, 0xe5a94fd, + 0x99bc0ae, 0x5089177, 0xfa1bd16, 0xf750354 }, + { 0x6cd31fd, 0xdd4e83a, 0x92fac84, 0xd335053, 0x1691382, 0xf914cbc, + 0xda6ade6, 0x669683f, 0x8878513, 0x6944643, 0x4b1a72d, 0x429d3cc, + 0x61eec36, 0x655c46a, 0x4bc4970, 0x881eded } + }, + { + { 0x7ca647f, 0x5b39d37, 0xe917b34, 0x41533c1, 0x7daf734, 0xea2aeb5, + 0x1286560, 0xf1ef1eb, 0x08e0473, 0x582f2e0, 0x5edc74a, 0x5913d7d, + 0x3c1e754, 0x588c7ec, 0x7146fe1, 0xbd6db05 }, + { 0x7634907, 0x3b0d49e, 0xe43b9cc, 0x4c65ce4, 0x2d92d5b, 0xb87e958, + 0x7ab1519, 0x0513572, 0x8c3aed0, 0x03ec084, 0x561a641, 0x4d7aa21, + 0x99e92ad, 0xe5f8211, 0x48a457c, 0x379b55f } + }, + { + { 0xd6a8442, 0x8317c34, 0xae499da, 0xb0ab4a5, 0x720e8eb, 0xebcb16e, + 0x9a96908, 0xfd5c563, 0xad23acf, 0xcab4d67, 0xbcdf748, 0xa600a79, + 0xa2a6a51, 0x18a6340, 0x3aabd69, 0xf2f415c }, + { 0x747258a, 0xdb38a4f, 0x2e24415, 0xb6ea560, 0xf1f7655, 0xfad1ea9, + 0xc957684, 0x4e27eb5, 0xb2e1cfc, 0xf8283e1, 0xaa6291c, 0x8f83bd6, + 0x5619e84, 0x28d23b5, 0x93770a4, 0xb9f34e8 } + }, +}, +{ + { + { 0x7515fb1, 0x1bb8437, 0x7b860a6, 0xac73f2a, 0x22b390f, 0x78afdfa, + 0x66048aa, 0x815502b, 0x85bf620, 0xf513b97, 0x3fc5d7c, 0x2524e65, + 0x178c969, 0xa10adc0, 0x5391c8d, 0xa1d5396 }, + { 0xa8bcc45, 0x09fccc5, 0x7710e1e, 0xa1f97d6, 0x897d0a1, 0xd694442, + 0x5f42400, 0x7030beb, 0x7127908, 0xdebe08c, 0x2187637, 0x96b715c, + 0xb528129, 0xc598250, 0xa1ccb07, 0x0f62f45 } + }, + { + { 0xb765479, 0x8404941, 0x5837dc4, 0xfdecff4, 0xadbd465, 0x1796372, + 0x3159806, 0x5f84c79, 0x6aaad34, 0x6d2e46b, 0x384b375, 0xd303b4a, + 0xb392002, 0x440acd5, 0xc475e87, 0x4f2a4a7 }, + { 0x5606fc2, 0x038e1da, 0x9c2f050, 0x2d821c2, 0xf139db4, 0xc074cb3, + 0x4ec59be, 0xde2fee7, 0xa84ed59, 0x5a819ee, 0x3e98711, 0xd65c62c, + 0xb9723c1, 0x72eb440, 0x01be611, 0xb927754 } + }, + { + { 0xab9e9fc, 0x929fe64, 0x0bf1e85, 0x04379fd, 0xbc28ee3, 0xb322093, + 0xe4555e1, 0x78ac4e2, 0xabc5588, 0xdb42b58, 0x77c8b12, 0x1c1b5e1, + 0x40366c4, 0xf6d78dd, 0xbdae22e, 0xc21ff75 }, + { 0xa211df2, 0x1e3d28e, 0x3617c0a, 0xc5a65a1, 0x58140d5, 0x3fa02c0, + 0xb62d10c, 0x155c346, 0xe48268f, 0xc9cf142, 0x1993bc3, 0xdc14083, + 0x0ee69dc, 0x07c44d4, 0x5e2ac46, 0x6169950 } + }, + { + { 0xd0fb585, 0x44e4a51, 0xf1f3ce8, 0x00846be, 0x8e2de1e, 0xedef39a, + 0x33b3934, 0x430afe3, 0x4337188, 0xac78b05, 0xc9a3f24, 0x0f39de4, + 0xc9ae6a4, 0x039eddd, 0x8eacd51, 0xf470157 }, + { 0x9a2f31a, 0x1e39694, 0xb19a8b1, 0xc8a40f4, 0x9d239d8, 0xdddd10c, + 0x887e066, 0xf974245, 0x3ea28c6, 0xfdb5111, 0xe1122a9, 0xb5af0fb, + 0x36e0267, 0xd30c89f, 0x74f024c, 0x7b1c0f7 } + }, + { + { 0x07a39bf, 0x1ec9956, 0x3a68d15, 0x1c3ecf2, 0x4f59fe9, 0xd8a5c4e, + 0x271abc3, 0xacb2032, 0x71ef239, 0xbc6bdf0, 0xb39b391, 0x660d7ab, + 0xb627a0e, 0x2e73bb2, 0x248fc7e, 0x3464d7e }, + { 0x1666760, 0xaa49249, 0x8582659, 0xa257b6a, 0x5593089, 0xf572cef, + 0x73ca6bf, 0x2f51bde, 0x764cff5, 0x234b63f, 0xd411a35, 0x29f48ea, + 0xafe1db1, 0xd837840, 0xd9f4c4b, 0x58ec0b1 } + }, + { + { 0x5e6f3dc, 0x8e1deba, 0x06a5ff7, 0xc636cf4, 0xc80ca0f, 0xe172b06, + 0x5ffb90a, 0x56dc098, 0x9a05e83, 0x895c218, 0x7561ac2, 0x6ddfaec, + 0x96283a0, 0xaa35749, 0x7e7cd43, 0x6dfb262 }, + { 0x2c8ca27, 0x6576de5, 0x49018eb, 0x6a4a872, 0x5c34342, 0x00c275c, + 0xd2d90c4, 0xe34805a, 0xd8743c4, 0x651b161, 0x7312bf3, 0xb3b9d9b, + 0x0bf7e00, 0x5d4b8e2, 0x78d3d7e, 0x8899bdf } + }, + { + { 0xfaa9cd1, 0x9644ad8, 0x6e0e58e, 0x34c98bf, 0x404c637, 0x6022aad, + 0x7ac013b, 0x2a11a73, 0x5540899, 0x5bdd103, 0x1e022a4, 0x2e67572, + 0xb834c33, 0xe32045d, 0x2f2d01c, 0x74a260c }, + { 0xc48841c, 0x20d59e9, 0xe560359, 0x05045dd, 0xac998ac, 0xeba779c, + 0x00a6218, 0x5bed10c, 0x5327ef4, 0x25d4f8e, 0x4597794, 0xa278474, + 0x831d11e, 0xefd68ca, 0x934446a, 0x9ad370d } + }, + { + { 0x73c92ac, 0x3089b3e, 0x957a75c, 0x0ff3f27, 0xd676f50, 0x843d3d9, + 0xd496d43, 0xe547a19, 0x8e924a4, 0x68911c9, 0x85b5522, 0xfab38f8, + 0x83e0ac5, 0x1048811, 0xdc788c4, 0xcaccea9 }, + { 0xe3c6aad, 0xfbe2e95, 0xb3a6cf1, 0xa7b3992, 0x87d78b1, 0x5302ec5, + 0x1826100, 0xf589a0e, 0x8610632, 0x2acdb97, 0x9232b26, 0x1e4ea8f, + 0x9c09a15, 0xb21194e, 0x849b909, 0xab13645 } + }, +}, +{ + { + { 0xf3a71c1, 0x92e5d6d, 0x297d661, 0x349ed29, 0x1713fc9, 0xe58bd52, + 0xb9ddfb5, 0xad999a7, 0x3c28ce0, 0x271c30f, 0x2a9d460, 0xf6cd7dc, + 0x207dec7, 0xaf728e9, 0xfcb8bf0, 0x9c2a532 }, + { 0x68bf486, 0xd702184, 0x7ab8ea8, 0x73b45be, 0x1795c93, 0xddfc658, + 0x6bb8da2, 0x7941660, 0x88e07a2, 0x658f197, 0x26d3d12, 0xa9d5b08, + 0x9535b52, 0x4d7c95f, 0x268ef8a, 0xad55e25 } + }, + { + { 0xa2bc326, 0x94a9b0b, 0x167e5f3, 0x485ecc5, 0xc97fc74, 0x8340bc7, + 0x07aaa5c, 0x06f882b, 0x849698a, 0x4b57455, 0xb36a0ba, 0xd9281eb, + 0x8b8108f, 0x8918c6c, 0x5b50d1d, 0xedd1eea }, + { 0x2a25f50, 0x94d737d, 0x2446ad0, 0x0e5a823, 0x7ced3e2, 0x02a5435, + 0x4af8ced, 0xb09a92a, 0xeeecef2, 0x85fc498, 0xe71e3d4, 0x06a02b9, + 0x84bb49a, 0x00ad307, 0x64a5b4a, 0xf61585e } + }, + { + { 0xb86a4c9, 0x915f6d8, 0xa861e1f, 0x944bc6b, 0x54465ef, 0x3091ca7, + 0xeb53a38, 0x11df859, 0x0144679, 0xd44dde5, 0x0994edd, 0x6c8da9a, + 0x91241ef, 0xeebcebf, 0xc2f6859, 0xc419354 }, + { 0x49581b6, 0x1f49693, 0xbb26cb4, 0x5712b10, 0xb09fd59, 0x8fcaa41, + 0x72e22e3, 0xbd39aad, 0xb1199b0, 0xf70e794, 0xc6f863d, 0xdf63c0c, + 0xee9df4f, 0xd58166f, 0xc45e70b, 0xb9224ea } + }, + { + { 0xce525f4, 0x80072fa, 0x66a5502, 0x8597bd6, 0xdbc9725, 0xf65e203, + 0xf2222a4, 0xeccfbe3, 0x2339834, 0x490aa42, 0x62489e8, 0x1348891, + 0xa735084, 0xaff3f80, 0xf3f1bd6, 0x69d53d2 }, + { 0x813341a, 0xb123ffc, 0x1173848, 0x359084c, 0xd29b08d, 0x751425e, + 0x3890ad4, 0x1edda52, 0x607cf20, 0xb64974c, 0xb42ac7c, 0xa8c8cb8, + 0xedd42e5, 0xd5cb305, 0x44c090a, 0xf3034dc } + }, + { + { 0xbb18e19, 0x428921d, 0xfed2127, 0x4cfd680, 0x92ac8c3, 0x671144d, + 0x132c894, 0x2121901, 0x7604cd9, 0x25d0e56, 0xafbc2a0, 0xa372223, + 0x56c16f7, 0xcf98a52, 0xb5459e1, 0x71f129a }, + { 0xb668b2e, 0xf4afdc5, 0x0c2d410, 0xc5d937a, 0x285d54a, 0xe2cc4af, + 0x8c53e18, 0x1c82777, 0x69a92f6, 0x270f2c3, 0x616327a, 0x799f9ac, + 0xd4246f2, 0xce658d9, 0xfb12e36, 0x0fb681f } + }, + { + { 0xe0690fe, 0xc5ab11e, 0x3f74249, 0x80261e3, 0x58c1cf2, 0x8eb4b47, + 0x184ae9b, 0x4895a80, 0xd3e27eb, 0x4a4bdb6, 0xbfd251c, 0xa7a1638, + 0x417a7e3, 0x29ec144, 0x3f1b960, 0xd073609 }, + { 0x49c73d1, 0xcb1ed83, 0x8d1945a, 0x33fc84a, 0xe965118, 0x9f668db, + 0xa82811f, 0x3331743, 0x28ba540, 0xf394dec, 0x654a454, 0x44ce601, + 0x3623645, 0x240dbb6, 0x2e61048, 0xf07e7f2 } + }, + { + { 0x3d45213, 0x7c9f176, 0x9c1f77f, 0x3eefa70, 0x1b48350, 0xde3c3c5, + 0x9d481a7, 0x4a2bc64, 0x7874f3d, 0xfd4a58a, 0x037b302, 0x96655d4, + 0x68bf5ab, 0x9452528, 0x75177f6, 0x1b6d46a }, + { 0xefb8d00, 0x7de6763, 0xa741b7b, 0xb2c1ba7, 0x7bae6ed, 0xcca6af4, + 0x5b68b3f, 0xe4378ca, 0xaf71948, 0xfb757de, 0xbc6ac99, 0x7f07b5e, + 0x27d636d, 0x752a568, 0x4b8a34f, 0xc8b7d1d } + }, + { + { 0x325331b, 0x76cb78e, 0xadd2eed, 0x41f41c9, 0x5c5f623, 0x03db238, + 0x7102fa2, 0xbbc1d17, 0x60182ec, 0x80f137a, 0x55adf15, 0xfdd8569, + 0xe3373dc, 0x4f53f5e, 0x21b669b, 0xec6faf0 }, + { 0x0b86081, 0x7d4e983, 0xf2d979c, 0x10d3cd9, 0x24a22c8, 0x0f48f58, + 0x02f99ee, 0x86c540c, 0x5e6c5fc, 0xf4c6654, 0xbc404c8, 0xaf0c588, + 0x423118a, 0x2e6edbd, 0x0690eab, 0x86e32e9 } + }, +}, +{ + { + { 0xdfbfa6f, 0x1d12656, 0x7646018, 0xa498095, 0xc3597d0, 0x2f1071b, + 0x1dda80a, 0x3df83f9, 0xf3ae449, 0x5853e28, 0x9e19aad, 0xb853d31, + 0xa0d8a46, 0x863f01b, 0x2fef108, 0xa84fca6 }, + { 0xfb84de9, 0xbe4c0b7, 0xc0727bf, 0x40a03dc, 0xb18575c, 0x781f841, + 0x466cddb, 0x6a63045, 0x05dc7a2, 0x6be7582, 0x07ae811, 0x420f87f, + 0x3bf96c8, 0x2808242, 0x51c6821, 0x723998c } + }, + { + { 0x81f5863, 0x38ab641, 0x05ff9e1, 0xd82ecbd, 0xa065856, 0x339c94e, + 0xa45156d, 0x143054a, 0x065628c, 0xe6d64bf, 0xa938589, 0xe530086, + 0x385d79b, 0x22d3a49, 0x0ab8245, 0x0b10790 }, + { 0xca387b5, 0xb0d80fb, 0x35551d7, 0x698206e, 0xa10bb73, 0x199685d, + 0x9107378, 0xa8e5fa8, 0xd99dbbf, 0x36e5724, 0xd581b03, 0xd67f476, + 0x88dd1e6, 0x7a15be7, 0xe5baa31, 0x8dac8e4 } + }, + { + { 0xe170ef8, 0x4d5d88f, 0x1e9e600, 0xb6ba5de, 0xedeabc5, 0x4a89d41, + 0x8fac936, 0x737c66b, 0x65c3125, 0x8d05b23, 0xb61b68e, 0x85a5cbc, + 0x20a6af9, 0x8fea626, 0xd8b50ec, 0x85115de }, + { 0x6a6f30b, 0x5430c8d, 0x8474295, 0x8bef9cf, 0xbe77f38, 0x0648f5b, + 0x9e47bd7, 0xfe2b72f, 0x93106e2, 0xad6c5da, 0xfa7a6c3, 0x4fa6f3d, + 0xb396650, 0xdcd2ed8, 0x1157ef9, 0x7de1cce } + }, + { + { 0x1f241d1, 0x70a5f6c, 0x798cd5c, 0x6c354d8, 0x1a729fb, 0x23c7838, + 0x523cbda, 0xcff8f15, 0x3493697, 0x5683ff4, 0x7534f53, 0xef7dbab, + 0x2243d53, 0xd7bd08e, 0xf8072a9, 0x6f644cb }, + { 0xb22db63, 0xac960f9, 0x23af04d, 0xa97f417, 0xd9798af, 0x692b652, + 0xfedb156, 0x0e35967, 0xdfe6ee8, 0x14b5e50, 0xb411070, 0x7597ede, + 0x442b3f9, 0x116f3ce, 0x1b2b6db, 0xe9b5ae8 } + }, + { + { 0x2315930, 0xf4385ee, 0x27a8740, 0xc8d0298, 0xd934a43, 0x7907a8d, + 0xc582191, 0x20bc946, 0x6a405e7, 0xa4acb3e, 0x43df2f5, 0x8c1d6c8, + 0x991f0b5, 0x9df1593, 0x4d9be9d, 0xbb9df98 }, + { 0x8e4b190, 0x6362008, 0xada3a88, 0xee1421e, 0xf93b027, 0xb84f0cc, + 0x8e95091, 0x7a5d667, 0xf3e3704, 0x3974462, 0xc593e98, 0xfa6fb5e, + 0xa6477d2, 0x44b6cf7, 0xb09a562, 0xe885b57 } + }, + { + { 0x09a0c02, 0x6e339e9, 0x0e75f29, 0x57afff0, 0xfb7db03, 0x797d8d6, + 0xd25a236, 0xc6e11a3, 0x0107260, 0x643ce1c, 0x62eae1c, 0xe644ec4, + 0x3f5a3f5, 0x821d5b8, 0xc0579d6, 0xa8ad453 }, + { 0x17d43a4, 0x6518ed4, 0x3f87ccd, 0x46e76a5, 0xf9bef95, 0xd6cbaab, + 0x4f7cbcf, 0x2568832, 0x08476b4, 0x367159a, 0xbe6d324, 0x1d1b401, + 0xa605026, 0x348cb98, 0x43b6b1e, 0x144f3fe } + }, + { + { 0x7b1822c, 0xbabbd78, 0x2aa51f8, 0xd34ba7e, 0x41fbea4, 0x086f1cc, + 0x746f3d9, 0x96f7eac, 0x281ecaf, 0xad97f26, 0xa14ee2c, 0x751a905, + 0x0d7335f, 0xb4e7fe9, 0x4892ff0, 0x0d97b8f }, + { 0x5a5c40e, 0xdb8a315, 0x7ba567b, 0x64e5de7, 0x1eefe88, 0x4f155f7, + 0xfb6fbf4, 0xe2297e9, 0x6c16be5, 0xfe24bf9, 0xcdd83e2, 0x2251847, + 0x5eda444, 0x13ac2c8, 0x283275f, 0x49d1b85 } + }, + { + { 0x423e08f, 0xca08731, 0x87d2f14, 0x7046bb0, 0x3bc846c, 0x876f10c, + 0x358fbe3, 0x2202b76, 0x0e26ac6, 0x0d4fc1c, 0xb986881, 0x1fc748b, + 0x8384a18, 0x609e61c, 0x0d88e00, 0x28a72d6 }, + { 0x78c6e2f, 0x1332a31, 0xb3526a4, 0x0367919, 0x698fe3e, 0x53989e4, + 0xb16a99b, 0x14b1145, 0xddbb75f, 0xef9ec80, 0x0e53955, 0x7625624, + 0x8744ae1, 0x54e087a, 0x672b875, 0xce50e8a } + }, +}, +{ + { + { 0xa29629c, 0x4c88b2b, 0x7b2642f, 0x946559c, 0xf7ebe4c, 0x933d432, + 0x63632c9, 0x97109b6, 0xe53184d, 0x799b3fb, 0x0f069a6, 0xd462871, + 0x3a68351, 0x0c182a1, 0x9a2437a, 0x974a839 }, + { 0x2a70278, 0x29f1997, 0xd9c424b, 0x01b98b6, 0x08f4c37, 0xd85a60b, + 0x2b1da15, 0xcc3523f, 0xddffb0f, 0xf922115, 0xde84ae2, 0xee0fe4d, + 0x55365be, 0x810440c, 0x1a457e8, 0xd2f6639 } + }, + { + { 0xe2ddd05, 0x5e6879f, 0xabdfc61, 0x92a7545, 0xa5cede8, 0x7dedd63, + 0x70df4bd, 0x8a03b3f, 0x91f6cbb, 0xa5d1f65, 0x10f3fb2, 0x372fde6, + 0xa9dee05, 0x4537f9e, 0xdf7aa50, 0x7eb85bb }, + { 0xe8c504d, 0x963edf8, 0xe7bdb6b, 0x53c8dca, 0x6fedf2d, 0xa246e4c, + 0x0c55bde, 0x7553340, 0x0270a54, 0x2aa748d, 0x05860dd, 0xadb6cf0, + 0x9b84763, 0x8d31450, 0xeb405ef, 0x626720d } + }, + { + { 0x6601328, 0xa3709ae, 0x2ac2478, 0x68e94fd, 0x9d5d247, 0x3879343, + 0x392c198, 0xfa467af, 0x15df607, 0x49e7b0d, 0x61792a8, 0x8c58122, + 0x1d3762f, 0x79f7658, 0x244a39d, 0xaa38895 }, + { 0xc5cd0bc, 0xef60af9, 0xa33b3bb, 0x2b0db53, 0x251015d, 0xe3e0b1f, + 0xe64489e, 0xc608afc, 0x03651aa, 0xe52b057, 0x1c6f7b9, 0x1dda8b9, + 0xff41893, 0x833f022, 0x192818c, 0x58eb0a0 } + }, + { + { 0xfc7b5a7, 0x6c1300c, 0xa83ab33, 0x6d2ffe1, 0x9c02eef, 0x7b3cd01, + 0xba60d55, 0x6c64559, 0x19e2f73, 0x2e9c16c, 0xdbe47b1, 0x11b24ae, + 0x1b8153b, 0xc10a2ee, 0x1e02e1a, 0x35c0e08 }, + { 0x1dd6f16, 0xa9f470c, 0xf41a290, 0x4ea93b6, 0x25ee03f, 0xac240f8, + 0xb85aabd, 0x6cd88ad, 0x1be2f8f, 0x378a64a, 0x417bac1, 0xbf254da, + 0x9231142, 0x7e4e5a5, 0x3b8c057, 0x057aadc } + }, + { + { 0x80af479, 0x607c77a, 0x5ccdf74, 0xd3e01ff, 0x101b4c7, 0x9680aaf, + 0x2fc50a6, 0xd2a7be1, 0xb72d782, 0x92a788d, 0x4640b52, 0x35daf2e, + 0x39e601c, 0xc170d69, 0x7b25c2f, 0x16e05f5 }, + { 0x6fe37f8, 0x47a42a6, 0xbeca298, 0xeb74271, 0x179da16, 0x401e11e, + 0xaa53873, 0xfb8da82, 0x5bb4783, 0xd657d63, 0xfcea0b1, 0x6847758, + 0x0993154, 0x2f261fb, 0x592853a, 0x868abe3 } + }, + { + { 0x35766ab, 0x1a4c543, 0x6f4e4ea, 0xa1c84d6, 0x60ba199, 0x5d737a6, + 0x98b15a2, 0x4a7b1e2, 0xfd967d3, 0x207877f, 0xc262b4d, 0xcaec82d, + 0x4f2a37d, 0x0b27849, 0x6ac1711, 0x3478141 }, + { 0x8fc6856, 0x28e3df1, 0x16d003f, 0xbec03f8, 0xff39ebd, 0x2bd705b, + 0x2d776d3, 0x1dcb53b, 0x5c0e7ce, 0xabafa7d, 0x4a53332, 0x5b9c8c2, + 0x9d90214, 0xe9f90d9, 0xc129690, 0x789747e } + }, + { + { 0x54e2dfa, 0x94d3c39, 0xafb2a8f, 0x919f406, 0x34e3927, 0x159ef05, + 0xa165c37, 0xcdb4d14, 0x288f337, 0xa23e5e8, 0x0f90242, 0x95867c0, + 0xe34e781, 0x2528150, 0x6657b95, 0x104e501 }, + { 0xbcdda24, 0x695a6c9, 0x23eb5fa, 0x609b995, 0x16a60f8, 0xcbce4f5, + 0xf084a29, 0xec63f7d, 0x20c811f, 0x3075ada, 0x8c716a1, 0x129a192, + 0xcd4cd4a, 0xd65f4d4, 0x62188be, 0xe18fa9c } + }, + { + { 0xbac60e3, 0x1672757, 0x577144b, 0x525b3b9, 0x887055b, 0x38fc997, + 0x31e4408, 0x7a77126, 0xcba2fcf, 0x884f173, 0x5962ac0, 0x783cbdc, + 0x22287dc, 0x4f3ed0a, 0x50e20e6, 0x8a73e34 }, + { 0xd764583, 0xe7a1cd0, 0x0d58ee6, 0x8997d8d, 0xaa13ed6, 0x0ea08e9, + 0xcf363cb, 0xed478d0, 0x5b37bf4, 0x068523d, 0x783f13c, 0x8b5a9e8, + 0x87528a9, 0xde47bbd, 0xcaec313, 0xd6499cc } + }, +}, +{ + { + { 0xe09859d, 0x54781bb, 0x7f5e648, 0x89b6e06, 0x7075824, 0xb006dfe, + 0x0717f68, 0x1731660, 0x0b4efe2, 0x9c86554, 0x5e30d8e, 0xdbdb257, + 0x3b4d50f, 0xa6a5db1, 0xfa47beb, 0x3b5662c }, + { 0x89d4a59, 0x9d4091f, 0x550a7dc, 0x790517b, 0xc52965e, 0x19eae96, + 0xb5ed7a4, 0x1a7b3c5, 0xeb16541, 0x19e9ac6, 0xef66852, 0x5f6262f, + 0xc4cda27, 0x1b83091, 0x3bf742b, 0xa4adf6f } + }, + { + { 0xa5100e7, 0x8cc2365, 0x8592422, 0x3026f50, 0x3d714d0, 0xa4de79a, + 0x90fcb30, 0xefa0d3f, 0x474ada0, 0x126d559, 0xc94350a, 0xd68fa77, + 0x0c7cb45, 0xfa80e57, 0x3985fbf, 0xe042bb8 }, + { 0xfe13dba, 0x51c80f1, 0xcf055d7, 0xeace234, 0x73f95f7, 0x6b8197b, + 0xdcdbe89, 0x9ca5a89, 0xdfd9896, 0x2124d5f, 0x9e7ca37, 0x7c69556, + 0x8babb37, 0x58e806a, 0xbaf99ce, 0x91b4cc7 } + }, + { + { 0x197e968, 0x874e253, 0x3160668, 0x36277f5, 0x8b95dbe, 0x0b65dda, + 0xf0872a1, 0x477a792, 0x314268d, 0x03a7e3a, 0x0c805c7, 0xa96c842, + 0xb7bc4a8, 0xb941968, 0x75db390, 0x79dce30 }, + { 0x6f4cc14, 0x577d4ef, 0xb5d1107, 0x5b0d205, 0x9f93624, 0x64ff20f, + 0x5034a2f, 0x0b15e31, 0x8b6f35c, 0x3a0f6bb, 0xe0d0ec5, 0x0399a84, + 0x0d5d521, 0xd0e5823, 0xcb1dd54, 0xdeb3da1 } + }, + { + { 0x182401a, 0x24684ae, 0x21a706f, 0x0b79c1c, 0xd8998af, 0xe1d81f8, + 0x4bb069f, 0xadf870f, 0xf3dd7aa, 0xd57f85c, 0xe4a40f8, 0x62d8e06, + 0x8b55aa1, 0x0c5228c, 0xa9c0a1a, 0xc34244a }, + { 0x68f544e, 0xb5c6cf9, 0xde23ab7, 0xa560533, 0x47c690c, 0xaa55120, + 0x12aaaa6, 0x20eda5b, 0x751a6a0, 0xea0a49a, 0x2baa272, 0x6d6cfff, + 0xbf4c28a, 0x95b756e, 0xe6178a4, 0xd747074 } + }, + { + { 0x221a94b, 0xa27b453, 0xe635f20, 0xd56ad13, 0x8c95117, 0x03574b0, + 0xed30b70, 0xf0ee953, 0x957796f, 0xb48d733, 0x58c336b, 0xf5d9583, + 0x82db529, 0x6170cd8, 0xec9d1ea, 0xcd3ef00 }, + { 0xe4d105f, 0xd1bea0d, 0xad6a559, 0xd2d670f, 0x52f9690, 0x652d012, + 0xc2529b0, 0x5f51fb2, 0xe89df2a, 0x5e88bf0, 0xcd686e4, 0x9a90684, + 0x882c7a1, 0xf519ccd, 0xc2f4d37, 0x933a0df } + }, + { + { 0x3f66938, 0x0720a9f, 0xd8149df, 0x99356b6, 0xa3d7f61, 0xb89c419, + 0x4ba6e31, 0xe658134, 0xab936c8, 0xd130561, 0x40dbef1, 0x0625f6c, + 0xb6bb847, 0x7b2d6a2, 0x84d506b, 0x3ca8b29 }, + { 0xfb011b0, 0x6bf729a, 0x33448c9, 0x01c3078, 0x0837420, 0x6ae9508, + 0xa207fb8, 0xf781a8d, 0x57562a9, 0xcc54d58, 0x858c5ab, 0xc9b7364, + 0x359908f, 0xdfb5035, 0x9631138, 0x8bf77fd } + }, + { + { 0xc13fbb1, 0xf523365, 0x9993ed5, 0x88532ea, 0x5a73492, 0x5318b02, + 0xe5a8f3c, 0x94bff5c, 0x306c2a0, 0x73f9e61, 0xf2668a3, 0x00abbac, + 0x076237d, 0x23ce332, 0x34c0f9b, 0xc867f17 }, + { 0xcfd2136, 0x1e50995, 0xb2b70f8, 0x0026a6e, 0x5077a7d, 0x66cb184, + 0xa3b498e, 0xc31b2b8, 0x260ec86, 0xc12035b, 0xe1b3df0, 0x1cbee81, + 0x8d55a42, 0xfd7b804, 0xf47a8c8, 0x912a41c } + }, + { + { 0x9e157e3, 0xab9ffe7, 0x44dc158, 0x9cfe46d, 0x8a4a3ef, 0x435551c, + 0x3b7e3a8, 0x638acc0, 0x49954a7, 0x08a4ebd, 0x13194f7, 0x295390c, + 0x253892a, 0x3a2b68b, 0x25d5b11, 0xc1662c2 }, + { 0x3a5d2bb, 0xcfba072, 0xcc327c9, 0xffaf6d3, 0xc67e254, 0x6c6314b, + 0x2f32208, 0x6661631, 0xbea72e1, 0xf780f97, 0x002122f, 0x495af40, + 0x7578a99, 0x3562f24, 0x77ce51e, 0x5f479a3 } + }, +}, +{ + { + { 0x1a82a12, 0x91a5884, 0x80f3a62, 0xa754175, 0xf73417a, 0x399009f, + 0x0a8c5cd, 0x2db1fb9, 0xc046d51, 0x82c8912, 0x8f18274, 0x0a3f577, + 0x26ccae2, 0x2ad0ede, 0x8a4e9c2, 0x7d6bd8b }, + { 0x4b3de44, 0xaa0d797, 0x96ac9bb, 0xf8658b9, 0x5f6c334, 0x31e7be2, + 0x4df12c9, 0x23836ce, 0x59eb5c9, 0x029027b, 0x5b8649d, 0x2f22531, + 0xd907162, 0xa0fdf03, 0x9e80226, 0x101d9df } + }, + { + { 0x9a90835, 0xf12037a, 0xf0222a7, 0xd2d0882, 0xc3814e2, 0xeaf8d40, + 0x8b8146b, 0xa986dc6, 0x8504653, 0x147a331, 0x2feaf67, 0x734e003, + 0x602bec5, 0x6f27bbf, 0x6a688f3, 0xa1e21f1 }, + { 0x73c4ae5, 0x5a8eeab, 0xe70b412, 0x4dbaddb, 0xcfd2af1, 0x871ceba, + 0x7d7a286, 0x1860382, 0xb5bb401, 0x024059d, 0x3c39b73, 0x2557c09, + 0x6681697, 0xfc5a711, 0x891b57c, 0xf881c0f } + }, + { + { 0x8ea191a, 0x3c443f1, 0xd700ad0, 0x76faa58, 0xbe7fcbf, 0x6fe6cfa, + 0x8990ef7, 0xaefc528, 0x80004cc, 0x44e30fa, 0x6d8ef85, 0xc744adc, + 0x912df70, 0xafcd931, 0x572a6d8, 0xf62a9d1 }, + { 0x3219f27, 0x47158a0, 0xad73136, 0x76fb27e, 0xcc2d614, 0x41bb2ad, + 0xde1ec21, 0x8858cb9, 0x5f15866, 0xab402c4, 0xbc82bbf, 0x6675d5b, + 0xf1b28d3, 0x4ee9dd6, 0xe373c17, 0x875884f } + }, + { + { 0x2a67d36, 0x17806dd, 0x32c9ec1, 0xaa23a86, 0xfc1ee55, 0xd914126, + 0x653701b, 0xbf8f7bd, 0xea71367, 0x9b0111a, 0xa98e417, 0x61fd4ab, + 0x561c5a5, 0xeb45298, 0xe7af394, 0x2187b0a }, + { 0x1616dde, 0x71f12db, 0x07da7b4, 0x0617609, 0x02ddb04, 0x414d376, + 0x286fb58, 0x1100be7, 0x6f0d95b, 0xd7cf88d, 0x746d703, 0x8539d23, + 0x4e23d73, 0xdccc9d6, 0xec89680, 0xaeef1d2 } + }, + { + { 0x336508d, 0x82ccf1a, 0x5bad150, 0xa128c1f, 0x29a188d, 0x551d8c0, + 0x771404f, 0xef13dd4, 0xc37b993, 0xdd67696, 0x0dddad2, 0x428c0e2, + 0x038c94c, 0x222278d, 0x078e3f2, 0x1a24a51 }, + { 0xedb0db9, 0xd297fe6, 0x8251a87, 0x00988d2, 0xbfaa0d7, 0xbb946f8, + 0xdf45ea0, 0x380f7b9, 0xafccf5e, 0x8526415, 0xe9ec7bc, 0x909bfbf, + 0x124755c, 0x2ed7093, 0x89404e2, 0x4368028 } + }, + { + { 0x36d9ef1, 0x21b9fa0, 0xe433526, 0xfd64b7c, 0x6544849, 0xd9d7eb7, + 0xd5b54b3, 0x201620c, 0xbb61159, 0x25fab3d, 0xc53e0d3, 0x90d4eb0, + 0x9e74772, 0xba09831, 0xec1681c, 0x8749658 }, + { 0xfec316b, 0xa354349, 0xa743ea2, 0x639a9b1, 0x37c50e6, 0x2e514ca, + 0xdbaf6c5, 0x9f4a4fd, 0x6f511c9, 0x0df87ef, 0x0c00d95, 0xadd4cef, + 0xaa1433f, 0x401c0eb, 0xbb38af9, 0x3c3a59e } + }, + { + { 0xf0e7dca, 0x8706245, 0x3fb29ca, 0xad238cd, 0x9b7d8f0, 0x0330443, + 0x154f495, 0xfdcd6e6, 0x7d4ad09, 0xc67e24a, 0x5438390, 0x1b209e8, + 0xb0c211e, 0xf893b81, 0x7e11e36, 0x1aa86f0 }, + { 0xedea8b1, 0x2cca3ff, 0x3b306cd, 0x7eedd07, 0x12ee222, 0x78e37bc, + 0xbc42a1d, 0x257870b, 0x1fbd397, 0x5fb2bb9, 0x09d6c60, 0x4702470, + 0x20bdc36, 0x11748a3, 0x04280e8, 0x3ff24dc } + }, + { + { 0x9839b52, 0x0eb1c67, 0xacfbd32, 0x5bcca27, 0x74898e3, 0xb506c16, + 0x2489e5e, 0x37d662e, 0xf694887, 0x8dc0731, 0xf43f1dc, 0x571149e, + 0x66d63dc, 0x6430a37, 0xb50dd70, 0x0d2640e }, + { 0x3b2675b, 0x2b56149, 0x88c604f, 0x1b48065, 0xaafbabc, 0x55c86a8, + 0x608aaba, 0xa7b9447, 0x04cad8c, 0xa42f635, 0xcee7788, 0x0f72b1d, + 0x755d99a, 0x1d68374, 0x5be2531, 0xd7cdd8f } + }, +}, +{ + { + { 0xbcdfee1, 0x67873bd, 0xfcd0a3f, 0xa5a0c0a, 0x3cfa3d4, 0x59389f9, + 0xe1c865c, 0x14e945c, 0x1d588cc, 0x62d2f8e, 0x8e228b4, 0xfd02f8a, + 0xb42b649, 0x208f791, 0xab397ad, 0x0e0dff1 }, + { 0x0bc6eb1, 0x30ac3d9, 0x5f313bb, 0xf14f16a, 0xe2a0ad2, 0x70fa447, + 0x5a0db84, 0x6e40685, 0xe32e1e7, 0xd52282b, 0x15ca330, 0x315a02a, + 0x867c2fe, 0x9a57a70, 0x0054923, 0x55f0765 } + }, + { + { 0xc0cf08f, 0x2d729f6, 0xebaf57f, 0x6b80138, 0x0200c25, 0x6285bcc, + 0x2cd2ac7, 0xee84519, 0x922778a, 0x28fce4d, 0xcd1011c, 0x761325c, + 0x5100e47, 0xd01f247, 0xc60d8e1, 0xc7a1665 }, + { 0x7ceb064, 0x950966d, 0x78420db, 0x0a88e85, 0xe096f29, 0x44f2cfc, + 0x640f1d2, 0x9d9325f, 0xd2426f1, 0x6a4a81f, 0x9c905ac, 0x3ed6b18, + 0x008854d, 0xba3c0e2, 0xa0d321b, 0x1df0bd6 } + }, + { + { 0x3feb1e7, 0x0117ad6, 0xf1ae02f, 0xa058ba2, 0x31b3f06, 0x5eee5aa, + 0xafacd4d, 0x540d9d4, 0x1571d91, 0x38992f4, 0xbf2c7de, 0xef2738e, + 0x92a798d, 0x28bfcab, 0x2286733, 0x37c7c5d }, + { 0x6470df0, 0xb99936e, 0x8af6a42, 0x3d762d5, 0xc74eec5, 0xa8c357a, + 0xf13afbc, 0x9917beb, 0xf2dc073, 0x28f0941, 0x6ce7df7, 0x306abf3, + 0xd6973c8, 0xa3c5f6f, 0x3677632, 0x640209b } + }, + { + { 0xe23aef7, 0xee872a2, 0xeb9b08e, 0xb497b6f, 0x3f33c63, 0xfb94d97, + 0x2b32315, 0x9ea1ff4, 0x49a4166, 0x537b492, 0xab4f8be, 0x89c7fe6, + 0xdad8f0f, 0xf68007f, 0x71b8474, 0xe56ef0b }, + { 0x3f333f9, 0x478b2e8, 0xb2607f5, 0x144e718, 0xa4c7ab5, 0x13aa605, + 0x1d0730d, 0xfc1fc99, 0x5ab3ea1, 0xe7a0437, 0x306d8d3, 0xc59986a, + 0x702a8b1, 0x24f6111, 0xe040ad2, 0x7741394 } + }, + { + { 0x60723a7, 0x34c6a25, 0xf4ea691, 0x8aabd0d, 0x5d7497f, 0x9d676a5, + 0x7d91fa4, 0x12c0957, 0x6479284, 0x581c7a8, 0xf4fd449, 0xa54f3da, + 0x4ef44cf, 0x2f89f3c, 0xc9ec97c, 0xfc266b5 }, + { 0x88b142a, 0xfcd3fbe, 0x4bd69c1, 0x9f3109f, 0xb5f5a6a, 0x08839c0, + 0x2e68303, 0x63ca850, 0xbba0a74, 0x2f0628d, 0x5d56b54, 0x743cccf, + 0x13e09fd, 0xbd4b066, 0xde2ba3e, 0x7a8415b } + }, + { + { 0xc076ab2, 0x2234a3b, 0x4977a98, 0xd6953e5, 0x31ebe2e, 0xc122158, + 0xbad78e2, 0x632145f, 0xa5c4b08, 0xd7ba78a, 0x998e32a, 0x6f4ea71, + 0x3485a63, 0x25900d2, 0x6a5176f, 0x97ac628 }, + { 0x1093f7b, 0x5df9118, 0xc844563, 0x2bf9829, 0x6272449, 0x525d99d, + 0xb5c8a18, 0x4281cb5, 0x0544a08, 0x35df278, 0xbaeb8f4, 0xf4c3d2d, + 0x5230447, 0xc7ff317, 0x5d2fbff, 0x6b4d764 } + }, + { + { 0x2b0c9cb, 0x4837f80, 0x8ce8418, 0xb65f816, 0x9fc1428, 0xdf66ea9, + 0x04ea7e8, 0x9788ee8, 0x8334e3c, 0x9eae900, 0xd6ba1b6, 0xbc91058, + 0xd7064b6, 0x634aba1, 0x397b368, 0x12d9bb3 }, + { 0xc413aa8, 0x0645c85, 0xac6b5e3, 0xb09dea6, 0x289a50b, 0x29a620d, + 0xbbcceb1, 0x104db3b, 0x87b3309, 0x42e4792, 0xec97f01, 0xdfc373e, + 0xb93f84e, 0xe953f94, 0x052dfbf, 0x3274b7f } + }, + { + { 0x1bd6fa9, 0x9d5670a, 0xdb6c4d4, 0xec42fc9, 0x1b42845, 0xaecd4ed, + 0x1b03549, 0x4eed90e, 0xbbab1fa, 0xeb3225c, 0x28a2816, 0x5345e1d, + 0x0b77d2a, 0x3741cfa, 0x7ea8caa, 0x712b19f }, + { 0x661853e, 0x42e6844, 0xe4a6e5d, 0x4cf4126, 0xc3649f6, 0x196a9cf, + 0xf21b6b1, 0x06621bc, 0x32e29ea, 0x887021c, 0x8c5680f, 0x5703aeb, + 0x660f6d7, 0x974be24, 0xc71864e, 0xaf09bad } + }, +}, +{ + { + { 0xa81b6d3, 0x3483535, 0xca037dc, 0x19e7301, 0x63ddfeb, 0x748cab7, + 0x6f01a38, 0xe5d87f6, 0x2795cd6, 0xbba4a5c, 0x615c36c, 0x411c5d4, + 0x706f412, 0xff48efc, 0x4b519df, 0x205bafc }, + { 0x5227110, 0xfcaa5be, 0x3ad0af0, 0x7832f46, 0x2642b1b, 0x34ef2c4, + 0x072f822, 0x7bbef7b, 0x923a616, 0x93cb0a8, 0x6d91ba7, 0x5df0236, + 0x42f7d21, 0x5da94f1, 0xa14e891, 0x3478298 } + }, + { + { 0xc831d39, 0xad79a0f, 0x4803c44, 0x24d1948, 0x86aeeb2, 0x4f8a864, + 0x926f6b9, 0x0ca284b, 0x1acd7cd, 0x501829c, 0x3d12c52, 0x9f6038b, + 0xf371ef5, 0x77223ab, 0x13bf4de, 0x2e03516 }, + { 0xb4468cc, 0x7a5a4f2, 0x470ae46, 0xdcea921, 0x11be696, 0xf23b7e8, + 0x720d6fb, 0xe59ad0d, 0x2983469, 0x9eacac2, 0xc4397ee, 0x4dd4110, + 0xcbe2675, 0x4ef85bd, 0xaa7c74b, 0xe4999f7 } + }, + { + { 0x8ea1e98, 0x031838c, 0x04d96a2, 0x539b383, 0x163956e, 0x5fbdef0, + 0xce3f52a, 0x6bd4d35, 0x55e897f, 0xe538c23, 0x472dd3f, 0x6078d3a, + 0xca9f452, 0x590241e, 0xfd7fc07, 0x2bc8495 }, + { 0xead4c8c, 0x23d0c89, 0x601c66e, 0x1ea55a9, 0x4f5b833, 0x41493c9, + 0xaa5a978, 0xc49a300, 0x0c69594, 0xc98bdc9, 0xccbdc8c, 0x4e44ced, + 0x6adccbf, 0xb0d4e91, 0x32c37ae, 0xd56e36b } + }, + { + { 0x5b93152, 0x052bd40, 0x4f1dbfa, 0x688b1d4, 0xbe5cc5f, 0xe77ba1a, + 0xa6ac543, 0x11f8a38, 0xe4bb988, 0x3355fd6, 0xf8dffb4, 0xdf29c5a, + 0x81f20ee, 0x751f589, 0xda9b7fb, 0x22a0f74 }, + { 0x6397b49, 0xec8f2bc, 0x3639201, 0xff59fc9, 0xa048264, 0xb7f130a, + 0xafdc4cc, 0xe156a63, 0xb13acaf, 0x0fd7c34, 0x0cb4999, 0x87698d4, + 0x7f26f24, 0x6d6ecae, 0x0f296e2, 0xae51fad } + }, + { + { 0xdd0f58d, 0xd0ad5eb, 0x5c67880, 0x6ec6a2c, 0x9af1e0f, 0xe1ce034, + 0x3996d32, 0x0801485, 0x5e69d20, 0x59af51e, 0xaa48ecf, 0x0ef743a, + 0x7dafcb0, 0x8d3d2ea, 0x89189b6, 0x4ac4fad }, + { 0xeae97f1, 0x92d91c2, 0x62b4662, 0xef5eca2, 0xb38b10a, 0x440b213, + 0xfc661da, 0xec90187, 0xf64cf8d, 0x85f3f25, 0x457ad1b, 0xcee53ca, + 0xf517672, 0x8deed4b, 0x4761828, 0x7706fb3 } + }, + { + { 0x17494fe, 0x1577d91, 0x2fd7239, 0x52d29be, 0x0186d37, 0x9a0eef0, + 0x27fe108, 0x241d0f5, 0xe6fb59f, 0x42824ba, 0x0d48c25, 0xb8d33df, + 0x47af4b0, 0xfffdb0a, 0x073b0b6, 0x534c601 }, + { 0x51c033b, 0xe6df359, 0x86c0f94, 0x3e1002b, 0x48fb9b6, 0xa7cb555, + 0xa7bbff8, 0x999818b, 0x84d8bf2, 0xe4ba3d6, 0x6358f0a, 0x53dbb32, + 0xf2568e8, 0xeebc1e2, 0xb3e0f68, 0xc6917eb } + }, + { + { 0x19f8d13, 0xbe1bbfc, 0x2d4795c, 0xc3951b6, 0xed535a9, 0x9371c49, + 0x68cebea, 0x77c389f, 0xa141d0e, 0xfc1a947, 0xde44f8b, 0x4b48d7a, + 0x8580a26, 0x3db1f05, 0x258b5fc, 0xeed1466 }, + { 0x9854b21, 0x5daa4a1, 0x1ab1ead, 0x5bfa46f, 0x59957eb, 0xc152e35, + 0xea48ada, 0xdc84277, 0xfc169b5, 0x68709cf, 0x720e617, 0xde50ce3, + 0xdd9a832, 0xe42f262, 0x2d6ce29, 0xddffd4d } + }, + { + { 0x8fa0a56, 0xd5ba557, 0xfafaf4c, 0x0d7d0f1, 0x38b63ed, 0x7666e41, + 0x5d87f02, 0x04e6513, 0xc958f32, 0xdca8866, 0x3ce2686, 0xaa8486d, + 0xf1cbcd3, 0xe3785ca, 0x03c8335, 0x8a9b114 }, + { 0x2e0ef60, 0x5c1dca2, 0x7d3fb20, 0x775af5b, 0x2b373a8, 0xe690ffc, + 0x28330e6, 0x30fe15d, 0xdd0f393, 0x8a1022b, 0x966a828, 0x6bd7364, + 0x949208a, 0x8d4b154, 0xb9d9828, 0xfb38c6b } + }, +}, +{ + { + { 0x0340ac2, 0x6d19764, 0xecab5ff, 0x969f473, 0xc458e42, 0xead46f7, + 0x1d00eed, 0x168646a, 0xe0ce0cf, 0xf70c878, 0x8d8d15a, 0xa7291d3, + 0xfdd10cc, 0x92cf916, 0x24f86d5, 0x6d36134 }, + { 0x2d5c4b4, 0xba50d17, 0x4626f15, 0xe0af502, 0xd76098a, 0x76f3809, + 0xd6caaa8, 0x433dc27, 0x70d97a7, 0x72dc67a, 0xf5c7355, 0x935b360, + 0x179bb31, 0xdbaac93, 0x7ed1a33, 0x7673848 } + }, + { + { 0x8f9fa0d, 0x8d1ca66, 0xa02f2bf, 0x4ed95d8, 0xf630d7b, 0xd19fc79, + 0xf46fa51, 0x0448ec4, 0x623bf3f, 0xb371dd8, 0xd650e94, 0xe94fabc, + 0xcd90a70, 0x3af3fca, 0x03ce3b7, 0x0f720c4 }, + { 0xd636c3b, 0x590814c, 0x4469945, 0xcf6928d, 0x484a4c6, 0x5843aaf, + 0xf9b4722, 0xb5a4c1a, 0x6cfb2f9, 0x25116b3, 0x32c2640, 0xf248cf0, + 0x27412a1, 0x8cd059e, 0x862fc5d, 0x866d536 } + }, + { + { 0x6de4a2e, 0x156e62f, 0xaafcc78, 0x0365af7, 0x19e925e, 0x65c8618, + 0xf8b2191, 0x4db5c01, 0xad564fa, 0x1fd26d1, 0x19c8610, 0x16bbc53, + 0x815f262, 0x0718eef, 0x27f83d1, 0x8684f47 }, + { 0xb0f48db, 0xa30fd28, 0x6ab8278, 0x6fef506, 0x1a652df, 0xd164e77, + 0xc6ebc8c, 0x5a486f3, 0xdc3132b, 0xb68b498, 0xd73323f, 0x264b6ef, + 0x69b2262, 0xc261eb6, 0x2a35748, 0xd17015f } + }, + { + { 0x7c4bb1d, 0x4241f65, 0xf5187c4, 0x5671702, 0x3973753, 0x8a9449f, + 0xcc0c0cd, 0x272f772, 0x58e280c, 0x1b7efee, 0x4b5ee9c, 0x7b32349, + 0x31142a5, 0xf23af47, 0xd62cc9e, 0x80c0e1d }, + { 0x675ffe3, 0xcbc05bf, 0x258ce3c, 0x66215cf, 0x28c9110, 0xc5d2239, + 0x2a69bc2, 0x30e12a3, 0x76a9f48, 0x5ef5e80, 0x2329d5f, 0x77964ed, + 0x8a72cf2, 0xdf81ba5, 0x6e1b365, 0x38ea70d } + }, + { + { 0x2f75c80, 0x1b18680, 0x698665a, 0x0c153a0, 0x522e8dd, 0x6f5a7fe, + 0x8ddfc27, 0x9673866, 0x0d3bdce, 0x7e421d5, 0x25001b2, 0x2d737cf, + 0x0e8490c, 0x568840f, 0xe30c8da, 0xea2610b }, + { 0x9561fd4, 0xe7b1bc0, 0x26decb0, 0xeda786c, 0x6a76160, 0x2236990, + 0x78a3da3, 0x371c714, 0x2a2d9bf, 0x1db8fce, 0x3292f92, 0x59d7b84, + 0x5a665f9, 0x8097af9, 0x542b7a9, 0x7cb4662 } + }, + { + { 0xc6b0c2f, 0xa5c53ae, 0x7312d84, 0xc4b8732, 0xc732736, 0xfc374cb, + 0x9310cc0, 0xa8d78fe, 0x65d1752, 0xd980e86, 0x6004727, 0xa62692d, + 0x0146220, 0x5d07928, 0x860fea5, 0xbd1fedb }, + { 0xb35d111, 0xcbc4f8a, 0x3e32f77, 0x5ba8cdf, 0xb614b93, 0xd5b71ad, + 0x2f8808d, 0x7b3a2df, 0x6ef2721, 0x09b89c2, 0x47c3030, 0x55a5054, + 0x2986ae6, 0x2104431, 0x2367d4c, 0x427a011 } + }, + { + { 0xc1942d8, 0xe9fe256, 0x96e3546, 0x9e7377d, 0xb0c1744, 0x43e734c, + 0x211fbca, 0x5f46821, 0x32b6203, 0x44f83dc, 0x6ad1d96, 0x8451308, + 0x2fbb455, 0x54dd519, 0x2f10089, 0xc2a1822 }, + { 0x1855bfa, 0x01055a2, 0x77078b4, 0x9e6d7b4, 0x30cea0e, 0x3f8df6d, + 0x32973f7, 0x81c2150, 0xc0b3d40, 0x17dd761, 0x50d0abe, 0x040424c, + 0x783deab, 0x5599413, 0x8f3146f, 0xde9271e } + }, + { + { 0xaf4a11d, 0x5edfd25, 0x7846783, 0x3a3c530, 0x73edd31, 0xb200868, + 0xfe0eef8, 0x74e00ec, 0x3dd78c7, 0xba65d2f, 0x71999f1, 0xab13643, + 0xde9a7e8, 0xfa9be5d, 0x87a8609, 0xeb146ce }, + { 0x65353e9, 0x76afd65, 0xd51ba1c, 0xfa7023d, 0x37ede4f, 0x7a09f22, + 0x0ba7a1b, 0xca08576, 0xb99950a, 0xd973882, 0xea5057a, 0xe894266, + 0x7f55e49, 0xd01c421, 0x5555679, 0x69cfb9c } + }, +}, +{ + { + { 0xc5d631a, 0x67867e7, 0x5bcf47b, 0x1de88c5, 0xafd1352, 0x8366d06, + 0x6e20337, 0xd7dbdef, 0x1253ec7, 0xb0f9e2f, 0x10ad240, 0x1be9845, + 0xf4a6118, 0x63ec533, 0x96ce633, 0xd5e4c5b }, + { 0x4df4a25, 0x1d0b6c3, 0x5a1b554, 0xef9486a, 0x47b6ef3, 0x2f0e59e, + 0x2ff84d7, 0x4d8042f, 0xda359c9, 0x3e74aa3, 0xd21c160, 0x1baa16f, + 0x0191cba, 0xb4cff21, 0xebc6472, 0x50032d8 } + }, + { + { 0x1fc1b13, 0xb6833e0, 0x1a5ad8f, 0x8a8b7ba, 0x622b820, 0xc0cafa2, + 0x738ed20, 0xc6663af, 0x8b18f97, 0xd894486, 0x774fbe4, 0xcf0c1f9, + 0x5be814f, 0xeedd435, 0xb57e543, 0xd81c02d }, + { 0x310bad8, 0x5e32afc, 0x9b813d1, 0x065bc81, 0x3142795, 0x8efc5fc, + 0x732d59c, 0x5006514, 0x2b5a3ce, 0x91e39df, 0xfaf4204, 0x2ad4477, + 0x4d9bd4f, 0x1a96b18, 0xa4d9c07, 0xc3fee95 } + }, + { + { 0x6b4ba61, 0xfac7df0, 0x061aaef, 0xa6ed551, 0x133f609, 0x35aa2d6, + 0x20ed13d, 0x420cfba, 0xea03d0c, 0x861c63e, 0xf936d6e, 0x75f0c56, + 0x3d9a3d5, 0xa25f68f, 0xcd9f66e, 0xba0b7fe }, + { 0x4680772, 0x292e135, 0xa73f405, 0x6f6a2db, 0x24ea9e4, 0xca6add9, + 0x268daaa, 0x81cfd61, 0xe6f147a, 0x7a4cb6c, 0xbded8f5, 0x8ec3454, + 0x11d61cb, 0xc8a893b, 0x7656022, 0x2256ffc } + }, + { + { 0x575cb78, 0x6b33271, 0xadcd23e, 0x560d305, 0xd6d834b, 0xeedbd3a, + 0x5a31e27, 0x614a64a, 0x47ee0c8, 0xe40b476, 0x8bd7c2c, 0x8ef4ff6, + 0x0b77727, 0xa5297fc, 0xbaf88ad, 0x8759208 }, + { 0x918df68, 0x86cfe64, 0xcdd882e, 0x9d60a73, 0xb953014, 0x546b642, + 0x8bbef55, 0xbaceae3, 0xf1c3467, 0xdf58e43, 0xe9f9bab, 0x99a83fe, + 0x57a4a8b, 0xcd52cbf, 0x8ae36ec, 0xf744e96 } + }, + { + { 0xa607124, 0xb945869, 0x440e6f6, 0x810dbe9, 0x738e381, 0x9911e60, + 0x343b80b, 0x51df68c, 0xf7a3f39, 0xe424336, 0x989015c, 0x2d32acb, + 0x31019e8, 0xa69b149, 0xec12f93, 0x8a31a38 }, + { 0x97c916a, 0x0d0d369, 0x8885372, 0xdc95f3b, 0x3549040, 0xcf1a261, + 0xabe95a2, 0x60f6f5e, 0xe141325, 0xa909e9f, 0x355c865, 0x7d598f2, + 0x931a9c9, 0x70c6442, 0xb423850, 0x2354a85 } + }, + { + { 0x97f9619, 0x4cdd224, 0xc22162e, 0x4776fff, 0x0cd31c2, 0xee5ec33, + 0xf209bb8, 0x7c04c10, 0x579e211, 0x35bbfde, 0x15cdfc2, 0x0e38325, + 0xe26ffa7, 0x657e6d3, 0xc65c604, 0xc66a7c3 }, + { 0xb45e567, 0x322acd7, 0x296db9b, 0x1589cf0, 0xba1db73, 0x1fd0bd3, + 0x9337a40, 0xe882610, 0xb3035c7, 0xf505a50, 0x6ed08d7, 0x4d5af06, + 0x5eda400, 0xb3c376b, 0x1944748, 0x9c7b700 } + }, + { + { 0x70c3716, 0xd768325, 0xdd540e0, 0xda62af0, 0x6580fea, 0x76b155d, + 0x32b5464, 0x4f42acc, 0x3f5b72b, 0x881bb60, 0xe68b9ba, 0x09c130e, + 0x5c50342, 0x37ede3b, 0xfd15e7d, 0xce61a9c }, + { 0x72605d0, 0xfff1d85, 0x062abc2, 0x62ac2d3, 0xfbe43dd, 0xa85e02e, + 0xa947020, 0x859d2ba, 0x111c20b, 0x2ebc8a9, 0xa656f66, 0x7f590a7, + 0x16b21a6, 0x0e13843, 0x00c7db6, 0x29b30c5 } + }, + { + { 0x906b8de, 0x61e55e2, 0x949974d, 0x6a97e96, 0x26eef67, 0x24b52b5, + 0x1aa595a, 0x512f536, 0x3c48fcb, 0x81cc7b8, 0x28115ad, 0xa64af23, + 0x3d44b8e, 0x9edf6f9, 0x1fe22e3, 0x68d7f7c }, + { 0x520d151, 0x2b2116a, 0x6aa3efb, 0x66a0b7d, 0x9b0f791, 0x48ae70a, + 0x037db88, 0xcf12174, 0x317d9f3, 0x36868cd, 0x22fc344, 0xb573059, + 0x46a5d23, 0xbaa8526, 0x37fc10d, 0xad65691 } + }, +}, +{ + { + { 0x12c78d5, 0xcf8e5f5, 0x805cdbd, 0xeb94d98, 0x2ab50b5, 0xad1dcdf, + 0xf33cd31, 0xf33c136, 0x10aeff5, 0x0d6226b, 0xf2f8fc5, 0xf7ff493, + 0xdf57165, 0x7e520d4, 0x05271a7, 0x41fbae5 }, + { 0x76480ba, 0x72c8987, 0x25f4523, 0x2608359, 0x49f5f01, 0xed36b8d, + 0xf3d49eb, 0x3bc1dce, 0x4940322, 0x30c1c1a, 0x7e0f731, 0x78c1cda, + 0x6d05a31, 0x51f2dc8, 0x07f3522, 0x57b0aa8 } + }, + { + { 0x71f88bc, 0x7ab628e, 0x8018f21, 0xcf585f3, 0x13d64f6, 0xdbbe3a4, + 0xec493a5, 0x0f86df1, 0x7725de9, 0x8355e6c, 0xe00fe1e, 0x3954ffe, + 0x9924e32, 0xbb8978f, 0x7812714, 0x1c19298 }, + { 0xaabca8b, 0x7c4ce3e, 0x9bf7019, 0xf861eb5, 0x682e541, 0x31a84fc, + 0xacd1b92, 0x2307ca9, 0x4bf2842, 0x6f8b6ce, 0xcb9f9a9, 0xde252ac, + 0x93c46d1, 0x7f0611d, 0x751dc98, 0x8e2bd80 } + }, + { + { 0xe27d54b, 0xf2fd8fb, 0xc248071, 0x2a1e37e, 0xab8f49a, 0x2fcc888, + 0xc18a9e5, 0x42c62a3, 0x70b2446, 0xe302908, 0xc5ac55d, 0x90277fa, + 0xd6dde41, 0x8d97d56, 0x5db04fe, 0xf4cf8a9 }, + { 0xd30d077, 0x3e280f5, 0x3cb3293, 0x2c90307, 0x24eb0dd, 0xe0be2ac, + 0x8bcb4f0, 0xa2d1a49, 0xcd0cd45, 0x16db466, 0x9a80232, 0x3b28aa7, + 0x17b008e, 0xdd7e52f, 0x868e4da, 0x20685f2 } + }, + { + { 0x7c7a486, 0x0a68c14, 0xc429633, 0xd8ef234, 0xffe7506, 0x470667b, + 0x8828d51, 0x55a13c8, 0x2e44bef, 0x5f32741, 0x5929f92, 0x537d92a, + 0x31c5cd5, 0x0a01d5b, 0x67eb3d7, 0xb77aa78 }, + { 0x8b82e4d, 0x36ec45f, 0xb37b199, 0x6821da0, 0xd7fa94e, 0x8af37aa, + 0x1085010, 0xf020642, 0x7e56851, 0x9b88678, 0x52948ce, 0x35f3944, + 0xafc1361, 0x125c2ba, 0x453e332, 0x8a57d0e } + }, + { + { 0x8043664, 0xefe9948, 0xdb1aa55, 0xb8b8509, 0x332523f, 0x1a2e5a9, + 0x1045c0f, 0x5e255dd, 0x7ae7180, 0xe68dd8a, 0x45bf532, 0x55f1cf3, + 0xe63a716, 0xe00722e, 0x6116bac, 0xd1c2138 }, + { 0x1c6d1f4, 0x626221f, 0x3773278, 0x240b830, 0x88def16, 0xe393a0d, + 0xca0495c, 0x229266e, 0xd3e4608, 0x7b5c6c9, 0x7927190, 0xdc559cb, + 0xc7b3c57, 0x06afe42, 0xb439c9b, 0x8a2ad0b } + }, + { + { 0xffc3e2f, 0xd7360fb, 0xfbd2e95, 0xf721317, 0x5748e69, 0x8cacbab, + 0x9054bb9, 0x7c89f27, 0xaa86881, 0xcbe50fa, 0x75206e4, 0x7aa05d3, + 0xc752c66, 0x1ea01bc, 0x1f2c2bc, 0x5968cde }, + { 0x09a853e, 0x487c55f, 0xe09204b, 0x82cbef1, 0xabd8670, 0xad5c492, + 0xf12dcb3, 0x7175963, 0xbf6aa06, 0x7a85762, 0xf8d5237, 0x02e5697, + 0x37c6157, 0xccf7d19, 0xc2fd59c, 0x3b14ca6 } + }, + { + { 0x1b9f77f, 0x5e610d8, 0x051b02f, 0x85876d0, 0xb8020dd, 0x5d81c63, + 0xd6ce614, 0xd0b4116, 0xaa8bf0c, 0x91810e5, 0xcbf8c66, 0xf27f91f, + 0x38480ae, 0x2e5dc5f, 0xbec7633, 0x0a13ffe }, + { 0x2bf6af8, 0x61ff649, 0x641f827, 0xe6aef2d, 0x5de5f04, 0xad5708a, + 0xcdfee20, 0xe5c3a80, 0x68fcfa2, 0x88466e2, 0xd6e1d7b, 0x8e5bb3a, + 0xed236b8, 0xa514f06, 0xa5f5274, 0x51c9c7b } + }, + { + { 0xf9bc3d8, 0xa19d228, 0x3381069, 0xf89c3f0, 0x5c3f379, 0xfee890e, + 0x32fb857, 0x3d3ef3d, 0x5b418dd, 0x3998849, 0xc46e89a, 0x6786f73, + 0x9e0f12f, 0x79691a5, 0x3bc022b, 0x76916bf }, + { 0x2cd8a0a, 0xea073b6, 0x102fdbc, 0x1fbedd4, 0xcb9d015, 0x1888b14, + 0x76655f7, 0x98f2cfd, 0x59f0494, 0xb9b5910, 0xe6986a3, 0xa3dbbe1, + 0xeaf2b04, 0xef016a5, 0xcd2d876, 0xf671ba7 } + }, +}, +{ + { + { 0x1ae05e9, 0x1dae3bf, 0x1f21fef, 0x6a02996, 0x7aec3c6, 0x95df2b9, + 0xd83189b, 0x9abbc5a, 0x2d13140, 0xaf994af, 0x86aa406, 0xc3f8846, + 0x75284c5, 0xcd77e50, 0x2a9a4d7, 0x1c1e13d }, + { 0x744b89d, 0x7f8815d, 0x2ba673e, 0xb189133, 0xd594570, 0x55ea93c, + 0xd61b041, 0x19c8a18, 0x8d2c580, 0x938ebaa, 0x05ba078, 0x9b4344d, + 0x8eaf9b7, 0x622da43, 0x9fea368, 0x809b807 } + }, + { + { 0xc33b7a2, 0x3780e51, 0x387b1c8, 0xd7a205c, 0x4be60e4, 0x79515f8, + 0x1e18277, 0xde02a8b, 0xf0d9150, 0x4645c96, 0xe0b3fd1, 0x45f8acb, + 0x9b53ac3, 0x5d532ba, 0xb0557c9, 0x7984dcd }, + { 0x8a92f01, 0x5ae5ca6, 0x9d569ca, 0xd2fbb3c, 0x0c297c1, 0x668cc57, + 0x6295e89, 0xa482943, 0xa33ad40, 0xf646bc1, 0xc3f425d, 0x066aaa4, + 0xd005de2, 0x23434cd, 0xdb35af4, 0x5aca9e9 } + }, + { + { 0x6877c56, 0x2bca35c, 0xf0ddd7d, 0xab864b4, 0x404f46c, 0x5f6aa74, + 0x539c279, 0x72be164, 0xe0283cf, 0x1b1d73e, 0xad583d9, 0xe550f46, + 0xe739ad1, 0x4ac6518, 0x8d42100, 0x6b6def7 }, + { 0xfa8468d, 0x4d36b8c, 0x5a3d7b8, 0x2cb3773, 0x5016281, 0x577f86f, + 0x9124733, 0xdb6fe5f, 0xe29e039, 0xacb6d2a, 0x580b8a1, 0x2ab8330, + 0x643b2d0, 0x130a4ac, 0x5e6884e, 0xa7996e3 } + }, + { + { 0x60a0aa8, 0x6fb6277, 0xcbe04f0, 0xe046843, 0xe6ad443, 0xc01d120, + 0xabef2fc, 0xa42a05c, 0x12ff09c, 0x6b793f1, 0xa3e5854, 0x5734ea8, + 0x775f0ad, 0xe482b36, 0xf864a34, 0x2f4f60d }, + { 0x84f2449, 0xf521c58, 0x9186a71, 0x58734a9, 0xac5eacc, 0x157f5d5, + 0x248ee61, 0x858d9a4, 0x48149c3, 0x0727e6d, 0xac9ec50, 0xd5c3eaa, + 0x20ee9b5, 0xa63a64a, 0x87be9de, 0x3f0dfc4 } + }, + { + { 0xb13e3f4, 0x836349d, 0x3e9316d, 0xebdd026, 0x324fd6c, 0x3fd61e8, + 0x0964f41, 0x85dddfa, 0x52add1b, 0x06e72de, 0x8c4a9e2, 0xb752cff, + 0xfdf09f7, 0x53b0894, 0x0bc24fd, 0xd5220ab }, + { 0xfb1981a, 0x8442b35, 0x3edd701, 0xa733a37, 0xd0ef089, 0x42b60c3, + 0x46e7bca, 0xa1b16ec, 0xa09aaf4, 0xc0df179, 0x638f3a1, 0xcd4f187, + 0x9eab1c2, 0x9af64f7, 0xd1d78e3, 0x86fed79 } + }, + { + { 0xfe29980, 0x42c8d86, 0x6575660, 0x6657b81, 0x80f92ca, 0x82d52c6, + 0x02d42be, 0x8587af1, 0x6e8bdf0, 0xb515131, 0xc333495, 0x706e2d9, + 0x9673064, 0xd53601a, 0x8219099, 0x27b1fbb }, + { 0x705f7c8, 0x3f0929d, 0xf3d6e6f, 0xff40b10, 0x026af5c, 0x673c703, + 0xe25a422, 0x2c1dce4, 0x3dad8b6, 0x5348bd7, 0xbe2c329, 0xc39b6b6, + 0xb921084, 0x47854ff, 0xb391f20, 0xb347b8b } + }, + { + { 0xeb9b774, 0x79fc841, 0xb4b6c1d, 0xf32da25, 0xfe492cb, 0xcbba76b, + 0xd623903, 0x76c51fc, 0xcf0705a, 0x114cf6f, 0x7815daf, 0x6b72049, + 0x473382e, 0x630b362, 0x9704db5, 0xbf40c3a }, + { 0xc5456eb, 0xa8a9ddc, 0x72f2dc1, 0x2b4472a, 0xd6d6ef3, 0x9874444, + 0xa0ba5ed, 0x27e8d85, 0x194849f, 0x5d225b4, 0xebaa40d, 0xe852cd6, + 0x8d4bf3f, 0xb669c24, 0x2343991, 0xa8601eb } + }, + { + { 0x59502d3, 0x8a04854, 0xe269a7b, 0xcab27ee, 0x4875ada, 0x4179307, + 0xe2405f9, 0x179e685, 0x7b28963, 0x0d7b698, 0x422a43e, 0x80c9db8, + 0xa0f43ee, 0xf5ff318, 0x4ba7aa7, 0x7a92805 }, + { 0x0c0834e, 0xa5c79fe, 0x1f849ec, 0x837ca0d, 0x628ab7b, 0xfe0d7fa, + 0x6edd19a, 0x94bcb95, 0x2226fbf, 0xa18bc93, 0xaad54a3, 0x2795379, + 0x371129e, 0xceeacf8, 0xa588be5, 0x65ca57f } + }, +}, +{ + { + { 0x2caa330, 0x7a578b5, 0xd8ca34a, 0x7c21944, 0x6447282, 0x6c0fbbb, + 0xf90b2e5, 0xa8a9957, 0x6586b71, 0xbbe1066, 0x49138a2, 0x716a902, + 0xe7ed66d, 0x2fa6034, 0x2b9916a, 0x56f77ed }, + { 0xbddefb3, 0x69f1e26, 0x8c08420, 0xa497809, 0x09bc184, 0xc3377eb, + 0xbe6dade, 0x796ce0c, 0xd103bbb, 0x3be0625, 0x992685c, 0x01be27c, + 0x7755f9f, 0xc0e2559, 0x1c0dbfa, 0x165c40d } + }, + { + { 0x659c761, 0xc63a397, 0x630fbad, 0x10a0e5b, 0x655ac56, 0xf21e8a6, + 0xc1181e2, 0xe8580fa, 0x0a84b5c, 0xbfc2d9c, 0x7afd5d1, 0x2cdbaff, + 0xf61e85a, 0x95f1182, 0x719eaf4, 0x1173e96 }, + { 0xc6de8b9, 0xc06d55e, 0xafcbcaa, 0x1b4c8eb, 0xbc2bbcd, 0x52af5cb, + 0x77bcd10, 0x564fab8, 0xae85a6e, 0xfd53a18, 0x94c712f, 0x2257859, + 0x1352121, 0x29b11d7, 0xc40491a, 0xab1cb76 } + }, + { + { 0xce32eb4, 0xb4e8ca8, 0xb250b49, 0x7e484ac, 0xa3e31a2, 0x062c6f7, + 0x625d1fc, 0x497fd83, 0x362dda7, 0x98f821c, 0x6be3111, 0xcae1f8f, + 0x5d4fa42, 0x9077e95, 0xa65855a, 0xa589971 }, + { 0x28832a9, 0xda6321d, 0x3936e9e, 0xf9ef5dc, 0xc9797ef, 0xa37f117, + 0xdb581be, 0x0eb3c80, 0xbaa0002, 0x207c5c4, 0xf38faa0, 0xc0401b5, + 0xd0f1e6e, 0xceee523, 0xd1f0045, 0x8d27a5f } + }, + { + { 0xcf0af29, 0x9411063, 0x89a6693, 0x3043857, 0x640145e, 0x9a9fb8f, + 0x54832eb, 0x7d82fe9, 0x898c520, 0xf2789e1, 0xf948dc0, 0x448b402, + 0x68996dd, 0xeca8fdf, 0xa149b2f, 0x22227e9 }, + { 0x8e62d6a, 0x63509ff, 0x8c9c57f, 0xe98d81c, 0x1fe3bed, 0xd387407, + 0x539538f, 0xf1db013, 0x48418ce, 0xb04092e, 0xd6d9d4d, 0xbbf8e76, + 0x2cec5ae, 0x2ea9cda, 0x5078fa9, 0x8414b3e } + }, + { + { 0xd68a073, 0x5ad1cdb, 0xc18b591, 0xd4cedaf, 0x8e4c1c9, 0x7826707, + 0x9ca302a, 0x9b8d920, 0x326115b, 0x3101bd2, 0x4c2717a, 0x6f154b5, + 0x263e84b, 0x618c31b, 0xbbd6942, 0x12c4138 }, + { 0x80da426, 0xf9ead25, 0x47d9680, 0xe748e99, 0x8a4210e, 0x9b396a3, + 0xf4b8f72, 0xfaf03dd, 0x66159e7, 0xbd94a52, 0x1d4c7cb, 0x5e73049, + 0x7910f38, 0x31d1f9a, 0x08d6dd1, 0x4fd10ca } + }, + { + { 0x9f2331e, 0x4f510ac, 0x7e3dcc2, 0xee872dc, 0xa0a0c73, 0x4a11a32, + 0xaa5a630, 0x27e5803, 0x7af4a8a, 0xe5ae503, 0x9fffeb0, 0x2dcdeba, + 0x719d91f, 0x8c27748, 0xb9cc61c, 0xd3b5b62 }, + { 0xcca7939, 0x998ac90, 0x64514e5, 0xc22b598, 0xb35738a, 0x950aaa1, + 0xdab0264, 0x4b208bb, 0xa557d2e, 0x6677931, 0xf7c17d3, 0x2c696d8, + 0x3e15c51, 0x1672d4a, 0x3db0e82, 0x95fab66 } + }, + { + { 0x6ff205e, 0x3d42734, 0x0ea9fbe, 0x7f187d9, 0x466b2af, 0xbd9367f, + 0x03daf2f, 0x188e532, 0x27b54d8, 0xefe1329, 0xef70435, 0x14faf85, + 0x1ec95c4, 0xa506128, 0xc22cba7, 0xad01705 }, + { 0x6197333, 0x7d2dfa6, 0x8b4f6ed, 0xedd7f07, 0x75df105, 0xe0cb685, + 0x80f76bc, 0x47c9ddb, 0x9073c54, 0x49ab531, 0xe607f44, 0x845255a, + 0xcc74b7c, 0x0b4ed9f, 0x0f5c3a6, 0xcfb52d5 } + }, + { + { 0xc278776, 0x545c7c6, 0x98c30f0, 0x92a39ae, 0xd2f4680, 0x8aa8c01, + 0x6b7f840, 0xa5409ed, 0xdcb24e7, 0x0c450ac, 0xc5770d9, 0x5da6fb2, + 0x8658333, 0x5b8e8be, 0x67ea4ad, 0xb26bf4a }, + { 0xc7d91fa, 0x2e30c81, 0x0eeb69f, 0x6e50a49, 0xee4bc26, 0x9458c2b, + 0x33be250, 0x419acf2, 0x87881ab, 0x79d6f81, 0x403b1be, 0x694565d, + 0x234fe1d, 0x34b3990, 0x2132b38, 0x60997d7 } + }, +}, +{ + { + { 0x26975dc, 0x00a9741, 0x6cf94e7, 0x42161c4, 0xc64ed99, 0xcc9fe4b, + 0x4680570, 0x020019a, 0x698da0d, 0x885595a, 0x77dd962, 0x008444b, + 0xa4fea0e, 0xbf3c22d, 0x2c81245, 0xc463048 }, + { 0x793ab18, 0xcb248c5, 0xeb4320b, 0x4dc7a20, 0x1572b7d, 0x9a0906f, + 0xf9ac20f, 0xd5b3019, 0x34520a3, 0x79b1bf5, 0x69b5322, 0x788dfe8, + 0x455b7e2, 0x9a05298, 0x016bca9, 0x2f4aecb } + }, + { + { 0x8745618, 0x414d379, 0xb7c983c, 0x64ba22e, 0x9f9d532, 0x9a5d19f, + 0x44a80c8, 0x81a00d8, 0xcae98d6, 0xb9e24f5, 0xaca965a, 0x6c3769c, + 0xf6e4e6d, 0x50d6081, 0x54422a6, 0x0d96980 }, + { 0x5cdd790, 0xbd7e792, 0x6a35219, 0xcff65da, 0x8b60ebe, 0x40dc363, + 0x92a50dc, 0x84bee74, 0x15ad65e, 0x57d4be4, 0x1a6d1d3, 0xc54256b, + 0x45717cc, 0x141c649, 0xcd1c736, 0x05eb609 } + }, + { + { 0x1e3c7ec, 0xfd52eab, 0x9f24895, 0xa4a5eca, 0x79fdb83, 0xaaa2a8d, + 0x72bdfda, 0xd105e60, 0x681d97e, 0x59e6ae2, 0x8e8077f, 0xfedf8e0, + 0x629e462, 0xb06d0ad, 0x96fa863, 0x8c7c2d0 }, + { 0xee8fc91, 0x5eecc4c, 0x9e61174, 0x5e83ab2, 0xb28c02d, 0x1fd8925, + 0x2072864, 0x93be538, 0x24c984e, 0xda0c886, 0xa008286, 0xdcf9f0c, + 0xa58ba75, 0x1ecb5a6, 0xc2e3c83, 0x1d9b890 } + }, + { + { 0xeeee062, 0x19e866e, 0x4f7b387, 0x31c1c7f, 0x1c06652, 0x9be6018, + 0x2b68bbb, 0xc00a93a, 0x9d52b2b, 0x54c65d6, 0xe8b744a, 0x4591416, + 0x9a64ab6, 0x641bcca, 0xab08098, 0xf22bcb1 }, + { 0xf1f726c, 0x3c0db8f, 0x9d2e6a6, 0x4f5739e, 0x45c9530, 0x5cb669b, + 0x7b472d0, 0x861b04e, 0x894da77, 0x3e30515, 0xc9ac39b, 0x3344685, + 0x73bdd29, 0x9e17305, 0x808dc85, 0x9cac12c } + }, + { + { 0x5e27087, 0xf152b86, 0x90a580e, 0x267bd85, 0x8baafc1, 0xba79cec, + 0x9442686, 0x6140ab1, 0x5b31693, 0xa67090c, 0x28b4117, 0x50a103a, + 0x0ddc08f, 0x7722e61, 0xe6569b2, 0x5d19d43 }, + { 0x5962bf6, 0x70e0c52, 0xfb5fb02, 0x808e316, 0x5b667be, 0x3fb80da, + 0xfcfacec, 0x8aa366e, 0x134280e, 0xcb0b3e7, 0xcd7d944, 0x0bf1de4, + 0xd092df5, 0x0cd23be, 0xa153a0c, 0xc9a6a79 } + }, + { + { 0x2d5a4b7, 0x1c69ad0, 0xd9e6f4a, 0x4bb28d0, 0xa984fc6, 0x815308c, + 0x9037ca5, 0x40929c7, 0x1bd0357, 0x0ea2b49, 0x42aad4e, 0xec17e5b, + 0x18e7235, 0x1f32ade, 0xa96a9d3, 0xbc60b05 }, + { 0xe20f707, 0x3b0229a, 0x56bdfad, 0xd635050, 0xd8b2e1e, 0xac2d922, + 0x235c748, 0x92b2998, 0xd766f97, 0x6002c3a, 0x1a2a862, 0x9919800, + 0xb58b684, 0x2af7567, 0xaaafce5, 0xd8fe707 } + }, + { + { 0x5df7a4b, 0x54487ab, 0xc57ccc2, 0x51cccde, 0x7510b53, 0x2394327, + 0xf555de3, 0x3a09f02, 0x1be484d, 0xa696aec, 0x37817a2, 0x56f459f, + 0x623dcb4, 0x8d8f61c, 0x5335656, 0xc52223c }, + { 0xb49914a, 0xf634111, 0x8e4f9bb, 0xbf8e1ab, 0xf4dba02, 0x2f59578, + 0xe004319, 0x2a94199, 0x654d005, 0x87931f0, 0x6fa0814, 0x7df57d9, + 0xa154031, 0xc8da316, 0x41f658b, 0x2a44ac0 } + }, + { + { 0x9e34ac6, 0xfb5f4f8, 0x97790f2, 0x0a1b10b, 0x4b8a06c, 0x58fe4e7, + 0x955f27c, 0x10c1710, 0xd5ebe19, 0x77b798a, 0x1f1c2dc, 0xaf1c35b, + 0xa1f8d69, 0xc25b8e6, 0xf76bf23, 0x49cf751 }, + { 0x436f7b7, 0x15cb2db, 0x7e74d1a, 0x186d7c2, 0xc00a415, 0x60731de, + 0x15f0772, 0xea1e156, 0x714463f, 0xf02d591, 0x51adeb1, 0x26a0c64, + 0xcc5229e, 0x20174cd, 0xefd512a, 0xb817e50 } + }, +}, +}; + +static const ge448_precomp base_i[16] = { + { + { 0x70cc05e, 0x26a82bc, 0x0938e26, 0x80e18b0, 0x511433b, 0xf72ab66, + 0x412ae1a, 0xa3d3a46, 0xa6de324, 0x0f1767e, 0x4657047, 0x36da9e1, + 0x5a622bf, 0xed221d1, 0x66bed0d, 0x4f1970c }, + { 0x230fa14, 0x08795bf, 0x7c8ad98, 0x132c4ed, 0x9c4fdbd, 0x1ce67c3, + 0x73ad3ff, 0x05a0c2d, 0x7789c1e, 0xa398408, 0xa73736c, 0xc7624be, + 0x03756c9, 0x2488762, 0x16eb6bc, 0x693f467 } + }, + { + { 0x6ff2f8f, 0x2817328, 0xda85757, 0xb769465, 0xfd6e862, 0xf7f6271, + 0x8daa9cb, 0x4a3fcfe, 0x2ba077a, 0xda82c7e, 0x41b8b8c, 0x9433322, + 0x4316cb6, 0x6455bd6, 0xb9108af, 0x0865886 }, + { 0x88ed6fc, 0x22ac135, 0x02dafb8, 0x9a68fed, 0x7f0bffa, 0x1bdb676, + 0x8bb3a33, 0xec4e1d5, 0xce43c82, 0x56c3b9f, 0xa8d9523, 0xa6449a4, + 0xa7ad43a, 0xf706cbd, 0xbd5125c, 0xe005a8d } + }, + { + { 0x2030034, 0xa99d109, 0x6f950d0, 0x2d8cefc, 0xc96f07b, 0x7a920c3, + 0x08bc0d5, 0x9588128, 0x6d761e8, 0x62ada75, 0xbcf7285, 0x0def80c, + 0x01eedb5, 0x0e2ba76, 0x5a48dcb, 0x7a9f933 }, + { 0x2f435eb, 0xb473147, 0xf225443, 0x5512881, 0x33c5840, 0xee59d2b, + 0x127d7a4, 0xb698017, 0x86551f7, 0xb18fced, 0xca1823a, 0x0ade260, + 0xce4fd58, 0xd3b9109, 0xa2517ed, 0xadfd751 } + }, + { + { 0xeb5eaf7, 0xdf9567c, 0x78ac7d7, 0x110a6b4, 0x4706e0b, 0x2d33501, + 0x0b5a209, 0x0df9c7b, 0x568e684, 0xba4223d, 0x8c3719b, 0xd78af2d, + 0xa5291b6, 0x77467b9, 0x5c89bef, 0x079748e }, + { 0xdac377f, 0xe20d3fa, 0x72b5c09, 0x34e8669, 0xc40bbb7, 0xd8687a3, + 0xd2f84c9, 0x7b3946f, 0xa78f50e, 0xd00e40c, 0x17e7179, 0xb875944, + 0xcb23583, 0x9c7373b, 0xc90fd69, 0x7ddeda3 } + }, + { + { 0x6ab686b, 0x3d0def7, 0x49f7c79, 0x1a467ec, 0xc8989ed, 0x3e53f4f, + 0x430a0d9, 0x101e344, 0x8ad44ee, 0xa3ae731, 0xae1d134, 0xaefa6cd, + 0x824ad4d, 0xaa8cd7d, 0xed584fc, 0xef1650c }, + { 0x4f4754f, 0xa74df67, 0xef3fb8b, 0xf52cea8, 0x2971140, 0x47c32d4, + 0xa256fbb, 0x391c15d, 0xa605671, 0xc165fab, 0x87993b9, 0xf2518c6, + 0xbd5a84d, 0x2daf7ac, 0x98f12ae, 0x1560b62 } + }, + { + { 0x54dc10a, 0xef4da02, 0x5940db8, 0x6311865, 0x82f2948, 0xe20b149, + 0x5581dba, 0x67b9377, 0x04f5029, 0x422ee71, 0x5122d34, 0x5d440db, + 0x1a4c640, 0xb1e56d7, 0xc2408ee, 0xbf12abb }, + { 0x016af01, 0x0cc9f86, 0xf3d8cab, 0x88366ab, 0xa2efe12, 0x85dda13, + 0x5d00674, 0x390df60, 0x6d187f7, 0xf18f580, 0xf0c5d20, 0x28c900f, + 0x3e01733, 0xad30812, 0x54bf2fd, 0x42d35b5 } + }, + { + { 0x2ffb1f1, 0x009135f, 0x8f9c605, 0x099fc7e, 0x26bfa5a, 0xcc67da6, + 0x344552b, 0xc186d12, 0x1b339e1, 0xb523250, 0xc9708c5, 0x70a544f, + 0x1e928e7, 0x06baaec, 0xef0f50f, 0x0baedd2 }, + { 0xbf479e5, 0x535d6d8, 0xe4ec3e9, 0x156e536, 0xddb9be2, 0x3165741, + 0x59fd736, 0x988af71, 0x2e33ddd, 0x13d8a78, 0x4e69002, 0x5460421, + 0x804a268, 0x34d56e0, 0x0e52a4c, 0xc59b84f } + }, + { + { 0x24729d9, 0x525d45f, 0x8712327, 0x5768aba, 0x43035db, 0xa25e43b, + 0x927ef21, 0x15a1ee8, 0x6056112, 0xa785d21, 0xd508af9, 0x45e2fbf, + 0x37ba969, 0xb6f721a, 0x216d8d3, 0x30d6d8c }, + { 0x52074c3, 0x3065e08, 0x2a0684e, 0xfa40b4a, 0x763f955, 0x851325a, + 0x9f25900, 0xd4ef19c, 0xf665756, 0x799c869, 0x3312990, 0x7b05222, + 0x28db802, 0xc986c2b, 0x28ade0a, 0xf48fb8f } + }, + { + { 0x1649b68, 0x1e46173, 0x5beb9dc, 0xa96e5d6, 0x481935d, 0x765ddff, + 0x9f3bf2a, 0x6cf132c, 0x7c35658, 0x9f6c5c9, 0x4696e60, 0x99cd139, + 0x9c0d5e4, 0x99fa924, 0x8845a95, 0x1acd063 }, + { 0x3636087, 0x0b06541, 0xea17b7f, 0xea20e78, 0x6161967, 0x20afc5f, + 0xdc81028, 0xfd6c8a2, 0xe32c8fd, 0x4ef1357, 0x00e4a88, 0x8aa4004, + 0x48cb82f, 0xd6fcaef, 0xb3cd4fa, 0x7ba7c6d } + }, + { + { 0xd19c7ab, 0xf843473, 0xc655c4d, 0x968e76d, 0xc4b9c2f, 0x52c87d9, + 0xe4aa082, 0x65f641a, 0x33c3603, 0x491a397, 0x5810098, 0xa606ffe, + 0x8bf8ad4, 0x09920e6, 0x6db7882, 0x691a0c8 }, + { 0xa4d3ef5, 0x5205883, 0xacf2efe, 0xee839b7, 0xc00ca66, 0x4b78e2a, + 0xf9fcb91, 0xbe3f071, 0xbf6943a, 0x61e66c9, 0x061b79d, 0xe9b4e57, + 0x56c06bd, 0x8d1b01b, 0xdf76ae5, 0x0dfa315 } + }, + { + { 0xf1fd093, 0x803df65, 0x489b77e, 0x1cd6523, 0xc20e295, 0x2cd2e15, + 0x9b912d1, 0xcd490be, 0x2e886d2, 0xdd9a2ff, 0xfe9d72a, 0xa3c836d, + 0x298e0c1, 0xfcad5f2, 0x4bcf067, 0xed126e2 }, + { 0x3dc81bc, 0x1e33953, 0xece6a08, 0xbea4d76, 0x991b252, 0x1d15de3, + 0xe6daf97, 0x74cc5cf, 0x0826493, 0x5ad343f, 0x1064049, 0x2d38a47, + 0xffcfa4d, 0xf7f47b9, 0x418066c, 0xef14490 } + }, + { + { 0x9bb55ab, 0x4e7f86b, 0x3f496a3, 0x310d785, 0x0dec42c, 0xbd682fc, + 0x411d32a, 0xbde047a, 0xc5a5ea2, 0xea639b4, 0xba08fa1, 0x5052078, + 0x07729f2, 0xc968b23, 0x23d3e28, 0x567b5a6 }, + { 0x977fbf7, 0x171e825, 0xbe990aa, 0x0319c70, 0xe12cd69, 0x8f65023, + 0xf5015e6, 0x1fb9b19, 0x3568a7c, 0x0083f60, 0x1f3c5ac, 0xba3d30b, + 0x3d7a988, 0xe7b509d, 0xcd0f6b6, 0x2318b99 } + }, + { + { 0x93ab2cf, 0x54d3b87, 0xd2d8306, 0x366abea, 0xd7a4977, 0x66e8eb6, + 0xae0072e, 0xa61888c, 0xdbc3315, 0x9eeeef5, 0x163e7f5, 0x93f09db, + 0x59ade9a, 0xee90959, 0xce59be0, 0xaf7f578 }, + { 0x5ece59e, 0x24bfd8d, 0x3689523, 0x8aa698b, 0x2de92cf, 0xa9a65de, + 0xa6ad300, 0xec11dbc, 0x09f88ca, 0x217f3fa, 0xb4d6af7, 0xf6c33e3, + 0x1d86d2d, 0xcd3bfa2, 0x5f13f25, 0x1497f83 } + }, + { + { 0xcd03d1d, 0xa579568, 0xe158af6, 0xd717cda, 0x389a19f, 0x59eda97, + 0x099e99c, 0xb32c370, 0xdabb591, 0xa2dba91, 0x77c2c97, 0x6d697d5, + 0xd43fa6d, 0x5423fc2, 0x0b382bf, 0x56ea8a5 }, + { 0xd80c11a, 0x4a987ba, 0x7d590a5, 0xe4cde21, 0xf97e559, 0x3dd8860, + 0x43b593c, 0xff45e25, 0x5343cb5, 0x00eb453, 0x7bbfbdd, 0x06b9b99, + 0x16aea24, 0x4da36b7, 0x57a624e, 0x2476517 } + }, + { + { 0x3474e0d, 0x32207d0, 0xb41cc73, 0x3ffbf04, 0x319eb39, 0x5c4dc45, + 0x758b463, 0xfee29be, 0xc30c7a7, 0xcc8a381, 0x9fe0e53, 0x147f4e4, + 0xe35a2de, 0x05b2e26, 0x92f3666, 0x4362f02 }, + { 0x8474b85, 0x0476d0c, 0xccaf108, 0x9d8c65f, 0x1d54b6a, 0xf58d404, + 0xf38e4b0, 0x3ee6862, 0x3b44f54, 0x7c7c9d5, 0x0fb0db5, 0x36a3fd8, + 0x18a8ac8, 0xfcd94ba, 0x8f35c05, 0xc1b1d56 } + }, + { + { 0x1bdd30d, 0x16539fc, 0x8df4afb, 0x1356e53, 0x5a1aedb, 0xc0545d8, + 0x489396b, 0xeb2037a, 0x5660894, 0x897fcbd, 0xb7d104a, 0x02a58a9, + 0xc96b980, 0x57fa24c, 0x5bd8946, 0xf6448e3 }, + { 0x8805c83, 0xee72741, 0x992cfc6, 0x10fa274, 0x9e66b21, 0x9514193, + 0xbd08009, 0xe0ffa44, 0x20da22b, 0x1743322, 0x59e6831, 0x4891ff3, + 0xa7d687b, 0x407ed73, 0x51d99cf, 0x2fb4e07 } + }, +}; +#endif + +/* Set the 0 point. + * + * p [in] Point to set to 0. + */ +static WC_INLINE void ge448_0(ge448_p2 *p) +{ + fe448_0(p->X); + fe448_1(p->Y); + fe448_1(p->Z); +} + +/* Set the precompute point to 0. + * + * p [in] Precompute point to set. + */ +static void ge448_precomp_0(ge448_precomp *p) +{ + fe448_0(p->x); + fe448_1(p->y); +} + +/* Double the point on the Twisted Edwards curve. r = 2.p + * + * r [in] Point to hold result. + * p [in] Point to double. + */ +static WC_INLINE void ge448_dbl(ge448_p2 *r,const ge448_p2 *p) +{ + ge448 t0[GE448_WORDS]; + ge448 t1[GE448_WORDS]; + + fe448_add(t0, p->X, p->Y); /* t0 = B1 = X1+Y1 */ + fe448_reduce(t0); + fe448_sqr(t0, t0); /* t0 = B = (X1+Y1)^2 */ + fe448_sqr(r->X, p->X); /* r->X = C = X1^2 */ + fe448_sqr(r->Y, p->Y); /* r->Y = D = Y1^2 */ + fe448_add(t1, r->X, r->Y); /* t1 = E = C+D */ + fe448_reduce(t1); + fe448_sub(r->Y, r->X, r->Y); /* r->Y = Y31 = C-D */ + fe448_sqr(r->Z, p->Z); /* r->Z = H = Z1^2 */ + fe448_add(r->Z, r->Z, r->Z); /* r->Z = J1 = 2*H */ + fe448_sub(r->Z, t1, r->Z); /* r->Z = J = E-2*H */ + fe448_reduce(r->Z); + fe448_sub(r->X, t0, t1); /* r->X = X31 = B-E */ + fe448_mul(r->X, r->X, r->Z); /* r->X = X3 = (B-E)*J */ + fe448_mul(r->Y, r->Y, t1); /* r->Y = Y3 = E*(C-D) */ + fe448_mul(r->Z, t1, r->Z); /* r->Z = Z3 = E*J */ +} + +/* Add two point on the Twisted Edwards curve. r = p + q + * Second point has z-ordinate of 1. + * + * r [in] Point to hold result. + * p [in] Point to add. + * q [in] Point to add. + */ +static WC_INLINE void ge448_madd(ge448_p2 *r, const ge448_p2 *p, + const ge448_precomp *q) +{ + ge448 t0[GE448_WORDS]; + ge448 t1[GE448_WORDS]; + ge448 t2[GE448_WORDS]; + ge448 t3[GE448_WORDS]; + ge448 t4[GE448_WORDS]; + + /* p->Z = A */ + fe448_mul(t1, p->X, q->x); /* t1 = C = X1*X2 */ + fe448_mul(t2, p->Y, q->y); /* t2 = D = Y1*Y2 */ + fe448_mul(t3, t1, t2); /* t3 = E1 = C*D */ + fe448_mul39081(t3, t3); /* t3 = E = d*C*D */ + fe448_sqr(t0, p->Z); /* t0 = B = A^2 */ + fe448_add(t4, t0, t3); /* t4 = F = B-(-E) */ + fe448_sub(t0, t0, t3); /* t0 = G = B+(-E) */ + fe448_reduce(t0); + fe448_add(r->X, p->X, p->Y); /* r->X = H1 = X1+Y1 */ + fe448_reduce(r->X); + fe448_add(r->Y, q->x, q->y); /* r->Y = H2 = X2+Y2 */ + fe448_reduce(r->Y); + fe448_mul(r->X, r->X, r->Y); /* r->X = H = (X1+Y1)*(X2+Y2) */ + fe448_sub(r->X, r->X, t1); /* r->X = X31 = H-C */ + fe448_sub(r->X, r->X, t2); /* r->X = X32 = H-C-D */ + fe448_reduce(r->X); + fe448_mul(r->X, r->X, t4); /* r->X = X33 = F*(H-C-D) */ + fe448_mul(r->X, r->X, p->Z); /* r->X = X3 = A*F*(H-C-D) */ + fe448_sub(r->Y, t2, t1); /* r->Y = Y31 = D-C */ + fe448_reduce(r->Y); + fe448_mul(r->Y, r->Y, t0); /* r->Y = Y32 = G*(D-C) */ + fe448_mul(r->Y, r->Y, p->Z); /* r->Y = Y3 = A*F*(D-C) */ + fe448_mul(r->Z, t4, t0); /* r->Z = Z3 = F*G */ +} + +/* Subtract one point from another on the Twisted Edwards curve. r = p - q + * Second point has z-ordinate of 1. + * + * r [in] Point to hold result. + * p [in] Point to subtract from. + * q [in] Point to subtract. + */ +static WC_INLINE void ge448_msub(ge448_p2 *r, const ge448_p2 *p, + const ge448_precomp *q) +{ + ge448 t0[GE448_WORDS]; + ge448 t1[GE448_WORDS]; + ge448 t2[GE448_WORDS]; + ge448 t3[GE448_WORDS]; + ge448 t4[GE448_WORDS]; + + /* p->Z = A */ + fe448_sqr(t0, p->Z); /* t0 = B = A^2 */ + fe448_mul(t1, p->X, q->x); /* t1 = C = X1*X2 */ + fe448_mul(t2, p->Y, q->y); /* t2 = D = Y1*Y2 */ + fe448_mul(t3, t1, t2); /* t3 = E1 = C*D */ + fe448_mul39081(t3, t3); /* t3 = E = d*C*D */ + fe448_sub(t4, t0, t3); /* t4 = F = B-(--E) */ + fe448_add(t0, t0, t3); /* t0 = G = B+(--E) */ + fe448_reduce(t0); + fe448_add(r->X, p->X, p->Y); /* r->X = H1 = X1+Y1 */ + fe448_reduce(r->X); + fe448_sub(r->Y, q->y, q->x); /* r->Y = H2 = Y2+(-X2) */ + fe448_reduce(r->Y); + fe448_mul(r->X, r->X, r->Y); /* r->X = H = (X1+Y1)*(X2+Y2) */ + fe448_add(r->X, r->X, t1); /* r->X = X31 = H-(-C) */ + fe448_sub(r->X, r->X, t2); /* r->X = X32 = H-(-C)-D */ + fe448_reduce(r->X); + fe448_mul(r->X, r->X, t4); /* r->X = X33 = F*(H-C-D) */ + fe448_mul(r->X, r->X, p->Z); /* r->X = X3 = A*F*(H-C-D) */ + fe448_add(r->Y, t2, t1); /* r->Y = Y31 = D-C */ + fe448_reduce(r->Y); + fe448_mul(r->Y, r->Y, t0); /* r->Y = Y32 = G*(D-C) */ + fe448_mul(r->Y, r->Y, p->Z); /* r->Y = Y3 = A*F*(D-C) */ + fe448_mul(r->Z, t4, t0); /* r->Z = Z3 = F*G */ +} + +/* Add two point on the Twisted Edwards curve. r = p + q + * + * r [in] Point to hold result. + * p [in] Point to add. + * q [in] Point to add. + */ +static WC_INLINE void ge448_add(ge448_p2* r, const ge448_p2* p, + const ge448_p2* q) +{ + ge448 t0[GE448_WORDS]; + ge448 t1[GE448_WORDS]; + ge448 t2[GE448_WORDS]; + ge448 t3[GE448_WORDS]; + ge448 t4[GE448_WORDS]; + + fe448_mul(t1, p->X, q->X); /* t1 = C = X1*X2 */ + fe448_mul(t2, p->Y, q->Y); /* t2 = D = Y1*Y2 */ + fe448_mul(t3, t1, t2); /* t3 = E1 = C*D */ + fe448_mul39081(t3, t3); /* t3 = E = d*C*D */ + fe448_mul(r->Z, p->Z, q->Z); /* r->Z = A = Z1*Z2 */ + fe448_sqr(t0, r->Z); /* t0 = B = A^2 */ + fe448_add(t4, t0, t3); /* t4 = F = B-(-E) */ + fe448_sub(t0, t0, t3); /* t0 = G = B+(-E) */ + fe448_reduce(t0); + fe448_add(r->X, p->X, p->Y); /* r->X = H1 = X1+Y1 */ + fe448_reduce(r->X); + fe448_add(r->Y, q->X, q->Y); /* r->Y = H2 = X2+Y2 */ + fe448_reduce(r->Y); + fe448_mul(r->X, r->X, r->Y); /* r->X = H = (X1+Y1)*(X2+Y2) */ + fe448_sub(r->X, r->X, t1); /* r->X = X31 = H-C */ + fe448_sub(r->X, r->X, t2); /* r->X = X32 = H-C-D */ + fe448_reduce(r->X); + fe448_mul(r->X, r->X, t4); /* r->X = X33 = F*(H-C-D) */ + fe448_mul(r->X, r->X, r->Z); /* r->X = X3 = A*F*(H-C-D) */ + fe448_sub(r->Y, t2, t1); /* r->Y = Y31 = D-C */ + fe448_reduce(r->Y); + fe448_mul(r->Y, r->Y, t0); /* r->Y = Y32 = G*(D-C) */ + fe448_mul(r->Y, r->Y, r->Z); /* r->Y = Y3 = A*F*(D-C) */ + fe448_mul(r->Z, t4, t0); /* r->Z = Z3 = F*G */ +} + +/* Subtract one point from another on the Twisted Edwards curve. r = p - q + * + * r [in] Point to hold result. + * p [in] Point to subtract from. + * q [in] Point to subtract. + */ +static WC_INLINE void ge448_sub(ge448_p2 *r, const ge448_p2 *p, + const ge448_p2 *q) +{ + ge448 t0[GE448_WORDS]; + ge448 t1[GE448_WORDS]; + ge448 t2[GE448_WORDS]; + ge448 t3[GE448_WORDS]; + ge448 t4[GE448_WORDS]; + + fe448_mul(t1, p->X, q->X); /* t1 = C = X1*X2 */ + fe448_mul(t2, p->Y, q->Y); /* t2 = D = Y1*Y2 */ + fe448_mul(t3, t1, t2); /* t3 = E1 = C*D */ + fe448_mul39081(t3, t3); /* t3 = E = d*C*D */ + fe448_mul(r->Z, p->Z, q->Z); /* r->Z = A = Z1*Z2 */ + fe448_sqr(t0, p->Z); /* t0 = B = A^2 */ + fe448_sub(t4, t0, t3); /* t4 = F = B-(--E) */ + fe448_add(t0, t0, t3); /* t0 = G = B+(--E) */ + fe448_reduce(t0); + fe448_add(r->X, p->X, p->Y); /* r->X = H1 = X1+Y1 */ + fe448_reduce(r->X); + fe448_sub(r->Y, q->Y, q->X); /* r->Y = H2 = Y2+(-X2) */ + fe448_reduce(r->Y); + fe448_mul(r->X, r->X, r->Y); /* r->X = H = (X1+Y1)*(X2+Y2) */ + fe448_add(r->X, r->X, t1); /* r->X = X31 = H-(-C) */ + fe448_sub(r->X, r->X, t2); /* r->X = X32 = H-(-C)-D */ + fe448_reduce(r->X); + fe448_mul(r->X, r->X, t4); /* r->X = X33 = F*(H-C-D) */ + fe448_mul(r->X, r->X, r->Z); /* r->X = X3 = A*F*(H-C-D) */ + fe448_add(r->Y, t2, t1); /* r->Y = Y31 = D-C */ + fe448_reduce(r->Y); + fe448_mul(r->Y, r->Y, t0); /* r->Y = Y32 = G*(D-C) */ + fe448_mul(r->Y, r->Y, r->Z); /* r->Y = Y3 = A*F*(D-C) */ + fe448_mul(r->Z, t4, t0); /* r->Z = Z3 = F*G */ +} + +/* Convert point to byte array assuming projective ordinates. + * + * b [in] Array of bytes to hold compressed point. + * p [in] Point to convert. + */ +void ge448_to_bytes(uint8_t *b, const ge448_p2 *p) +{ + ge448 recip[GE448_WORDS]; + ge448 x[GE448_WORDS]; + ge448 y[GE448_WORDS]; + + fe448_invert(recip, p->Z); + fe448_mul(x, p->X, recip); + fe448_mul(y, p->Y, recip); + fe448_to_bytes(b, y); + b[56] = fe448_isnegative(x) << 7; +} + +/* Convert point to byte array assuming z is 1. + * + * b [in] Array of bytes to hold compressed point. + * p [in] Point to convert. + */ +static void ge448_p2z1_to_bytes(uint8_t *b, const ge448_p2 *p) +{ + fe448_to_bytes(b, p->Y); + b[56] = fe448_isnegative(p->X) << 7; +} + +/* Compress the point to y-ordinate and negative bit. + * + * out [in] Array of bytes to hold compressed key. + * xIn [in] The x-ordinate. + * yIn [in] The y-ordinate. + */ +int ge448_compress_key(uint8_t* out, const uint8_t* xIn, const uint8_t* yIn) +{ + ge448_p2 g; + uint8_t bArray[ED448_KEY_SIZE]; + uint32_t i; + + fe448_from_bytes(g.X, xIn); + fe448_from_bytes(g.Y, yIn); + fe448_1(g.Z); + + ge448_p2z1_to_bytes(bArray, &g); + + for (i = 0; i < 57; i++) { + out[57 - 1 - i] = bArray[i]; + } + + return 0; +} + +/* Determine whether the value is negative. + * + * b [in] An 8-bit signed value. + * returns 1 when negative and 0 otherwise. + */ +static uint8_t negative(int8_t b) +{ + return ((uint8_t)b) >> 7; +} + +/* Determine whether two values are equal. a == b + * Constant time implementation. + * + * a [in] An 8-bit unsigned value. + * b [in] An 8-bit unsigned value. + * returns 1 when equal and 0 otherwise. + */ +static uint8_t equal(uint8_t a, uint8_t b) +{ + return (uint8_t)(((uint32_t)(a ^ b) - 1) >> 31); +} + +/* Conditional move the point into result point if two values are equal. + * Constant time implementation. + * + * f [in] Point to conditionally overwrite. + * p [in] Point to conditionally copy. + * b [in] An 8-bit unsigned value. + * n [in] An 8-bit unsigned value. + */ +static WC_INLINE void cmov(ge448_precomp* r, const ge448_precomp* p, uint8_t b, + uint8_t n) +{ + b = equal(b, n); + fe448_cmov(r->x, p->x, b); + fe448_cmov(r->y, p->y, b); +} + +/* Select one of the entries from the precomputed table and negate if required. + * Constant time implementation. + * + * r [in] Point to hold chosen point. + * pos [in] Position of array of entries to choose from. + * b [in] Index of point to select. -ve value means negate the point. + */ +static void ge448_select(ge448_precomp* r, int pos, int8_t b) +{ + ge448 minusx[16]; + uint8_t bnegative = negative(b); + uint8_t babs = b - (((-bnegative) & b) << 1); + + ge448_precomp_0(r); + cmov(r, &base[pos][0], babs, 1); + cmov(r, &base[pos][1], babs, 2); + cmov(r, &base[pos][2], babs, 3); + cmov(r, &base[pos][3], babs, 4); + cmov(r, &base[pos][4], babs, 5); + cmov(r, &base[pos][5], babs, 6); + cmov(r, &base[pos][6], babs, 7); + cmov(r, &base[pos][7], babs, 8); + fe448_neg(minusx, r->x); + fe448_cmov(r->x, minusx, bnegative); +} + +/* Perform a scalar multiplication of the base point. r = a * base + * + * r [in] Point to hold result. + * a [in] Scalar to multiply by. + */ +void ge448_scalarmult_base(ge448_p2* r, const uint8_t* a) +{ + int8_t carry; + ge448_precomp t; + int i; + int8_t e[113]; + + carry = 0; + for (i = 0; i < 56; ++i) { + e[2 * i + 0] = ((a[i] >> 0) & 0xf) + carry; + carry = e[2 * i + 0] + 8; + carry >>= 4; + e[2 * i + 0] -= carry << 4; + + e[2 * i + 1] = ((a[i] >> 4) & 0xf) + carry; + carry = e[2 * i + 1] + 8; + carry >>= 4; + e[2 * i + 1] -= carry << 4; + } + e[112] = carry; + /* each e[i] is between -8 and 8 */ + + /* Odd indeces first - sum based on even index so multiply by 16 */ + ge448_select(&t, 0, e[1]); + fe448_copy(r->X, t.x); + fe448_copy(r->Y, t.y); + fe448_1(r->Z); + for (i = 3; i < 112; i += 2) { + ge448_select(&t, i / 2, e[i]); + ge448_madd(r, r, &t); + } + + ge448_dbl(r, r); + ge448_dbl(r, r); + ge448_dbl(r, r); + ge448_dbl(r, r); + + /* Add even indeces */ + for (i = 0; i <= 112; i += 2) { + ge448_select(&t, i / 2, e[i]); + ge448_madd(r, r, &t); + } +} + +/* Create to a sliding window for the scalar multiplicaton. + * + * r [in] Array of indeces. + * a [in] Scalar to break up. + */ +static void slide(int8_t *r, const uint8_t *a) +{ + int i; + int b; + int k; + + for (i = 0; i < 448; ++i) { + r[i] = (a[i >> 3] >> (i & 7)) & 1; + } + + for (i = 0; i < 448; ++i) { + if (r[i] == 0) { + continue; + } + + for (b = 1; b <= 7 && i + b < 448; ++b) { + if (r[i + b] == 0) { + continue; + } + + if (r[i] + (r[i + b] << b) <= 31) { + r[i] += r[i + b] << b; r[i + b] = 0; + } + else if (r[i] - (r[i + b] << b) >= -31) { + r[i] -= r[i + b] << b; + for (k = i + b; k < 448; ++k) { + if (!r[k]) { + r[k] = 1; + break; + } + r[k] = 0; + } + } + else { + break; + } + } + } +} + +/* Perform a scalar multplication of the base point and public point. + * r = a * p + b * base + * Uses a sliding window of 5 bits. + * Not constant time. + * + * r [in] Point to hold result. + * a [in] Scalar to multiply by. + */ +int ge448_double_scalarmult_vartime(ge448_p2 *r, const uint8_t *a, + const ge448_p2 *p, const uint8_t *b) +{ + int8_t aslide[448]; + int8_t bslide[448]; + ge448_p2 pi[16]; /* p,3p,..,31p */ + ge448_p2 p2; + int i; + + slide(aslide, a); + slide(bslide, b); + + fe448_copy(pi[0].X, p->X); + fe448_copy(pi[0].Y, p->Y); + fe448_copy(pi[0].Z, p->Z); + ge448_dbl(&p2, p); + ge448_add(&pi[1], &p2, &pi[0]); + ge448_add(&pi[2], &p2, &pi[1]); + ge448_add(&pi[3], &p2, &pi[2]); + ge448_add(&pi[4], &p2, &pi[3]); + ge448_add(&pi[5], &p2, &pi[4]); + ge448_add(&pi[6], &p2, &pi[5]); + ge448_add(&pi[7], &p2, &pi[6]); + ge448_add(&pi[8], &p2, &pi[7]); + ge448_add(&pi[9], &p2, &pi[8]); + ge448_add(&pi[10], &p2, &pi[9]); + ge448_add(&pi[11], &p2, &pi[10]); + ge448_add(&pi[12], &p2, &pi[11]); + ge448_add(&pi[13], &p2, &pi[12]); + ge448_add(&pi[14], &p2, &pi[13]); + ge448_add(&pi[15], &p2, &pi[14]); + + ge448_0(r); + + /* Find first index that is not 0. */ + for (i = 447; i >= 0; --i) { + if (aslide[i] || bslide[i]) { + break; + } + } + + for (; i >= 0; --i) { + ge448_dbl(r, r); + + if (aslide[i] > 0) + ge448_add(r, r, &pi[aslide[i]/2]); + else if (aslide[i] < 0) + ge448_sub(r, r ,&pi[(-aslide[i])/2]); + + if (bslide[i] > 0) + ge448_madd(r, r, &base_i[bslide[i]/2]); + else if (bslide[i] < 0) + ge448_msub(r, r, &base_i[(-bslide[i])/2]); + } + + return 0; +} + +/* Convert compressed point to negative of affine point. + * Calculates x from the y and the negative bit. + * Not constant time. + * + * r [in] Uncompressed point. + * b [in] Array of bytes representing point. + * returns 0 on success and -1 on failure. + */ +int ge448_from_bytes_negate_vartime(ge448_p2 *r, const uint8_t *b) +{ + int ret = 0; + ge448 u[GE448_WORDS]; + ge448 v[GE448_WORDS]; + ge448 u3[GE448_WORDS]; + ge448 vxx[GE448_WORDS]; + ge448 check[GE448_WORDS]; + + fe448_from_bytes(r->Y, b); + fe448_1(r->Z); + fe448_sqr(u, r->Y); /* u = y^2 */ + fe448_mul39081(v, u); /* v = 39081.y^2 */ + fe448_sub(u, u, r->Z); /* u = y^2-1 */ + fe448_reduce(u); + fe448_add(v, v, r->Z); /* v = 39081.y^2-1 */ + fe448_reduce(v); + fe448_neg(v, v); /* v = -39081.y^2-1 = d.y^2-1 */ + + fe448_sqr(r->X, v); /* x = v^2 */ + fe448_mul(r->X, r->X, v); /* x = v^3 */ + fe448_sqr(u3, u); /* x = u^2.v^3 */ + fe448_mul(r->X, r->X, u3); /* x = u^2.v^3 */ + fe448_mul(u3, u3, u); /* u3 = u^3 */ + fe448_mul(r->X, r->X, u3); /* x = u^5.v^3 */ + + fe448_pow_2_446_222_1(r->X, r->X); /* x = (u^5.v^3)^((q-3)/4) */ + fe448_mul(r->X, r->X, u3); /* x = u^3(u^5.v^3)^((q-3)/4) */ + fe448_mul(r->X, r->X, v); /* x = u^3.v(u^5.v^3)^((q-3)/4) */ + + fe448_sqr(vxx, r->X); + fe448_mul(vxx, vxx, v); + fe448_sub(check, vxx, u); /* check = v.x^2-u */ + fe448_reduce(check); + /* Note; vx^2+u is NOT correct. */ + if (fe448_isnonzero(check)) { + ret = -1; + } + + /* Calculating negative of point in bytes - negate only if X is correct. */ + if (fe448_isnegative(r->X) == (b[56] >> 7)) { + fe448_neg(r->X, r->X); + } + + return ret; +} + +#endif /* ED448_SMALL */ +#endif /* HAVE_CURVE448 || HAVE_ED448 */ diff --git a/wolfcrypt/src/hash.c b/wolfcrypt/src/hash.c index 0dc0ba2c5..c53f5e67a 100644 --- a/wolfcrypt/src/hash.c +++ b/wolfcrypt/src/hash.c @@ -1362,6 +1362,45 @@ int wc_HashGetFlags(wc_HashAlg* hash, enum wc_HashType type, word32* flags) return ret; } #endif /* !WOLFSSL_NOSHA3_512 */ + +#if defined(WOLFSSL_SHAKE256) && !defined(WOLFSSL_NO_SHAKE256) + int wc_Shake256Hash(const byte* data, word32 len, byte* hash, + word32 hashLen) + { + int ret = 0; + #ifdef WOLFSSL_SMALL_STACK + wc_Shake* shake; + #else + wc_Shake shake[1]; + #endif + + #ifdef WOLFSSL_SMALL_STACK + shake = (wc_Shake*)XMALLOC(sizeof(wc_Shake), NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (shake == NULL) + return MEMORY_E; + #endif + + if ((ret = wc_InitShake256(shake, NULL, INVALID_DEVID)) != 0) { + WOLFSSL_MSG("InitShake256 failed"); + } + else { + if ((ret = wc_Shake256_Update(shake, data, len)) != 0) { + WOLFSSL_MSG("Shake256_Update failed"); + } + else if ((ret = wc_Shake256_Final(shake, hash, hashLen)) != 0) { + WOLFSSL_MSG("Shake256_Final failed"); + } + wc_Shake256_Free(shake); + } + + #ifdef WOLFSSL_SMALL_STACK + XFREE(shake, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + + return ret; + } +#endif /* WOLFSSL_SHAKE_256 && !WOLFSSL_NO_SHAKE256 */ #endif /* WOLFSSL_SHA3 */ #endif /* !NO_HASH_WRAPPER */ diff --git a/wolfcrypt/src/sha3.c b/wolfcrypt/src/sha3.c index 4e6ec6e41..66e7c3150 100644 --- a/wolfcrypt/src/sha3.c +++ b/wolfcrypt/src/sha3.c @@ -636,11 +636,10 @@ static int Sha3Update(wc_Sha3* sha3, const byte* data, word32 len, byte p) * len Number of bytes in output. * returns 0 on success. */ -static int Sha3Final(wc_Sha3* sha3, byte* hash, byte p, byte l) +static int Sha3Final(wc_Sha3* sha3, byte padChar, byte* hash, byte p, byte l) { byte i; byte *s8 = (byte *)sha3->s; - byte padChar = 0x06; /* NIST SHA-3 */ sha3->t[p * 8 - 1] = 0x00; #ifdef WOLFSSL_HASH_FLAGS @@ -759,7 +758,7 @@ static int wc_Sha3Final(wc_Sha3* sha3, byte* hash, byte p, byte len) } #endif /* WOLFSSL_ASYNC_CRYPT */ - ret = Sha3Final(sha3, hash, p, len); + ret = Sha3Final(sha3, 0x06, hash, p, len); if (ret != 0) return ret; @@ -1140,4 +1139,74 @@ int wc_Sha3_GetFlags(wc_Sha3* sha3, word32* flags) } #endif +#if defined(WOLFSSL_SHAKE256) +/* Initialize the state for a Shake256 hash operation. + * + * shake wc_Shake object holding state. + * heap Heap reference for dynamic memory allocation. (Used in async ops.) + * devId Device identifier for asynchronous operation. + * returns 0 on success. + */ +int wc_InitShake256(wc_Shake* shake, void* heap, int devId) +{ + return wc_InitSha3(shake, heap, devId); +} + +/* Update the SHAKE256 hash state with message data. + * + * shake wc_Shake object holding state. + * data Message data to be hashed. + * len Length of the message data. + * returns 0 on success. + */ +int wc_Shake256_Update(wc_Shake* shake, const byte* data, word32 len) +{ + return wc_Sha3Update(shake, data, len, WC_SHA3_256_COUNT); +} + +/* Calculate the SHAKE256 hash based on all the message data seen. + * The state is initialized ready for a new message to hash. + * + * shake wc_Shake object holding state. + * hash Buffer to hold the hash result. Must be at least 64 bytes. + * returns 0 on success. + */ +int wc_Shake256_Final(wc_Shake* shake, byte* hash, word32 hashLen) +{ + int ret; + + if (shake == NULL || hash == NULL) { + return BAD_FUNC_ARG; + } + + ret = Sha3Final(shake, 0x1f, hash, WC_SHA3_256_COUNT, hashLen); + if (ret != 0) + return ret; + + return InitSha3(shake); /* reset state */ +} + +/* Dispose of any dynamically allocated data from the SHAKE256 operation. + * (Required for async ops.) + * + * shake wc_Shake object holding state. + * returns 0 on success. + */ +void wc_Shake256_Free(wc_Shake* shake) +{ + wc_Sha3Free(shake); +} + +/* Copy the state of the SHA3-512 operation. + * + * src wc_Shake object holding state top copy. + * dst wc_Shake object to copy into. + * returns 0 on success. + */ +int wc_Shake256_Copy(wc_Shake* src, wc_Shake* dst) +{ + return wc_Sha3Copy(src, dst); +} +#endif + #endif /* WOLFSSL_SHA3 */ diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index 7a58d14af..9371b8d45 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -167,6 +167,12 @@ #ifdef HAVE_ED25519 #include #endif +#ifdef HAVE_CURVE448 + #include +#endif +#ifdef HAVE_ED448 + #include +#endif #if defined(HAVE_BLAKE2) || defined(HAVE_BLAKE2S) #include #endif @@ -282,6 +288,7 @@ int sha256_test(void); int sha512_test(void); int sha384_test(void); int sha3_test(void); +int shake256_test(void); int hash_test(void); int hmac_md5_test(void); int hmac_sha_test(void); @@ -350,6 +357,12 @@ int scrypt_test(void); #ifdef HAVE_ED25519 int ed25519_test(void); #endif +#ifdef HAVE_CURVE448 + int curve448_test(void); +#endif +#ifdef HAVE_ED448 + int ed448_test(void); +#endif #ifdef HAVE_BLAKE2 int blake2b_test(void); #endif @@ -691,6 +704,13 @@ initDefaultName(); test_pass("SHA-3 test passed!\n"); #endif +#ifdef WOLFSSL_SHAKE256 + if ( (ret = shake256_test()) != 0) + return err_sys("SHAKE256 test failed!\n", ret); + else + test_pass("SHAKE256 test passed!\n"); +#endif + if ( (ret = hash_test()) != 0) return err_sys("Hash test failed!\n", ret); else @@ -1043,6 +1063,20 @@ initDefaultName(); test_pass("ED25519 test passed!\n"); #endif +#ifdef HAVE_CURVE448 + if ( (ret = curve448_test()) != 0) + return err_sys("CURVE448 test failed!\n", ret); + else + test_pass("CURVE448 test passed!\n"); +#endif + +#ifdef HAVE_ED448 + if ( (ret = ed448_test()) != 0) + return err_sys("ED448 test failed!\n", ret); + else + test_pass("ED448 test passed!\n"); +#endif + #if defined(WOLFSSL_CMAC) && !defined(NO_AES) if ( (ret = cmac_test()) != 0) return err_sys("CMAC test failed!\n", ret); @@ -1216,8 +1250,8 @@ initDefaultName(); #ifdef HAVE_WNR if (wc_InitNetRandom(wnrConfigFile, NULL, 5000) != 0) { - err_sys("Whitewood netRandom global config failed", -1002); - return -1001; + err_sys("Whitewood netRandom global config failed", -1001); + return -1002; } #endif #ifndef WOLFSSL_ESPIDF @@ -1352,14 +1386,14 @@ int error_test(void) if (XSTRNCMP(errStr, out, XSTRLEN(errStr)) != 0) return -1104; if (XSTRLEN(errStr) >= WOLFSSL_MAX_ERROR_SZ) - return -1109; + return -1105; } else { j++; if (XSTRNCMP(errStr, unknownStr, XSTRLEN(unknownStr)) != 0) - return -1105; - if (XSTRNCMP(out, unknownStr, XSTRLEN(unknownStr)) != 0) return -1106; + if (XSTRNCMP(out, unknownStr, XSTRLEN(unknownStr)) != 0) + return -1107; } } @@ -1367,9 +1401,9 @@ int error_test(void) errStr = wc_GetErrorString(i); wc_ErrorString(i, out); if (XSTRNCMP(errStr, unknownStr, XSTRLEN(unknownStr)) != 0) - return -1107; - if (XSTRNCMP(out, unknownStr, XSTRLEN(unknownStr)) != 0) return -1108; + if (XSTRNCMP(out, unknownStr, XSTRLEN(unknownStr)) != 0) + return -1109; #endif return 0; @@ -2150,18 +2184,18 @@ int blake2s_test(void) for (i = 0; i < BLAKE2S_TESTS; i++) { ret = wc_InitBlake2s(&b2s, 32); if (ret != 0) - return -2000 - i; + return -2100 - i; ret = wc_Blake2sUpdate(&b2s, input, i); if (ret != 0) - return -2010 - 1; + return -2110 - 1; ret = wc_Blake2sFinal(&b2s, digest, 32); if (ret != 0) - return -2020 - i; + return -2120 - i; if (XMEMCMP(digest, blake2s_vec[i], 32) != 0) { - return -2030 - i; + return -2130 - i; } } @@ -2206,33 +2240,33 @@ int sha224_test(void) ret = wc_InitSha224_ex(&sha, HEAP_HINT, devId); if (ret != 0) - return -2100; + return -2200; ret = wc_InitSha224_ex(&shaCopy, HEAP_HINT, devId); if (ret != 0) { wc_Sha224Free(&sha); - return -2101; + return -2201; } for (i = 0; i < times; ++i) { ret = wc_Sha224Update(&sha, (byte*)test_sha[i].input, (word32)test_sha[i].inLen); if (ret != 0) - ERROR_OUT(-2102 - i, exit); + ERROR_OUT(-2202 - i, exit); ret = wc_Sha224GetHash(&sha, hashcopy); if (ret != 0) - ERROR_OUT(-2103 - i, exit); + ERROR_OUT(-2203 - i, exit); ret = wc_Sha224Copy(&sha, &shaCopy); if (ret != 0) - ERROR_OUT(-2104 - i, exit); + ERROR_OUT(-2204 - i, exit); ret = wc_Sha224Final(&sha, hash); if (ret != 0) - ERROR_OUT(-2105 - i, exit); + ERROR_OUT(-2205 - i, exit); wc_Sha224Free(&shaCopy); if (XMEMCMP(hash, test_sha[i].output, WC_SHA224_DIGEST_SIZE) != 0) - ERROR_OUT(-2106 - i, exit); + ERROR_OUT(-2206 - i, exit); if (XMEMCMP(hash, hashcopy, WC_SHA224_DIGEST_SIZE) != 0) - ERROR_OUT(-2107 - i, exit); + ERROR_OUT(-2207 - i, exit); } exit: @@ -2283,34 +2317,34 @@ int sha256_test(void) ret = wc_InitSha256_ex(&sha, HEAP_HINT, devId); if (ret != 0) - return -2200; + return -2300; ret = wc_InitSha256_ex(&shaCopy, HEAP_HINT, devId); if (ret != 0) { wc_Sha256Free(&sha); - return -2201; + return -2301; } for (i = 0; i < times; ++i) { ret = wc_Sha256Update(&sha, (byte*)test_sha[i].input, (word32)test_sha[i].inLen); if (ret != 0) { - ERROR_OUT(-2202 - i, exit); + ERROR_OUT(-2302 - i, exit); } ret = wc_Sha256GetHash(&sha, hashcopy); if (ret != 0) - ERROR_OUT(-2203 - i, exit); + ERROR_OUT(-2303 - i, exit); ret = wc_Sha256Copy(&sha, &shaCopy); if (ret != 0) - ERROR_OUT(-2204 - i, exit); + ERROR_OUT(-2304 - i, exit); ret = wc_Sha256Final(&sha, hash); if (ret != 0) - ERROR_OUT(-2205 - i, exit); + ERROR_OUT(-2305 - i, exit); wc_Sha256Free(&shaCopy); if (XMEMCMP(hash, test_sha[i].output, WC_SHA256_DIGEST_SIZE) != 0) - ERROR_OUT(-2206 - i, exit); + ERROR_OUT(-2306 - i, exit); if (XMEMCMP(hash, hashcopy, WC_SHA256_DIGEST_SIZE) != 0) - ERROR_OUT(-2207 - i, exit); + ERROR_OUT(-2307 - i, exit); } /* BEGIN LARGE HASH TEST */ { @@ -2339,13 +2373,13 @@ int sha256_test(void) ret = wc_Sha256Update(&sha, (byte*)large_input, (word32)sizeof(large_input)); if (ret != 0) - ERROR_OUT(-2208, exit); + ERROR_OUT(-2308, exit); } ret = wc_Sha256Final(&sha, hash); if (ret != 0) - ERROR_OUT(-2209, exit); + ERROR_OUT(-2309, exit); if (XMEMCMP(hash, large_digest, WC_SHA256_DIGEST_SIZE) != 0) - ERROR_OUT(-2210, exit); + ERROR_OUT(-2310, exit); } /* END LARGE HASH TEST */ exit: @@ -2404,33 +2438,33 @@ int sha512_test(void) ret = wc_InitSha512_ex(&sha, HEAP_HINT, devId); if (ret != 0) - return -2300; + return -2400; ret = wc_InitSha512_ex(&shaCopy, HEAP_HINT, devId); if (ret != 0) { wc_Sha512Free(&sha); - return -2301; + return -2401; } for (i = 0; i < times; ++i) { ret = wc_Sha512Update(&sha, (byte*)test_sha[i].input, (word32)test_sha[i].inLen); if (ret != 0) - ERROR_OUT(-2302 - i, exit); + ERROR_OUT(-2402 - i, exit); ret = wc_Sha512GetHash(&sha, hashcopy); if (ret != 0) - ERROR_OUT(-2303 - i, exit); + ERROR_OUT(-2403 - i, exit); ret = wc_Sha512Copy(&sha, &shaCopy); if (ret != 0) - ERROR_OUT(-2304 - i, exit); + ERROR_OUT(-2404 - i, exit); ret = wc_Sha512Final(&sha, hash); if (ret != 0) - ERROR_OUT(-2305 - i, exit); + ERROR_OUT(-2405 - i, exit); wc_Sha512Free(&shaCopy); if (XMEMCMP(hash, test_sha[i].output, WC_SHA512_DIGEST_SIZE) != 0) - ERROR_OUT(-2306 - i, exit); + ERROR_OUT(-2406 - i, exit); if (XMEMCMP(hash, hashcopy, WC_SHA512_DIGEST_SIZE) != 0) - ERROR_OUT(-2307 - i, exit); + ERROR_OUT(-2407 - i, exit); } /* BEGIN LARGE HASH TEST */ { @@ -2449,13 +2483,13 @@ int sha512_test(void) ret = wc_Sha512Update(&sha, (byte*)large_input, (word32)sizeof(large_input)); if (ret != 0) - ERROR_OUT(-2308, exit); + ERROR_OUT(-2408, exit); } ret = wc_Sha512Final(&sha, hash); if (ret != 0) - ERROR_OUT(-2309, exit); + ERROR_OUT(-2409, exit); if (XMEMCMP(hash, large_digest, WC_SHA512_DIGEST_SIZE) != 0) - ERROR_OUT(-2310, exit); + ERROR_OUT(-2410, exit); } /* END LARGE HASH TEST */ exit: @@ -2511,33 +2545,33 @@ int sha384_test(void) ret = wc_InitSha384_ex(&sha, HEAP_HINT, devId); if (ret != 0) - return -2400; + return -2500; ret = wc_InitSha384_ex(&shaCopy, HEAP_HINT, devId); if (ret != 0) { wc_Sha384Free(&sha); - return -2401; + return -2501; } for (i = 0; i < times; ++i) { ret = wc_Sha384Update(&sha, (byte*)test_sha[i].input, (word32)test_sha[i].inLen); if (ret != 0) - ERROR_OUT(-2402 - i, exit); + ERROR_OUT(-2502 - i, exit); ret = wc_Sha384GetHash(&sha, hashcopy); if (ret != 0) - ERROR_OUT(-2403 - i, exit); + ERROR_OUT(-2503 - i, exit); ret = wc_Sha384Copy(&sha, &shaCopy); if (ret != 0) - ERROR_OUT(-2404 - i, exit); + ERROR_OUT(-2504 - i, exit); ret = wc_Sha384Final(&sha, hash); if (ret != 0) - ERROR_OUT(-2405 - i, exit); + ERROR_OUT(-2505 - i, exit); wc_Sha384Free(&shaCopy); if (XMEMCMP(hash, test_sha[i].output, WC_SHA384_DIGEST_SIZE) != 0) - ERROR_OUT(-2406 - i, exit); + ERROR_OUT(-2506 - i, exit); if (XMEMCMP(hash, hashcopy, WC_SHA384_DIGEST_SIZE) != 0) - ERROR_OUT(-2407 - i, exit); + ERROR_OUT(-2507 - i, exit); } /* BEGIN LARGE HASH TEST */ { @@ -2555,13 +2589,13 @@ int sha384_test(void) ret = wc_Sha384Update(&sha, (byte*)large_input, (word32)sizeof(large_input)); if (ret != 0) - ERROR_OUT(-2408, exit); + ERROR_OUT(-2508, exit); } ret = wc_Sha384Final(&sha, hash); if (ret != 0) - ERROR_OUT(-2409, exit); + ERROR_OUT(-2509, exit); if (XMEMCMP(hash, large_digest, WC_SHA384_DIGEST_SIZE) != 0) - ERROR_OUT(-2410, exit); + ERROR_OUT(-2510, exit); } /* END LARGE HASH TEST */ exit: @@ -2610,24 +2644,24 @@ static int sha3_224_test(void) ret = wc_InitSha3_224(&sha, HEAP_HINT, devId); if (ret != 0) - return -2500; + return -2600; for (i = 0; i < times; ++i) { ret = wc_Sha3_224_Update(&sha, (byte*)test_sha[i].input, (word32)test_sha[i].inLen); if (ret != 0) - ERROR_OUT(-2501 - i, exit); + ERROR_OUT(-2601 - i, exit); ret = wc_Sha3_224_GetHash(&sha, hashcopy); if (ret != 0) - ERROR_OUT(-2502 - i, exit); + ERROR_OUT(-2602 - i, exit); ret = wc_Sha3_224_Final(&sha, hash); if (ret != 0) - ERROR_OUT(-2503 - i, exit); + ERROR_OUT(-2603 - i, exit); if (XMEMCMP(hash, test_sha[i].output, WC_SHA3_224_DIGEST_SIZE) != 0) - ERROR_OUT(-2504 - i, exit); + ERROR_OUT(-2604 - i, exit); if (XMEMCMP(hash, hashcopy, WC_SHA3_224_DIGEST_SIZE) != 0) - ERROR_OUT(-2505 - i, exit); + ERROR_OUT(-2605 - i, exit); } /* BEGIN LARGE HASH TEST */ { @@ -2644,13 +2678,13 @@ static int sha3_224_test(void) ret = wc_Sha3_224_Update(&sha, (byte*)large_input, (word32)sizeof(large_input)); if (ret != 0) - ERROR_OUT(-2506, exit); + ERROR_OUT(-2606, exit); } ret = wc_Sha3_224_Final(&sha, hash); if (ret != 0) - ERROR_OUT(-2507, exit); + ERROR_OUT(-2607, exit); if (XMEMCMP(hash, large_digest, WC_SHA3_224_DIGEST_SIZE) != 0) - ERROR_OUT(-2508, exit); + ERROR_OUT(-2608, exit); } /* END LARGE HASH TEST */ exit: @@ -2711,24 +2745,24 @@ static int sha3_256_test(void) ret = wc_InitSha3_256(&sha, HEAP_HINT, devId); if (ret != 0) - return -2600; + return -2700; for (i = 0; i < times; ++i) { ret = wc_Sha3_256_Update(&sha, (byte*)test_sha[i].input, (word32)test_sha[i].inLen); if (ret != 0) - ERROR_OUT(-2601 - i, exit); + ERROR_OUT(-2701 - i, exit); ret = wc_Sha3_256_GetHash(&sha, hashcopy); if (ret != 0) - ERROR_OUT(-2602 - i, exit); + ERROR_OUT(-2702 - i, exit); ret = wc_Sha3_256_Final(&sha, hash); if (ret != 0) - ERROR_OUT(-2603 - i, exit); + ERROR_OUT(-2703 - i, exit); if (XMEMCMP(hash, test_sha[i].output, WC_SHA3_256_DIGEST_SIZE) != 0) - ERROR_OUT(-2604 - i, exit); + ERROR_OUT(-2704 - i, exit); if (XMEMCMP(hash, hashcopy, WC_SHA3_256_DIGEST_SIZE) != 0) - ERROR_OUT(-2605 - i, exit); + ERROR_OUT(-2705 - i, exit); } /* BEGIN LARGE HASH TEST */ { @@ -2740,13 +2774,13 @@ static int sha3_256_test(void) ret = wc_Sha3_256_Update(&sha, (byte*)large_input, (word32)sizeof(large_input)); if (ret != 0) - ERROR_OUT(-2606, exit); + ERROR_OUT(-2706, exit); } ret = wc_Sha3_256_Final(&sha, hash); if (ret != 0) - ERROR_OUT(-2607, exit); + ERROR_OUT(-2707, exit); if (XMEMCMP(hash, large_digest, WC_SHA3_256_DIGEST_SIZE) != 0) - ERROR_OUT(-2608, exit); + ERROR_OUT(-2708, exit); } /* END LARGE HASH TEST */ /* this is a software only variant of SHA3 not supported by external hardware devices */ @@ -2754,18 +2788,18 @@ static int sha3_256_test(void) /* Test for Keccak256 */ ret = wc_Sha3_SetFlags(&sha, WC_HASH_SHA3_KECCAK256); if (ret != 0) { - ERROR_OUT(-2609, exit); + ERROR_OUT(-2709, exit); } ret = wc_Sha3_256_Update(&sha, (byte*)"", 0); if (ret != 0) { - ERROR_OUT(-2610, exit); + ERROR_OUT(-2710, exit); } ret = wc_Sha3_256_Final(&sha, hash); if (ret != 0) { - ERROR_OUT(-2611, exit); + ERROR_OUT(-2711, exit); } if (XMEMCMP(hash, Keccak256EmptyOut, WC_SHA3_256_DIGEST_SIZE) != 0) { - ERROR_OUT(-2612, exit); + ERROR_OUT(-2712, exit); } #endif /* WOLFSSL_HASH_FLAGS && !WOLFSSL_ASYNC_CRYPT */ @@ -2835,27 +2869,27 @@ static int sha3_384_test(void) ret = wc_InitSha3_384(&sha, HEAP_HINT, devId); if (ret != 0) - return -2700; + return -2800; for (i = 0; i < times; ++i) { ret = wc_Sha3_384_Update(&sha, (byte*)test_sha[i].input, (word32)test_sha[i].inLen); if (ret != 0) - ERROR_OUT(-2701 - i, exit); + ERROR_OUT(-2801 - i, exit); #ifndef NO_INTM_HASH_TEST ret = wc_Sha3_384_GetHash(&sha, hashcopy); if (ret != 0) - ERROR_OUT(-2702 - i, exit); + ERROR_OUT(-2802 - i, exit); #endif ret = wc_Sha3_384_Final(&sha, hash); if (ret != 0) - ERROR_OUT(-2703 - i, exit); + ERROR_OUT(-2803 - i, exit); if (XMEMCMP(hash, test_sha[i].output, WC_SHA3_384_DIGEST_SIZE) != 0) - ERROR_OUT(-2704 - i, exit); + ERROR_OUT(-2804 - i, exit); #ifndef NO_INTM_HASH_TEST if (XMEMCMP(hash, hashcopy, WC_SHA3_384_DIGEST_SIZE) != 0) - ERROR_OUT(-2705 - i, exit); + ERROR_OUT(-2805 - i, exit); #endif } @@ -2874,13 +2908,13 @@ static int sha3_384_test(void) ret = wc_Sha3_384_Update(&sha, (byte*)large_input, (word32)sizeof(large_input)); if (ret != 0) - ERROR_OUT(-2706, exit); + ERROR_OUT(-2806, exit); } ret = wc_Sha3_384_Final(&sha, hash); if (ret != 0) - ERROR_OUT(-2707, exit); + ERROR_OUT(-2807, exit); if (XMEMCMP(hash, large_digest, WC_SHA3_384_DIGEST_SIZE) != 0) - ERROR_OUT(-2708, exit); + ERROR_OUT(-2808, exit); } /* END LARGE HASH TEST */ exit: @@ -2935,24 +2969,24 @@ static int sha3_512_test(void) ret = wc_InitSha3_512(&sha, HEAP_HINT, devId); if (ret != 0) - return -2800; + return -2900; for (i = 0; i < times; ++i) { ret = wc_Sha3_512_Update(&sha, (byte*)test_sha[i].input, (word32)test_sha[i].inLen); if (ret != 0) - ERROR_OUT(-2801 - i, exit); + ERROR_OUT(-2901 - i, exit); ret = wc_Sha3_512_GetHash(&sha, hashcopy); if (ret != 0) - ERROR_OUT(-2802 - i, exit); + ERROR_OUT(-2902 - i, exit); ret = wc_Sha3_512_Final(&sha, hash); if (ret != 0) - ERROR_OUT(-2803 - i, exit); + ERROR_OUT(-2903 - i, exit); if (XMEMCMP(hash, test_sha[i].output, WC_SHA3_512_DIGEST_SIZE) != 0) - ERROR_OUT(-2804 - i, exit); + ERROR_OUT(-2904 - i, exit); if (XMEMCMP(hash, hashcopy, WC_SHA3_512_DIGEST_SIZE) != 0) - ERROR_OUT(-2805 - i, exit); + ERROR_OUT(-2905 - i, exit); } /* BEGIN LARGE HASH TEST */ { @@ -2971,13 +3005,13 @@ static int sha3_512_test(void) ret = wc_Sha3_512_Update(&sha, (byte*)large_input, (word32)sizeof(large_input)); if (ret != 0) - ERROR_OUT(-2806, exit); + ERROR_OUT(-2906, exit); } ret = wc_Sha3_512_Final(&sha, hash); if (ret != 0) - ERROR_OUT(-2807, exit); + ERROR_OUT(-2907, exit); if (XMEMCMP(hash, large_digest, WC_SHA3_512_DIGEST_SIZE) != 0) - ERROR_OUT(-2808, exit); + ERROR_OUT(-2908, exit); } /* END LARGE HASH TEST */ exit: @@ -3014,6 +3048,114 @@ int sha3_test(void) } #endif /* WOLFSSL_SHA3 */ +#ifdef WOLFSSL_SHAKE256 +int shake256_test(void) +{ +#ifndef WOLFSSL_NO_SHAKE256 + wc_Shake sha; + byte hash[114]; + + testVector a, b, c; + testVector test_sha[3]; + int ret = 0; + int times = sizeof(test_sha) / sizeof(struct testVector), i; + + byte large_input[1024]; + const char* large_digest = + "\x90\x32\x4a\xcc\xd1\xdf\xb8\x0b\x79\x1f\xb8\xc8\x5b\x54\xc8\xe7" + "\x45\xf5\x60\x6b\x38\x26\xb2\x0a\xee\x38\x01\xf3\xd9\xfa\x96\x9f" + "\x6a\xd7\x15\xdf\xb6\xc2\xf4\x20\x33\x44\x55\xe8\x2a\x09\x2b\x68" + "\x2e\x18\x65\x5e\x65\x93\x28\xbc\xb1\x9e\xe2\xb1\x92\xea\x98\xac" + "\x21\xef\x4c\xe1\xb4\xb7\xbe\x81\x5c\x1d\xd3\xb7\x17\xe5\xbb\xc5" + "\x8c\x68\xb7\xfb\xac\x55\x8a\x9b\x4d\x91\xe4\x9f\x72\xbb\x6e\x38" + "\xaf\x21\x7d\x21\xaa\x98\x4e\x75\xc4\xb4\x1c\x7c\x50\x45\x54\xf9" + "\xea\x26"; + + a.input = ""; + a.output = "\x46\xb9\xdd\x2b\x0b\xa8\x8d\x13\x23\x3b\x3f\xeb\x74\x3e\xeb" + "\x24\x3f\xcd\x52\xea\x62\xb8\x1b\x82\xb5\x0c\x27\x64\x6e\xd5" + "\x76\x2f\xd7\x5d\xc4\xdd\xd8\xc0\xf2\x00\xcb\x05\x01\x9d\x67" + "\xb5\x92\xf6\xfc\x82\x1c\x49\x47\x9a\xb4\x86\x40\x29\x2e\xac" + "\xb3\xb7\xc4\xbe\x14\x1e\x96\x61\x6f\xb1\x39\x57\x69\x2c\xc7" + "\xed\xd0\xb4\x5a\xe3\xdc\x07\x22\x3c\x8e\x92\x93\x7b\xef\x84" + "\xbc\x0e\xab\x86\x28\x53\x34\x9e\xc7\x55\x46\xf5\x8f\xb7\xc2" + "\x77\x5c\x38\x46\x2c\x50\x10\xd8\x46"; + a.inLen = XSTRLEN(a.input); + a.outLen = sizeof(hash); + + b.input = "abc"; + b.output = "\x48\x33\x66\x60\x13\x60\xa8\x77\x1c\x68\x63\x08\x0c\xc4\x11" + "\x4d\x8d\xb4\x45\x30\xf8\xf1\xe1\xee\x4f\x94\xea\x37\xe7\x8b" + "\x57\x39\xd5\xa1\x5b\xef\x18\x6a\x53\x86\xc7\x57\x44\xc0\x52" + "\x7e\x1f\xaa\x9f\x87\x26\xe4\x62\xa1\x2a\x4f\xeb\x06\xbd\x88" + "\x01\xe7\x51\xe4\x13\x85\x14\x12\x04\xf3\x29\x97\x9f\xd3\x04" + "\x7a\x13\xc5\x65\x77\x24\xad\xa6\x4d\x24\x70\x15\x7b\x3c\xdc" + "\x28\x86\x20\x94\x4d\x78\xdb\xcd\xdb\xd9\x12\x99\x3f\x09\x13" + "\xf1\x64\xfb\x2c\xe9\x51\x31\xa2\xd0"; + b.inLen = XSTRLEN(b.input); + b.outLen = sizeof(hash); + + c.input = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; + c.output = "\x4d\x8c\x2d\xd2\x43\x5a\x01\x28\xee\xfb\xb8\xc3\x6f\x6f\x87" + "\x13\x3a\x79\x11\xe1\x8d\x97\x9e\xe1\xae\x6b\xe5\xd4\xfd\x2e" + "\x33\x29\x40\xd8\x68\x8a\x4e\x6a\x59\xaa\x80\x60\xf1\xf9\xbc" + "\x99\x6c\x05\xac\xa3\xc6\x96\xa8\xb6\x62\x79\xdc\x67\x2c\x74" + "\x0b\xb2\x24\xec\x37\xa9\x2b\x65\xdb\x05\x39\xc0\x20\x34\x55" + "\xf5\x1d\x97\xcc\xe4\xcf\xc4\x91\x27\xd7\x26\x0a\xfc\x67\x3a" + "\xf2\x08\xba\xf1\x9b\xe2\x12\x33\xf3\xde\xbe\x78\xd0\x67\x60" + "\xcf\xa5\x51\xee\x1e\x07\x91\x41\xd4"; + c.inLen = XSTRLEN(c.input); + c.outLen = sizeof(hash); + + test_sha[0] = a; + test_sha[1] = b; + test_sha[2] = c; + + ret = wc_InitShake256(&sha, HEAP_HINT, devId); + if (ret != 0) + return -3100; + + for (i = 0; i < times; ++i) { + ret = wc_Shake256_Update(&sha, (byte*)test_sha[i].input, + (word32)test_sha[i].inLen); + if (ret != 0) + ERROR_OUT(-3101 - i, exit); + ret = wc_Shake256_Final(&sha, hash, (word32)test_sha[i].outLen); + if (ret != 0) + ERROR_OUT(-3102 - i, exit); + + if (XMEMCMP(hash, test_sha[i].output, test_sha[i].outLen) != 0) + ERROR_OUT(-3103 - i, exit); + } + + /* BEGIN LARGE HASH TEST */ { + for (i = 0; i < (int)sizeof(large_input); i++) { + large_input[i] = (byte)(i & 0xFF); + } + times = 100; + for (i = 0; i < times; ++i) { + ret = wc_Shake256_Update(&sha, (byte*)large_input, + (word32)sizeof(large_input)); + if (ret != 0) + ERROR_OUT(-3104, exit); + } + ret = wc_Shake256_Final(&sha, hash, (word32)sizeof(hash)); + if (ret != 0) + ERROR_OUT(-3105, exit); + if (XMEMCMP(hash, large_digest, sizeof(hash)) != 0) + ERROR_OUT(-3106, exit); + } /* END LARGE HASH TEST */ + +exit: + wc_Shake256_Free(&sha); + + return ret; +#else + return 0; +#endif +} +#endif + int hash_test(void) { @@ -3076,37 +3218,37 @@ int hash_test(void) /* Parameter Validation testing. */ ret = wc_HashInit(NULL, WC_HASH_TYPE_SHA256); if (ret != BAD_FUNC_ARG) - return -2900; + return -3200; ret = wc_HashUpdate(NULL, WC_HASH_TYPE_SHA256, NULL, sizeof(data)); if (ret != BAD_FUNC_ARG) - return -2901; + return -3201; ret = wc_HashUpdate(&hash, WC_HASH_TYPE_SHA256, NULL, sizeof(data)); if (ret != BAD_FUNC_ARG) - return -2902; + return -3202; ret = wc_HashUpdate(NULL, WC_HASH_TYPE_SHA256, data, sizeof(data)); if (ret != BAD_FUNC_ARG) - return -2903; + return -3203; ret = wc_HashFinal(NULL, WC_HASH_TYPE_SHA256, NULL); if (ret != BAD_FUNC_ARG) - return -2904; + return -3204; ret = wc_HashFinal(&hash, WC_HASH_TYPE_SHA256, NULL); if (ret != BAD_FUNC_ARG) - return -2905; + return -3205; ret = wc_HashFinal(NULL, WC_HASH_TYPE_SHA256, out); if (ret != BAD_FUNC_ARG) - return -2906; + return -3206; /* Try invalid hash algorithms. */ for (i = 0; i < (int)(sizeof(typesBad)/sizeof(*typesBad)); i++) { ret = wc_HashInit(&hash, typesBad[i]); if (ret != BAD_FUNC_ARG) - return -2907 - i; + return -3207 - i; ret = wc_HashUpdate(&hash, typesBad[i], data, sizeof(data)); if (ret != BAD_FUNC_ARG) - return -2917 - i; + return -3217 - i; ret = wc_HashFinal(&hash, typesBad[i], out); if (ret != BAD_FUNC_ARG) - return -2927 - i; + return -3227 - i; wc_HashFree(&hash, typesBad[i]); } @@ -3120,203 +3262,203 @@ int hash_test(void) } ret = wc_HashInit(&hash, typesGood[i]); if (ret != exp_ret) - return -2937 - i; + return -3237 - i; ret = wc_HashUpdate(&hash, typesGood[i], data, sizeof(data)); if (ret != exp_ret) - return -2947 - i; + return -3247 - i; ret = wc_HashFinal(&hash, typesGood[i], out); if (ret != exp_ret) - return -2957 - i; + return -3257 - i; wc_HashFree(&hash, typesGood[i]); digestSz = wc_HashGetDigestSize(typesGood[i]); if (exp_ret < 0 && digestSz != exp_ret) - return -2967 - i; + return -3267 - i; if (exp_ret == 0 && digestSz < 0) - return -2977 - i; + return -3277 - i; if (exp_ret == 0) { ret = wc_Hash(typesGood[i], data, sizeof(data), hashOut, digestSz - 1); if (ret != BUFFER_E) - return -2987 - i; + return -3287 - i; } ret = wc_Hash(typesGood[i], data, sizeof(data), hashOut, digestSz); if (ret != exp_ret) - return -2997 - i; + return -3297 - i; if (exp_ret == 0 && XMEMCMP(out, hashOut, digestSz) != 0) - return -3007 -i; + return -3307 -i; ret = wc_HashGetBlockSize(typesGood[i]); if (exp_ret < 0 && ret != exp_ret) - return -3008 - i; + return -3308 - i; if (exp_ret == 0 && ret < 0) - return -3018 - i; + return -3318 - i; #if !defined(NO_ASN) || !defined(NO_DH) || defined(HAVE_ECC) ret = wc_HashGetOID(typesGood[i]); if (ret == BAD_FUNC_ARG || (exp_ret == 0 && ret == HASH_TYPE_E) || (exp_ret != 0 && ret != HASH_TYPE_E)) { - return -3028 - i; + return -3328 - i; } hashType = wc_OidGetHash(ret); if (exp_ret < 0 && ret != exp_ret) - return -3038 - i; + return -3338 - i; if (exp_ret == 0 && hashType != typesGood[i]) - return -3048 - i; + return -3348 - i; #endif /* !defined(NO_ASN) || !defined(NO_DH) || defined(HAVE_ECC) */ } for (i = 0; i < (int)(sizeof(typesHashBad)/sizeof(*typesHashBad)); i++) { ret = wc_Hash(typesHashBad[i], data, sizeof(data), out, sizeof(out)); if (ret != BAD_FUNC_ARG && ret != BUFFER_E) - return -3058 - i; + return -3358 - i; } #if !defined(NO_ASN) || !defined(NO_DH) || defined(HAVE_ECC) ret = wc_HashGetOID(WC_HASH_TYPE_MD2); #ifdef WOLFSSL_MD2 if (ret == HASH_TYPE_E || ret == BAD_FUNC_ARG) - return -3068; + return -3368; #else if (ret != HASH_TYPE_E) - return -3069; + return -3369; #endif hashType = wc_OidGetHash(646); /* Md2h */ #ifdef WOLFSSL_MD2 if (hashType != WC_HASH_TYPE_MD2) - return -3070; + return -3370; #else if (hashType != WC_HASH_TYPE_NONE) - return -3071; + return -3371; #endif ret = wc_HashGetOID(WC_HASH_TYPE_MD5_SHA); #ifndef NO_MD5 if (ret == HASH_TYPE_E || ret == BAD_FUNC_ARG) - return -3072; + return -3372; #else if (ret != HASH_TYPE_E) - return -3073; + return -3373; #endif ret = wc_HashGetOID(WC_HASH_TYPE_MD4); if (ret != BAD_FUNC_ARG) - return -3074; + return -3374; ret = wc_HashGetOID(WC_HASH_TYPE_NONE); if (ret != BAD_FUNC_ARG) - return -3075; + return -3375; hashType = wc_OidGetHash(0); if (hashType != WC_HASH_TYPE_NONE) - return -3076; + return -3376; #endif /* !defined(NO_ASN) || !defined(NO_DH) || defined(HAVE_ECC) */ ret = wc_HashGetBlockSize(WC_HASH_TYPE_MD2); #ifdef WOLFSSL_MD2 if (ret == HASH_TYPE_E || ret == BAD_FUNC_ARG) - return -3077; + return -3377; #else if (ret != HASH_TYPE_E) - return -3078; + return -3378; #endif ret = wc_HashGetDigestSize(WC_HASH_TYPE_MD2); #ifdef WOLFSSL_MD2 if (ret == HASH_TYPE_E || ret == BAD_FUNC_ARG) - return -3079; + return -3379; #else if (ret != HASH_TYPE_E) - return -3080; + return -3380; #endif ret = wc_HashGetBlockSize(WC_HASH_TYPE_MD4); #ifndef NO_MD4 if (ret == HASH_TYPE_E || ret == BAD_FUNC_ARG) - return -3081; + return -3381; #else if (ret != HASH_TYPE_E) - return -3082; + return -3382; #endif ret = wc_HashGetDigestSize(WC_HASH_TYPE_MD4); #ifndef NO_MD4 if (ret == HASH_TYPE_E || ret == BAD_FUNC_ARG) - return -3083; + return -3383; #else if (ret != HASH_TYPE_E) - return -3084; + return -3384; #endif ret = wc_HashGetBlockSize(WC_HASH_TYPE_MD5_SHA); #if !defined(NO_MD5) && !defined(NO_SHA) if (ret == HASH_TYPE_E || ret == BAD_FUNC_ARG) - return -3085; + return -3385; #else if (ret != HASH_TYPE_E) - return -3086; + return -3386; #endif ret = wc_HashGetBlockSize(WC_HASH_TYPE_BLAKE2B); #if defined(HAVE_BLAKE2) || defined(HAVE_BLAKE2S) if (ret == HASH_TYPE_E || ret == BAD_FUNC_ARG) - return -3091; + return -3387; #else if (ret != HASH_TYPE_E) - return -3091; + return -3388; #endif ret = wc_HashGetDigestSize(WC_HASH_TYPE_BLAKE2B); #if defined(HAVE_BLAKE2) || defined(HAVE_BLAKE2S) if (ret == HASH_TYPE_E || ret == BAD_FUNC_ARG) - return -3092; + return -3389; #else if (ret != HASH_TYPE_E) - return -3092; + return -3390; #endif ret = wc_HashGetBlockSize(WC_HASH_TYPE_NONE); if (ret != BAD_FUNC_ARG) - return -3093; + return -3391; ret = wc_HashGetDigestSize(WC_HASH_TYPE_NONE); if (ret != BAD_FUNC_ARG) - return -3094; + return -3392; #ifndef NO_CERTS #if defined(WOLFSSL_MD2) && !defined(HAVE_SELFTEST) ret = wc_GetCTC_HashOID(MD2); if (ret == 0) - return -3095; + return -3393; #endif #ifndef NO_MD5 ret = wc_GetCTC_HashOID(WC_MD5); if (ret == 0) - return -3096; + return -3394; #endif #ifndef NO_SHA ret = wc_GetCTC_HashOID(WC_SHA); if (ret == 0) - return -3097; + return -3395; #endif #ifdef WOLFSSL_SHA224 ret = wc_GetCTC_HashOID(WC_SHA224); if (ret == 0) - return -3098; + return -3396; #endif #ifndef NO_SHA256 ret = wc_GetCTC_HashOID(WC_SHA256); if (ret == 0) - return -3099; + return -3397; #endif #ifdef WOLFSSL_SHA384 ret = wc_GetCTC_HashOID(WC_SHA384); if (ret == 0) - return -3100; + return -3398; #endif #ifdef WOLFSSL_SHA512 ret = wc_GetCTC_HashOID(WC_SHA512); if (ret == 0) - return -3101; + return -3399; #endif ret = wc_GetCTC_HashOID(-1); if (ret != 0) - return -3102; + return -3400; #endif return 0; @@ -3374,30 +3516,30 @@ int hmac_md5_test(void) #endif if (wc_HmacInit(&hmac, HEAP_HINT, devId) != 0) { - return -3200; + return -3500; } ret = wc_HmacSetKey(&hmac, WC_MD5, (byte*)keys[i], (word32)XSTRLEN(keys[i])); if (ret != 0) - return -3201; + return -3501; ret = wc_HmacUpdate(&hmac, (byte*)test_hmac[i].input, (word32)test_hmac[i].inLen); if (ret != 0) - return -3202; + return -3502; ret = wc_HmacFinal(&hmac, hash); if (ret != 0) - return -3203; + return -3503; if (XMEMCMP(hash, test_hmac[i].output, WC_MD5_DIGEST_SIZE) != 0) - return -3204 - i; + return -3504 - i; wc_HmacFree(&hmac); } #ifndef HAVE_FIPS if (wc_HmacSizeByType(WC_MD5) != WC_MD5_DIGEST_SIZE) - return -3214; + return -3514; #endif return 0; @@ -3457,29 +3599,29 @@ int hmac_sha_test(void) #endif if (wc_HmacInit(&hmac, HEAP_HINT, devId) != 0) - return -3300; + return -3600; ret = wc_HmacSetKey(&hmac, WC_SHA, (byte*)keys[i], (word32)XSTRLEN(keys[i])); if (ret != 0) - return -3301; + return -3601; ret = wc_HmacUpdate(&hmac, (byte*)test_hmac[i].input, (word32)test_hmac[i].inLen); if (ret != 0) - return -3302; + return -3602; ret = wc_HmacFinal(&hmac, hash); if (ret != 0) - return -3303; + return -3603; if (XMEMCMP(hash, test_hmac[i].output, WC_SHA_DIGEST_SIZE) != 0) - return -3304 - i; + return -3604 - i; wc_HmacFree(&hmac); } #ifndef HAVE_FIPS if (wc_HmacSizeByType(WC_SHA) != WC_SHA_DIGEST_SIZE) - return -3314; + return -3614; #endif return 0; @@ -3552,29 +3694,29 @@ int hmac_sha224_test(void) #endif if (wc_HmacInit(&hmac, HEAP_HINT, devId) != 0) - return -3400; + return -3700; ret = wc_HmacSetKey(&hmac, WC_SHA224, (byte*)keys[i], (word32)XSTRLEN(keys[i])); if (ret != 0) - return -3401; + return -3701; ret = wc_HmacUpdate(&hmac, (byte*)test_hmac[i].input, (word32)test_hmac[i].inLen); if (ret != 0) - return -3402; + return -3702; ret = wc_HmacFinal(&hmac, hash); if (ret != 0) - return -3403; + return -3703; if (XMEMCMP(hash, test_hmac[i].output, WC_SHA224_DIGEST_SIZE) != 0) - return -3404 - i; + return -3704 - i; wc_HmacFree(&hmac); } #ifndef HAVE_FIPS if (wc_HmacSizeByType(WC_SHA224) != WC_SHA224_DIGEST_SIZE) - return -3414; + return -3714; #endif return 0; @@ -3652,36 +3794,36 @@ int hmac_sha256_test(void) #endif if (wc_HmacInit(&hmac, HEAP_HINT, devId) != 0) - return -3500 - i; + return -3800 - i; ret = wc_HmacSetKey(&hmac, WC_SHA256, (byte*)keys[i], (word32)XSTRLEN(keys[i])); if (ret != 0) - return -3510 - i; + return -3810 - i; if (test_hmac[i].input != NULL) { ret = wc_HmacUpdate(&hmac, (byte*)test_hmac[i].input, (word32)test_hmac[i].inLen); if (ret != 0) - return -3520 - i; + return -3820 - i; } ret = wc_HmacFinal(&hmac, hash); if (ret != 0) - return -3530 - i; + return -3830 - i; if (XMEMCMP(hash, test_hmac[i].output, WC_SHA256_DIGEST_SIZE) != 0) - return -3540 - i; + return -3840 - i; wc_HmacFree(&hmac); } #ifndef HAVE_FIPS if (wc_HmacSizeByType(WC_SHA256) != WC_SHA256_DIGEST_SIZE) - return -3550; + return -3850; if (wc_HmacSizeByType(20) != BAD_FUNC_ARG) - return -3551; + return -3851; #endif if (wolfSSL_GetHmacMaxSize() != WC_MAX_DIGEST_SIZE) - return -3552; + return -3852; return 0; } @@ -3765,29 +3907,29 @@ int hmac_sha384_test(void) #endif if (wc_HmacInit(&hmac, HEAP_HINT, devId) != 0) - return -3700; + return -3900; ret = wc_HmacSetKey(&hmac, WC_SHA384, (byte*)keys[i], (word32)XSTRLEN(keys[i])); if (ret != 0) - return -3701; + return -3901; ret = wc_HmacUpdate(&hmac, (byte*)test_hmac[i].input, (word32)test_hmac[i].inLen); if (ret != 0) - return -3702; + return -3902; ret = wc_HmacFinal(&hmac, hash); if (ret != 0) - return -3703; + return -3903; if (XMEMCMP(hash, test_hmac[i].output, WC_SHA384_DIGEST_SIZE) != 0) - return -3704 - i; + return -3904 - i; wc_HmacFree(&hmac); } #ifndef HAVE_FIPS if (wc_HmacSizeByType(WC_SHA384) != WC_SHA384_DIGEST_SIZE) - return -3714; + return -3914; #endif return 0; @@ -3876,29 +4018,29 @@ int hmac_sha512_test(void) #endif if (wc_HmacInit(&hmac, HEAP_HINT, devId) != 0) - return -3800; + return -4000; ret = wc_HmacSetKey(&hmac, WC_SHA512, (byte*)keys[i], (word32)XSTRLEN(keys[i])); if (ret != 0) - return -3801; + return -4001; ret = wc_HmacUpdate(&hmac, (byte*)test_hmac[i].input, (word32)test_hmac[i].inLen); if (ret != 0) - return -3802; + return -4002; ret = wc_HmacFinal(&hmac, hash); if (ret != 0) - return -3803; + return -4003; if (XMEMCMP(hash, test_hmac[i].output, WC_SHA512_DIGEST_SIZE) != 0) - return -3804 - i; + return -4004 - i; wc_HmacFree(&hmac); } #ifndef HAVE_FIPS if (wc_HmacSizeByType(WC_SHA512) != WC_SHA512_DIGEST_SIZE) - return -3814; + return -4014; #endif return 0; @@ -4046,21 +4188,21 @@ int hmac_sha3_test(void) for (; i < iMax; i++) { for (j = 0; j < jMax; j++) { if (wc_HmacInit(&hmac, HEAP_HINT, devId) != 0) - return -3900; + return -4100; ret = wc_HmacSetKey(&hmac, hashType[j], (byte*)key[i], (word32)XSTRLEN(key[i])); if (ret != 0) - return -3901; + return -4101; ret = wc_HmacUpdate(&hmac, (byte*)input[i], (word32)XSTRLEN(input[i])); if (ret != 0) - return -3902; + return -4102; ret = wc_HmacFinal(&hmac, hash); if (ret != 0) - return -3903; + return -4103; if (XMEMCMP(hash, output[(i*jMax) + j], hashSz[j]) != 0) - return -3904; + return -4104; wc_HmacFree(&hmac); @@ -4070,7 +4212,7 @@ int hmac_sha3_test(void) #ifndef HAVE_FIPS ret = wc_HmacSizeByType(hashType[j]); if (ret != hashSz[j]) - return -3905; + return -4105; #endif } } @@ -4132,9 +4274,9 @@ int arc4_test(void) keylen = 4; if (wc_Arc4Init(&enc, HEAP_HINT, devId) != 0) - return -4000; + return -4200; if (wc_Arc4Init(&dec, HEAP_HINT, devId) != 0) - return -4001; + return -4201; wc_Arc4SetKey(&enc, (byte*)keys[i], keylen); wc_Arc4SetKey(&dec, (byte*)keys[i], keylen); @@ -4144,10 +4286,10 @@ int arc4_test(void) wc_Arc4Process(&dec, plain, cipher, (word32)test_arc4[i].outLen); if (XMEMCMP(plain, test_arc4[i].input, test_arc4[i].outLen)) - return -4002 - i; + return -4202 - i; if (XMEMCMP(cipher, test_arc4[i].output, test_arc4[i].outLen)) - return -4012 - i; + return -4212 - i; wc_Arc4Free(&enc); wc_Arc4Free(&dec); @@ -4226,18 +4368,18 @@ int hc128_test(void) XMEMCPY(plain, test_hc128[i].input, test_hc128[i].outLen); if (wc_Hc128_Process(&enc, cipher, plain, (word32)test_hc128[i].outLen) != 0) { - return -4100; + return -4300; } if (wc_Hc128_Process(&dec, plain, cipher, (word32)test_hc128[i].outLen) != 0) { - return -4101; + return -4301; } if (XMEMCMP(plain, test_hc128[i].input, test_hc128[i].outLen)) - return -4102 - i; + return -4302 - i; if (XMEMCMP(cipher, test_hc128[i].output, test_hc128[i].outLen)) - return -4112 - i; + return -4312 - i; } #endif /* HAVE_HC128 */ @@ -4310,10 +4452,10 @@ int rabbit_test(void) wc_RabbitProcess(&dec, plain, cipher, (word32)test_rabbit[i].outLen); if (XMEMCMP(plain, test_rabbit[i].input, test_rabbit[i].outLen)) - return -4200 - i; + return -4400 - i; if (XMEMCMP(cipher, test_rabbit[i].output, test_rabbit[i].outLen)) - return -4210 - i; + return -4410 - i; } return 0; @@ -4566,10 +4708,10 @@ int chacha_test(void) return ret; if (XMEMCMP(test_chacha[i], cipher, 8)) - return -4300 - i; + return -4500 - i; if (XMEMCMP(plain, input, 8)) - return -4310 - i; + return -4510 - i; } /* test of starting at a different counter @@ -4595,7 +4737,7 @@ int chacha_test(void) return ret; if (XMEMCMP(plain + 64, sliver, 64)) - return -4320; + return -4520; #ifndef BENCH_EMBEDDED /* test of encrypting more data */ @@ -4618,10 +4760,10 @@ int chacha_test(void) return ret; if (XMEMCMP(plain_big, input_big, CHACHA_BIG_TEST_SIZE)) - return -4330; + return -4521; if (XMEMCMP(cipher_big, cipher_big_result, CHACHA_BIG_TEST_SIZE)) - return -4331; + return -4522; for (i = 0; i < 18; ++i) { /* this will test all paths */ @@ -4645,10 +4787,10 @@ int chacha_test(void) return ret; if (XMEMCMP(plain_big, input_big, block_size)) - return -4340-i; + return -4523-i; if (XMEMCMP(cipher_big, cipher_big_result, block_size)) - return -4360-i; + return -4524-i; } #ifdef WOLFSSL_SMALL_STACK @@ -4829,33 +4971,33 @@ int poly1305_test(void) for (i = 0; i < 6; i++) { ret = wc_Poly1305SetKey(&enc, keys[i], 32); if (ret != 0) - return -4400 - i; + return -4600 - i; ret = wc_Poly1305Update(&enc, msgs[i], szm[i]); if (ret != 0) - return -4410 - i; + return -4610 - i; ret = wc_Poly1305Final(&enc, tag); if (ret != 0) - return -4420 - i; + return -4620 - i; if (XMEMCMP(tag, tests[i], sizeof(tag))) - return -4430 - i; + return -4630 - i; } /* Check TLS MAC function from 2.8.2 https://tools.ietf.org/html/rfc7539 */ XMEMSET(tag, 0, sizeof(tag)); ret = wc_Poly1305SetKey(&enc, key4, sizeof(key4)); if (ret != 0) - return -4440; + return -4640; ret = wc_Poly1305_MAC(&enc, additional, sizeof(additional), (byte*)msg4, sizeof(msg4), tag, sizeof(tag)); if (ret != 0) - return -4441; + return -4641; if (XMEMCMP(tag, correct4, sizeof(tag))) - return -4442; + return -4642; /* Check fail of TLS MAC function if altering additional data */ XMEMSET(tag, 0, sizeof(tag)); @@ -4863,10 +5005,10 @@ int poly1305_test(void) ret = wc_Poly1305_MAC(&enc, additional, sizeof(additional), (byte*)msg4, sizeof(msg4), tag, sizeof(tag)); if (ret != 0) - return -4443; + return -4643; if (XMEMCMP(tag, correct4, sizeof(tag)) == 0) - return -4444; + return -4644; return 0; @@ -5062,53 +5204,53 @@ int chacha20_poly1305_aead_test(void) err = wc_ChaCha20Poly1305_Encrypt(NULL, iv1, aad1, sizeof(aad1), plaintext1, sizeof(plaintext1), generatedCiphertext, generatedAuthTag); if (err != BAD_FUNC_ARG) - return -4500; + return -4700; err = wc_ChaCha20Poly1305_Encrypt(key1, NULL, aad1, sizeof(aad1), plaintext1, sizeof(plaintext1), generatedCiphertext, generatedAuthTag); if (err != BAD_FUNC_ARG) - return -4501; + return -4701; err = wc_ChaCha20Poly1305_Encrypt(key1, iv1, aad1, sizeof(aad1), NULL, sizeof(plaintext1), generatedCiphertext, generatedAuthTag); if (err != BAD_FUNC_ARG) - return -4502; + return -4702; err = wc_ChaCha20Poly1305_Encrypt(key1, iv1, aad1, sizeof(aad1), plaintext1, sizeof(plaintext1), NULL, generatedAuthTag); if (err != BAD_FUNC_ARG) - return -4503; + return -4703; err = wc_ChaCha20Poly1305_Encrypt(key1, iv1, aad1, sizeof(aad1), plaintext1, sizeof(plaintext1), generatedCiphertext, NULL); if (err != BAD_FUNC_ARG) - return -4504; + return -4704; err = wc_ChaCha20Poly1305_Encrypt(key1, iv1, aad1, sizeof(aad1), plaintext1, 0, generatedCiphertext, generatedAuthTag); if (err != BAD_FUNC_ARG) - return -4505; + return -4705; /* Decrypt */ err = wc_ChaCha20Poly1305_Decrypt(NULL, iv2, aad2, sizeof(aad2), cipher2, sizeof(cipher2), authTag2, generatedPlaintext); if (err != BAD_FUNC_ARG) - return -4506; + return -4706; err = wc_ChaCha20Poly1305_Decrypt(key2, NULL, aad2, sizeof(aad2), cipher2, sizeof(cipher2), authTag2, generatedPlaintext); if (err != BAD_FUNC_ARG) - return -4507; + return -4707; err = wc_ChaCha20Poly1305_Decrypt(key2, iv2, aad2, sizeof(aad2), NULL, sizeof(cipher2), authTag2, generatedPlaintext); if (err != BAD_FUNC_ARG) - return -4508; + return -4708; err = wc_ChaCha20Poly1305_Decrypt(key2, iv2, aad2, sizeof(aad2), cipher2, sizeof(cipher2), NULL, generatedPlaintext); if (err != BAD_FUNC_ARG) - return -4509; + return -4709; err = wc_ChaCha20Poly1305_Decrypt(key2, iv2, aad2, sizeof(aad2), cipher2, sizeof(cipher2), authTag2, NULL); if (err != BAD_FUNC_ARG) - return -4510; + return -4710; err = wc_ChaCha20Poly1305_Decrypt(key2, iv2, aad2, sizeof(aad2), cipher2, 0, authTag2, generatedPlaintext); if (err != BAD_FUNC_ARG) - return -4511; + return -4711; /* Test #1 */ @@ -5122,10 +5264,10 @@ int chacha20_poly1305_aead_test(void) /* -- Check the ciphertext and authtag */ if (XMEMCMP(generatedCiphertext, cipher1, sizeof(cipher1))) { - return -4512; + return -4712; } if (XMEMCMP(generatedAuthTag, authTag1, sizeof(authTag1))) { - return -4513; + return -4713; } /* -- Verify decryption works */ @@ -5137,7 +5279,7 @@ int chacha20_poly1305_aead_test(void) return err; } if (XMEMCMP(generatedPlaintext, plaintext1, sizeof(plaintext1))) { - return -4514; + return -4714; } @@ -5156,10 +5298,10 @@ int chacha20_poly1305_aead_test(void) /* -- Check the ciphertext and authtag */ if (XMEMCMP(generatedCiphertext, cipher2, sizeof(cipher2))) { - return -4515; + return -4715; } if (XMEMCMP(generatedAuthTag, authTag2, sizeof(authTag2))) { - return -4516; + return -4716; } /* -- Verify decryption works */ @@ -5172,7 +5314,7 @@ int chacha20_poly1305_aead_test(void) } if (XMEMCMP(generatedPlaintext, plaintext2, sizeof(plaintext2))) { - return -4517; + return -4717; } @@ -5180,62 +5322,62 @@ int chacha20_poly1305_aead_test(void) err = wc_ChaCha20Poly1305_Init(NULL, key1, iv1, CHACHA20_POLY1305_AEAD_DECRYPT); if (err != BAD_FUNC_ARG) - return -4520; + return -4718; err = wc_ChaCha20Poly1305_Init(&aead, NULL, iv1, CHACHA20_POLY1305_AEAD_DECRYPT); if (err != BAD_FUNC_ARG) - return -4521; + return -4719; err = wc_ChaCha20Poly1305_Init(&aead, key1, NULL, CHACHA20_POLY1305_AEAD_DECRYPT); if (err != BAD_FUNC_ARG) - return -4522; + return -4720; err = wc_ChaCha20Poly1305_UpdateAad(NULL, aad1, sizeof(aad1)); if (err != BAD_FUNC_ARG) - return -4523; + return -4721; err = wc_ChaCha20Poly1305_UpdateAad(&aead, NULL, sizeof(aad1)); if (err != BAD_FUNC_ARG) - return -4524; + return -4722; err = wc_ChaCha20Poly1305_UpdateData(NULL, generatedPlaintext, generatedPlaintext, sizeof(plaintext1)); if (err != BAD_FUNC_ARG) - return -4525; + return -4723; err = wc_ChaCha20Poly1305_UpdateData(&aead, generatedPlaintext, NULL, sizeof(plaintext1)); if (err != BAD_FUNC_ARG) - return -4526; + return -4724; err = wc_ChaCha20Poly1305_UpdateData(&aead, NULL, generatedPlaintext, sizeof(plaintext1)); if (err != BAD_FUNC_ARG) - return -4526; + return -4725; err = wc_ChaCha20Poly1305_Final(NULL, generatedAuthTag); if (err != BAD_FUNC_ARG) - return -4527; + return -4726; err = wc_ChaCha20Poly1305_Final(&aead, NULL); if (err != BAD_FUNC_ARG) - return -4528; + return -4727; /* AEAD init/update/final - state tests */ aead.state = CHACHA20_POLY1305_STATE_INIT; err = wc_ChaCha20Poly1305_UpdateAad(&aead, aad1, sizeof(aad1)); if (err != BAD_STATE_E) - return -4529; + return -4728; aead.state = CHACHA20_POLY1305_STATE_DATA; err = wc_ChaCha20Poly1305_UpdateAad(&aead, aad1, sizeof(aad1)); if (err != BAD_STATE_E) - return -4530; + return -4729; aead.state = CHACHA20_POLY1305_STATE_INIT; err = wc_ChaCha20Poly1305_UpdateData(&aead, generatedPlaintext, generatedPlaintext, sizeof(plaintext1)); if (err != BAD_STATE_E) - return -4531; + return -4730; aead.state = CHACHA20_POLY1305_STATE_INIT; err = wc_ChaCha20Poly1305_Final(&aead, generatedAuthTag); if (err != BAD_STATE_E) - return -4532; + return -4731; aead.state = CHACHA20_POLY1305_STATE_READY; err = wc_ChaCha20Poly1305_Final(&aead, generatedAuthTag); if (err != BAD_STATE_E) - return -4533; + return -4732; XMEMSET(generatedCiphertext, 0, sizeof(generatedCiphertext)); XMEMSET(generatedAuthTag, 0, sizeof(generatedAuthTag)); @@ -5245,10 +5387,10 @@ int chacha20_poly1305_aead_test(void) err = wc_ChaCha20Poly1305_Init(&aead, key1, iv1, CHACHA20_POLY1305_AEAD_ENCRYPT); if (err != 0) - return -4537; + return -4733; err = wc_ChaCha20Poly1305_UpdateAad(&aead, aad1, sizeof(aad1)); if (err != 0) - return -4538; + return -4734; #ifdef TEST_SMALL_CHACHA_CHUNKS /* test doing data in smaller chunks */ for (testLen=0; testLen= 2)) @@ -8846,7 +8988,7 @@ int gmac_test(void) wc_GmacSetKey(&gmac, k2, sizeof(k2)); wc_GmacUpdate(&gmac, iv2, sizeof(iv2), a2, sizeof(a2), tag, sizeof(t2)); if (XMEMCMP(t2, tag, sizeof(t2)) != 0) - return -5801; + return -6201; #if !(defined(WC_NO_RNG) || defined(HAVE_SELFTEST)) { @@ -8861,30 +9003,30 @@ int gmac_test(void) #ifndef HAVE_FIPS if (wc_InitRng_ex(&rng, HEAP_HINT, devId) != 0) - return -8214; + return -6202; #else if (wc_InitRng(&rng) != 0) - return -8214; + return -6203; #endif if (wc_GmacVerify(k1, sizeof(k1), iv1, sizeof(iv1), a1, sizeof(a1), t1, sizeof(t1)) != 0) - return -8215; + return -6204; if (wc_GmacVerify(k1, sizeof(k1), iv1, sizeof(iv1), a1, sizeof(a1), badT, sizeof(badT)) != AES_GCM_AUTH_E) - return -8216; + return -6205; if (wc_GmacVerify(k2, sizeof(k2), iv2, sizeof(iv2), a2, sizeof(a2), t2, sizeof(t2)) != 0) - return -8217; + return -6206; XMEMSET(tag, 0, sizeof(tag)); XMEMSET(iv, 0, sizeof(iv)); if (wc_Gmac(k1, sizeof(k1), iv, sizeof(iv), a1, sizeof(a1), tag, sizeof(tag), &rng) != 0) - return -8218; + return -6207; if (wc_GmacVerify(k1, sizeof(k1), iv, sizeof(iv), a1, sizeof(a1), tag, sizeof(tag)) != 0) - return -8219; + return -6208; wc_FreeRng(&rng); } #endif /* WC_NO_RNG HAVE_SELFTEST */ @@ -8953,37 +9095,37 @@ int aesccm_test(void) result = wc_AesCcmSetKey(&enc, k, sizeof(k)); if (result != 0) - return -5900; + return -6300; /* AES-CCM encrypt and decrypt both use AES encrypt internally */ result = wc_AesCcmEncrypt(&enc, c2, p, sizeof(c2), iv, sizeof(iv), t2, sizeof(t2), a, sizeof(a)); if (result != 0) - return -5901; + return -6301; if (XMEMCMP(c, c2, sizeof(c2))) - return -5902; + return -6302; if (XMEMCMP(t, t2, sizeof(t2))) - return -5903; + return -6303; result = wc_AesCcmDecrypt(&enc, p2, c2, sizeof(p2), iv, sizeof(iv), t2, sizeof(t2), a, sizeof(a)); if (result != 0) - return -5904; + return -6304; if (XMEMCMP(p, p2, sizeof(p2))) - return -5905; + return -6305; /* Test the authentication failure */ t2[0]++; /* Corrupt the authentication tag. */ result = wc_AesCcmDecrypt(&enc, p2, c, sizeof(p2), iv, sizeof(iv), t2, sizeof(t2), a, sizeof(a)); if (result == 0) - return -5906; + return -6306; /* Clear c2 to compare against p2. p2 should be set to zero in case of * authentication fail. */ XMEMSET(c2, 0, sizeof(c2)); if (XMEMCMP(p2, c2, sizeof(p2))) - return -5907; + return -6307; XMEMSET(&enc, 0, sizeof(Aes)); /* clear context */ XMEMSET(t2, 0, sizeof(t2)); @@ -8995,19 +9137,19 @@ int aesccm_test(void) /* selftest build does not have wc_AesCcmSetNonce() or * wc_AesCcmEncrypt_ex() */ if (wc_AesCcmSetKey(&enc, k, sizeof(k)) != 0) - return -8220; + return -6308; if (wc_AesCcmSetNonce(&enc, iv, sizeof(iv)) != 0) - return -8221; + return -6309; if (wc_AesCcmEncrypt_ex(&enc, c2, p, sizeof(c2), iv2, sizeof(iv2), t2, sizeof(t2), a, sizeof(a)) != 0) - return -8222; + return -6310; if (XMEMCMP(iv, iv2, sizeof(iv2))) - return -8223; + return -6311; if (XMEMCMP(c, c2, sizeof(c2))) - return -8224; + return -6312; if (XMEMCMP(t, t2, sizeof(t2))) - return -8225; + return -6313; #endif return 0; @@ -9197,20 +9339,20 @@ int aeskeywrap_test(void) output, sizeof(output), NULL); if ( (wrapSz < 0) || (wrapSz != (int)test_wrap[i].verifyLen) ) - return -6000; + return -6400; if (XMEMCMP(output, test_wrap[i].verify, test_wrap[i].verifyLen) != 0) - return -6001; + return -6401; plainSz = wc_AesKeyUnWrap((byte*)test_wrap[i].kek, test_wrap[i].kekLen, output, wrapSz, plain, sizeof(plain), NULL); if ( (plainSz < 0) || (plainSz != (int)test_wrap[i].dataLen) ) - return -6002; + return -6402; if (XMEMCMP(plain, test_wrap[i].data, test_wrap[i].dataLen) != 0) - return -6003 - i; + return -6403 - i; } return 0; @@ -9403,24 +9545,24 @@ int camellia_test(void) /* Setting the IV and checking it was actually set. */ ret = wc_CamelliaSetIV(&cam, ivc); if (ret != 0 || XMEMCMP(cam.reg, ivc, CAMELLIA_BLOCK_SIZE)) - return -6100; + return -6500; /* Setting the IV to NULL should be same as all zeros IV */ if (wc_CamelliaSetIV(&cam, NULL) != 0 || XMEMCMP(cam.reg, ive, CAMELLIA_BLOCK_SIZE)) - return -6101; + return -6501; /* First parameter should never be null */ if (wc_CamelliaSetIV(NULL, NULL) == 0) - return -6102; + return -6502; /* First parameter should never be null, check it fails */ if (wc_CamelliaSetKey(NULL, k1, sizeof(k1), NULL) == 0) - return -6103; + return -6503; /* Key should have a size of 16, 24, or 32 */ if (wc_CamelliaSetKey(&cam, k1, 0, NULL) == 0) - return -6104; + return -6504; return 0; } @@ -9497,14 +9639,14 @@ int idea_test(void) NULL, IDEA_ENCRYPTION); if (ret != 0) { printf("wc_IdeaSetKey (enc) failed\n"); - return -6200; + return -6600; } /* Data encryption */ ret = wc_IdeaCipher(&idea, data, v1_plain[i]); if (ret != 0 || XMEMCMP(&v1_cipher[i], data, IDEA_BLOCK_SIZE)) { printf("Bad encryption\n"); - return -6201; + return -6601; } /* Set decryption key */ @@ -9513,14 +9655,14 @@ int idea_test(void) NULL, IDEA_DECRYPTION); if (ret != 0) { printf("wc_IdeaSetKey (dec) failed\n"); - return -6202; + return -6602; } /* Data decryption */ ret = wc_IdeaCipher(&idea, data, data); if (ret != 0 || XMEMCMP(v1_plain[i], data, IDEA_BLOCK_SIZE)) { printf("Bad decryption\n"); - return -6203; + return -6603; } /* Set encryption key */ @@ -9529,7 +9671,7 @@ int idea_test(void) v_key[i], IDEA_ENCRYPTION); if (ret != 0) { printf("wc_IdeaSetKey (enc) failed\n"); - return -6204; + return -6604; } XMEMSET(msg_enc, 0, sizeof(msg_enc)); @@ -9537,7 +9679,7 @@ int idea_test(void) (word32)XSTRLEN(message)+1); if (ret != 0) { printf("wc_IdeaCbcEncrypt failed\n"); - return -6205; + return -6605; } /* Set decryption key */ @@ -9546,7 +9688,7 @@ int idea_test(void) v_key[i], IDEA_DECRYPTION); if (ret != 0) { printf("wc_IdeaSetKey (dec) failed\n"); - return -6206; + return -6606; } XMEMSET(msg_dec, 0, sizeof(msg_dec)); @@ -9554,12 +9696,12 @@ int idea_test(void) (word32)XSTRLEN(message)+1); if (ret != 0) { printf("wc_IdeaCbcDecrypt failed\n"); - return -6207; + return -6607; } if (XMEMCMP(message, msg_dec, (word32)XSTRLEN(message))) { printf("Bad CBC decryption\n"); - return -6208; + return -6608; } } @@ -9570,7 +9712,7 @@ int idea_test(void) NULL, IDEA_ENCRYPTION); if (ret != 0) { printf("wc_IdeaSetKey (enc) failed\n"); - return -6209; + return -6609; } /* 100 times data encryption */ @@ -9578,13 +9720,13 @@ int idea_test(void) for (j = 0; j < 100; j++) { ret = wc_IdeaCipher(&idea, data, data); if (ret != 0) { - return -6210; + return -6610; } } if (XMEMCMP(v1_cipher_100[i], data, IDEA_BLOCK_SIZE)) { printf("Bad encryption (100 times)\n"); - return -6211; + return -6611; } /* 1000 times data encryption */ @@ -9592,13 +9734,13 @@ int idea_test(void) for (j = 0; j < 1000; j++) { ret = wc_IdeaCipher(&idea, data, data); if (ret != 0) { - return -6212; + return -6612; } } if (XMEMCMP(v1_cipher_1000[i], data, IDEA_BLOCK_SIZE)) { printf("Bad encryption (100 times)\n"); - return -6213; + return -6613; } } @@ -9616,30 +9758,30 @@ int idea_test(void) ret = wc_InitRng(&rng); #endif if (ret != 0) - return -6214; + return -6614; for (i = 0; i < 1000; i++) { /* random key */ ret = wc_RNG_GenerateBlock(&rng, key, sizeof(key)); if (ret != 0) - return -6215; + return -6615; /* random iv */ ret = wc_RNG_GenerateBlock(&rng, iv, sizeof(iv)); if (ret != 0) - return -6216; + return -6616; /* random data */ ret = wc_RNG_GenerateBlock(&rng, rnd, sizeof(rnd)); if (ret != 0) - return -6217; + return -6617; /* Set encryption key */ XMEMSET(&idea, 0, sizeof(Idea)); ret = wc_IdeaSetKey(&idea, key, IDEA_KEY_SIZE, iv, IDEA_ENCRYPTION); if (ret != 0) { printf("wc_IdeaSetKey (enc) failed\n"); - return -6218; + return -6618; } /* Data encryption */ @@ -9647,7 +9789,7 @@ int idea_test(void) ret = wc_IdeaCbcEncrypt(&idea, enc, rnd, sizeof(rnd)); if (ret != 0) { printf("wc_IdeaCbcEncrypt failed\n"); - return -6219; + return -6619; } /* Set decryption key */ @@ -9655,7 +9797,7 @@ int idea_test(void) ret = wc_IdeaSetKey(&idea, key, IDEA_KEY_SIZE, iv, IDEA_DECRYPTION); if (ret != 0) { printf("wc_IdeaSetKey (enc) failed\n"); - return -6220; + return -6620; } /* Data decryption */ @@ -9663,12 +9805,12 @@ int idea_test(void) ret = wc_IdeaCbcDecrypt(&idea, dec, enc, sizeof(enc)); if (ret != 0) { printf("wc_IdeaCbcDecrypt failed\n"); - return -6221; + return -6621; } if (XMEMCMP(rnd, dec, sizeof(rnd))) { printf("Bad CBC decryption\n"); - return -6222; + return -6622; } } @@ -9691,7 +9833,7 @@ static int _rng_test(WC_RNG* rng, int errorOffset) ret = wc_RNG_GenerateBlock(rng, block, sizeof(block)); if (ret != 0) { - ret = -1; + ret = -6623; goto exit; } @@ -9703,36 +9845,36 @@ static int _rng_test(WC_RNG* rng, int errorOffset) } /* All zeros count check */ if (ret >= (int)sizeof(block)) { - ret = -2; + ret = -6624; goto exit; } ret = wc_RNG_GenerateByte(rng, block); if (ret != 0) { - ret = -3; + ret = -6625; goto exit; } /* Parameter validation testing. */ ret = wc_RNG_GenerateBlock(NULL, block, sizeof(block)); if (ret != BAD_FUNC_ARG) { - ret = -4; + ret = -6626; goto exit; } ret = wc_RNG_GenerateBlock(rng, NULL, sizeof(block)); if (ret != BAD_FUNC_ARG) { - ret = -5; + ret = -6627; goto exit; } ret = wc_RNG_GenerateByte(NULL, block); if (ret != BAD_FUNC_ARG) { - ret = -6; + ret = -6628; goto exit; } ret = wc_RNG_GenerateByte(rng, NULL); if (ret != BAD_FUNC_ARG) { - ret = -7; + ret = -6629; goto exit; } @@ -9759,7 +9901,7 @@ static int random_rng_test(void) #else ret = wc_InitRng(rng); #endif - if (ret != 0) return -6300; + if (ret != 0) return -6700; ret = _rng_test(rng, -6300); @@ -9773,7 +9915,7 @@ static int random_rng_test(void) byte nonce[8] = { 0 }; /* Test dynamic RNG. */ rng = wc_rng_new(nonce, (word32)sizeof(nonce), HEAP_HINT); - if (rng == NULL) return -6310; + if (rng == NULL) return -6701; ret = _rng_test(rng, -6310); @@ -9843,19 +9985,19 @@ int random_test(void) ret = wc_RNG_HealthTest(0, test1Entropy, sizeof(test1Entropy), NULL, 0, output, sizeof(output)); if (ret != 0) - return -6400; + return -6800; if (XMEMCMP(test1Output, output, sizeof(output)) != 0) - return -6401; + return -6801; ret = wc_RNG_HealthTest(1, test2EntropyA, sizeof(test2EntropyA), test2EntropyB, sizeof(test2EntropyB), output, sizeof(output)); if (ret != 0) - return -6402; + return -6802; if (XMEMCMP(test2Output, output, sizeof(output)) != 0) - return -6403; + return -6803; /* Basic RNG generate block test */ if ((ret = random_rng_test()) != 0) @@ -9872,7 +10014,7 @@ int random_test(void) XMEMSET(output, 1, outputSz); ret = wc_RNG_TestSeed(output, outputSz); if (ret == 0) - return -6404; + return -6804; /* Every byte of the entropy scratch is different, * entropy is a single byte that shouldn't match. */ @@ -9881,14 +10023,14 @@ int random_test(void) output[i] = (byte)i; ret = wc_RNG_TestSeed(output, outputSz); if (ret != 0) - return -6405; + return -6805; outputSz = sizeof(output); for (i = 0; i < outputSz; i++) output[i] = (byte)i; ret = wc_RNG_TestSeed(output, outputSz); if (ret != 0) - return -6406; + return -6806; } #endif return 0; @@ -9917,7 +10059,7 @@ static int simple_mem_test(int sz) b = (byte*)XMALLOC(sz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (b == NULL) { - return -6517; + return -6900; } /* utilize memory */ for (i = 0; i < sz; i++) { @@ -9926,7 +10068,7 @@ static int simple_mem_test(int sz) /* read back and verify */ for (i = 0; i < sz; i++) { if (b[i] != (byte)i) { - ret = -6518; + ret = -6901; break; } } @@ -9955,84 +10097,84 @@ int memory_test(void) #ifdef WOLFSSL_STATIC_MEMORY /* check macro settings */ if (sizeof(size)/sizeof(word32) != WOLFMEM_MAX_BUCKETS) { - return -6500; + return -7000; } if (sizeof(dist)/sizeof(word32) != WOLFMEM_MAX_BUCKETS) { - return -6501; + return -7001; } for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) { if ((size[i] % WOLFSSL_STATIC_ALIGN) != 0) { /* each element in array should be divisible by alignment size */ - return -6502; + return -7002; } } for (i = 1; i < WOLFMEM_MAX_BUCKETS; i++) { if (size[i - 1] >= size[i]) { - return -6503; /* sizes should be in increasing order */ + return -7003; /* sizes should be in increasing order */ } } /* check that padding size returned is possible */ if (wolfSSL_MemoryPaddingSz() < WOLFSSL_STATIC_ALIGN) { - return -6504; /* no room for wc_Memory struct */ + return -7004; /* no room for wc_Memory struct */ } if (wolfSSL_MemoryPaddingSz() < 0) { - return -6505; + return -7005; } if (wolfSSL_MemoryPaddingSz() % WOLFSSL_STATIC_ALIGN != 0) { - return -6506; /* not aligned! */ + return -7006; /* not aligned! */ } /* check function to return optimum buffer size (rounded down) */ ret = wolfSSL_StaticBufferSz(buffer, sizeof(buffer), WOLFMEM_GENERAL); if ((ret - pad) % WOLFSSL_STATIC_ALIGN != 0) { - return -6507; /* not aligned! */ + return -7007; /* not aligned! */ } if (ret < 0) { - return -6508; + return -7008; } if ((unsigned int)ret > sizeof(buffer)) { - return -6509; /* did not round down as expected */ + return -7009; /* did not round down as expected */ } if (ret != wolfSSL_StaticBufferSz(buffer, ret, WOLFMEM_GENERAL)) { - return -6510; /* return value changed when using suggested value */ + return -7010; /* return value changed when using suggested value */ } ret = wolfSSL_MemoryPaddingSz(); ret += pad; /* add space that is going to be needed if buffer not aligned */ if (wolfSSL_StaticBufferSz(buffer, size[0] + ret + 1, WOLFMEM_GENERAL) != (ret + (int)size[0])) { - return -6511; /* did not round down to nearest bucket value */ + return -7011; /* did not round down to nearest bucket value */ } ret = wolfSSL_StaticBufferSz(buffer, sizeof(buffer), WOLFMEM_IO_POOL); if ((ret - pad) < 0) { - return -6512; + return -7012; } if (((ret - pad) % (WOLFMEM_IO_SZ + wolfSSL_MemoryPaddingSz())) != 0) { - return -6513; /* not even chunks of memory for IO size */ + return -7013; /* not even chunks of memory for IO size */ } if (((ret - pad) % WOLFSSL_STATIC_ALIGN) != 0) { - return -6514; /* memory not aligned */ + return -7014; /* memory not aligned */ } /* check for passing bad or unknown arguments to functions */ if (wolfSSL_StaticBufferSz(NULL, 1, WOLFMEM_GENERAL) > 0) { - return -6515; + return -7015; } if (wolfSSL_StaticBufferSz(buffer, 1, WOLFMEM_GENERAL) != 0) { - return -6516; /* should round to 0 since struct + bucket will not fit */ + return -7016; /* should round to 0 since struct + bucket will not fit */ } (void)dist; /* avoid static analysis warning of variable not used */ @@ -10060,7 +10202,7 @@ int memory_test(void) DYNAMIC_TYPE_TMP_BUFFER); } if (b == NULL) { - return -6519; + return -7017; } XFREE(b, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); #endif @@ -10184,6 +10326,13 @@ byte GetEntropy(ENTROPY_CMD cmd, byte* out) CERT_ROOT "ed25519/ca-ed25519.der"; #endif #endif + #ifdef HAVE_ED448 + #ifdef WOLFSSL_TEST_CERT + static const char* serverEd448Cert = + CERT_ROOT "ed448/server-ed448.der"; + static const char* caEd448Cert = CERT_ROOT "ed448/ca-ed448.der"; + #endif + #endif #endif /* !USE_CERT_BUFFER_* */ #ifndef NO_WRITE_TEMP_FILES @@ -10234,7 +10383,8 @@ byte GetEntropy(ENTROPY_CMD cmd, byte* out) #endif /* !NO_FILESYSTEM */ -#ifdef WOLFSSL_CERT_GEN +#if defined(WOLFSSL_CERT_GEN) && (!defined(NO_RSA) && defined(HAVE_ECC) || \ + defined(WOLFSSL_TEST_CERT) && (defined(HAVE_ED25519) || defined(HAVE_ED448))) #ifdef WOLFSSL_MULTI_ATTRIB static CertName certDefaultName; static void initDefaultName(void) @@ -10308,8 +10458,8 @@ static const CertName certDefaultName = { #endif /* WOLFSSL_MULTI_ATTRIB */ #ifdef WOLFSSL_CERT_EXT - #if (defined(HAVE_ED25519) && defined(WOLFSSL_TEST_CERT)) || \ - defined(HAVE_ECC) + #if ((defined(HAVE_ED25519) || defined(HAVE_ED448)) && \ + defined(WOLFSSL_TEST_CERT)) || defined(HAVE_ECC) static const char certKeyUsage[] = "digitalSignature,nonRepudiation"; #endif @@ -10405,7 +10555,7 @@ static int cert_asn1_test(void) ret = ParseCert(&cert, CERT_TYPE, NO_VERIFY, NULL); FreeDecodedCert(&cert); if (ret != 0) { - ERROR_OUT(-6630, done); + ERROR_OUT(-7100, done); } /* Bad issuer name */ @@ -10421,7 +10571,7 @@ static int cert_asn1_test(void) ret = ParseCert(&cert, CERT_TYPE, NO_VERIFY, NULL); FreeDecodedCert(&cert); if (ret != ASN_PARSE_E) { - ERROR_OUT(-6631, done); + ERROR_OUT(-7101, done); } XFREE(badCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); badCert = NULL; @@ -10444,7 +10594,7 @@ int cert_test(void) tmp = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (tmp == NULL) - return -6600; + return -7200; /* Certificate with Name Constraints extension. */ #ifdef FREESCALE_MQX @@ -10453,14 +10603,14 @@ int cert_test(void) file = XFOPEN("./certs/test/cert-ext-nc.der", "rb"); #endif if (!file) { - ERROR_OUT(-6601, done); + ERROR_OUT(-7201, done); } bytes = XFREAD(tmp, 1, FOURK_BUF, file); XFCLOSE(file); InitDecodedCert(&cert, tmp, (word32)bytes, 0); ret = ParseCert(&cert, CERT_TYPE, NO_VERIFY, NULL); if (ret != 0) { - ERROR_OUT(-6602, done); + ERROR_OUT(-7202, done); } FreeDecodedCert(&cert); @@ -10471,14 +10621,14 @@ int cert_test(void) file = XFOPEN("./certs/test/cert-ext-ia.der", "rb"); #endif if (!file) { - ERROR_OUT(-6603, done); + ERROR_OUT(-7203, done); } bytes = XFREAD(tmp, 1, FOURK_BUF, file); XFCLOSE(file); InitDecodedCert(&cert, tmp, (word32)bytes, 0); ret = ParseCert(&cert, CERT_TYPE, NO_VERIFY, NULL); if (ret != 0) { - ERROR_OUT(-6604, done); + ERROR_OUT(-7204, done); } done: @@ -10530,13 +10680,13 @@ int certext_test(void) tmp = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (tmp == NULL) - return -6700; + return -7300; /* load othercert.der (Cert signed by an authority) */ file = XFOPEN(otherCertDerFile, "rb"); if (!file) { XFREE(tmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); - return -6701; + return -7301; } bytes = XFREAD(tmp, 1, FOURK_BUF, file); @@ -10546,34 +10696,34 @@ int certext_test(void) ret = ParseCert(&cert, CERT_TYPE, NO_VERIFY, 0); if (ret != 0) - return -6702; + return -7302; /* check the SKID from a RSA certificate */ if (XMEMCMP(skid_rsa, cert.extSubjKeyId, sizeof(cert.extSubjKeyId))) - return -6703; + return -7303; /* check the AKID from an RSA certificate */ if (XMEMCMP(akid_rsa, cert.extAuthKeyId, sizeof(cert.extAuthKeyId))) - return -6704; + return -7304; /* check the Key Usage from an RSA certificate */ if (!cert.extKeyUsageSet) - return -6705; + return -7305; if (cert.extKeyUsage != (KEYUSE_KEY_ENCIPHER|KEYUSE_KEY_AGREE)) - return -6706; + return -7306; /* check the CA Basic Constraints from an RSA certificate */ if (cert.isCA) - return -6707; + return -7307; #ifndef WOLFSSL_SEP /* test only if not using SEP policies */ /* check the Certificate Policies Id */ if (cert.extCertPoliciesNb != 1) - return -6708; + return -7308; if (strncmp(cert.extCertPolicies[0], "2.16.840.1.101.3.4.1.42", 23)) - return -6709; + return -7309; #endif FreeDecodedCert(&cert); @@ -10583,7 +10733,7 @@ int certext_test(void) file = XFOPEN(certEccDerFile, "rb"); if (!file) { XFREE(tmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); - return -6710; + return -7310; } bytes = XFREAD(tmp, 1, FOURK_BUF, file); @@ -10593,35 +10743,35 @@ int certext_test(void) ret = ParseCert(&cert, CERT_TYPE, NO_VERIFY, 0); if (ret != 0) - return -6711; + return -7311; /* check the SKID from a ECC certificate - generated dynamically */ /* check the AKID from an ECC certificate */ if (XMEMCMP(akid_ecc, cert.extAuthKeyId, sizeof(cert.extAuthKeyId))) - return -6712; + return -7312; /* check the Key Usage from an ECC certificate */ if (!cert.extKeyUsageSet) - return -6713; + return -7313; if (cert.extKeyUsage != (KEYUSE_DIGITAL_SIG|KEYUSE_CONTENT_COMMIT)) - return -6714; + return -7314; /* check the CA Basic Constraints from an ECC certificate */ if (cert.isCA) - return -6715; + return -7315; #ifndef WOLFSSL_SEP /* test only if not using SEP policies */ /* check the Certificate Policies Id */ if (cert.extCertPoliciesNb != 2) - return -6716; + return -7316; if (strncmp(cert.extCertPolicies[0], "2.4.589440.587.101.2.1.9632587.1", 32)) - return -6717; + return -7317; if (strncmp(cert.extCertPolicies[1], "1.2.13025.489.1.113549", 22)) - return -6718; + return -7318; #endif FreeDecodedCert(&cert); @@ -10631,7 +10781,7 @@ int certext_test(void) file = XFOPEN(certDerFile, "rb"); if (!file) { XFREE(tmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); - return -6719; + return -7319; } bytes = XFREAD(tmp, 1, FOURK_BUF, file); @@ -10641,37 +10791,37 @@ int certext_test(void) ret = ParseCert(&cert, CERT_TYPE, NO_VERIFY, 0); if (ret != 0) - return -6720; + return -7320; /* check the SKID from a CA certificate */ if (XMEMCMP(kid_ca, cert.extSubjKeyId, sizeof(cert.extSubjKeyId))) - return -6721; + return -7321; /* check the AKID from an CA certificate */ if (XMEMCMP(kid_ca, cert.extAuthKeyId, sizeof(cert.extAuthKeyId))) - return -6722; + return -7322; /* check the Key Usage from CA certificate */ if (!cert.extKeyUsageSet) - return -6723; + return -7323; if (cert.extKeyUsage != (KEYUSE_KEY_CERT_SIGN|KEYUSE_CRL_SIGN)) - return -6724; + return -7324; /* check the CA Basic Constraints CA certificate */ if (!cert.isCA) - return -6725; + return -7325; #ifndef WOLFSSL_SEP /* test only if not using SEP policies */ /* check the Certificate Policies Id */ if (cert.extCertPoliciesNb != 2) - return -6726; + return -7326; if (strncmp(cert.extCertPolicies[0], "2.16.840.1.101.3.4.1.42", 23)) - return -6727; + return -7327; if (strncmp(cert.extCertPolicies[1], "1.2.840.113549.1.9.16.6.5", 25)) - return -6728; + return -7328; #endif FreeDecodedCert(&cert); @@ -10694,7 +10844,7 @@ int decodedCertCache_test(void) derSz = FOURK_BUF; der = XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (der == NULL) - ret = -1; + ret = -7400; if (ret == 0) { /* load cert.der */ @@ -10704,12 +10854,12 @@ int decodedCertCache_test(void) XFCLOSE(file); } else - ret = -1; + ret = -7401; } if (ret == 0) { if (wc_InitCert(&cert)) { - ret = -1; + ret = -7402; } } @@ -10719,75 +10869,75 @@ int decodedCertCache_test(void) if (ret == 0) { if(wc_SetSubjectBuffer(NULL, der, derSz) != BAD_FUNC_ARG) - ret = -1; + ret = -7403; } if (ret == 0) { if (wc_SetSubjectRaw(&cert, der, derSz) != 0) - ret = -1; + ret = -7404; } if (ret == 0) { if(wc_SetSubjectRaw(NULL, der, derSz) != BAD_FUNC_ARG) - ret = -1; + ret = -7405; } if (ret == 0) { if(wc_SetIssuerBuffer(&cert, der, derSz) != 0) - ret = -1; + ret = -7406; } if (ret == 0) { if(wc_SetIssuerBuffer(NULL, der, derSz) != BAD_FUNC_ARG) - ret = -1; + ret = -7407; } if (ret == 0) { if(wc_SetIssuerRaw(&cert, der, derSz) != 0) - ret = -1; + ret = -7408; } if (ret == 0) { if(wc_SetIssuerRaw(NULL, der, derSz) != BAD_FUNC_ARG) - ret = -1; + ret = -7409; } #ifdef WOLFSSL_ALT_NAMES if (ret == 0) { if(wc_SetAltNamesBuffer(&cert, der, derSz) != 0) - ret = -1; + ret = -7410; } if (ret == 0) { if(wc_SetAltNamesBuffer(NULL, der, derSz) != BAD_FUNC_ARG) - ret = -1; + ret = -7411; } if (ret == 0) { if(wc_SetDatesBuffer(&cert, der, derSz) != 0) - ret = -1; + ret = -7412; } if (ret == 0) { if(wc_SetDatesBuffer(NULL, der, derSz) != BAD_FUNC_ARG) - ret = -1; + ret = -7413; } #endif if (ret == 0) { if(wc_SetAuthKeyIdFromCert(&cert, der, derSz) != 0) - ret = -1; + ret = -7414; } if (ret == 0) { if(wc_SetAuthKeyIdFromCert(NULL, der, derSz) != BAD_FUNC_ARG) - ret = -1; + ret = -7415; } wc_SetCert_Free(&cert); if (ret == 0) { if(cert.decodedCert != NULL) - ret = -1; + ret = -7416; } XFREE(der, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); @@ -10818,7 +10968,7 @@ static int rsa_flatten_test(RsaKey* key) #else if (ret != BAD_FUNC_ARG) #endif - return -6729; + return -7417; ret = wc_RsaFlattenPublicKey(key, NULL, &eSz, n, &nSz); #ifdef HAVE_USER_RSA /* Implementation using IPP Libraries returns: @@ -10828,7 +10978,7 @@ static int rsa_flatten_test(RsaKey* key) #else if (ret != BAD_FUNC_ARG) #endif - return -6730; + return -7418; ret = wc_RsaFlattenPublicKey(key, e, NULL, n, &nSz); #ifdef HAVE_USER_RSA /* Implementation using IPP Libraries returns: @@ -10838,7 +10988,7 @@ static int rsa_flatten_test(RsaKey* key) #else if (ret != BAD_FUNC_ARG) #endif - return -6731; + return -7419; ret = wc_RsaFlattenPublicKey(key, e, &eSz, NULL, &nSz); #ifdef HAVE_USER_RSA /* Implementation using IPP Libraries returns: @@ -10848,7 +10998,7 @@ static int rsa_flatten_test(RsaKey* key) #else if (ret != BAD_FUNC_ARG) #endif - return -6732; + return -7420; ret = wc_RsaFlattenPublicKey(key, e, &eSz, n, NULL); #ifdef HAVE_USER_RSA /* Implementation using IPP Libraries returns: @@ -10858,10 +11008,10 @@ static int rsa_flatten_test(RsaKey* key) #else if (ret != BAD_FUNC_ARG) #endif - return -6733; + return -7421; ret = wc_RsaFlattenPublicKey(key, e, &eSz, n, &nSz); if (ret != 0) - return -6734; + return -7422; eSz = 0; ret = wc_RsaFlattenPublicKey(key, e, &eSz, n, &nSz); #ifdef HAVE_USER_RSA @@ -10875,7 +11025,7 @@ static int rsa_flatten_test(RsaKey* key) #else if (ret != RSA_BUFFER_E) #endif - return -6735; + return -7423; eSz = sizeof(e); nSz = 0; ret = wc_RsaFlattenPublicKey(key, e, &eSz, n, &nSz); @@ -10887,7 +11037,7 @@ static int rsa_flatten_test(RsaKey* key) #else if (ret != RSA_BUFFER_E) #endif - return -6736; + return -7424; return 0; } @@ -10912,59 +11062,59 @@ static int rsa_export_key_test(RsaKey* key) ret = wc_RsaExportKey(NULL, e, &eSz, n, &nSz, d, &dSz, p, &pSz, q, &qSz); if (ret != BAD_FUNC_ARG) - return -6737; + return -7425; ret = wc_RsaExportKey(key, NULL, &eSz, n, &nSz, d, &dSz, p, &pSz, q, &qSz); if (ret != BAD_FUNC_ARG) - return -6738; + return -7426; ret = wc_RsaExportKey(key, e, NULL, n, &nSz, d, &dSz, p, &pSz, q, &qSz); if (ret != BAD_FUNC_ARG) - return -6739; + return -7427; ret = wc_RsaExportKey(key, e, &eSz, NULL, &nSz, d, &dSz, p, &pSz, q, &qSz); if (ret != BAD_FUNC_ARG) - return -6740; + return -7428; ret = wc_RsaExportKey(key, e, &eSz, n, NULL, d, &dSz, p, &pSz, q, &qSz); if (ret != BAD_FUNC_ARG) - return -6741; + return -7429; ret = wc_RsaExportKey(key, e, &eSz, n, &nSz, NULL, &dSz, p, &pSz, q, &qSz); if (ret != BAD_FUNC_ARG) - return -6742; + return -7430; ret = wc_RsaExportKey(key, e, &eSz, n, &nSz, d, NULL, p, &pSz, q, &qSz); if (ret != BAD_FUNC_ARG) - return -6743; + return -7431; ret = wc_RsaExportKey(key, e, &eSz, n, &nSz, d, &dSz, NULL, &pSz, q, &qSz); if (ret != BAD_FUNC_ARG) - return -6744; + return -7432; ret = wc_RsaExportKey(key, e, &eSz, n, &nSz, d, &dSz, p, NULL, q, &qSz); if (ret != BAD_FUNC_ARG) - return -6745; + return -7433; ret = wc_RsaExportKey(key, e, &eSz, n, &nSz, d, &dSz, p, &pSz, NULL, &qSz); if (ret != BAD_FUNC_ARG) - return -6746; + return -7434; ret = wc_RsaExportKey(key, e, &eSz, n, &nSz, d, &dSz, p, &pSz, q, NULL); if (ret != BAD_FUNC_ARG) - return -6747; + return -7435; ret = wc_RsaExportKey(key, e, &zero, n, &nSz, d, &dSz, p, &pSz, q, &qSz); if (ret != RSA_BUFFER_E) - return -6748; + return -7436; ret = wc_RsaExportKey(key, e, &eSz, n, &zero, d, &dSz, p, &pSz, q, &qSz); if (ret != RSA_BUFFER_E) - return -6749; + return -7437; #ifndef WOLFSSL_RSA_PUBLIC_ONLY ret = wc_RsaExportKey(key, e, &eSz, n, &nSz, d, &zero, p, &pSz, q, &qSz); if (ret != RSA_BUFFER_E) - return -6750; + return -7438; ret = wc_RsaExportKey(key, e, &eSz, n, &nSz, d, &dSz, p, &zero, q, &qSz); if (ret != RSA_BUFFER_E) - return -6751; + return -7439; ret = wc_RsaExportKey(key, e, &eSz, n, &nSz, d, &dSz, p, &pSz, q, &zero); if (ret != RSA_BUFFER_E) - return -6752; + return -7440; #endif /* WOLFSSL_RSA_PUBLIC_ONLY */ ret = wc_RsaExportKey(key, e, &eSz, n, &nSz, d, &dSz, p, &pSz, q, &qSz); if (ret != 0) - return -6753; + return -7441; return 0; } @@ -10998,36 +11148,36 @@ static int rsa_sig_test(RsaKey* key, word32 keyLen, int modLen, WC_RNG* rng) /* Parameter Validation testing. */ ret = wc_SignatureGetSize(WC_SIGNATURE_TYPE_NONE, key, keyLen); if (ret != BAD_FUNC_ARG) - return -6754; + return -7442; ret = wc_SignatureGetSize(WC_SIGNATURE_TYPE_RSA, key, 0); if (ret != BAD_FUNC_ARG) - return -6755; + return -7443; sigSz = (word32)modLen; ret = wc_SignatureGenerate(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, NULL, inLen, out, &sigSz, key, keyLen, rng); if (ret != BAD_FUNC_ARG) - return -6756; + return -7444; ret = wc_SignatureGenerate(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, in, 0, out, &sigSz, key, keyLen, rng); if (ret != BAD_FUNC_ARG) - return -6757; + return -7445; ret = wc_SignatureGenerate(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, in, inLen, NULL, &sigSz, key, keyLen, rng); if (ret != BAD_FUNC_ARG) - return -6758; + return -7446; ret = wc_SignatureGenerate(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, in, inLen, out, NULL, key, keyLen, rng); if (ret != BAD_FUNC_ARG) - return -6759; + return -7447; ret = wc_SignatureGenerate(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, in, inLen, out, &sigSz, NULL, keyLen, rng); if (ret != BAD_FUNC_ARG) - return -6760; + return -7448; ret = wc_SignatureGenerate(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, in, inLen, out, &sigSz, key, 0, rng); if (ret != BAD_FUNC_ARG) - return -6761; + return -7449; ret = wc_SignatureGenerate(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, in, inLen, out, &sigSz, key, keyLen, NULL); #ifdef HAVE_USER_RSA @@ -11053,51 +11203,51 @@ static int rsa_sig_test(RsaKey* key, word32 keyLen, int modLen, WC_RNG* rng) #else if (ret != MISSING_RNG_E) #endif - return -6762; + return -7450; sigSz = 0; ret = wc_SignatureGenerate(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, in, inLen, out, &sigSz, key, keyLen, rng); if (ret != BAD_FUNC_ARG) - return -6763; + return -7451; ret = wc_SignatureVerify(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, NULL, inLen, out, (word32)modLen, key, keyLen); if (ret != BAD_FUNC_ARG) - return -6764; + return -7452; ret = wc_SignatureVerify(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, in, 0, out, (word32)modLen, key, keyLen); if (ret != BAD_FUNC_ARG) - return -6765; + return -7453; ret = wc_SignatureVerify(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, in, inLen, NULL, (word32)modLen, key, keyLen); if (ret != BAD_FUNC_ARG) - return -6766; + return -7454; ret = wc_SignatureVerify(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, in, inLen, out, 0, key, keyLen); if (ret != BAD_FUNC_ARG) - return -6767; + return -7455; ret = wc_SignatureVerify(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, in, inLen, out, (word32)modLen, NULL, keyLen); if (ret != BAD_FUNC_ARG) - return -6768; + return -7456; ret = wc_SignatureVerify(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, in, inLen, out, (word32)modLen, key, 0); if (ret != BAD_FUNC_ARG) - return -6769; + return -7457; #ifndef HAVE_ECC ret = wc_SignatureGetSize(WC_SIGNATURE_TYPE_ECC, key, keyLen); if (ret != SIG_TYPE_E) - return -6770; + return -7458; #endif /* Use APIs. */ ret = wc_SignatureGetSize(WC_SIGNATURE_TYPE_RSA, key, keyLen); if (ret != modLen) - return -6771; + return -7459; ret = wc_SignatureGetSize(WC_SIGNATURE_TYPE_RSA_W_ENC, key, keyLen); if (ret != modLen) - return -6772; + return -7460; sigSz = (word32)ret; #ifndef WOLFSSL_RSA_PUBLIC_ONLY @@ -11105,52 +11255,52 @@ static int rsa_sig_test(RsaKey* key, word32 keyLen, int modLen, WC_RNG* rng) ret = wc_SignatureGenerate(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, in, inLen, out, &sigSz, key, keyLen, rng); if (ret != 0) - return -6773; + return -7461; ret = wc_SignatureVerify(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, in, inLen, out, (word32)modLen, key, keyLen); if (ret != 0) - return -6774; + return -7462; sigSz = (word32)sizeof(out); ret = wc_SignatureGenerate(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA_W_ENC, in, inLen, out, &sigSz, key, keyLen, rng); if (ret != 0) - return -6775; + return -7463; ret = wc_SignatureVerify(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA_W_ENC, in, inLen, out, (word32)modLen, key, keyLen); if (ret != 0) - return -6776; + return -7464; /* Wrong signature type. */ ret = wc_SignatureVerify(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, in, inLen, out, (word32)modLen, key, keyLen); if (ret == 0) - return -6777; + return -7465; /* check hash functions */ sigSz = (word32)sizeof(out); ret = wc_SignatureGenerateHash(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, hash, (int)sizeof(hash), out, &sigSz, key, keyLen, rng); if (ret != 0) - return -6778; + return -7466; ret = wc_SignatureVerifyHash(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA, hash, (int)sizeof(hash), out, (word32)modLen, key, keyLen); if (ret != 0) - return -6779; + return -7467; sigSz = (word32)sizeof(out); ret = wc_SignatureGenerateHash(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA_W_ENC, hashEnc, (int)sizeof(hashEnc), out, &sigSz, key, keyLen, rng); if (ret != 0) - return -6780; + return -7468; ret = wc_SignatureVerifyHash(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_RSA_W_ENC, hashEnc, (int)sizeof(hashEnc), out, (word32)modLen, key, keyLen); if (ret != 0) - return -6781; + return -7469; #else (void)hash; (void)hashEnc; @@ -11285,70 +11435,70 @@ static int rsa_decode_test(RsaKey* keyPub) ret = wc_InitRsaKey(keyPub, NULL); if (ret != 0) - return -6782; + return -7470; /* Parameter Validation testing. */ ret = wc_RsaPublicKeyDecodeRaw(NULL, sizeof(n), e, sizeof(e), keyPub); if (ret != BAD_FUNC_ARG) { - ret = -6783; + ret = -7471; goto done; } ret = wc_RsaPublicKeyDecodeRaw(n, sizeof(n), NULL, sizeof(e), keyPub); if (ret != BAD_FUNC_ARG) { - ret = -6784; + ret = -7472; goto done; } ret = wc_RsaPublicKeyDecodeRaw(n, sizeof(n), e, sizeof(e), NULL); if (ret != BAD_FUNC_ARG) { - ret = -6785; + ret = -7473; goto done; } /* TODO: probably should fail when length is -1! */ ret = wc_RsaPublicKeyDecodeRaw(n, (word32)-1, e, sizeof(e), keyPub); if (ret != 0) { - ret = -6786; + ret = -7474; goto done; } wc_FreeRsaKey(keyPub); ret = wc_InitRsaKey(keyPub, NULL); if (ret != 0) - return -6787; + return -7475; ret = wc_RsaPublicKeyDecodeRaw(n, sizeof(n), e, (word32)-1, keyPub); if (ret != 0) { - ret = -6788; + ret = -7476; goto done; } wc_FreeRsaKey(keyPub); ret = wc_InitRsaKey(keyPub, NULL); if (ret != 0) - return -6789; + return -7477; /* Use API. */ ret = wc_RsaPublicKeyDecodeRaw(n, sizeof(n), e, sizeof(e), keyPub); if (ret != 0) { - ret = -6790; + ret = -7478; goto done; } wc_FreeRsaKey(keyPub); ret = wc_InitRsaKey(keyPub, NULL); if (ret != 0) - return -6791; + return -7479; /* Parameter Validation testing. */ inSz = sizeof(good); ret = wc_RsaPublicKeyDecode(NULL, &inOutIdx, keyPub, inSz); if (ret != BAD_FUNC_ARG) { - ret = -6792; + ret = -7480; goto done; } ret = wc_RsaPublicKeyDecode(good, NULL, keyPub, inSz); if (ret != BAD_FUNC_ARG) { - ret = -6793; + ret = -7481; goto done; } ret = wc_RsaPublicKeyDecode(good, &inOutIdx, NULL, inSz); if (ret != BAD_FUNC_ARG) { - ret = -6794; + ret = -7482; goto done; } @@ -11357,14 +11507,14 @@ static int rsa_decode_test(RsaKey* keyPub) inSz = sizeof(good) - inOutIdx; ret = wc_RsaPublicKeyDecode(good, &inOutIdx, keyPub, inSz); if (ret != ASN_PARSE_E) { - ret = -6795; + ret = -7483; goto done; } inOutIdx = 2; inSz = sizeof(goodAlgId) - inOutIdx; ret = wc_RsaPublicKeyDecode(goodAlgId, &inOutIdx, keyPub, inSz); if (ret != ASN_PARSE_E) { - ret = -6796; + ret = -7484; goto done; } inOutIdx = 2; @@ -11376,7 +11526,7 @@ static int rsa_decode_test(RsaKey* keyPub) if (ret != ASN_RSA_KEY_E) #endif { - ret = -6797; + ret = -7485; goto done; } /* Try different bad data. */ @@ -11384,49 +11534,49 @@ static int rsa_decode_test(RsaKey* keyPub) inOutIdx = 0; ret = wc_RsaPublicKeyDecode(badAlgIdNull, &inOutIdx, keyPub, inSz); if (ret != ASN_EXPECT_0_E) { - ret = -6798; + ret = -7486; goto done; } inSz = sizeof(badNotBitString); inOutIdx = 0; ret = wc_RsaPublicKeyDecode(badNotBitString, &inOutIdx, keyPub, inSz); if (ret != ASN_BITSTR_E) { - ret = -6799; + ret = -7487; goto done; } inSz = sizeof(badBitStringLen); inOutIdx = 0; ret = wc_RsaPublicKeyDecode(badBitStringLen, &inOutIdx, keyPub, inSz); if (ret != ASN_PARSE_E) { - ret = -6800; + ret = -7488; goto done; } inSz = sizeof(badNoSeq); inOutIdx = 0; ret = wc_RsaPublicKeyDecode(badNoSeq, &inOutIdx, keyPub, inSz); if (ret != ASN_PARSE_E) { - ret = -6801; + ret = -7489; goto done; } inSz = sizeof(badNoObj); inOutIdx = 0; ret = wc_RsaPublicKeyDecode(badNoObj, &inOutIdx, keyPub, inSz); if (ret != ASN_PARSE_E) { - ret = -6802; + ret = -7490; goto done; } inSz = sizeof(badIntN); inOutIdx = 0; ret = wc_RsaPublicKeyDecode(badIntN, &inOutIdx, keyPub, inSz); if (ret != ASN_RSA_KEY_E) { - ret = -6803; + ret = -7491; goto done; } inSz = sizeof(badNotIntE); inOutIdx = 0; ret = wc_RsaPublicKeyDecode(badNotIntE, &inOutIdx, keyPub, inSz); if (ret != ASN_RSA_KEY_E) { - ret = -6804; + ret = -7492; goto done; } /* TODO: Shouldn't pass as the sequence length is too small. */ @@ -11434,69 +11584,69 @@ static int rsa_decode_test(RsaKey* keyPub) inOutIdx = 0; ret = wc_RsaPublicKeyDecode(badLength, &inOutIdx, keyPub, inSz); if (ret != 0) { - ret = -6805; + ret = -7493; goto done; } /* TODO: Shouldn't ignore object id's data. */ wc_FreeRsaKey(keyPub); ret = wc_InitRsaKey(keyPub, NULL); if (ret != 0) - return -6806; + return -7494; inSz = sizeof(badBitStrNoZero); inOutIdx = 0; ret = wc_RsaPublicKeyDecode(badBitStrNoZero, &inOutIdx, keyPub, inSz); if (ret != ASN_EXPECT_0_E) { - ret = -6807; + ret = -7495; goto done; } wc_FreeRsaKey(keyPub); ret = wc_InitRsaKey(keyPub, NULL); if (ret != 0) - return -6808; + return -7496; /* Valid data cases. */ inSz = sizeof(good); inOutIdx = 0; ret = wc_RsaPublicKeyDecode(good, &inOutIdx, keyPub, inSz); if (ret != 0) { - ret = -6809; + ret = -7497; goto done; } if (inOutIdx != inSz) { - ret = -6810; + ret = -7498; goto done; } wc_FreeRsaKey(keyPub); ret = wc_InitRsaKey(keyPub, NULL); if (ret != 0) - return -6811; + return -7499; inSz = sizeof(goodAlgId); inOutIdx = 0; ret = wc_RsaPublicKeyDecode(goodAlgId, &inOutIdx, keyPub, inSz); if (ret != 0) { - ret = -6812; + ret = -7500; goto done; } if (inOutIdx != inSz) { - ret = -6813; + ret = -7501; goto done; } wc_FreeRsaKey(keyPub); ret = wc_InitRsaKey(keyPub, NULL); if (ret != 0) - return -6814; + return -7502; inSz = sizeof(goodAlgIdNull); inOutIdx = 0; ret = wc_RsaPublicKeyDecode(goodAlgIdNull, &inOutIdx, keyPub, inSz); if (ret != 0) { - ret = -6815; + ret = -7503; goto done; } if (inOutIdx != inSz) { - ret = -6816; + ret = -7504; goto done; } @@ -11562,7 +11712,7 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key) /* Calculate hash of message. */ ret = wc_Hash(hash[j], in, inLen, digest, sizeof(digest)); if (ret != 0) - ERROR_OUT(-6817, exit_rsa_pss); + ERROR_OUT(-7505, exit_rsa_pss); digestSz = wc_HashGetDigestSize(hash[j]); for (i = 0; i < (int)(sizeof(mgf)/sizeof(*mgf)); i++) { @@ -11578,7 +11728,7 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key) } } while (ret == WC_PENDING_E); if (ret <= 0) - ERROR_OUT(-6818, exit_rsa_pss); + ERROR_OUT(-7506, exit_rsa_pss); outSz = ret; XMEMCPY(sig, out, outSz); @@ -11596,7 +11746,7 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key) } } while (ret == WC_PENDING_E); if (ret <= 0) - ERROR_OUT(-6819, exit_rsa_pss); + ERROR_OUT(-7507, exit_rsa_pss); plainSz = ret; TEST_SLEEP(); @@ -11608,7 +11758,7 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key) hash[j], -1, wc_RsaEncryptSize(key)*8); #endif if (ret != 0) - ERROR_OUT(-6820, exit_rsa_pss); + ERROR_OUT(-7508, exit_rsa_pss); #ifdef RSA_PSS_TEST_WRONG_PARAMS for (k = 0; k < (int)(sizeof(mgf)/sizeof(*mgf)); k++) { @@ -11629,7 +11779,7 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key) } } while (ret == WC_PENDING_E); if (ret >= 0) - ERROR_OUT(-6821, exit_rsa_pss); + ERROR_OUT(-7509, exit_rsa_pss); } } #endif @@ -11650,7 +11800,7 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key) } } while (ret == WC_PENDING_E); if (ret <= 0) - ERROR_OUT(-6822, exit_rsa_pss); + ERROR_OUT(-7510, exit_rsa_pss); outSz = ret; TEST_SLEEP(); @@ -11665,7 +11815,7 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key) } } while (ret == WC_PENDING_E); if (ret <= 0) - ERROR_OUT(-6823, exit_rsa_pss); + ERROR_OUT(-7511, exit_rsa_pss); plainSz = ret; TEST_SLEEP(); @@ -11685,7 +11835,7 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key) } } while (ret == WC_PENDING_E); if (ret != 0) - ERROR_OUT(-6824, exit_rsa_pss); + ERROR_OUT(-7512, exit_rsa_pss); XMEMCPY(sig, out, outSz); plain = NULL; @@ -11700,7 +11850,7 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key) } } while (ret == WC_PENDING_E); if (ret <= 0) - ERROR_OUT(-6825, exit_rsa_pss); + ERROR_OUT(-7513, exit_rsa_pss); plainSz = ret; TEST_SLEEP(); @@ -11712,7 +11862,7 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key) 0, 0); #endif if (ret != 0) - ERROR_OUT(-6826, exit_rsa_pss); + ERROR_OUT(-7514, exit_rsa_pss); /* Test bad salt lengths in various APIs. */ digestSz = wc_HashGetDigestSize(hash[0]); @@ -11733,7 +11883,7 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key) } } while (ret == WC_PENDING_E); if (ret != PSS_SALTLEN_E) - ERROR_OUT(-6827, exit_rsa_pss); + ERROR_OUT(-7515, exit_rsa_pss); do { #if defined(WOLFSSL_ASYNC_CRYPT) @@ -11746,7 +11896,7 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key) } } while (ret == WC_PENDING_E); if (ret != PSS_SALTLEN_E) - ERROR_OUT(-6828, exit_rsa_pss); + ERROR_OUT(-7516, exit_rsa_pss); TEST_SLEEP(); do { @@ -11760,7 +11910,7 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key) } } while (ret == WC_PENDING_E); if (ret != PSS_SALTLEN_E) - ERROR_OUT(-6829, exit_rsa_pss); + ERROR_OUT(-7517, exit_rsa_pss); TEST_SLEEP(); do { @@ -11774,7 +11924,7 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key) } } while (ret == WC_PENDING_E); if (ret != PSS_SALTLEN_E) - ERROR_OUT(-6830, exit_rsa_pss); + ERROR_OUT(-7518, exit_rsa_pss); TEST_SLEEP(); #ifndef WOLFSSL_PSS_SALT_LEN_DISCOVER @@ -11790,7 +11940,7 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key) len, 0); #endif if (ret != PSS_SALTLEN_E) - ERROR_OUT(-6831, exit_rsa_pss); + ERROR_OUT(-7519, exit_rsa_pss); #ifndef WOLFSSL_PSS_LONG_SALT len = digestSz + 1; #else @@ -11804,7 +11954,7 @@ static int rsa_pss_test(WC_RNG* rng, RsaKey* key) len, 0); #endif if (ret != PSS_SALTLEN_E) - ERROR_OUT(-6832, exit_rsa_pss); + ERROR_OUT(-7520, exit_rsa_pss); ret = 0; exit_rsa_pss: @@ -11857,7 +12007,7 @@ int rsa_no_pad_test(void) || out == NULL || plain == NULL #endif ) { - ERROR_OUT(-6900, exit_rsa_nopadding); + ERROR_OUT(-7600, exit_rsa_nopadding); } #ifdef USE_CERT_BUFFERS_1024 @@ -11873,23 +12023,23 @@ int rsa_no_pad_test(void) if (!file) { err_sys("can't open ./certs/client-key.der, " "Please run from wolfSSL home dir", -40); - ERROR_OUT(-6901, exit_rsa_nopadding); + ERROR_OUT(-7601, exit_rsa_nopadding); } bytes = XFREAD(tmp, 1, FOURK_BUF, file); XFCLOSE(file); #else /* No key to use. */ - ERROR_OUT(-6902, exit_rsa_nopadding); + ERROR_OUT(-7602, exit_rsa_nopadding); #endif /* USE_CERT_BUFFERS */ ret = wc_InitRsaKey_ex(&key, HEAP_HINT, devId); if (ret != 0) { - ERROR_OUT(-6903, exit_rsa_nopadding); + ERROR_OUT(-7603, exit_rsa_nopadding); } ret = wc_RsaPrivateKeyDecode(tmp, &idx, &key, (word32)bytes); if (ret != 0) { - ERROR_OUT(-6904, exit_rsa_nopadding); + ERROR_OUT(-7604, exit_rsa_nopadding); } /* after loading in key use tmp as the test buffer */ @@ -11900,7 +12050,7 @@ int rsa_no_pad_test(void) ret = wc_InitRng(&rng); #endif if (ret != 0) { - ERROR_OUT(-6905, exit_rsa_nopadding); + ERROR_OUT(-7605, exit_rsa_nopadding); } #ifndef WOLFSSL_RSA_VERIFY_ONLY @@ -11918,12 +12068,12 @@ int rsa_no_pad_test(void) } } while (ret == WC_PENDING_E); if (ret <= 0) { - ERROR_OUT(-6906, exit_rsa_nopadding); + ERROR_OUT(-7606, exit_rsa_nopadding); } /* encrypted result should not be the same as input */ if (XMEMCMP(out, tmp, inLen) == 0) { - ERROR_OUT(-6907, exit_rsa_nopadding); + ERROR_OUT(-7607, exit_rsa_nopadding); } TEST_SLEEP(); @@ -11938,11 +12088,11 @@ int rsa_no_pad_test(void) } } while (ret == WC_PENDING_E); if (ret <= 0) { - ERROR_OUT(-6908, exit_rsa_nopadding); + ERROR_OUT(-7608, exit_rsa_nopadding); } if (XMEMCMP(plain, tmp, inLen) != 0) { - ERROR_OUT(-6909, exit_rsa_nopadding); + ERROR_OUT(-7609, exit_rsa_nopadding); } TEST_SLEEP(); #endif @@ -11950,12 +12100,12 @@ int rsa_no_pad_test(void) #ifdef WC_RSA_BLINDING ret = wc_RsaSetRNG(NULL, &rng); if (ret != BAD_FUNC_ARG) { - ERROR_OUT(-6910, exit_rsa_nopadding); + ERROR_OUT(-7610, exit_rsa_nopadding); } ret = wc_RsaSetRNG(&key, &rng); if (ret < 0) { - ERROR_OUT(-6911, exit_rsa_nopadding); + ERROR_OUT(-7611, exit_rsa_nopadding); } #endif @@ -11971,7 +12121,7 @@ int rsa_no_pad_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-6912, exit_rsa_nopadding); + ERROR_OUT(-7612, exit_rsa_nopadding); } TEST_SLEEP(); #endif /* WOLFSSL_RSA_VERIFY_ONLY */ @@ -11987,11 +12137,11 @@ int rsa_no_pad_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-6913, exit_rsa_nopadding); + ERROR_OUT(-7613, exit_rsa_nopadding); } if (XMEMCMP(plain, tmp, inLen) != 0) { - ERROR_OUT(-6914, exit_rsa_nopadding); + ERROR_OUT(-7614, exit_rsa_nopadding); } TEST_SLEEP(); #endif /* WOLFSSL_RSA_PUBLIC_ONLY */ @@ -12000,25 +12150,25 @@ int rsa_no_pad_test(void) ret = wc_RsaDirect(out, outSz, plain, &plainSz, &key, -1, &rng); if (ret != BAD_FUNC_ARG) { - ERROR_OUT(-6915, exit_rsa_nopadding); + ERROR_OUT(-7615, exit_rsa_nopadding); } ret = wc_RsaDirect(out, outSz, plain, &plainSz, NULL, RSA_PUBLIC_DECRYPT, &rng); if (ret != BAD_FUNC_ARG) { - ERROR_OUT(-6916, exit_rsa_nopadding); + ERROR_OUT(-7616, exit_rsa_nopadding); } ret = wc_RsaDirect(out, outSz, NULL, &plainSz, &key, RSA_PUBLIC_DECRYPT, &rng); if (ret != LENGTH_ONLY_E || plainSz != inLen) { - ERROR_OUT(-6917, exit_rsa_nopadding); + ERROR_OUT(-7617, exit_rsa_nopadding); } ret = wc_RsaDirect(out, outSz - 10, plain, &plainSz, &key, RSA_PUBLIC_DECRYPT, &rng); if (ret != BAD_FUNC_ARG) { - ERROR_OUT(-6918, exit_rsa_nopadding); + ERROR_OUT(-7618, exit_rsa_nopadding); } /* if making it to this point of code without hitting an ERROR_OUT then @@ -12065,20 +12215,20 @@ static int rsa_certgen_test(RsaKey* key, RsaKey* keypub, WC_RNG* rng, byte* tmp) der = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (der == NULL) { - ERROR_OUT(-6919, exit_rsa); + ERROR_OUT(-7619, exit_rsa); } pem = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT,DYNAMIC_TYPE_TMP_BUFFER); if (pem == NULL) { - ERROR_OUT(-6920, exit_rsa); + ERROR_OUT(-7620, exit_rsa); } myCert = (Cert*)XMALLOC(sizeof(Cert), HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (myCert == NULL) { - ERROR_OUT(-6921, exit_rsa); + ERROR_OUT(-7621, exit_rsa); } /* self signed */ if (wc_InitCert(myCert)) { - ERROR_OUT(-6922, exit_rsa); + ERROR_OUT(-7622, exit_rsa); } XMEMCPY(&myCert->subject, &certDefaultName, sizeof(CertName)); @@ -12102,24 +12252,24 @@ static int rsa_certgen_test(RsaKey* key, RsaKey* keypub, WC_RNG* rng, byte* tmp) /* add SKID from the Public Key */ if (wc_SetSubjectKeyIdFromPublicKey(myCert, keypub, NULL) != 0) { - ERROR_OUT(-6923, exit_rsa); + ERROR_OUT(-7623, exit_rsa); } /* add AKID from the Public Key */ if (wc_SetAuthKeyIdFromPublicKey(myCert, keypub, NULL) != 0) { - ERROR_OUT(-6924, exit_rsa); + ERROR_OUT(-7624, exit_rsa); } /* add Key Usage */ if (wc_SetKeyUsage(myCert,"cRLSign,keyCertSign") != 0) { - ERROR_OUT(-6925, exit_rsa); + ERROR_OUT(-7625, exit_rsa); } #ifdef WOLFSSL_EKU_OID { const char unique[] = "2.16.840.1.111111.100.1.10.1"; if (wc_SetExtKeyUsageOID(myCert, unique, sizeof(unique), 0, HEAP_HINT) != 0) { - ERROR_OUT(-6926, exit_rsa); + ERROR_OUT(-7626, exit_rsa); } } #endif /* WOLFSSL_EKU_OID */ @@ -12135,7 +12285,7 @@ static int rsa_certgen_test(RsaKey* key, RsaKey* keypub, WC_RNG* rng, byte* tmp) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-6927, exit_rsa); + ERROR_OUT(-7627, exit_rsa); } certSz = ret; @@ -12144,7 +12294,7 @@ static int rsa_certgen_test(RsaKey* key, RsaKey* keypub, WC_RNG* rng, byte* tmp) ret = ParseCert(&decode, CERT_TYPE, NO_VERIFY, 0); if (ret != 0) { FreeDecodedCert(&decode); - ERROR_OUT(-6928, exit_rsa); + ERROR_OUT(-7628, exit_rsa); } FreeDecodedCert(&decode); #endif @@ -12157,7 +12307,7 @@ static int rsa_certgen_test(RsaKey* key, RsaKey* keypub, WC_RNG* rng, byte* tmp) /* Setup Certificate */ if (wc_InitCert(myCert)) { - ERROR_OUT(-6929, exit_rsa); + ERROR_OUT(-7629, exit_rsa); } #ifdef WOLFSSL_ALT_NAMES @@ -12171,7 +12321,7 @@ static int rsa_certgen_test(RsaKey* key, RsaKey* keypub, WC_RNG* rng, byte* tmp) #else file3 = XFOPEN(rsaCaCertDerFile, "rb"); if (!file3) { - ERROR_OUT(-6930, exit_rsa); + ERROR_OUT(-7630, exit_rsa); } bytes3 = XFREAD(tmp, 1, FOURK_BUF, file3); XFCLOSE(file3); @@ -12181,25 +12331,25 @@ static int rsa_certgen_test(RsaKey* key, RsaKey* keypub, WC_RNG* rng, byte* tmp) !defined(USE_CERT_BUFFERS_2048) && !defined(NO_ASN) ret = wc_SetAltNames(myCert, rsaCaCertFile); if (ret != 0) { - ERROR_OUT(-6931, exit_rsa); + ERROR_OUT(-7631, exit_rsa); } #endif /* get alt names from der */ ret = wc_SetAltNamesBuffer(myCert, tmp, (int)bytes3); if (ret != 0) { - ERROR_OUT(-6932, exit_rsa); + ERROR_OUT(-7632, exit_rsa); } /* get dates from der */ ret = wc_SetDatesBuffer(myCert, tmp, (int)bytes3); if (ret != 0) { - ERROR_OUT(-6933, exit_rsa); + ERROR_OUT(-7633, exit_rsa); } #ifndef NO_ASN_TIME ret = wc_GetCertDates(myCert, &beforeTime, &afterTime); if (ret < 0) { - ERROR_OUT(-6934, exit_rsa); + ERROR_OUT(-7634, exit_rsa); } #endif #endif /* WOLFSSL_ALT_NAMES */ @@ -12214,7 +12364,7 @@ static int rsa_certgen_test(RsaKey* key, RsaKey* keypub, WC_RNG* rng, byte* tmp) #else file3 = XFOPEN(rsaCaKeyFile, "rb"); if (!file3) { - ERROR_OUT(-6935, exit_rsa); + ERROR_OUT(-7635, exit_rsa); } bytes3 = XFREAD(tmp, 1, FOURK_BUF, file3); @@ -12223,11 +12373,11 @@ static int rsa_certgen_test(RsaKey* key, RsaKey* keypub, WC_RNG* rng, byte* tmp) ret = wc_InitRsaKey(&caKey, HEAP_HINT); if (ret != 0) { - ERROR_OUT(-6936, exit_rsa); + ERROR_OUT(-7636, exit_rsa); } ret = wc_RsaPrivateKeyDecode(tmp, &idx3, &caKey, (word32)bytes3); if (ret != 0) { - ERROR_OUT(-6937, exit_rsa); + ERROR_OUT(-7637, exit_rsa); } #ifndef NO_SHA256 @@ -12246,7 +12396,7 @@ static int rsa_certgen_test(RsaKey* key, RsaKey* keypub, WC_RNG* rng, byte* tmp) /* add SKID from the Public Key */ if (wc_SetSubjectKeyIdFromPublicKey(myCert, key, NULL) != 0) { - ERROR_OUT(-6938, exit_rsa); + ERROR_OUT(-7638, exit_rsa); } /* add AKID from the CA certificate */ @@ -12260,12 +12410,12 @@ static int rsa_certgen_test(RsaKey* key, RsaKey* keypub, WC_RNG* rng, byte* tmp) ret = wc_SetAuthKeyId(myCert, rsaCaCertFile); #endif if (ret != 0) { - ERROR_OUT(-6939, exit_rsa); + ERROR_OUT(-7639, exit_rsa); } /* add Key Usage */ if (wc_SetKeyUsage(myCert,"keyEncipherment,keyAgreement") != 0) { - ERROR_OUT(-6940, exit_rsa); + ERROR_OUT(-7640, exit_rsa); } #endif /* WOLFSSL_CERT_EXT */ @@ -12279,12 +12429,12 @@ static int rsa_certgen_test(RsaKey* key, RsaKey* keypub, WC_RNG* rng, byte* tmp) ret = wc_SetIssuer(myCert, rsaCaCertFile); #endif if (ret < 0) { - ERROR_OUT(-6941, exit_rsa); + ERROR_OUT(-7641, exit_rsa); } certSz = wc_MakeCert(myCert, der, FOURK_BUF, key, NULL, rng); if (certSz < 0) { - ERROR_OUT(-6942, exit_rsa); + ERROR_OUT(-7642, exit_rsa); } ret = 0; @@ -12298,7 +12448,7 @@ static int rsa_certgen_test(RsaKey* key, RsaKey* keypub, WC_RNG* rng, byte* tmp) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-6943, exit_rsa); + ERROR_OUT(-7643, exit_rsa); } certSz = ret; @@ -12307,7 +12457,7 @@ static int rsa_certgen_test(RsaKey* key, RsaKey* keypub, WC_RNG* rng, byte* tmp) ret = ParseCert(&decode, CERT_TYPE, NO_VERIFY, 0); if (ret != 0) { FreeDecodedCert(&decode); - ERROR_OUT(-6944, exit_rsa); + ERROR_OUT(-7644, exit_rsa); } FreeDecodedCert(&decode); #endif @@ -12357,15 +12507,15 @@ static int rsa_ecc_certgen_test(WC_RNG* rng, byte* tmp) der = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (der == NULL) { - ERROR_OUT(-6945, exit_rsa); + ERROR_OUT(-7645, exit_rsa); } pem = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (pem == NULL) { - ERROR_OUT(-6946, exit_rsa); + ERROR_OUT(-7646, exit_rsa); } myCert = (Cert*)XMALLOC(sizeof(Cert), HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (myCert == NULL) { - ERROR_OUT(-6947, exit_rsa); + ERROR_OUT(-7647, exit_rsa); } /* Get CA Key */ @@ -12378,7 +12528,7 @@ static int rsa_ecc_certgen_test(WC_RNG* rng, byte* tmp) #else file3 = XFOPEN(rsaCaKeyFile, "rb"); if (!file3) { - ERROR_OUT(-6948, exit_rsa); + ERROR_OUT(-7648, exit_rsa); } bytes3 = XFREAD(tmp, 1, FOURK_BUF, file3); @@ -12387,11 +12537,11 @@ static int rsa_ecc_certgen_test(WC_RNG* rng, byte* tmp) ret = wc_InitRsaKey(&caKey, HEAP_HINT); if (ret != 0) { - ERROR_OUT(-6949, exit_rsa); + ERROR_OUT(-7649, exit_rsa); } ret = wc_RsaPrivateKeyDecode(tmp, &idx3, &caKey, (word32)bytes3); if (ret != 0) { - ERROR_OUT(-6950, exit_rsa); + ERROR_OUT(-7650, exit_rsa); } /* Get Cert Key */ @@ -12401,7 +12551,7 @@ static int rsa_ecc_certgen_test(WC_RNG* rng, byte* tmp) #else file3 = XFOPEN(eccKeyPubFile, "rb"); if (!file3) { - ERROR_OUT(-6951, exit_rsa); + ERROR_OUT(-7651, exit_rsa); } bytes3 = XFREAD(tmp, 1, FOURK_BUF, file3); @@ -12410,18 +12560,18 @@ static int rsa_ecc_certgen_test(WC_RNG* rng, byte* tmp) ret = wc_ecc_init_ex(&caEccKeyPub, HEAP_HINT, devId); if (ret != 0) { - ERROR_OUT(-6952, exit_rsa); + ERROR_OUT(-7652, exit_rsa); } idx3 = 0; ret = wc_EccPublicKeyDecode(tmp, &idx3, &caEccKeyPub, (word32)bytes3); if (ret != 0) { - ERROR_OUT(-6953, exit_rsa); + ERROR_OUT(-7653, exit_rsa); } /* Setup Certificate */ if (wc_InitCert(myCert)) { - ERROR_OUT(-6954, exit_rsa); + ERROR_OUT(-7654, exit_rsa); } #ifndef NO_SHA256 @@ -12442,7 +12592,7 @@ static int rsa_ecc_certgen_test(WC_RNG* rng, byte* tmp) /* add SKID from the Public Key */ if (wc_SetSubjectKeyIdFromPublicKey(myCert, NULL, &caEccKeyPub) != 0) { - ERROR_OUT(-6955, exit_rsa); + ERROR_OUT(-7655, exit_rsa); } /* add AKID from the CA certificate */ @@ -12456,12 +12606,12 @@ static int rsa_ecc_certgen_test(WC_RNG* rng, byte* tmp) ret = wc_SetAuthKeyId(myCert, rsaCaCertFile); #endif if (ret != 0) { - ERROR_OUT(-6956, exit_rsa); + ERROR_OUT(-7656, exit_rsa); } /* add Key Usage */ if (wc_SetKeyUsage(myCert, certKeyUsage) != 0) { - ERROR_OUT(-6957, exit_rsa); + ERROR_OUT(-7657, exit_rsa); } #endif /* WOLFSSL_CERT_EXT */ @@ -12475,12 +12625,12 @@ static int rsa_ecc_certgen_test(WC_RNG* rng, byte* tmp) ret = wc_SetIssuer(myCert, rsaCaCertFile); #endif if (ret < 0) { - ERROR_OUT(-6958, exit_rsa); + ERROR_OUT(-7658, exit_rsa); } certSz = wc_MakeCert(myCert, der, FOURK_BUF, NULL, &caEccKeyPub, rng); if (certSz < 0) { - ERROR_OUT(-6959, exit_rsa); + ERROR_OUT(-7659, exit_rsa); } ret = 0; @@ -12494,7 +12644,7 @@ static int rsa_ecc_certgen_test(WC_RNG* rng, byte* tmp) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-6960, exit_rsa); + ERROR_OUT(-7660, exit_rsa); } certSz = ret; @@ -12503,7 +12653,7 @@ static int rsa_ecc_certgen_test(WC_RNG* rng, byte* tmp) ret = ParseCert(&decode, CERT_TYPE, NO_VERIFY, 0); if (ret != 0) { FreeDecodedCert(&decode); - ERROR_OUT(-6961, exit_rsa); + ERROR_OUT(-7661, exit_rsa); } FreeDecodedCert(&decode); @@ -12552,7 +12702,7 @@ static int rsa_keygen_test(WC_RNG* rng) ret = wc_InitRsaKey_ex(&genKey, HEAP_HINT, devId); if (ret != 0) { - ERROR_OUT(-6962, exit_rsa); + ERROR_OUT(-7662, exit_rsa); } ret = wc_MakeRsaKey(&genKey, keySz, WC_RSA_EXPONENT, rng); @@ -12560,7 +12710,7 @@ static int rsa_keygen_test(WC_RNG* rng) ret = wc_AsyncWait(ret, &genKey.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) { - ERROR_OUT(-6963, exit_rsa); + ERROR_OUT(-7663, exit_rsa); } TEST_SLEEP(); @@ -12571,21 +12721,21 @@ static int rsa_keygen_test(WC_RNG* rng) !defined(HAVE_SELFTEST) && !defined(HAVE_INTEL_QA) ret = wc_CheckRsaKey(&genKey); if (ret != 0) { - ERROR_OUT(-8228, exit_rsa); + ERROR_OUT(-7664, exit_rsa); } #endif der = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (der == NULL) { - ERROR_OUT(-6964, exit_rsa); + ERROR_OUT(-7665, exit_rsa); } pem = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (pem == NULL) { - ERROR_OUT(-6965, exit_rsa); + ERROR_OUT(-7666, exit_rsa); } derSz = wc_RsaKeyToDer(&genKey, der, FOURK_BUF); if (derSz < 0) { - ERROR_OUT(-6966, exit_rsa); + ERROR_OUT(-7667, exit_rsa); } ret = SaveDerAndPem(der, derSz, pem, FOURK_BUF, keyDerFile, keyPemFile, @@ -12597,14 +12747,14 @@ static int rsa_keygen_test(WC_RNG* rng) wc_FreeRsaKey(&genKey); ret = wc_InitRsaKey(&genKey, HEAP_HINT); if (ret != 0) { - ERROR_OUT(-6967, exit_rsa); + ERROR_OUT(-7668, exit_rsa); } idx = 0; #if !defined(WOLFSSL_CRYPTOCELL) /* The private key part of the key gen pairs from cryptocell can't be exported */ ret = wc_RsaPrivateKeyDecode(der, &idx, &genKey, derSz); if (ret != 0) { - ERROR_OUT(-6968, exit_rsa); + ERROR_OUT(-7669, exit_rsa); } #endif /* WOLFSSL_CRYPTOCELL */ @@ -12717,7 +12867,7 @@ int rsa_test(void) || out == NULL || plain == NULL #endif ) { - return -7000; + return -7700; } #ifdef USE_CERT_BUFFERS_1024 @@ -12733,24 +12883,24 @@ int rsa_test(void) if (!file) { err_sys("can't open ./certs/client-key.der, " "Please run from wolfSSL home dir", -40); - ERROR_OUT(-7001, exit_rsa); + ERROR_OUT(-7701, exit_rsa); } bytes = XFREAD(tmp, 1, FOURK_BUF, file); XFCLOSE(file); #else /* No key to use. */ - ERROR_OUT(-7002, exit_rsa); + ERROR_OUT(-7702, exit_rsa); #endif /* USE_CERT_BUFFERS */ ret = wc_InitRsaKey_ex(&key, HEAP_HINT, devId); if (ret != 0) { - ERROR_OUT(-7003, exit_rsa); + ERROR_OUT(-7703, exit_rsa); } #ifndef NO_ASN ret = wc_RsaPrivateKeyDecode(tmp, &idx, &key, (word32)bytes); if (ret != 0) { - ERROR_OUT(-7004, exit_rsa); + ERROR_OUT(-7704, exit_rsa); } #ifndef NO_SIG_WRAPPER modLen = wc_RsaEncryptSize(&key); @@ -12759,11 +12909,11 @@ int rsa_test(void) #ifdef USE_CERT_BUFFERS_2048 ret = mp_read_unsigned_bin(&key.n, &tmp[12], 256); if (ret != 0) { - ERROR_OUT(-7004, exit_rsa); + ERROR_OUT(-7705, exit_rsa); } ret = mp_set_int(&key.e, WC_RSA_EXPONENT); if (ret != 0) { - ERROR_OUT(-7004, exit_rsa); + ERROR_OUT(-7706, exit_rsa); } #ifndef NO_SIG_WRAPPER modLen = 2048; @@ -12780,7 +12930,7 @@ int rsa_test(void) ret = wc_InitRng(&rng); #endif if (ret != 0) { - ERROR_OUT(-7005, exit_rsa); + ERROR_OUT(-7707, exit_rsa); } #endif @@ -12806,7 +12956,7 @@ int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7006, exit_rsa); + ERROR_OUT(-7708, exit_rsa); } TEST_SLEEP(); @@ -12815,7 +12965,7 @@ int rsa_test(void) int tmpret = ret; ret = wc_RsaSetRNG(&key, &rng); if (ret < 0) { - ERROR_OUT(-7007, exit_rsa); + ERROR_OUT(-7709, exit_rsa); } ret = tmpret; } @@ -12831,11 +12981,11 @@ int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7008, exit_rsa); + ERROR_OUT(-7710, exit_rsa); } if (XMEMCMP(plain, in, inLen)) { - ERROR_OUT(-7009, exit_rsa); + ERROR_OUT(-7711, exit_rsa); } TEST_SLEEP(); @@ -12848,13 +12998,13 @@ int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7010, exit_rsa); + ERROR_OUT(-7712, exit_rsa); } if (ret != (int)inLen) { - ERROR_OUT(-7011, exit_rsa); + ERROR_OUT(-7713, exit_rsa); } if (XMEMCMP(res, in, inLen)) { - ERROR_OUT(-7012, exit_rsa); + ERROR_OUT(-7714, exit_rsa); } TEST_SLEEP(); @@ -12867,7 +13017,7 @@ int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7013, exit_rsa); + ERROR_OUT(-7715, exit_rsa); } TEST_SLEEP(); @@ -12950,11 +13100,11 @@ int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7014, exit_rsa); + ERROR_OUT(-7716, exit_rsa); } if (XMEMCMP(plain, in, (size_t)ret)) { - ERROR_OUT(-7015, exit_rsa); + ERROR_OUT(-7717, exit_rsa); } TEST_SLEEP(); #endif @@ -12978,7 +13128,7 @@ int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7016, exit_rsa); + ERROR_OUT(-7718, exit_rsa); } TEST_SLEEP(); @@ -12994,11 +13144,11 @@ int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7017, exit_rsa); + ERROR_OUT(-7719, exit_rsa); } if (XMEMCMP(plain, in, inLen)) { - ERROR_OUT(-7018, exit_rsa); + ERROR_OUT(-7720, exit_rsa); } TEST_SLEEP(); #endif /* NO_SHA */ @@ -13017,7 +13167,7 @@ int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7019, exit_rsa); + ERROR_OUT(-7721, exit_rsa); } TEST_SLEEP(); #endif /* WOLFSSL_RSA_VERIFY_ONLY */ @@ -13034,11 +13184,11 @@ int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7020, exit_rsa); + ERROR_OUT(-7722, exit_rsa); } if (XMEMCMP(plain, in, inLen)) { - ERROR_OUT(-7021, exit_rsa); + ERROR_OUT(-7723, exit_rsa); } TEST_SLEEP(); #endif /* WOLFSSL_RSA_PUBLIC_ONLY */ @@ -13054,13 +13204,13 @@ int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7022, exit_rsa); + ERROR_OUT(-7724, exit_rsa); } if (ret != (int)inLen) { - ERROR_OUT(-7023, exit_rsa); + ERROR_OUT(-7725, exit_rsa); } if (XMEMCMP(res, in, inLen)) { - ERROR_OUT(-7024, exit_rsa); + ERROR_OUT(-7726, exit_rsa); } TEST_SLEEP(); #endif /* WOLFSSL_RSA_PUBLIC_ONLY */ @@ -13078,7 +13228,7 @@ int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7025, exit_rsa); + ERROR_OUT(-7727, exit_rsa); } TEST_SLEEP(); #endif /* WOLFSSL_RSA_VERIFY_ONLY */ @@ -13098,7 +13248,7 @@ int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret > 0) { /* in this case decrypt should fail */ - ERROR_OUT(-7026, exit_rsa); + ERROR_OUT(-7728, exit_rsa); } ret = 0; TEST_SLEEP(); @@ -13117,7 +13267,7 @@ int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7027, exit_rsa); + ERROR_OUT(-7729, exit_rsa); } TEST_SLEEP(); #endif /* WOLFSSL_RSA_VERIFY_ONLY */ @@ -13134,11 +13284,11 @@ int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7028, exit_rsa); + ERROR_OUT(-7730, exit_rsa); } if (XMEMCMP(plain, in, inLen)) { - ERROR_OUT(-7029, exit_rsa); + ERROR_OUT(-7731, exit_rsa); } TEST_SLEEP(); #endif /* WOLFSSL_RSA_PUBLIC_ONLY */ @@ -13157,7 +13307,7 @@ int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7030, exit_rsa); + ERROR_OUT(-7732, exit_rsa); } TEST_SLEEP(); @@ -13176,7 +13326,7 @@ int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret > 0) { /* should fail */ - ERROR_OUT(-7031, exit_rsa); + ERROR_OUT(-7733, exit_rsa); } ret = 0; TEST_SLEEP(); @@ -13202,7 +13352,7 @@ int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7032, exit_rsa); + ERROR_OUT(-7734, exit_rsa); } TEST_SLEEP(); @@ -13218,11 +13368,11 @@ int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7033, exit_rsa); + ERROR_OUT(-7735, exit_rsa); } if (XMEMCMP(plain, in, inLen)) { - ERROR_OUT(-7034, exit_rsa); + ERROR_OUT(-7736, exit_rsa); } TEST_SLEEP(); #endif /* WOLFSSL_RSA_PUBLIC_ONLY */ @@ -13241,7 +13391,7 @@ int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7035, exit_rsa); + ERROR_OUT(-7737, exit_rsa); } TEST_SLEEP(); @@ -13257,11 +13407,11 @@ int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7036, exit_rsa); + ERROR_OUT(-7738, exit_rsa); } if (XMEMCMP(plain, in, inLen)) { - ERROR_OUT(-7037, exit_rsa); + ERROR_OUT(-7739, exit_rsa); } TEST_SLEEP(); #endif /* WOLFSSL_RSA_PUBLIC_ONLY */ @@ -13301,14 +13451,14 @@ int rsa_test(void) #elif !defined(NO_FILESYSTEM) file2 = XFOPEN(clientCert, "rb"); if (!file2) { - ERROR_OUT(-7038, exit_rsa); + ERROR_OUT(-7740, exit_rsa); } bytes = XFREAD(tmp, 1, FOURK_BUF, file2); XFCLOSE(file2); #else /* No certificate to use. */ - ERROR_OUT(-7039, exit_rsa); + ERROR_OUT(-7741, exit_rsa); #endif #ifdef sizeof @@ -13321,7 +13471,7 @@ int rsa_test(void) ret = ParseCert(&cert, CERT_TYPE, NO_VERIFY, 0); if (ret != 0) { FreeDecodedCert(&cert); - ERROR_OUT(-7040, exit_rsa); + ERROR_OUT(-7742, exit_rsa); } FreeDecodedCert(&cert); @@ -13348,7 +13498,7 @@ int rsa_test(void) if (!file) { err_sys("can't open ./certs/client-keyPub.der, " "Please run from wolfSSL home dir", -40); - ERROR_OUT(-7041, exit_rsa); + ERROR_OUT(-7743, exit_rsa); } bytes = XFREAD(tmp, 1, FOURK_BUF, file); @@ -13357,13 +13507,13 @@ int rsa_test(void) ret = wc_InitRsaKey(&keypub, HEAP_HINT); if (ret != 0) { - ERROR_OUT(-7042, exit_rsa); + ERROR_OUT(-7744, exit_rsa); } idx = 0; ret = wc_RsaPublicKeyDecode(tmp, &idx, &keypub, (word32)bytes); if (ret != 0) { - ERROR_OUT(-7043, exit_rsa); + ERROR_OUT(-7745, exit_rsa); } #endif /* WOLFSSL_CERT_EXT */ @@ -13408,26 +13558,26 @@ int rsa_test(void) word32 rc = ntru_crypto_drbg_instantiate(112, pers_str, sizeof(pers_str), GetEntropy, &drbg); if (rc != DRBG_OK) { - ERROR_OUT(-7044, exit_rsa); + ERROR_OUT(-7746, exit_rsa); } rc = ntru_crypto_ntru_encrypt_keygen(drbg, NTRU_EES401EP2, &public_key_len, NULL, &private_key_len, NULL); if (rc != NTRU_OK) { - ERROR_OUT(-7045, exit_rsa); + ERROR_OUT(-7747, exit_rsa); } rc = ntru_crypto_ntru_encrypt_keygen(drbg, NTRU_EES401EP2, &public_key_len, public_key, &private_key_len, private_key); if (rc != NTRU_OK) { - ERROR_OUT(-7046, exit_rsa); + ERROR_OUT(-7748, exit_rsa); } rc = ntru_crypto_drbg_uninstantiate(drbg); if (rc != NTRU_OK) { - ERROR_OUT(-7047, exit_rsa); + ERROR_OUT(-7749, exit_rsa); } #ifdef USE_CERT_BUFFERS_1024 @@ -13439,7 +13589,7 @@ int rsa_test(void) #else caFile = XFOPEN(rsaCaKeyFile, "rb"); if (!caFile) { - ERROR_OUT(-7048, exit_rsa); + ERROR_OUT(-7750, exit_rsa); } bytes = XFREAD(tmp, 1, FOURK_BUF, caFile); @@ -13448,15 +13598,15 @@ int rsa_test(void) ret = wc_InitRsaKey(&caKey, HEAP_HINT); if (ret != 0) { - ERROR_OUT(-7049, exit_rsa); + ERROR_OUT(-7751, exit_rsa); } ret = wc_RsaPrivateKeyDecode(tmp, &idx3, &caKey, (word32)bytes); if (ret != 0) { - ERROR_OUT(-7050, exit_rsa); + ERROR_OUT(-7752, exit_rsa); } if (wc_InitCert(&myCert)) { - ERROR_OUT(-7051, exit_rsa); + ERROR_OUT(-7753, exit_rsa); } XMEMCPY(&myCert.subject, &certDefaultName, sizeof(CertName)); @@ -13466,7 +13616,7 @@ int rsa_test(void) /* add SKID from the Public Key */ if (wc_SetSubjectKeyIdFromNtruPublicKey(&myCert, public_key, public_key_len) != 0) { - ERROR_OUT(-7052, exit_rsa); + ERROR_OUT(-7754, exit_rsa); } /* add AKID from the CA certificate */ @@ -13480,12 +13630,12 @@ int rsa_test(void) ret = wc_SetAuthKeyId(&myCert, rsaCaCertFile); #endif if (ret != 0) { - ERROR_OUT(-7053, exit_rsa); + ERROR_OUT(-7755, exit_rsa); } /* add Key Usage */ if (wc_SetKeyUsage(&myCert, certKeyUsage2) != 0) { - ERROR_OUT(-7054, exit_rsa); + ERROR_OUT(-7756, exit_rsa); } #endif /* WOLFSSL_CERT_EXT */ @@ -13499,22 +13649,22 @@ int rsa_test(void) ret = wc_SetIssuer(&myCert, rsaCaCertFile); #endif if (ret < 0) { - ERROR_OUT(-7055, exit_rsa); + ERROR_OUT(-7757, exit_rsa); } der = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (der == NULL) { - ERROR_OUT(-7056, exit_rsa); + ERROR_OUT(-7758, exit_rsa); } pem = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT,DYNAMIC_TYPE_TMP_BUFFER); if (pem == NULL) { - ERROR_OUT(-7057, exit_rsa); + ERROR_OUT(-7759, exit_rsa); } certSz = wc_MakeNtruCert(&myCert, der, FOURK_BUF, public_key, public_key_len, &rng); if (certSz < 0) { - ERROR_OUT(-7058, exit_rsa); + ERROR_OUT(-7760, exit_rsa); } ret = 0; @@ -13529,7 +13679,7 @@ int rsa_test(void) } while (ret == WC_PENDING_E); wc_FreeRsaKey(&caKey); if (ret < 0) { - ERROR_OUT(-7059, exit_rsa); + ERROR_OUT(-7761, exit_rsa); } certSz = ret; @@ -13538,7 +13688,7 @@ int rsa_test(void) ret = ParseCert(&decode, CERT_TYPE, NO_VERIFY, 0); if (ret != 0) { FreeDecodedCert(&decode); - ERROR_OUT(-7060, exit_rsa); + ERROR_OUT(-7762, exit_rsa); } FreeDecodedCert(&decode); #endif @@ -13552,12 +13702,12 @@ int rsa_test(void) #if !defined(NO_FILESYSTEM) && !defined(NO_WRITE_TEMP_FILES) ntruPrivFile = XFOPEN("./ntru-key.raw", "wb"); if (!ntruPrivFile) { - ERROR_OUT(-7061, exit_rsa); + ERROR_OUT(-7763, exit_rsa); } ret = (int)XFWRITE(private_key, 1, private_key_len, ntruPrivFile); XFCLOSE(ntruPrivFile); if (ret != private_key_len) { - ERROR_OUT(-7062, exit_rsa); + ERROR_OUT(-7764, exit_rsa); } #endif @@ -13574,15 +13724,15 @@ int rsa_test(void) der = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT,DYNAMIC_TYPE_TMP_BUFFER); if (der == NULL) { - ERROR_OUT(-7063, exit_rsa); + ERROR_OUT(-7765, exit_rsa); } pem = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT,DYNAMIC_TYPE_TMP_BUFFER); if (pem == NULL) { - ERROR_OUT(-7064, exit_rsa); + ERROR_OUT(-7766, exit_rsa); } if (wc_InitCert(&req)) { - ERROR_OUT(-7065, exit_rsa); + ERROR_OUT(-7767, exit_rsa); } req.version = 0; @@ -13599,25 +13749,25 @@ int rsa_test(void) #ifdef WOLFSSL_CERT_EXT /* add SKID from the Public Key */ if (wc_SetSubjectKeyIdFromPublicKey(&req, &keypub, NULL) != 0) { - ERROR_OUT(-7066, exit_rsa); + ERROR_OUT(-7768, exit_rsa); } /* add Key Usage */ if (wc_SetKeyUsage(&req, certKeyUsage2) != 0) { - ERROR_OUT(-7067, exit_rsa); + ERROR_OUT(-7769, exit_rsa); } /* add Extended Key Usage */ if (wc_SetExtKeyUsage(&req, "serverAuth,clientAuth,codeSigning," "emailProtection,timeStamping,OCSPSigning") != 0) { - ERROR_OUT(-7068, exit_rsa); + ERROR_OUT(-7770, exit_rsa); } #ifdef WOLFSSL_EKU_OID { const char unique[] = "2.16.840.1.111111.100.1.10.1"; if (wc_SetExtKeyUsageOID(&req, unique, sizeof(unique), 0, HEAP_HINT) != 0) { - ERROR_OUT(-7069, exit_rsa); + ERROR_OUT(-7771, exit_rsa); } } #endif /* WOLFSSL_EKU_OID */ @@ -13625,17 +13775,17 @@ int rsa_test(void) derSz = wc_MakeCertReq(&req, der, FOURK_BUF, &key, NULL); if (derSz < 0) { - ERROR_OUT(-7070, exit_rsa); + ERROR_OUT(-7772, exit_rsa); } #ifdef WOLFSSL_CERT_EXT /* Try again with "any" flag set, will override all others */ if (wc_SetExtKeyUsage(&req, "any") != 0) { - ERROR_OUT(-7071, exit_rsa); + ERROR_OUT(-7773, exit_rsa); } derSz = wc_MakeCertReq(&req, der, FOURK_BUF, &key, NULL); if (derSz < 0) { - ERROR_OUT(-7072, exit_rsa); + ERROR_OUT(-7774, exit_rsa); } #endif /* WOLFSSL_CERT_EXT */ @@ -13650,7 +13800,7 @@ int rsa_test(void) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-7073, exit_rsa); + ERROR_OUT(-7775, exit_rsa); } derSz = ret; @@ -13662,7 +13812,7 @@ int rsa_test(void) derSz = wc_MakeCertReq_ex(&req, der, FOURK_BUF, RSA_TYPE, &key); if (derSz < 0) { - ERROR_OUT(-7074, exit_rsa); + ERROR_OUT(-7776, exit_rsa); } XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); @@ -13803,41 +13953,41 @@ static int dh_fips_generate_test(WC_RNG *rng) /* Parameter Validation testing. */ ret = wc_DhGenerateKeyPair(NULL, rng, priv, &privSz, pub, &pubSz); if (ret != BAD_FUNC_ARG) - return -7074; + return -7777; ret = wc_DhGenerateKeyPair(&key, NULL, priv, &privSz, pub, &pubSz); if (ret != BAD_FUNC_ARG) - return -7075; + return -7778; ret = wc_DhGenerateKeyPair(&key, rng, NULL, &privSz, pub, &pubSz); if (ret != BAD_FUNC_ARG) - return -7076; + return -7779; ret = wc_DhGenerateKeyPair(&key, rng, priv, NULL, pub, &pubSz); if (ret != BAD_FUNC_ARG) - return -7077; + return -7780; ret = wc_DhGenerateKeyPair(&key, rng, priv, &privSz, NULL, &pubSz); if (ret != BAD_FUNC_ARG) - return -7078; + return -7781; ret = wc_DhGenerateKeyPair(&key, rng, priv, &privSz, pub, NULL); if (ret != BAD_FUNC_ARG) - return -7079; + return -7782; ret = wc_InitDhKey_ex(&key, HEAP_HINT, devId); if (ret != 0) - return -7080; + return -7783; ret = wc_DhSetKey_ex(&key, p, sizeof(p), g, sizeof(g), q0, sizeof(q0)); if (ret != 0) { - ERROR_OUT(-7081, exit_gen_test); + ERROR_OUT(-7784, exit_gen_test); } wc_FreeDhKey(&key); ret = wc_InitDhKey_ex(&key, HEAP_HINT, devId); if (ret != 0) - return -7082; + return -7785; ret = wc_DhSetKey_ex(&key, p, sizeof(p), g, sizeof(g), q, sizeof(q)); if (ret != 0) { - ERROR_OUT(-7083, exit_gen_test); + ERROR_OUT(-7786, exit_gen_test); } /* Use API. */ @@ -13846,51 +13996,51 @@ static int dh_fips_generate_test(WC_RNG *rng) ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) { - ERROR_OUT(-7084, exit_gen_test); + ERROR_OUT(-7787, exit_gen_test); } ret = wc_DhCheckPubKey_ex(&key, pub, pubSz, q0, sizeof(q0)); if (ret != 0) { - ERROR_OUT(-7085, exit_gen_test); + ERROR_OUT(-7788, exit_gen_test); } wc_FreeDhKey(&key); ret = wc_InitDhKey_ex(&key, HEAP_HINT, devId); if (ret != 0) - return -7086; + return -7789; ret = wc_DhSetKey(&key, p, sizeof(p), g, sizeof(g)); if (ret != 0) { - ERROR_OUT(-7087, exit_gen_test); + ERROR_OUT(-7790, exit_gen_test); } ret = wc_DhCheckPubKey_ex(&key, pub, pubSz, q, sizeof(q)); if (ret != 0) { - ERROR_OUT(-7088, exit_gen_test); + ERROR_OUT(-7791, exit_gen_test); } #ifndef HAVE_SELFTEST ret = wc_DhCheckKeyPair(&key, pub, pubSz, priv, privSz); if (ret != 0) { - ERROR_OUT(-8229, exit_gen_test); + ERROR_OUT(-7792, exit_gen_test); } /* Taint the public key so the check fails. */ pub[0]++; ret = wc_DhCheckKeyPair(&key, pub, pubSz, priv, privSz); if (ret != MP_CMP_E) { - ERROR_OUT(-8230, exit_gen_test); + ERROR_OUT(-7793, exit_gen_test); } #ifdef WOLFSSL_KEY_GEN wc_FreeDhKey(&key); ret = wc_InitDhKey_ex(&key, HEAP_HINT, devId); if (ret != 0) - return -8231; + return -7794; ret = wc_DhGenerateParams(rng, 2048, &key); if (ret != 0) { - ERROR_OUT(-8226, exit_gen_test); + ERROR_OUT(-7795, exit_gen_test); } privSz = sizeof(priv); @@ -13901,7 +14051,7 @@ static int dh_fips_generate_test(WC_RNG *rng) ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) { - ERROR_OUT(-8227, exit_gen_test); + ERROR_OUT(-7796, exit_gen_test); } #endif /* WOLFSSL_KEY_GEN */ @@ -13936,37 +14086,37 @@ static int dh_generate_test(WC_RNG *rng) ret = wc_InitDhKey_ex(&smallKey, HEAP_HINT, devId); if (ret != 0) - return -7089; + return -7797; /* Parameter Validation testing. */ ret = wc_InitDhKey_ex(NULL, HEAP_HINT, devId); if (ret != BAD_FUNC_ARG) - return -7090; + return -7798; wc_FreeDhKey(NULL); ret = wc_DhSetKey(NULL, p, sizeof(p), g, sizeof(g)); if (ret != BAD_FUNC_ARG) { - ERROR_OUT(-7091, exit_gen_test); + ERROR_OUT(-7799, exit_gen_test); } ret = wc_DhSetKey(&smallKey, NULL, sizeof(p), g, sizeof(g)); if (ret != BAD_FUNC_ARG) { - ERROR_OUT(-7092, exit_gen_test); + ERROR_OUT(-7800, exit_gen_test); } ret = wc_DhSetKey(&smallKey, p, 0, g, sizeof(g)); if (ret != BAD_FUNC_ARG) { - ERROR_OUT(-7093, exit_gen_test); + ERROR_OUT(-7801, exit_gen_test); } ret = wc_DhSetKey(&smallKey, p, sizeof(p), NULL, sizeof(g)); if (ret != BAD_FUNC_ARG) { - ERROR_OUT(-7094, exit_gen_test); + ERROR_OUT(-7802, exit_gen_test); } ret = wc_DhSetKey(&smallKey, p, sizeof(p), g, 0); if (ret != BAD_FUNC_ARG) { - ERROR_OUT(-7095, exit_gen_test); + ERROR_OUT(-7803, exit_gen_test); } ret = wc_DhSetKey(&smallKey, p, sizeof(p), g, sizeof(g)); if (ret != 0) { - ERROR_OUT(-7096, exit_gen_test); + ERROR_OUT(-7804, exit_gen_test); } #ifndef WOLFSSL_SP_MATH @@ -13976,7 +14126,7 @@ static int dh_generate_test(WC_RNG *rng) ret = wc_AsyncWait(ret, &smallKey.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) { - ret = -7097; + ret = -7805; } #else (void)rng; @@ -14040,14 +14190,14 @@ static int dh_test_check_pubvalue(void) ret = wc_DhCheckPubValue(prime, sizeof(prime), dh_pubval_fail[i].data, dh_pubval_fail[i].len); if (ret != MP_VAL) - return -7150 - (int)i; + return -7806 - (int)i; } for (i = 0; i < sizeof(dh_pubval_pass) / sizeof(*dh_pubval_pass); i++) { ret = wc_DhCheckPubValue(prime, sizeof(prime), dh_pubval_pass[i].data, dh_pubval_pass[i].len); if (ret != 0) - return -7160 - (int)i; + return -7816 - (int)i; } return 0; @@ -14082,22 +14232,22 @@ static int dh_test_ffdhe(WC_RNG *rng, const DhParams* params) ret = wc_InitDhKey_ex(&key, HEAP_HINT, devId); if (ret != 0) { - ERROR_OUT(-7180, done); + ERROR_OUT(-7826, done); } ret = wc_InitDhKey_ex(&key2, HEAP_HINT, devId); if (ret != 0) { - ERROR_OUT(-7181, done); + ERROR_OUT(-7827, done); } ret = wc_DhSetKey(&key, params->p, params->p_len, params->g, params->g_len); if (ret != 0) { - ERROR_OUT(-7182, done); + ERROR_OUT(-7828, done); } ret = wc_DhSetKey(&key2, params->p, params->p_len, params->g, params->g_len); if (ret != 0) { - ERROR_OUT(-7183, done); + ERROR_OUT(-7829, done); } ret = wc_DhGenerateKeyPair(&key, rng, priv, &privSz, pub, &pubSz); @@ -14105,7 +14255,7 @@ static int dh_test_ffdhe(WC_RNG *rng, const DhParams* params) ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) { - ERROR_OUT(-7184, done); + ERROR_OUT(-7830, done); } ret = wc_DhGenerateKeyPair(&key2, rng, priv2, &privSz2, pub2, &pubSz2); @@ -14113,7 +14263,7 @@ static int dh_test_ffdhe(WC_RNG *rng, const DhParams* params) ret = wc_AsyncWait(ret, &key2.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) { - ERROR_OUT(-7185, done); + ERROR_OUT(-7831, done); } ret = wc_DhAgree(&key, agree, &agreeSz, priv, privSz, pub2, pubSz2); @@ -14121,7 +14271,7 @@ static int dh_test_ffdhe(WC_RNG *rng, const DhParams* params) ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) { - ERROR_OUT(-7186, done); + ERROR_OUT(-7832, done); } ret = wc_DhAgree(&key2, agree2, &agreeSz2, priv2, privSz2, pub, pubSz); @@ -14129,11 +14279,11 @@ static int dh_test_ffdhe(WC_RNG *rng, const DhParams* params) ret = wc_AsyncWait(ret, &key2.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) { - ERROR_OUT(-7187, done); + ERROR_OUT(-7833, done); } if (agreeSz != agreeSz2 || XMEMCMP(agree, agree2, agreeSz)) { - ERROR_OUT(-7188, done); + ERROR_OUT(-7834, done); } done: @@ -14174,13 +14324,13 @@ int dh_test(void) #elif !defined(NO_FILESYSTEM) XFILE file = XFOPEN(dhKey, "rb"); if (!file) - return -7100; + return -7900; bytes = (word32) XFREAD(tmp, 1, sizeof(tmp), file); XFCLOSE(file); #else /* No DH key to use. */ - return -7101; + return -7901; #endif /* USE_CERT_BUFFERS */ (void)idx; @@ -14190,40 +14340,40 @@ int dh_test(void) /* Use API for coverage. */ ret = wc_InitDhKey(&key); if (ret != 0) { - ERROR_OUT(-7102, done); + ERROR_OUT(-7902, done); } wc_FreeDhKey(&key); ret = wc_InitDhKey_ex(&key, HEAP_HINT, devId); if (ret != 0) { - ERROR_OUT(-7103, done); + ERROR_OUT(-7903, done); } keyInit = 1; ret = wc_InitDhKey_ex(&key2, HEAP_HINT, devId); if (ret != 0) { - ERROR_OUT(-7104, done); + ERROR_OUT(-7904, done); } #ifdef NO_ASN ret = wc_DhSetKey(&key, dh_p, sizeof(dh_p), dh_g, sizeof(dh_g)); if (ret != 0) { - ERROR_OUT(-7105, done); + ERROR_OUT(-7905, done); } ret = wc_DhSetKey(&key2, dh_p, sizeof(dh_p), dh_g, sizeof(dh_g)); if (ret != 0) { - ERROR_OUT(-7106, done); + ERROR_OUT(-7906, done); } #else ret = wc_DhKeyDecode(tmp, &idx, &key, bytes); if (ret != 0) { - ERROR_OUT(-7107, done); + ERROR_OUT(-7907, done); } idx = 0; ret = wc_DhKeyDecode(tmp, &idx, &key2, bytes); if (ret != 0) { - ERROR_OUT(-7108, done); + ERROR_OUT(-7908, done); } #endif @@ -14233,7 +14383,7 @@ int dh_test(void) ret = wc_InitRng(&rng); #endif if (ret != 0) { - ERROR_OUT(-7109, done); + ERROR_OUT(-7909, done); } ret = wc_DhGenerateKeyPair(&key, &rng, priv, &privSz, pub, &pubSz); @@ -14241,7 +14391,7 @@ int dh_test(void) ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) { - ERROR_OUT(-7110, done); + ERROR_OUT(-7910, done); } ret = wc_DhGenerateKeyPair(&key2, &rng, priv2, &privSz2, pub2, &pubSz2); @@ -14249,7 +14399,7 @@ int dh_test(void) ret = wc_AsyncWait(ret, &key2.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) { - ERROR_OUT(-7111, done); + ERROR_OUT(-7911, done); } ret = wc_DhAgree(&key, agree, &agreeSz, priv, privSz, pub2, pubSz2); @@ -14257,7 +14407,7 @@ int dh_test(void) ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) { - ERROR_OUT(-7112, done); + ERROR_OUT(-7912, done); } ret = wc_DhAgree(&key2, agree2, &agreeSz2, priv2, privSz2, pub, pubSz); @@ -14265,26 +14415,26 @@ int dh_test(void) ret = wc_AsyncWait(ret, &key2.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) { - ERROR_OUT(-7113, done); + ERROR_OUT(-7913, done); } if (agreeSz != agreeSz2 || XMEMCMP(agree, agree2, agreeSz)) { - ERROR_OUT(-7114, done); + ERROR_OUT(-7914, done); } #if defined(WOLFSSL_KEY_GEN) && !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST) if (wc_DhCheckPrivKey(NULL, NULL, 0) != BAD_FUNC_ARG) - return -7115; + return -7915; if (wc_DhCheckPrivKey(&key, priv, privSz) != 0) - return -7116; + return -7916; if (wc_DhExportParamsRaw(NULL, NULL, NULL, NULL, NULL, NULL, NULL) != BAD_FUNC_ARG) - return -7117; + return -7917; { word32 pSz, qSz, gSz; if (wc_DhExportParamsRaw(&key, NULL, &pSz, NULL, &qSz, NULL, &gSz) != LENGTH_ONLY_E) - return -7118; + return -7918; } #endif @@ -14361,7 +14511,7 @@ int dsa_test(void) #else XFILE file = XFOPEN(dsaKey, "rb"); if (!file) - return -7200; + return -8000; bytes = (word32) XFREAD(tmp, 1, sizeof(tmp), file); XFCLOSE(file); @@ -14369,30 +14519,30 @@ int dsa_test(void) ret = wc_InitSha_ex(&sha, HEAP_HINT, devId); if (ret != 0) - return -7201; + return -8001; wc_ShaUpdate(&sha, tmp, bytes); wc_ShaFinal(&sha, hash); wc_ShaFree(&sha); ret = wc_InitDsaKey(&key); - if (ret != 0) return -7202; + if (ret != 0) return -8002; ret = wc_DsaPrivateKeyDecode(tmp, &idx, &key, bytes); - if (ret != 0) return -7203; + if (ret != 0) return -8003; #ifndef HAVE_FIPS ret = wc_InitRng_ex(&rng, HEAP_HINT, devId); #else ret = wc_InitRng(&rng); #endif - if (ret != 0) return -7204; + if (ret != 0) return -8004; ret = wc_DsaSign(hash, signature, &key, &rng); - if (ret != 0) return -7205; + if (ret != 0) return -8005; ret = wc_DsaVerify(hash, signature, &key, &answer); - if (ret != 0) return -7206; - if (answer != 1) return -7207; + if (ret != 0) return -8006; + if (answer != 1) return -8007; wc_FreeDsaKey(&key); @@ -14405,37 +14555,37 @@ int dsa_test(void) DsaKey genKey; ret = wc_InitDsaKey(&genKey); - if (ret != 0) return -7208; + if (ret != 0) return -8008; ret = wc_MakeDsaParameters(&rng, 1024, &genKey); if (ret != 0) { wc_FreeDsaKey(&genKey); - return -7209; + return -8009; } ret = wc_MakeDsaKey(&rng, &genKey); if (ret != 0) { wc_FreeDsaKey(&genKey); - return -7210; + return -8010; } der = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (der == NULL) { wc_FreeDsaKey(&genKey); - return -7211; + return -8011; } pem = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (pem == NULL) { XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_FreeDsaKey(&genKey); - return -7212; + return -8012; } derSz = wc_DsaKeyToDer(&genKey, der, FOURK_BUF); if (derSz < 0) { XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - return -7213; + return -8013; } ret = SaveDerAndPem(der, derSz, pem, FOURK_BUF, keyDerFile, @@ -14452,7 +14602,7 @@ int dsa_test(void) XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_FreeDsaKey(&genKey); - return -7214; + return -8014; } idx = 0; @@ -14462,7 +14612,7 @@ int dsa_test(void) XFREE(pem, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_FreeDsaKey(&derIn); wc_FreeDsaKey(&genKey); - return -7215; + return -8015; } wc_FreeDsaKey(&derIn); @@ -14473,7 +14623,7 @@ int dsa_test(void) #endif /* WOLFSSL_KEY_GEN */ if (wc_InitDsaKey_h(&key, NULL) != 0) - return -7216; + return -8016; wc_FreeRng(&rng); return 0; @@ -14485,11 +14635,11 @@ int dsa_test(void) static int generate_random_salt(byte *buf, word32 size) { - int ret = -7216; + int ret = -8017; WC_RNG rng; if(NULL == buf || !size) - return -7217; + return -8018; if (buf && size && wc_InitRng_ex(&rng, HEAP_HINT, devId) == 0) { ret = wc_RNG_GenerateBlock(&rng, (byte *)buf, size); @@ -14633,25 +14783,25 @@ static int openssl_aes_test(void) EVP_CIPHER_CTX_init(&en); if (EVP_CipherInit(&en, EVP_aes_128_cbc(), (unsigned char*)key, (unsigned char*)iv, 1) == 0) - return -7300; + return -8200; if (EVP_CipherUpdate(&en, (byte*)cipher, &outlen, (byte*)cbcPlain, 9) == 0) - return -7301; + return -8201; if (outlen != 0) - return -7302; + return -8202; total += outlen; if (EVP_CipherUpdate(&en, (byte*)&cipher[total], &outlen, (byte*)&cbcPlain[9] , 9) == 0) - return -7303; + return -8203; if (outlen != 16) - return -7304; + return -8204; total += outlen; if (EVP_CipherFinal(&en, (byte*)&cipher[total], &outlen) == 0) - return -7305; + return -8205; if (outlen != 16) - return -7306; + return -8206; total += outlen; if (total != 32) return 3408; @@ -14660,107 +14810,107 @@ static int openssl_aes_test(void) EVP_CIPHER_CTX_init(&de); if (EVP_CipherInit(&de, EVP_aes_128_cbc(), (unsigned char*)key, (unsigned char*)iv, 0) == 0) - return -7307; + return -8207; if (EVP_CipherUpdate(&de, (byte*)plain, &outlen, (byte*)cipher, 6) == 0) - return -7308; + return -8208; if (outlen != 0) - return -7309; + return -8209; total += outlen; if (EVP_CipherUpdate(&de, (byte*)&plain[total], &outlen, (byte*)&cipher[6], 12) == 0) - return -7310; + return -8210; if (outlen != 0) total += outlen; if (EVP_CipherUpdate(&de, (byte*)&plain[total], &outlen, (byte*)&cipher[6+12], 14) == 0) - return -7311; + return -8211; if (outlen != 16) - return -7312; + return -8212; total += outlen; if (EVP_CipherFinal(&de, (byte*)&plain[total], &outlen) == 0) - return -7313; + return -8213; if (outlen != 2) - return -7314; + return -8214; total += outlen; if (total != 18) return 3427; if (XMEMCMP(plain, cbcPlain, 18)) - return -7315; + return -8215; /* test with encrypting/decrypting more than 16 bytes at once */ total = 0; EVP_CIPHER_CTX_init(&en); if (EVP_CipherInit(&en, EVP_aes_128_cbc(), (unsigned char*)key, (unsigned char*)iv, 1) == 0) - return -7316; + return -8216; if (EVP_CipherUpdate(&en, (byte*)cipher, &outlen, (byte*)cbcPlain, 17) == 0) - return -7317; + return -8217; if (outlen != 16) - return -7318; + return -8218; total += outlen; if (EVP_CipherUpdate(&en, (byte*)&cipher[total], &outlen, (byte*)&cbcPlain[17] , 1) == 0) - return -7319; + return -8219; if (outlen != 0) - return -7320; + return -8220; total += outlen; if (EVP_CipherFinal(&en, (byte*)&cipher[total], &outlen) == 0) - return -7321; + return -8221; if (outlen != 16) - return -7322; + return -8222; total += outlen; if (total != 32) - return -7323; + return -8223; total = 0; EVP_CIPHER_CTX_init(&de); if (EVP_CipherInit(&de, EVP_aes_128_cbc(), (unsigned char*)key, (unsigned char*)iv, 0) == 0) - return -7324; + return -8224; if (EVP_CipherUpdate(&de, (byte*)plain, &outlen, (byte*)cipher, 17) == 0) - return -7325; + return -8225; if (outlen != 16) - return -7326; + return -8226; total += outlen; /* final call on non block size should fail */ if (EVP_CipherFinal(&de, (byte*)&plain[total], &outlen) != 0) - return -7327; + return -8227; if (EVP_CipherUpdate(&de, (byte*)&plain[total], &outlen, (byte*)&cipher[17], 1) == 0) - return -7328; + return -8228; if (outlen != 0) total += outlen; if (EVP_CipherUpdate(&de, (byte*)&plain[total], &outlen, (byte*)&cipher[17+1], 14) == 0) - return -7329; + return -8229; if (outlen != 0) - return -7330; + return -8230; total += outlen; if (EVP_CipherFinal(&de, (byte*)&plain[total], &outlen) == 0) - return -7331; + return -8231; if (outlen != 2) - return -7332; + return -8232; total += outlen; if (total != 18) - return -7333; + return -8233; if (XMEMCMP(plain, cbcPlain, 18)) - return -7334; + return -8234; /* test byte by byte decrypt */ for (i = 0; i < AES_BLOCK_SIZE * 3; i++) { @@ -14771,32 +14921,32 @@ static int openssl_aes_test(void) EVP_CIPHER_CTX_init(&en); if (EVP_CipherInit(&en, EVP_aes_128_cbc(), (unsigned char*)key, (unsigned char*)iv, 1) == 0) - return -7335; + return -8235; if (EVP_CipherUpdate(&en, (byte*)cipher, &outlen, (byte*)plain, AES_BLOCK_SIZE * 3) == 0) - return -7336; + return -8236; if (outlen != AES_BLOCK_SIZE * 3) - return -7337; + return -8237; total += outlen; if (EVP_CipherFinal(&en, (byte*)&cipher[total], &outlen) == 0) - return -7338; + return -8238; if (outlen != AES_BLOCK_SIZE) - return -7339; + return -8239; total += outlen; if (total != sizeof(plain)) - return -7340; + return -8240; total = 0; EVP_CIPHER_CTX_init(&de); if (EVP_CipherInit(&de, EVP_aes_128_cbc(), (unsigned char*)key, (unsigned char*)iv, 0) == 0) - return -7341; + return -8241; for (i = 0; i < AES_BLOCK_SIZE * 4; i++) { if (EVP_CipherUpdate(&de, (byte*)plain + total, &outlen, (byte*)cipher + i, 1) == 0) - return -7342; + return -8242; if (outlen > 0) { int j; @@ -14804,21 +14954,21 @@ static int openssl_aes_test(void) total += outlen; for (j = 0; j < total; j++) { if (plain[j] != j) { - return -7343; + return -8243; } } } } if (EVP_CipherFinal(&de, (byte*)&plain[total], &outlen) == 0) - return -7344; + return -8244; total += outlen; if (total != AES_BLOCK_SIZE * 3) { - return -7345; + return -8245; } for (i = 0; i < AES_BLOCK_SIZE * 3; i++) { if (plain[i] != i) { - return -7346; + return -8246; } } } @@ -14854,40 +15004,40 @@ static int openssl_aes_test(void) EVP_CIPHER_CTX_init(&en); if (EVP_CipherInit(&en, EVP_aes_128_cbc(), (unsigned char*)key, (unsigned char*)iv, 1) == 0) - return -7370; + return -8247; if (EVP_CIPHER_CTX_set_padding(&en, 0) != 1) - return -7372; + return -8248; if (EVP_CipherUpdate(&en, (byte*)cipher, &outlen, (byte*)cbcPlain, EVP_TEST_BUF_SZ) == 0) - return -7372; + return -8249; if (outlen != 16) - return -7373; + return -8250; total += outlen; /* should fail here */ if (EVP_CipherFinal(&en, (byte*)&cipher[total], &outlen) != 0) - return -7374; + return -8251; /* turn padding back on and do successful encrypt */ total = 0; EVP_CIPHER_CTX_init(&en); if (EVP_CipherInit(&en, EVP_aes_128_cbc(), (unsigned char*)key, (unsigned char*)iv, 1) == 0) - return -7375; + return -8252; if (EVP_CIPHER_CTX_set_padding(&en, 1) != 1) - return -7376; + return -8253; if (EVP_CipherUpdate(&en, (byte*)padded, &outlen, (byte*)cbcPlain, EVP_TEST_BUF_SZ) == 0) - return -7377; + return -8254; if (outlen != 16) - return -7378; + return -8255; total += outlen; if (EVP_CipherFinal(&en, (byte*)&padded[total], &outlen) == 0) - return -7379; + return -8256; total += outlen; if (total != 32) - return -7380; + return -8257; XMEMCPY(cipher, padded, EVP_TEST_BUF_SZ); /* test out of bounds read on buffers w/o padding during decryption */ @@ -14895,39 +15045,39 @@ static int openssl_aes_test(void) EVP_CIPHER_CTX_init(&de); if (EVP_CipherInit(&de, EVP_aes_128_cbc(), (unsigned char*)key, (unsigned char*)iv, 0) == 0) - return -7381; + return -8258; if (EVP_CIPHER_CTX_set_padding(&de, 0) != 1) - return -7382; + return -8259; if (EVP_CipherUpdate(&de, (byte*)plain, &outlen, (byte*)cipher, EVP_TEST_BUF_SZ) == 0) - return -7383; + return -8260; if (outlen != 16) - return -7384; + return -8261; total += outlen; /* should fail since not using padding */ if (EVP_CipherFinal(&de, (byte*)&plain[total], &outlen) != 0) - return -7385; + return -8262; total = 0; EVP_CIPHER_CTX_init(&de); if (EVP_CipherInit(&de, EVP_aes_128_cbc(), (unsigned char*)key, (unsigned char*)iv, 0) == 0) - return -7386; + return -8263; if (EVP_CIPHER_CTX_set_padding(&de, 1) != 1) - return -7387; + return -8264; if (EVP_CipherUpdate(&de, (byte*)padded, &outlen, (byte*)padded, EVP_TEST_BUF_PAD) == 0) - return -7388; + return -8265; if (outlen != 16) - return -7389; + return -8266; total += outlen; if (EVP_CipherFinal(&de, (byte*)&padded[total], &outlen) == 0) - return -7390; + return -8267; if (XMEMCMP(padded, cbcPlain, EVP_TEST_BUF_SZ)) - return -7391; + return -8268; } { /* evp_cipher test: EVP_aes_128_cbc */ @@ -14953,23 +15103,23 @@ static int openssl_aes_test(void) EVP_CIPHER_CTX_init(&ctx); if (EVP_CipherInit(&ctx, EVP_aes_128_cbc(), key, iv, 1) == 0) - return -7335; + return -8269; if (EVP_Cipher(&ctx, cipher, (byte*)msg, 16) == 0) - return -7336; + return -8270; if (XMEMCMP(cipher, verify, AES_BLOCK_SIZE)) - return -7337; + return -8271; EVP_CIPHER_CTX_init(&ctx); if (EVP_CipherInit(&ctx, EVP_aes_128_cbc(), key, iv, 0) == 0) - return -7338; + return -8272; if (EVP_Cipher(&ctx, plain, cipher, 16) == 0) - return -7339; + return -8273; if (XMEMCMP(plain, msg, AES_BLOCK_SIZE)) - return -7340; + return -8274; } /* end evp_cipher test: EVP_aes_128_cbc*/ @@ -15005,23 +15155,23 @@ static int openssl_aes_test(void) EVP_CIPHER_CTX_init(&ctx); if (EVP_CipherInit(&ctx, EVP_aes_256_ecb(), (unsigned char*)key, NULL, 1) == 0) - return -7322; + return -8275; if (EVP_Cipher(&ctx, cipher, (byte*)msg, 16) == 0) - return -7323; + return -8276; if (XMEMCMP(cipher, verify, AES_BLOCK_SIZE)) - return -7324; + return -8277; EVP_CIPHER_CTX_init(&ctx); if (EVP_CipherInit(&ctx, EVP_aes_256_ecb(), (unsigned char*)key, NULL, 0) == 0) - return -7325; + return -8278; if (EVP_Cipher(&ctx, plain, cipher, 16) == 0) - return -7326; + return -8279; if (XMEMCMP(plain, msg, AES_BLOCK_SIZE)) - return -7327; + return -8280; } /* end evp_cipher test */ #endif /* HAVE_AES_ECB && WOLFSSL_AES_256 */ @@ -15066,11 +15216,11 @@ static int openssl_aes_test(void) #ifdef HAVE_AES_DECRYPT AES_decrypt(cipher, plain, &dec); if (XMEMCMP(plain, msg, AES_BLOCK_SIZE)) - return -7328; + return -8281; #endif /* HAVE_AES_DECRYPT */ if (XMEMCMP(cipher, verify, AES_BLOCK_SIZE)) - return -7329; + return -8282; } #endif /* WOLFSSL_AES_DIRECT && WOLFSSL_AES_256 */ @@ -15195,130 +15345,130 @@ static int openssl_aes_test(void) EVP_CIPHER_CTX_init(&en); if (EVP_CipherInit(&en, EVP_aes_128_ctr(), (unsigned char*)ctrKey, (unsigned char*)ctrIv, 0) == 0) - return -7330; + return -8283; if (EVP_Cipher(&en, (byte*)cipherBuff, (byte*)ctrPlain, AES_BLOCK_SIZE*4) == 0) - return -7331; + return -8284; EVP_CIPHER_CTX_init(&de); if (EVP_CipherInit(&de, EVP_aes_128_ctr(), (unsigned char*)ctrKey, (unsigned char*)ctrIv, 0) == 0) - return -7332; + return -8285; if (EVP_Cipher(&de, (byte*)plainBuff, (byte*)cipherBuff, AES_BLOCK_SIZE*4) == 0) - return -7333; + return -8286; if (XMEMCMP(cipherBuff, ctrCipher, AES_BLOCK_SIZE*4)) - return -7334; + return -8287; if (XMEMCMP(plainBuff, ctrPlain, AES_BLOCK_SIZE*4)) - return -7335; + return -8288; p_en = wolfSSL_EVP_CIPHER_CTX_new(); if (p_en == NULL) - return -7336; + return -8289; p_de = wolfSSL_EVP_CIPHER_CTX_new(); if (p_de == NULL) - return -7337; + return -8290; if (EVP_CipherInit(p_en, EVP_aes_128_ctr(), (unsigned char*)ctrKey, (unsigned char*)ctrIv, 0) == 0) - return -7338; + return -8291; if (EVP_Cipher(p_en, (byte*)cipherBuff, (byte*)ctrPlain, AES_BLOCK_SIZE*4) == 0) - return -7339; + return -8292; if (EVP_CipherInit(p_de, EVP_aes_128_ctr(), (unsigned char*)ctrKey, (unsigned char*)ctrIv, 0) == 0) - return -7340; + return -8293; if (EVP_Cipher(p_de, (byte*)plainBuff, (byte*)cipherBuff, AES_BLOCK_SIZE*4) == 0) - return -7341; + return -8294; wolfSSL_EVP_CIPHER_CTX_free(p_en); wolfSSL_EVP_CIPHER_CTX_free(p_de); if (XMEMCMP(cipherBuff, ctrCipher, AES_BLOCK_SIZE*4)) - return -7342; + return -8295; if (XMEMCMP(plainBuff, ctrPlain, AES_BLOCK_SIZE*4)) - return -7343; + return -8296; EVP_CIPHER_CTX_init(&en); if (EVP_CipherInit(&en, EVP_aes_128_ctr(), (unsigned char*)ctrKey, (unsigned char*)ctrIv, 0) == 0) - return -7344; + return -8297; if (EVP_Cipher(&en, (byte*)cipherBuff, (byte*)ctrPlain, 9) == 0) - return -7345; + return -8298; EVP_CIPHER_CTX_init(&de); if (EVP_CipherInit(&de, EVP_aes_128_ctr(), (unsigned char*)ctrKey, (unsigned char*)ctrIv, 0) == 0) - return -7346; + return -8299; if (EVP_Cipher(&de, (byte*)plainBuff, (byte*)cipherBuff, 9) == 0) - return -7347; + return -8300; if (XMEMCMP(plainBuff, ctrPlain, 9)) - return -7348; + return -8301; if (XMEMCMP(cipherBuff, ctrCipher, 9)) - return -7349; + return -8302; if (EVP_Cipher(&en, (byte*)cipherBuff, (byte*)ctrPlain, 9) == 0) - return -7350; + return -8303; if (EVP_Cipher(&de, (byte*)plainBuff, (byte*)cipherBuff, 9) == 0) - return -7351; + return -8304; if (XMEMCMP(plainBuff, ctrPlain, 9)) - return -7352; + return -8305; if (XMEMCMP(cipherBuff, oddCipher, 9)) - return -7353; + return -8306; #endif /* WOLFSSL_AES_128 */ #ifdef WOLFSSL_AES_192 EVP_CIPHER_CTX_init(&en); if (EVP_CipherInit(&en, EVP_aes_192_ctr(), (unsigned char*)ctr192Key, (unsigned char*)ctr192Iv, 0) == 0) - return -7354; + return -8307; if (EVP_Cipher(&en, (byte*)cipherBuff, (byte*)ctr192Plain, AES_BLOCK_SIZE) == 0) - return -7355; + return -8308; EVP_CIPHER_CTX_init(&de); if (EVP_CipherInit(&de, EVP_aes_192_ctr(), (unsigned char*)ctr192Key, (unsigned char*)ctr192Iv, 0) == 0) - return -7356; + return -8309; XMEMSET(plainBuff, 0, sizeof(plainBuff)); if (EVP_Cipher(&de, (byte*)plainBuff, (byte*)cipherBuff, AES_BLOCK_SIZE) == 0) - return -7357; + return -8310; if (XMEMCMP(plainBuff, ctr192Plain, sizeof(ctr192Plain))) - return -7358; + return -8311; if (XMEMCMP(ctr192Cipher, cipherBuff, sizeof(ctr192Cipher))) - return -7359; + return -8312; #endif /* WOLFSSL_AES_192 */ #ifdef WOLFSSL_AES_256 EVP_CIPHER_CTX_init(&en); if (EVP_CipherInit(&en, EVP_aes_256_ctr(), (unsigned char*)ctr256Key, (unsigned char*)ctr256Iv, 0) == 0) - return -7360; + return -8313; if (EVP_Cipher(&en, (byte*)cipherBuff, (byte*)ctr256Plain, AES_BLOCK_SIZE) == 0) - return -7361; + return -8314; EVP_CIPHER_CTX_init(&de); if (EVP_CipherInit(&de, EVP_aes_256_ctr(), (unsigned char*)ctr256Key, (unsigned char*)ctr256Iv, 0) == 0) - return -7362; + return -8315; XMEMSET(plainBuff, 0, sizeof(plainBuff)); if (EVP_Cipher(&de, (byte*)plainBuff, (byte*)cipherBuff, AES_BLOCK_SIZE) == 0) - return -7363; + return -8316; if (XMEMCMP(plainBuff, ctr256Plain, sizeof(ctr256Plain))) - return -7364; + return -8317; if (XMEMCMP(ctr256Cipher, cipherBuff, sizeof(ctr256Cipher))) - return -7365; + return -8318; #endif /* WOLFSSL_AES_256 */ } #endif /* HAVE_AES_COUNTER */ @@ -15367,20 +15517,20 @@ static int openssl_aes_test(void) &num, AES_ENCRYPT); if (XMEMCMP(cipher, cipher1, AES_BLOCK_SIZE - 1)) - return -7366; + return -8319; if (num != 15) /* should have used 15 of the 16 bytes */ - return -7367; + return -8320; wolfSSL_AES_cfb128_encrypt(msg + AES_BLOCK_SIZE - 1, cipher + AES_BLOCK_SIZE - 1, AES_BLOCK_SIZE + 1, &enc, iv, &num, AES_ENCRYPT); if (XMEMCMP(cipher, cipher1, AES_BLOCK_SIZE * 2)) - return -7368; + return -8321; if (num != 0) - return -7369; + return -8322; } #endif /* WOLFSSL_AES_CFB && WOLFSSL_AES_128 */ return 0; @@ -15410,7 +15560,7 @@ int openssl_test(void) byte* p; p = (byte*)CRYPTO_malloc(10, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (p == NULL) { - return -7400; + return -8400; } XMEMSET(p, 0, 10); #ifdef WOLFSSL_QT @@ -15436,7 +15586,7 @@ int openssl_test(void) EVP_DigestFinal(&md_ctx, hash, 0); if (XMEMCMP(hash, a.output, WC_MD5_DIGEST_SIZE) != 0) - return -7401; + return -8401; #endif /* NO_MD5 */ @@ -15457,7 +15607,7 @@ int openssl_test(void) EVP_DigestFinal(&md_ctx, hash, 0); if (XMEMCMP(hash, b.output, WC_SHA_DIGEST_SIZE) != 0) - return -7402; + return -8402; #endif /* NO_SHA */ @@ -15477,7 +15627,7 @@ int openssl_test(void) EVP_DigestFinal(&md_ctx, hash, 0); if (XMEMCMP(hash, e.output, WC_SHA224_DIGEST_SIZE) != 0) - return -7403; + return -8403; #endif /* WOLFSSL_SHA224 */ @@ -15496,7 +15646,7 @@ int openssl_test(void) EVP_DigestFinal(&md_ctx, hash, 0); if (XMEMCMP(hash, d.output, WC_SHA256_DIGEST_SIZE) != 0) - return -7404; + return -8404; #ifdef WOLFSSL_SHA384 @@ -15516,7 +15666,7 @@ int openssl_test(void) EVP_DigestFinal(&md_ctx, hash, 0); if (XMEMCMP(hash, e.output, WC_SHA384_DIGEST_SIZE) != 0) - return -7405; + return -8405; #endif /* WOLFSSL_SHA384 */ @@ -15540,7 +15690,7 @@ int openssl_test(void) EVP_DigestFinal(&md_ctx, hash, 0); if (XMEMCMP(hash, f.output, WC_SHA512_DIGEST_SIZE) != 0) - return -7406; + return -8406; #endif /* WOLFSSL_SHA512 */ #ifdef WOLFSSL_SHA3 @@ -15559,7 +15709,7 @@ int openssl_test(void) EVP_DigestFinal(&md_ctx, hash, 0); if (XMEMCMP(hash, e.output, WC_SHA3_224_DIGEST_SIZE) != 0) - return -7403; + return -8407; #endif /* WOLFSSL_NOSHA3_224 */ @@ -15580,7 +15730,7 @@ int openssl_test(void) EVP_DigestFinal(&md_ctx, hash, 0); if (XMEMCMP(hash, d.output, WC_SHA3_256_DIGEST_SIZE) != 0) - return -7404; + return -8408; #endif /* WOLFSSL_NOSHA3_256 */ @@ -15597,7 +15747,7 @@ int openssl_test(void) EVP_DigestFinal(&md_ctx, hash, 0); if (XMEMCMP(hash, e.output, WC_SHA3_384_DIGEST_SIZE) != 0) - return -7405; + return -8409; @@ -15616,14 +15766,14 @@ int openssl_test(void) EVP_DigestFinal(&md_ctx, hash, 0); if (XMEMCMP(hash, f.output, WC_SHA3_512_DIGEST_SIZE) != 0) - return -7406; + return -8410; #endif /* WOLFSSL_NOSHA3_512 */ #endif /* WOLFSSL_SHA3 */ #ifndef NO_MD5 if (RAND_bytes(hash, sizeof(hash)) != 1) - return -7407; + return -8411; c.input = "what do ya want for nothing?"; c.output = "\x55\x78\xe8\x48\x4b\xcc\x93\x80\x93\xec\x53\xaf\x22\xd6\x14" @@ -15635,7 +15785,7 @@ int openssl_test(void) "JefeJefeJefeJefe", 16, (byte*)c.input, (int)c.inLen, hash, 0); if (XMEMCMP(hash, c.output, WC_MD5_DIGEST_SIZE) != 0) - return -7408; + return -8412; #endif /* NO_MD5 */ @@ -15675,17 +15825,17 @@ int openssl_test(void) DES_cbc_encrypt(cipher, plain, sizeof(vector), &sched, &iv, DES_DECRYPT); if (XMEMCMP(plain, vector, sizeof(vector)) != 0) - return -7409; + return -8413; if (XMEMCMP(cipher, verify, sizeof(verify)) != 0) - return -7410; + return -8414; /* test changing iv */ DES_ncbc_encrypt(vector, cipher, 8, &sched, &iv, DES_ENCRYPT); DES_ncbc_encrypt(vector + 8, cipher + 8, 16, &sched, &iv, DES_ENCRYPT); if (XMEMCMP(cipher, verify, sizeof(verify)) != 0) - return -7411; + return -8415; } /* end des test */ @@ -15693,7 +15843,7 @@ int openssl_test(void) #if !defined(NO_AES) && !defined(WOLFCRYPT_ONLY) if (openssl_aes_test() != 0) { - return -7412; + return -8416; } #if defined(WOLFSSL_AES_128) && defined(HAVE_AES_CBC) @@ -15731,62 +15881,62 @@ int openssl_test(void) EVP_CIPHER_CTX_init(&ctx); if (EVP_CipherInit(&ctx, EVP_aes_128_cbc(), key, iv, 1) == 0) - return -7413; + return -8417; if (EVP_CipherUpdate(&ctx, cipher, &idx, (byte*)msg, sizeof(msg)) == 0) - return -7414; + return -8418; cipherSz = idx; if (EVP_CipherFinal(&ctx, cipher + cipherSz, &idx) == 0) - return -7415; + return -8419; cipherSz += idx; if ((cipherSz != (int)sizeof(verify)) && XMEMCMP(cipher, verify, cipherSz)) - return -7416; + return -8420; EVP_CIPHER_CTX_init(&ctx); if (EVP_CipherInit(&ctx, EVP_aes_128_cbc(), key, iv, 0) == 0) - return -7417; + return -8421; /* check partial decrypt (not enough padding for full block) */ if (EVP_CipherUpdate(&ctx, plain, &idx, cipher, 1) == 0) - return -7418; + return -8422; plainSz = idx; if (EVP_CipherFinal(&ctx, plain + plainSz, &idx) != 0) - return -7419; + return -8423; EVP_CIPHER_CTX_init(&ctx); if (EVP_CipherInit(&ctx, EVP_aes_128_cbc(), key, iv, 0) == 0) - return -7420; + return -8424; if (EVP_CipherUpdate(&ctx, plain, &idx, cipher, cipherSz) == 0) - return -7421; + return -8425; plainSz = idx; if (EVP_CipherFinal(&ctx, plain + plainSz, &idx) == 0) - return -7422; + return -8426; plainSz += idx; if ((plainSz != sizeof(msg)) || XMEMCMP(plain, msg, sizeof(msg))) - return -7423; + return -8427; EVP_CIPHER_CTX_init(&ctx); if (EVP_CipherInit(&ctx, EVP_aes_128_cbc(), key, iv, 1) == 0) - return -7424; + return -8428; if (EVP_CipherUpdate(&ctx, cipher, &idx, msg, AES_BLOCK_SIZE) == 0) - return -7425; + return -8429; cipherSz = idx; if (EVP_CipherFinal(&ctx, cipher + cipherSz, &idx) == 0) - return -7426; + return -8430; cipherSz += idx; if ((cipherSz != (int)sizeof(verify2)) || XMEMCMP(cipher, verify2, cipherSz)) - return -7427; + return -8431; } /* end evp_cipher test: EVP_aes_128_cbc*/ #endif /* WOLFSSL_AES_128 && HAVE_AES_CBC */ @@ -15821,24 +15971,24 @@ int openssl_test(void) EVP_CIPHER_CTX_init(&ctx); if (EVP_CipherInit(&ctx, EVP_aes_256_ecb(), (unsigned char*)key, NULL, 1) == 0) - return -7425; + return -8432; if (EVP_Cipher(&ctx, cipher, (byte*)msg, 16) == 0) - return -7426; + return -8433; if (XMEMCMP(cipher, verify, AES_BLOCK_SIZE)) - return -7427; + return -8434; EVP_CIPHER_CTX_init(&ctx); if (EVP_CipherInit(&ctx, EVP_aes_256_ecb(), (unsigned char*)key, NULL, 0) == 0) - return -7428; + return -8435; if (EVP_Cipher(&ctx, plain, cipher, 16) == 0) - return -7429; + return -8436; if (XMEMCMP(plain, msg, AES_BLOCK_SIZE)) - return -7430; + return -8437; } /* end evp_cipher test */ #endif /* HAVE_AES_ECB && WOLFSSL_AES_128 */ @@ -16019,128 +16169,128 @@ int openssl_test(void) EVP_CIPHER_CTX_init(&en); if (EVP_CipherInit(&en, EVP_aes_128_ctr(), (unsigned char*)ctrKey, (unsigned char*)ctrIv, 0) == 0) - return -7431; + return -8438; if (EVP_Cipher(&en, (byte*)cipherBuff, (byte*)ctrPlain, AES_BLOCK_SIZE*4) == 0) - return -7432; + return -8439; EVP_CIPHER_CTX_init(&de); if (EVP_CipherInit(&de, EVP_aes_128_ctr(), (unsigned char*)ctrKey, (unsigned char*)ctrIv, 0) == 0) - return -7433; + return -8440; if (EVP_Cipher(&de, (byte*)plainBuff, (byte*)cipherBuff, AES_BLOCK_SIZE*4) == 0) - return -7434; + return -8441; if (XMEMCMP(cipherBuff, ctrCipher, AES_BLOCK_SIZE*4)) - return -7435; + return -8442; if (XMEMCMP(plainBuff, ctrPlain, AES_BLOCK_SIZE*4)) - return -7436; + return -8443; p_en = wolfSSL_EVP_CIPHER_CTX_new(); - if(p_en == NULL)return -7437; + if(p_en == NULL)return -8444; p_de = wolfSSL_EVP_CIPHER_CTX_new(); - if(p_de == NULL)return -7438; + if(p_de == NULL)return -8445; if (EVP_CipherInit(p_en, EVP_aes_128_ctr(), (unsigned char*)ctrKey, (unsigned char*)ctrIv, 0) == 0) - return -7439; + return -8446; if (EVP_Cipher(p_en, (byte*)cipherBuff, (byte*)ctrPlain, AES_BLOCK_SIZE*4) == 0) - return -7440; + return -8447; if (EVP_CipherInit(p_de, EVP_aes_128_ctr(), (unsigned char*)ctrKey, (unsigned char*)ctrIv, 0) == 0) - return -7441; + return -8448; if (EVP_Cipher(p_de, (byte*)plainBuff, (byte*)cipherBuff, AES_BLOCK_SIZE*4) == 0) - return -7442; + return -8449; wolfSSL_EVP_CIPHER_CTX_free(p_en); wolfSSL_EVP_CIPHER_CTX_free(p_de); if (XMEMCMP(cipherBuff, ctrCipher, AES_BLOCK_SIZE*4)) - return -7443; + return -8450; if (XMEMCMP(plainBuff, ctrPlain, AES_BLOCK_SIZE*4)) - return -7444; + return -8451; EVP_CIPHER_CTX_init(&en); if (EVP_CipherInit(&en, EVP_aes_128_ctr(), (unsigned char*)ctrKey, (unsigned char*)ctrIv, 0) == 0) - return -7445; + return -8452; if (EVP_Cipher(&en, (byte*)cipherBuff, (byte*)ctrPlain, 9) == 0) - return -7446; + return -8453; EVP_CIPHER_CTX_init(&de); if (EVP_CipherInit(&de, EVP_aes_128_ctr(), (unsigned char*)ctrKey, (unsigned char*)ctrIv, 0) == 0) - return -7447; + return -8454; if (EVP_Cipher(&de, (byte*)plainBuff, (byte*)cipherBuff, 9) == 0) - return -7448; + return -8455; if (XMEMCMP(plainBuff, ctrPlain, 9)) - return -7449; + return -8456; if (XMEMCMP(cipherBuff, ctrCipher, 9)) - return -7450; + return -8457; if (EVP_Cipher(&en, (byte*)cipherBuff, (byte*)ctrPlain, 9) == 0) - return -7451; + return -8458; if (EVP_Cipher(&de, (byte*)plainBuff, (byte*)cipherBuff, 9) == 0) - return -7452; + return -8459; if (XMEMCMP(plainBuff, ctrPlain, 9)) - return -7453; + return -8460; if (XMEMCMP(cipherBuff, oddCipher, 9)) - return -7454; + return -8461; #endif /* WOLFSSL_AES_128 */ #ifdef WOLFSSL_AES_192 EVP_CIPHER_CTX_init(&en); if (EVP_CipherInit(&en, EVP_aes_192_ctr(), (unsigned char*)ctr192Key, (unsigned char*)ctr192Iv, 0) == 0) - return -7455; + return -8462; if (EVP_Cipher(&en, (byte*)cipherBuff, (byte*)ctr192Plain, AES_BLOCK_SIZE) == 0) - return -7456; + return -8463; EVP_CIPHER_CTX_init(&de); if (EVP_CipherInit(&de, EVP_aes_192_ctr(), (unsigned char*)ctr192Key, (unsigned char*)ctr192Iv, 0) == 0) - return -7457; + return -8464; XMEMSET(plainBuff, 0, sizeof(plainBuff)); if (EVP_Cipher(&de, (byte*)plainBuff, (byte*)cipherBuff, AES_BLOCK_SIZE) == 0) - return -7458; + return -8465; if (XMEMCMP(plainBuff, ctr192Plain, sizeof(ctr192Plain))) - return -7459; + return -8466; if (XMEMCMP(ctr192Cipher, cipherBuff, sizeof(ctr192Cipher))) - return -7460; + return -8467; #endif /* WOLFSSL_AES_192 */ #ifdef WOLFSSL_AES_256 EVP_CIPHER_CTX_init(&en); if (EVP_CipherInit(&en, EVP_aes_256_ctr(), (unsigned char*)ctr256Key, (unsigned char*)ctr256Iv, 0) == 0) - return -7461; + return -8468; if (EVP_Cipher(&en, (byte*)cipherBuff, (byte*)ctr256Plain, AES_BLOCK_SIZE) == 0) - return -7462; + return -8469; EVP_CIPHER_CTX_init(&de); if (EVP_CipherInit(&de, EVP_aes_256_ctr(), (unsigned char*)ctr256Key, (unsigned char*)ctr256Iv, 0) == 0) - return -7463; + return -8470; XMEMSET(plainBuff, 0, sizeof(plainBuff)); if (EVP_Cipher(&de, (byte*)plainBuff, (byte*)cipherBuff, AES_BLOCK_SIZE) == 0) - return -7464; + return -8471; if (XMEMCMP(plainBuff, ctr256Plain, sizeof(ctr256Plain))) - return -7465; + return -8472; if (XMEMCMP(ctr256Cipher, cipherBuff, sizeof(ctr256Cipher))) - return -7466; + return -8473; #endif /* WOLFSSL_AES_256 */ } #endif /* HAVE_AES_COUNTER */ @@ -16175,96 +16325,96 @@ int openssl_test(void) EVP_CIPHER_CTX_init(&en); if (EVP_CipherInit(&en, EVP_aes_128_cbc(), (unsigned char*)key, (unsigned char*)iv, 1) == 0) - return -7467; + return -8474; /* openSSL compatibility, if(inlen == 0)return 1; */ if (EVP_CipherUpdate(&en, (byte*)cipher, &outlen, (byte*)cbcPlain, 0) != 1) - return -7468; + return -8475; EVP_CIPHER_CTX_init(&en); if (EVP_CipherInit(&en, EVP_aes_128_cbc(), (unsigned char*)key, (unsigned char*)iv, 1) == 0) - return -7469; + return -8476; if (EVP_CipherUpdate(&en, (byte*)cipher, &outlen, (byte*)cbcPlain, 9) == 0) - return -7470; + return -8477; if(outlen != 0) - return -7471; + return -8478; total += outlen; if (EVP_CipherUpdate(&en, (byte*)&cipher[total], &outlen, (byte*)&cbcPlain[9] , 9) == 0) - return -7472; + return -8479; if(outlen != 16) - return -7473; + return -8480; total += outlen; if (EVP_CipherFinal(&en, (byte*)&cipher[total], &outlen) == 0) - return -7474; + return -8481; if(outlen != 16) - return -7475; + return -8482; total += outlen; if(total != 32) - return -7476; + return -8483; total = 0; EVP_CIPHER_CTX_init(&de); if (EVP_CipherInit(&de, EVP_aes_128_cbc(), (unsigned char*)key, (unsigned char*)iv, 0) == 0) - return -7477; + return -8484; if (EVP_CipherUpdate(&de, (byte*)plain, &outlen, (byte*)cipher, 6) == 0) - return -7478; + return -8485; if(outlen != 0) - return -7479; + return -8486; total += outlen; if (EVP_CipherUpdate(&de, (byte*)&plain[total], &outlen, (byte*)&cipher[6], 12) == 0) - return -7480; + return -8487; if(outlen != 0) total += outlen; if (EVP_CipherUpdate(&de, (byte*)&plain[total], &outlen, (byte*)&cipher[6+12], 14) == 0) - return -7481; + return -8488; if(outlen != 16) - return -7482; + return -8489; total += outlen; if (EVP_CipherFinal(&de, (byte*)&plain[total], &outlen) == 0) - return -7483; + return -8490; if(outlen != 2) - return -7484; + return -8491; total += outlen; if(total != 18) - return -7485; + return -8492; if (XMEMCMP(plain, cbcPlain, 18)) - return -7486; + return -8493; total = 0; EVP_CIPHER_CTX_init(&en); if (EVP_EncryptInit(&en, EVP_aes_128_cbc(), (unsigned char*)key, (unsigned char*)iv) == 0) - return -7487; + return -8494; if (EVP_CipherUpdate(&en, (byte*)cipher, &outlen, (byte*)cbcPlain, 9) == 0) - return -7488; + return -8495; if(outlen != 0) - return -7489; + return -8496; total += outlen; if (EVP_CipherUpdate(&en, (byte*)&cipher[total], &outlen, (byte*)&cbcPlain[9] , 9) == 0) - return -7490; + return -8497; if(outlen != 16) - return -7491; + return -8498; total += outlen; if (EVP_EncryptFinal(&en, (byte*)&cipher[total], &outlen) == 0) - return -7492; + return -8499; if(outlen != 16) - return -7493; + return -8500; total += outlen; if(total != 32) return 3438; @@ -16273,108 +16423,108 @@ int openssl_test(void) EVP_CIPHER_CTX_init(&de); if (EVP_DecryptInit(&de, EVP_aes_128_cbc(), (unsigned char*)key, (unsigned char*)iv) == 0) - return -7494; + return -8501; if (EVP_CipherUpdate(&de, (byte*)plain, &outlen, (byte*)cipher, 6) == 0) - return -7495; + return -8502; if(outlen != 0) - return -7496; + return -8503; total += outlen; if (EVP_CipherUpdate(&de, (byte*)&plain[total], &outlen, (byte*)&cipher[6], 12) == 0) - return -7497; + return -8504; if(outlen != 0) total += outlen; if (EVP_CipherUpdate(&de, (byte*)&plain[total], &outlen, (byte*)&cipher[6+12], 14) == 0) - return -7498; + return -8505; if(outlen != 16) - return -7499; + return -8506; total += outlen; if (EVP_DecryptFinal(&de, (byte*)&plain[total], &outlen) == 0) - return -7500; + return -8507; if(outlen != 2) - return -7501; + return -8508; total += outlen; if(total != 18) return 3447; if (XMEMCMP(plain, cbcPlain, 18)) - return -7502; + return -8509; if (EVP_CIPHER_key_length(NULL) != 0) - return -7503; + return -8510; if (EVP_CIPHER_key_length(EVP_aes_128_cbc()) != 16) - return -7504; + return -8511; if (EVP_CIPHER_CTX_mode(NULL) != 0) - return -7505; + return -8512; if (EVP_CIPHER_CTX_mode(&en) != (en.flags & WOLFSSL_EVP_CIPH_MODE)) - return -7506; + return -8513; EVP_CIPHER_CTX_init(&en); if (EVP_CipherInit_ex(&en, EVP_aes_128_cbc(), NULL, (unsigned char*)key, (unsigned char*)iv, 0) == 0) - return -7507; + return -8514; EVP_CIPHER_CTX_init(&en); if (EVP_EncryptInit_ex(&en, EVP_aes_128_cbc(), NULL, (unsigned char*)key, (unsigned char*)iv) == 0) - return -7508; + return -8515; if (wolfSSL_EVP_EncryptFinal_ex(NULL, NULL, NULL) != WOLFSSL_FAILURE) - return -7509; + return -8516; if (wolfSSL_EVP_EncryptFinal(NULL, NULL, NULL) != WOLFSSL_FAILURE) - return -7510; + return -8517; EVP_CIPHER_CTX_init(&de); if (EVP_DecryptInit_ex(&de, EVP_aes_128_cbc(), NULL, (unsigned char*)key, (unsigned char*)iv) == 0) - return -7511; + return -8518; if (wolfSSL_EVP_DecryptFinal(NULL, NULL, NULL) != WOLFSSL_FAILURE) - return -7512; + return -8519; if (wolfSSL_EVP_DecryptFinal_ex(NULL, NULL, NULL) != WOLFSSL_FAILURE) - return -7513; + return -8520; if (EVP_CIPHER_CTX_block_size(NULL) != BAD_FUNC_ARG) - return -7514; + return -8521; EVP_CIPHER_CTX_init(&en); EVP_EncryptInit_ex(&en, EVP_aes_128_cbc(), NULL, (unsigned char*)key, (unsigned char*)iv); if (EVP_CIPHER_CTX_block_size(&en) != en.block_size) - return -7514; + return -8522; if (EVP_CIPHER_block_size(NULL) != BAD_FUNC_ARG) - return -7515; + return -8523; if (EVP_CIPHER_block_size(EVP_aes_128_cbc()) != AES_BLOCK_SIZE) - return -7516; + return -8524; if (WOLFSSL_EVP_CIPHER_mode(NULL) != 0) - return -7517; + return -8525; if (EVP_CIPHER_flags(EVP_aes_128_cbc()) != WOLFSSL_EVP_CIPH_CBC_MODE) - return -7518; + return -8526; EVP_CIPHER_CTX_clear_flags(&en, 0xFFFFFFFF); EVP_CIPHER_CTX_set_flags(&en, 42); if (en.flags != 42) - return -7519; + return -8527; if (EVP_CIPHER_CTX_set_padding(NULL, 0) != BAD_FUNC_ARG) - return -7520; + return -8528; if (EVP_CIPHER_CTX_set_padding(&en, 0) != WOLFSSL_SUCCESS) - return -7521; + return -8529; if (EVP_CIPHER_CTX_set_padding(&en, 1) != WOLFSSL_SUCCESS) - return -7522; + return -8530; } #endif /* WOLFSSL_AES_128 && HAVE_AES_CBC */ @@ -16394,60 +16544,60 @@ int openSSL_evpMD_test(void) ret = EVP_DigestInit(ctx, EVP_sha256()); if (ret != SSL_SUCCESS) { - ret = -7600; + ret = -8600; goto openSSL_evpMD_test_done; } ret = EVP_MD_CTX_copy(ctx2, ctx); if (ret != SSL_SUCCESS) { - ret = -7601; + ret = -8601; goto openSSL_evpMD_test_done; } if (EVP_MD_type(EVP_sha256()) != EVP_MD_CTX_type(ctx2)) { - ret = -7602; + ret = -8602; goto openSSL_evpMD_test_done; } ret = EVP_DigestInit(ctx, EVP_sha1()); if (ret != SSL_SUCCESS) { - ret = -7603; + ret = -8603; goto openSSL_evpMD_test_done; } if (EVP_MD_type(EVP_sha256()) != EVP_MD_CTX_type(ctx2)) { - ret = -7604; + ret = -8604; goto openSSL_evpMD_test_done; } ret = EVP_MD_CTX_copy_ex(ctx2, ctx); if (ret != SSL_SUCCESS) { - ret = -7605; + ret = -8605; goto openSSL_evpMD_test_done; } if (EVP_MD_type(EVP_sha256()) == EVP_MD_CTX_type(ctx2)) { - ret = -7606; + ret = -8606; goto openSSL_evpMD_test_done; } if (EVP_MD_type(EVP_sha1()) != EVP_MD_CTX_type(ctx2)) { - ret = -7607; + ret = -8607; goto openSSL_evpMD_test_done; } if (EVP_DigestInit_ex(ctx, EVP_sha1(), NULL) != SSL_SUCCESS) { - ret = -7608; + ret = -8608; goto openSSL_evpMD_test_done; } if (EVP_add_digest(NULL) != 0) { - ret = -7609; + ret = -8609; goto openSSL_evpMD_test_done; } if (wolfSSL_EVP_add_cipher(NULL) != 0) { - ret = -7610; + ret = -8610; goto openSSL_evpMD_test_done; } @@ -16750,7 +16900,7 @@ int openssl_pkey1_test(void) if (!f) { err_sys("can't open ./certs/client-key.der, " "Please run from wolfSSL home dir", -41); - return -7700; + return -8800; } cliKeySz = (long)XFREAD(tmp, 1, FOURK_BUF, f); @@ -16762,69 +16912,69 @@ int openssl_pkey1_test(void) clikey = tmp; if ((prvKey = EVP_PKEY_new()) == NULL) { - return -7701; + return -8801; } EVP_PKEY_free(prvKey); prvKey = NULL; if (x509 == NULL) { - ret = -7702; + ret = -8802; goto openssl_pkey1_test_done; } pubKey = X509_get_pubkey(x509); if (pubKey == NULL) { - ret = -7703; + ret = -8803; goto openssl_pkey1_test_done; } prvKey = d2i_PrivateKey(EVP_PKEY_RSA, NULL, &clikey, cliKeySz); if (prvKey == NULL) { - ret = -7704; + ret = -8804; goto openssl_pkey1_test_done; } /* phase 2 API to create EVP_PKEY_CTX and encrypt/decrypt */ if (EVP_PKEY_bits(prvKey) != keyLenBits) { - ret = -7705; + ret = -8805; goto openssl_pkey1_test_done; } if (EVP_PKEY_size(prvKey) != keyLenBits/8) { - ret = -7706; + ret = -8806; goto openssl_pkey1_test_done; } dec = EVP_PKEY_CTX_new(prvKey, NULL); enc = EVP_PKEY_CTX_new(pubKey, NULL); if (dec == NULL || enc == NULL) { - ret = -7707; + ret = -8807; goto openssl_pkey1_test_done; } if (EVP_PKEY_decrypt_init(dec) != 1) { - ret = -7708; + ret = -8808; goto openssl_pkey1_test_done; } if (EVP_PKEY_encrypt_init(enc) != 1) { - ret = -7709; + ret = -8809; goto openssl_pkey1_test_done; } if (EVP_PKEY_CTX_set_rsa_padding(dec, RSA_PKCS1_PADDING) <= 0) { - ret = -7710; + ret = -8810; goto openssl_pkey1_test_done; } #ifndef HAVE_FIPS if (EVP_PKEY_CTX_set_rsa_padding(dec, RSA_PKCS1_OAEP_PADDING) <= 0){ - ret = -7711; + ret = -8811; goto openssl_pkey1_test_done; } if (EVP_PKEY_CTX_set_rsa_padding(enc, RSA_PKCS1_OAEP_PADDING) <= 0) { - ret = -7712; + ret = -8812; goto openssl_pkey1_test_done; } #endif @@ -16832,13 +16982,13 @@ int openssl_pkey1_test(void) XMEMSET(cipher, 0, sizeof(cipher)); outlen = keyLenBits/8; if (EVP_PKEY_encrypt(enc, cipher, &outlen, msg, sizeof(msg)) < 0) { - ret = -7713; + ret = -8813; goto openssl_pkey1_test_done; } XMEMSET(plain, 0, sizeof(plain)); if (EVP_PKEY_decrypt(dec, plain, &outlen, cipher, outlen) != 1) { - ret = -7714; + ret = -8814; goto openssl_pkey1_test_done; } @@ -16941,7 +17091,7 @@ int openssl_evpSig_test(void) if((prvRsa == NULL) || (pubRsa == NULL)){ XFREE(pubTmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); XFREE(prvTmp, HEAP_HINT ,DYNAMIC_TYPE_TMP_BUFFER); - err_sys("ERROR with RSA_new", -41); + err_sys("ERROR with RSA_new", -8900); return ERR_BASE_EVPSIG-5; } @@ -17095,42 +17245,42 @@ int scrypt_test(void) ret = wc_scrypt(derived, NULL, 0, NULL, 0, 4, 1, 1, sizeof(verify1)); if (ret != 0) - return -7800; + return -9000; if (XMEMCMP(derived, verify1, sizeof(verify1)) != 0) - return -7801; + return -9001; ret = wc_scrypt(derived, (byte*)"password", 8, (byte*)"NaCl", 4, 10, 8, 16, sizeof(verify2)); if (ret != 0) - return -7802; + return -9002; if (XMEMCMP(derived, verify2, sizeof(verify2)) != 0) - return -7803; + return -9003; /* Don't run these test on embedded, since they use large mallocs */ #if !defined(BENCH_EMBEDDED) && !defined(HAVE_INTEL_QA) ret = wc_scrypt(derived, (byte*)"pleaseletmein", 13, (byte*)"SodiumChloride", 14, 14, 8, 1, sizeof(verify3)); if (ret != 0) - return -7804; + return -9004; if (XMEMCMP(derived, verify3, sizeof(verify3)) != 0) - return -7805; + return -9005; #ifdef SCRYPT_TEST_ALL ret = wc_scrypt(derived, (byte*)"pleaseletmein", 13, (byte*)"SodiumChloride", 14, 20, 8, 1, sizeof(verify4)); if (ret != 0) - return -7806; + return -9006; if (XMEMCMP(derived, verify4, sizeof(verify4)) != 0) - return -7807; + return -9007; #endif #endif /* !BENCH_EMBEDDED && !HAVE_INTEL_QA */ ret = wc_scrypt_ex(derived, (byte*)"password", 8, (byte*)"NaCl", 4, 1<<10, 8, 16, sizeof(verify2)); if (ret != 0) - return -7808; + return -9008; if (XMEMCMP(derived, verify2, sizeof(verify2)) != 0) - return -7809; + return -9009; return 0; } @@ -17167,24 +17317,24 @@ int pkcs12_test(void) iterations, kLen, WC_SHA256, id); if (ret < 0) - return -7900; + return -9100; if ( (ret = XMEMCMP(derived, verify, kLen)) != 0) - return -7901; + return -9101; iterations = 1000; ret = wc_PKCS12_PBKDF(derived, passwd2, sizeof(passwd2), salt2, 8, iterations, kLen, WC_SHA256, id); if (ret < 0) - return -7902; + return -9102; ret = wc_PKCS12_PBKDF_ex(derived, passwd2, sizeof(passwd2), salt2, 8, iterations, kLen, WC_SHA256, id, HEAP_HINT); if (ret < 0) - return -7903; + return -9103; if ( (ret = XMEMCMP(derived, verify2, 24)) != 0) - return -7904; + return -9104; return 0; } @@ -17210,7 +17360,7 @@ int pbkdf2_test(void) return ret; if (XMEMCMP(derived, verify, sizeof(verify)) != 0) - return -8000; + return -9200; return 0; @@ -17238,7 +17388,7 @@ int pbkdf1_test(void) return ret; if (XMEMCMP(derived, verify, sizeof(verify)) != 0) - return -8100; + return -9300; return 0; } @@ -17322,38 +17472,38 @@ int hkdf_test(void) #ifndef NO_SHA ret = wc_HKDF(WC_SHA, ikm1, 22, NULL, 0, NULL, 0, okm1, L); if (ret != 0) - return -8200; + return -9500; if (XMEMCMP(okm1, res1, L) != 0) - return -8201; + return -9501; #ifndef HAVE_FIPS /* fips can't have key size under 14 bytes, salt is key too */ ret = wc_HKDF(WC_SHA, ikm1, 11, salt1, 13, info1, 10, okm1, L); if (ret != 0) - return -8202; + return -9502; if (XMEMCMP(okm1, res2, L) != 0) - return -8203; + return -9503; #endif /* HAVE_FIPS */ #endif /* NO_SHA */ #ifndef NO_SHA256 ret = wc_HKDF(WC_SHA256, ikm1, 22, NULL, 0, NULL, 0, okm1, L); if (ret != 0) - return -8204; + return -9504; if (XMEMCMP(okm1, res3, L) != 0) - return -8205; + return -9505; #ifndef HAVE_FIPS /* fips can't have key size under 14 bytes, salt is key too */ ret = wc_HKDF(WC_SHA256, ikm1, 22, salt1, 13, info1, 10, okm1, L); if (ret != 0) - return -8206; + return -9506; if (XMEMCMP(okm1, res4, L) != 0) - return -8207; + return -9507; #endif /* HAVE_FIPS */ #endif /* NO_SHA256 */ @@ -17469,38 +17619,38 @@ int x963kdf_test(void) ret = wc_X963_KDF(WC_HASH_TYPE_SHA, Z, sizeof(Z), NULL, 0, kek, sizeof(verify)); if (ret != 0) - return -8300; + return -9600; if (XMEMCMP(verify, kek, sizeof(verify)) != 0) - return -8301; + return -9601; #endif #ifndef NO_SHA256 ret = wc_X963_KDF(WC_HASH_TYPE_SHA256, Z2, sizeof(Z2), NULL, 0, kek, sizeof(verify2)); if (ret != 0) - return -8302; + return -9602; if (XMEMCMP(verify2, kek, sizeof(verify2)) != 0) - return -8303; + return -9603; #endif #ifdef WOLFSSL_SHA512 ret = wc_X963_KDF(WC_HASH_TYPE_SHA512, Z3, sizeof(Z3), NULL, 0, kek, sizeof(verify3)); if (ret != 0) - return -8304; + return -9604; if (XMEMCMP(verify3, kek, sizeof(verify3)) != 0) - return -8305; + return -9605; ret = wc_X963_KDF(WC_HASH_TYPE_SHA512, Z4, sizeof(Z4), info4, sizeof(info4), kek, sizeof(verify4)); if (ret != 0) - return -8306; + return -9606; if (XMEMCMP(verify4, kek, sizeof(verify4)) != 0) - return -8307; + return -9607; #endif return 0; @@ -17583,7 +17733,7 @@ static int ecc_test_vector_item(const eccVector* vector) goto done; if (sigSz != sigRawSz || XMEMCMP(sig, sigRaw, sigSz) != 0) { - ret = -8308; + ret = -9608; goto done; } #endif @@ -17601,7 +17751,7 @@ static int ecc_test_vector_item(const eccVector* vector) TEST_SLEEP(); if (verify != 1) - ret = -8309; + ret = -9609; done: wc_ecc_free(&userA); @@ -17911,11 +18061,11 @@ static int ecc_test_sign_vectors(WC_RNG* rng) TEST_SLEEP(); if (sigSz != sizeof(expSig)) { - ret = -8350; + ret = -9610; goto done; } if (XMEMCMP(sig, expSig, sigSz) != 0) { - ret = -8351; + ret = -9611; goto done; } @@ -17993,7 +18143,7 @@ static int ecc_test_cdh_vectors(void) /* compare results */ if (x != z || XMEMCMP(sharedA, sharedB, x)) { - ERROR_OUT(-8310, done); + ERROR_OUT(-9612, done); } done: @@ -18030,28 +18180,28 @@ static int ecc_test_make_pub(WC_RNG* rng) #ifdef USE_CERT_BUFFERS_256 tmp = (byte*)XMALLOC((size_t)sizeof_ecc_key_der_256, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (tmp == NULL) { - return -8311; + return -9613; } exportBuf = (byte*)XMALLOC((size_t)sizeof_ecc_key_der_256, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (exportBuf == NULL) { XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - return -8312; + return -9614; } XMEMCPY(tmp, ecc_key_der_256, (size_t)sizeof_ecc_key_der_256); tmpSz = (size_t)sizeof_ecc_key_der_256; #else tmp = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (tmp == NULL) { - return -8311; + return -9615; } exportBuf = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (exportBuf == NULL) { XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - return -8312; + return -9616; } file = XFOPEN(eccKeyDerFile, "rb"); if (!file) { - ERROR_OUT(-8313, done); + ERROR_OUT(-9617, done); } tmpSz = (word32)XFREAD(tmp, 1, FOURK_BUF, file); @@ -18061,25 +18211,25 @@ static int ecc_test_make_pub(WC_RNG* rng) /* import private only then test with */ ret = wc_ecc_import_private_key(tmp, tmpSz, NULL, 0, NULL); if (ret == 0) { - ERROR_OUT(-8314, done); + ERROR_OUT(-9618, done); } ret = wc_ecc_import_private_key(NULL, tmpSz, NULL, 0, &key); if (ret == 0) { - ERROR_OUT(-8315, done); + ERROR_OUT(-9619, done); } x = 0; ret = wc_EccPrivateKeyDecode(tmp, &x, &key, tmpSz); if (ret != 0) { - ERROR_OUT(-8316, done); + ERROR_OUT(-9620, done); } #ifdef HAVE_ECC_KEY_EXPORT x = FOURK_BUF; ret = wc_ecc_export_private_only(&key, exportBuf, &x); if (ret != 0) { - ERROR_OUT(-8317, done); + ERROR_OUT(-9621, done); } /* make private only key */ @@ -18087,31 +18237,31 @@ static int ecc_test_make_pub(WC_RNG* rng) wc_ecc_init_ex(&key, HEAP_HINT, devId); ret = wc_ecc_import_private_key(exportBuf, x, NULL, 0, &key); if (ret != 0) { - ERROR_OUT(-8318, done); + ERROR_OUT(-9622, done); } x = FOURK_BUF; ret = wc_ecc_export_x963_ex(&key, exportBuf, &x, 0); if (ret == 0) { - ERROR_OUT(-8319, done); + ERROR_OUT(-9623, done); } #endif /* HAVE_ECC_KEY_EXPORT */ ret = wc_ecc_make_pub(NULL, NULL); if (ret == 0) { - ERROR_OUT(-8320, done); + ERROR_OUT(-9624, done); } TEST_SLEEP(); pubPoint = wc_ecc_new_point_h(HEAP_HINT); if (pubPoint == NULL) { - ERROR_OUT(-8321, done); + ERROR_OUT(-9625, done); } ret = wc_ecc_make_pub(&key, pubPoint); if (ret != 0) { - ERROR_OUT(-8322, done); + ERROR_OUT(-9626, done); } TEST_SLEEP(); @@ -18121,14 +18271,14 @@ static int ecc_test_make_pub(WC_RNG* rng) x = FOURK_BUF; ret = wc_ecc_export_x963_ex(&key, exportBuf, &x, 0); if (ret == 0) { - ERROR_OUT(-8323, done); + ERROR_OUT(-9627, done); } #endif /* HAVE_ECC_KEY_EXPORT */ #if defined(WOLFSSL_CRYPTOCELL) /* create a new key since building private key from public key is unsupported */ ret = wc_ecc_make_key(rng, 32, &key); if (ret == 0) { - ERROR_OUT(-8323, done); + ERROR_OUT(-9628, done); } #endif #ifdef HAVE_ECC_SIGN @@ -18142,7 +18292,7 @@ static int ecc_test_make_pub(WC_RNG* rng) ret = wc_ecc_sign_hash(msg, sizeof(msg), tmp, &tmpSz, rng, &key); } while (ret == WC_PENDING_E); if (ret != 0) { - ERROR_OUT(-8324, done); + ERROR_OUT(-9629, done); } TEST_SLEEP(); @@ -18157,11 +18307,11 @@ static int ecc_test_make_pub(WC_RNG* rng) ret = wc_ecc_verify_hash(tmp, tmpSz, msg, sizeof(msg), &verify, &key); } while (ret == WC_PENDING_E); if (ret != 0) { - ERROR_OUT(-8325, done); + ERROR_OUT(-9630, done); } if (verify != 1) { - ERROR_OUT(-8326, done); + ERROR_OUT(-9631, done); } TEST_SLEEP(); #ifdef HAVE_ECC_KEY_EXPORT @@ -18169,7 +18319,7 @@ static int ecc_test_make_pub(WC_RNG* rng) x = FOURK_BUF; ret = wc_ecc_export_x963_ex(&key, exportBuf, &x, 0); if (ret != 0) { - ERROR_OUT(-8327, done); + ERROR_OUT(-9632, done); } #endif /* HAVE_ECC_KEY_EXPORT */ #endif /* HAVE_ECC_VERIFY */ @@ -18181,7 +18331,7 @@ static int ecc_test_make_pub(WC_RNG* rng) x = FOURK_BUF; ret = wc_ecc_export_private_only(&key, exportBuf, &x); if (ret != 0) { - ERROR_OUT(-8328, done); + ERROR_OUT(-9633, done); } /* make private only key */ @@ -18189,14 +18339,14 @@ static int ecc_test_make_pub(WC_RNG* rng) wc_ecc_init_ex(&key, HEAP_HINT, devId); ret = wc_ecc_import_private_key(exportBuf, x, NULL, 0, &key); if (ret != 0) { - ERROR_OUT(-8329, done); + ERROR_OUT(-9634, done); } /* check that public export fails with private only key */ x = FOURK_BUF; ret = wc_ecc_export_x963_ex(&key, exportBuf, &x, 0); if (ret == 0) { - ERROR_OUT(-8330, done); + ERROR_OUT(-9635, done); } /* make public key for shared secret */ @@ -18206,7 +18356,7 @@ static int ecc_test_make_pub(WC_RNG* rng) ret = wc_AsyncWait(ret, &pub.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) { - ERROR_OUT(-8331, done); + ERROR_OUT(-9636, done); } TEST_SLEEP(); @@ -18221,7 +18371,7 @@ static int ecc_test_make_pub(WC_RNG* rng) } while (ret == WC_PENDING_E); wc_ecc_free(&pub); if (ret != 0) { - ERROR_OUT(-8332, done); + ERROR_OUT(-9637, done); } TEST_SLEEP(); #endif /* HAVE_ECC_DHE && HAVE_ECC_KEY_EXPORT */ @@ -18253,12 +18403,12 @@ static int ecc_test_key_gen(WC_RNG* rng, int keySize) der = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (der == NULL) { - return -8333; + return -9638; } pem = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (pem == NULL) { XFREE(der, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - return -8334; + return -9639; } ret = wc_ecc_init_ex(&userA, HEAP_HINT, devId); @@ -18295,7 +18445,7 @@ static int ecc_test_key_gen(WC_RNG* rng, int keySize) ERROR_OUT(derSz, done); } if (derSz == 0) { - ERROR_OUT(-8335, done); + ERROR_OUT(-9640, done); } ret = SaveDerAndPem(der, derSz, NULL, 0, eccPubKeyDerFile, @@ -18313,7 +18463,7 @@ static int ecc_test_key_gen(WC_RNG* rng, int keySize) } if (derSz == 0) { - ERROR_OUT(-8336, done); + ERROR_OUT(-9641, done); } ret = SaveDerAndPem(der, derSz, NULL, 0, eccPkcs8KeyDerFile, @@ -18398,7 +18548,7 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, if (wc_ecc_get_curve_idx(curve_id) != -1) { curveSize = wc_ecc_get_curve_size_from_id(userA.dp->id); if (curveSize != userA.dp->size) { - ret = -8337; + ret = -9642; goto done; } } @@ -18448,10 +18598,10 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, goto done; if (y != x) - ERROR_OUT(-8338, done); + ERROR_OUT(-9643, done); if (XMEMCMP(sharedA, sharedB, x)) - ERROR_OUT(-8339, done); + ERROR_OUT(-9644, done); TEST_SLEEP(); #endif /* HAVE_ECC_DHE */ @@ -18485,10 +18635,10 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, goto done; if (y != x) - ERROR_OUT(-8340, done); + ERROR_OUT(-9645, done); if (XMEMCMP(sharedA, sharedB, x)) - ERROR_OUT(-8341, done); + ERROR_OUT(-9646, done); TEST_SLEEP(); /* remove cofactor flag */ @@ -18526,7 +18676,7 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, goto done; if (XMEMCMP(sharedA, sharedB, y)) - ERROR_OUT(-8342, done); + ERROR_OUT(-9647, done); TEST_SLEEP(); #endif /* HAVE_ECC_DHE */ @@ -18564,7 +18714,7 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, goto done; if (XMEMCMP(sharedA, sharedB, y)) - ERROR_OUT(-8343, done); + ERROR_OUT(-9648, done); TEST_SLEEP(); #endif /* HAVE_ECC_DHE */ #endif /* HAVE_COMP_KEY */ @@ -18608,7 +18758,7 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, if (ret != 0) goto done; if (verify != 1) - ERROR_OUT(-8344, done); + ERROR_OUT(-9649, done); TEST_SLEEP(); } #endif /* HAVE_ECC_VERIFY */ @@ -18629,7 +18779,7 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, &userA); } while (ret == WC_PENDING_E); if (ret != 0) - ERROR_OUT(-8345, done); + ERROR_OUT(-9650, done); TEST_SLEEP(); #ifdef HAVE_ECC_VERIFY @@ -18646,7 +18796,7 @@ static int ecc_test_curve_size(WC_RNG* rng, int keySize, int testVerifyCount, if (ret != 0) goto done; if (verify != 1) - ERROR_OUT(-8346, done); + ERROR_OUT(-9651, done); TEST_SLEEP(); } #endif /* HAVE_ECC_VERIFY */ @@ -18774,25 +18924,25 @@ static int ecc_point_test(void) outLen = sizeof(out); point = wc_ecc_new_point(); if (point == NULL) - return -8400; + return -9700; point2 = wc_ecc_new_point(); if (point2 == NULL) { wc_ecc_del_point(point); - return -8401; + return -9701; } #ifdef HAVE_COMP_KEY point3 = wc_ecc_new_point(); if (point3 == NULL) { wc_ecc_del_point(point2); wc_ecc_del_point(point); - return -8402; + return -9702; } point4 = wc_ecc_new_point(); if (point4 == NULL) { wc_ecc_del_point(point3); wc_ecc_del_point(point2); wc_ecc_del_point(point); - return -8403; + return -9703; } #endif @@ -18800,130 +18950,130 @@ static int ecc_point_test(void) wc_ecc_del_point(NULL); ret = wc_ecc_import_point_der(NULL, sizeof(der), curve_idx, point); if (ret != ECC_BAD_ARG_E) { - ret = -8404; + ret = -9704; goto done; } ret = wc_ecc_import_point_der(der, sizeof(der), ECC_CURVE_INVALID, point); if (ret != ECC_BAD_ARG_E) { - ret = -8405; + ret = -9705; goto done; } ret = wc_ecc_import_point_der(der, sizeof(der), curve_idx, NULL); if (ret != ECC_BAD_ARG_E) { - ret = -8406; + ret = -9706; goto done; } ret = wc_ecc_export_point_der(-1, point, out, &outLen); if (ret != ECC_BAD_ARG_E) { - ret = -8407; + ret = -9707; goto done; } ret = wc_ecc_export_point_der(curve_idx, NULL, out, &outLen); if (ret != ECC_BAD_ARG_E) { - ret = -8408; + ret = -9708; goto done; } ret = wc_ecc_export_point_der(curve_idx, point, NULL, &outLen); if (ret != LENGTH_ONLY_E || outLen != sizeof(out)) { - ret = -8409; + ret = -9709; goto done; } ret = wc_ecc_export_point_der(curve_idx, point, out, NULL); if (ret != ECC_BAD_ARG_E) { - ret = -8410; + ret = -9710; goto done; } outLen = 0; ret = wc_ecc_export_point_der(curve_idx, point, out, &outLen); if (ret != BUFFER_E) { - ret = -8411; + ret = -9711; goto done; } ret = wc_ecc_copy_point(NULL, NULL); if (ret != ECC_BAD_ARG_E) { - ret = -8412; + ret = -9712; goto done; } ret = wc_ecc_copy_point(NULL, point2); if (ret != ECC_BAD_ARG_E) { - ret = -8413; + ret = -9713; goto done; } ret = wc_ecc_copy_point(point, NULL); if (ret != ECC_BAD_ARG_E) { - ret = -8414; + ret = -9714; goto done; } ret = wc_ecc_cmp_point(NULL, NULL); if (ret != BAD_FUNC_ARG) { - ret = -8415; + ret = -9715; goto done; } ret = wc_ecc_cmp_point(NULL, point2); if (ret != BAD_FUNC_ARG) { - ret = -8416; + ret = -9716; goto done; } ret = wc_ecc_cmp_point(point, NULL); if (ret != BAD_FUNC_ARG) { - ret = -8417; + ret = -9717; goto done; } /* Use API. */ ret = wc_ecc_import_point_der(der, sizeof(der), curve_idx, point); if (ret != 0) { - ret = -8418; + ret = -9718; goto done; } outLen = sizeof(out); ret = wc_ecc_export_point_der(curve_idx, point, out, &outLen); if (ret != 0) { - ret = -8419; + ret = -9719; goto done; } if (outLen != sizeof(der)) { - ret = -8420; + ret = -9720; goto done; } if (XMEMCMP(out, der, outLen) != 0) { - ret = -8421; + ret = -9721; goto done; } ret = wc_ecc_copy_point(point2, point); if (ret != MP_OKAY) { - ret = -8422; + ret = -9722; goto done; } ret = wc_ecc_cmp_point(point2, point); if (ret != MP_EQ) { - ret = -8423; + ret = -9723; goto done; } ret = wc_ecc_import_point_der(altDer, sizeof(altDer), curve_idx, point2); if (ret != 0) { - ret = -8424; + ret = -9724; goto done; } ret = wc_ecc_cmp_point(point2, point); if (ret != MP_GT) { - ret = -8425; + ret = -9725; goto done; } #ifdef HAVE_COMP_KEY ret = wc_ecc_import_point_der(derComp0, sizeof(der), curve_idx, point3); if (ret != 0) { - ret = -8426; + ret = -9726; goto done; } ret = wc_ecc_import_point_der(derComp1, sizeof(der), curve_idx, point4); if (ret != 0) { - ret = -8427; + ret = -9727; goto done; } #endif @@ -18960,32 +19110,32 @@ static int ecc_sig_test(WC_RNG* rng, ecc_key* key) ret = wc_SignatureGetSize(WC_SIGNATURE_TYPE_ECC, key, sizeof(*key)); if (ret != size) - return -8428; + return -9728; sigSz = (word32)ret; ret = wc_SignatureGenerate(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_ECC, in, inLen, out, &sigSz, key, sizeof(*key), rng); if (ret != 0) - return -8429; + return -9729; TEST_SLEEP(); ret = wc_SignatureVerify(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_ECC, in, inLen, out, sigSz, key, sizeof(*key)); if (ret != 0) - return -8430; + return -9730; TEST_SLEEP(); sigSz = (word32)sizeof(out); ret = wc_SignatureGenerateHash(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_ECC, hash, (int)sizeof(hash), out, &sigSz, key, sizeof(*key), rng); if (ret != 0) - return -8431; + return -9731; TEST_SLEEP(); ret = wc_SignatureVerifyHash(WC_HASH_TYPE_SHA256, WC_SIGNATURE_TYPE_ECC, hash, (int)sizeof(hash), out, sigSz, key, sizeof(*key)); if (ret != 0) - return -8432; + return -9732; TEST_SLEEP(); return 0; @@ -19014,19 +19164,19 @@ static int ecc_exp_imp_test(ecc_key* key) privLen = sizeof(priv); ret = wc_ecc_export_private_only(key, priv, &privLen); if (ret != 0) { - ret = -8433; + ret = -9733; goto done; } pubLen = sizeof(pub); ret = wc_ecc_export_point_der(key->idx, &key->pubkey, pub, &pubLen); if (ret != 0) { - ret = -8434; + ret = -9734; goto done; } ret = wc_ecc_import_private_key(priv, privLen, pub, pubLen, &keyImp); if (ret != 0) { - ret = -8435; + ret = -9735; goto done; } @@ -19035,7 +19185,7 @@ static int ecc_exp_imp_test(ecc_key* key) ret = wc_ecc_import_raw_ex(&keyImp, qx, qy, d, ECC_SECP256R1); if (ret != 0) { - ret = -8436; + ret = -9736; goto done; } @@ -19044,7 +19194,7 @@ static int ecc_exp_imp_test(ecc_key* key) curve_id = wc_ecc_get_curve_id(key->idx); if (curve_id < 0) { - ret = -8437; + ret = -9737; goto done; } @@ -19052,7 +19202,7 @@ static int ecc_exp_imp_test(ecc_key* key) ret = wc_ecc_import_private_key_ex(priv, privLen, NULL, 0, &keyImp, curve_id); if (ret != 0) { - ret = -8438; + ret = -9738; goto done; } @@ -19063,7 +19213,7 @@ static int ecc_exp_imp_test(ecc_key* key) pubLenX = pubLenY = 32; ret = wc_ecc_export_public_raw(key, pub, &pubLenX, &pub[32], &pubLenY); if (ret != 0) { - ret = -8439; + ret = -9739; goto done; } @@ -19071,7 +19221,7 @@ static int ecc_exp_imp_test(ecc_key* key) /* test import of public */ ret = wc_ecc_import_unsigned(&keyImp, pub, &pub[32], NULL, ECC_SECP256R1); if (ret != 0) { - ret = -8440; + ret = -9740; goto done; } #endif @@ -19084,7 +19234,7 @@ static int ecc_exp_imp_test(ecc_key* key) ret = wc_ecc_export_private_raw(key, pub, &pubLenX, &pub[32], &pubLenY, priv, &privLen); if (ret != 0) { - ret = -8441; + ret = -9741; goto done; } @@ -19092,7 +19242,7 @@ static int ecc_exp_imp_test(ecc_key* key) /* test import of private and public */ ret = wc_ecc_import_unsigned(&keyImp, pub, &pub[32], priv, ECC_SECP256R1); if (ret != 0) { - ret = -8442; + ret = -9742; goto done; } #endif @@ -19134,7 +19284,7 @@ static int ecc_mulmod_test(ecc_key* key1) ret = wc_ecc_mulmod(&key1->k, &key2.pubkey, &key3.pubkey, &key2.k, &key3.k, 1); if (ret != 0) { - ret = -8443; + ret = -9743; goto done; } @@ -19155,16 +19305,16 @@ static int ecc_ssh_test(ecc_key* key) /* Parameter Validation testing. */ ret = wc_ecc_shared_secret_ssh(NULL, &key->pubkey, out, &outLen); if (ret != BAD_FUNC_ARG) - return -8444; + return -9744; ret = wc_ecc_shared_secret_ssh(key, NULL, out, &outLen); if (ret != BAD_FUNC_ARG) - return -8445; + return -9745; ret = wc_ecc_shared_secret_ssh(key, &key->pubkey, NULL, &outLen); if (ret != BAD_FUNC_ARG) - return -8446; + return -9746; ret = wc_ecc_shared_secret_ssh(key, &key->pubkey, out, NULL); if (ret != BAD_FUNC_ARG) - return -8447; + return -9747; /* Use API. */ ret = 0; @@ -19176,7 +19326,7 @@ static int ecc_ssh_test(ecc_key* key) ret = wc_ecc_shared_secret_ssh(key, &key->pubkey, out, &outLen); } while (ret == WC_PENDING_E); if (ret != 0) - return -8448; + return -9748; TEST_SLEEP(); return 0; } @@ -19193,12 +19343,12 @@ static int ecc_def_curve_test(WC_RNG *rng) /* Use API */ ret = wc_ecc_set_flags(NULL, 0); if (ret != BAD_FUNC_ARG) { - ret = -8449; + ret = -9749; goto done; } ret = wc_ecc_set_flags(&key, 0); if (ret != 0) { - ret = -8450; + ret = -9750; goto done; } @@ -19207,7 +19357,7 @@ static int ecc_def_curve_test(WC_RNG *rng) ret = wc_AsyncWait(ret, &key.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) { - ret = -8451; + ret = -9751; goto done; } TEST_SLEEP(); @@ -19289,22 +19439,22 @@ static int ecc_decode_test(void) inSz = sizeof(good); ret = wc_EccPublicKeyDecode(NULL, &inOutIdx, &key, inSz); if (ret != BAD_FUNC_ARG) { - ret = -8500; + ret = -9800; goto done; } ret = wc_EccPublicKeyDecode(good, NULL, &key, inSz); if (ret != BAD_FUNC_ARG) { - ret = -8501; + ret = -9801; goto done; } ret = wc_EccPublicKeyDecode(good, &inOutIdx, NULL, inSz); if (ret != BAD_FUNC_ARG) { - ret = -8502; + ret = -9802; goto done; } ret = wc_EccPublicKeyDecode(good, &inOutIdx, &key, 0); if (ret != BAD_FUNC_ARG) { - ret = -8503; + ret = -9803; goto done; } @@ -19313,14 +19463,14 @@ static int ecc_decode_test(void) inSz = sizeof(good) - inOutIdx; ret = wc_EccPublicKeyDecode(good, &inOutIdx, &key, inSz); if (ret != ASN_PARSE_E) { - ret = -8504; + ret = -9804; goto done; } inOutIdx = 4; inSz = sizeof(good) - inOutIdx; ret = wc_EccPublicKeyDecode(good, &inOutIdx, &key, inSz); if (ret != ASN_PARSE_E) { - ret = -8505; + ret = -9805; goto done; } /* Bad data. */ @@ -19328,56 +19478,56 @@ static int ecc_decode_test(void) inOutIdx = 0; ret = wc_EccPublicKeyDecode(badNoObjId, &inOutIdx, &key, inSz); if (ret != ASN_OBJECT_ID_E) { - ret = -8506; + ret = -9806; goto done; } inSz = sizeof(badOneObjId); inOutIdx = 0; ret = wc_EccPublicKeyDecode(badOneObjId, &inOutIdx, &key, inSz); if (ret != ASN_OBJECT_ID_E) { - ret = -8507; + ret = -9807; goto done; } inSz = sizeof(badObjId1Len); inOutIdx = 0; ret = wc_EccPublicKeyDecode(badObjId1Len, &inOutIdx, &key, inSz); if (ret != ASN_PARSE_E) { - ret = -8508; + ret = -9808; goto done; } inSz = sizeof(badObj2d1Len); inOutIdx = 0; ret = wc_EccPublicKeyDecode(badObj2d1Len, &inOutIdx, &key, inSz); if (ret != ASN_PARSE_E) { - ret = -8509; + ret = -9809; goto done; } inSz = sizeof(badNotBitStr); inOutIdx = 0; ret = wc_EccPublicKeyDecode(badNotBitStr, &inOutIdx, &key, inSz); if (ret != ASN_BITSTR_E) { - ret = -8510; + ret = -9810; goto done; } inSz = sizeof(badBitStrLen); inOutIdx = 0; ret = wc_EccPublicKeyDecode(badBitStrLen, &inOutIdx, &key, inSz); if (ret != ASN_PARSE_E) { - ret = -8511; + ret = -9811; goto done; } inSz = sizeof(badNoBitStrZero); inOutIdx = 0; ret = wc_EccPublicKeyDecode(badNoBitStrZero, &inOutIdx, &key, inSz); if (ret != ASN_EXPECT_0_E) { - ret = -8512; + ret = -9812; goto done; } inSz = sizeof(badPoint); inOutIdx = 0; ret = wc_EccPublicKeyDecode(badPoint, &inOutIdx, &key, inSz); if (ret != ASN_ECC_KEY_E) { - ret = -8513; + ret = -9813; goto done; } @@ -19385,7 +19535,7 @@ static int ecc_decode_test(void) inOutIdx = 0; ret = wc_EccPublicKeyDecode(good, &inOutIdx, &key, inSz); if (ret != 0) { - ret = -8514; + ret = -9814; goto done; } @@ -19493,14 +19643,14 @@ static int ecc_test_custom_curves(WC_RNG* rng) ret = wc_ecc_init_ex(&key, HEAP_HINT, devId); if (ret != 0) { - return -8515; + return -9815; } inOutIdx = 0; ret = wc_EccPublicKeyDecode(eccKeyExplicitCurve, &inOutIdx, &key, sizeof(eccKeyExplicitCurve)); if (ret != 0) - return -8516; + return -9816; wc_ecc_free(&key); @@ -19534,11 +19684,11 @@ static int ecc_test_cert_gen(WC_RNG* rng) der = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (der == NULL) { - ERROR_OUT(-8517, exit); + ERROR_OUT(-9817, exit); } pem = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (pem == NULL) { - ERROR_OUT(-8518, exit); + ERROR_OUT(-9818, exit); } /* Get cert private key */ @@ -19550,7 +19700,7 @@ static int ecc_test_cert_gen(WC_RNG* rng) #else file = XFOPEN(eccCaKey384File, "rb"); if (!file) { - ERROR_OUT(-8519, exit); + ERROR_OUT(-9819, exit); } bytes = XFREAD(der, 1, FOURK_BUF, file); @@ -19564,7 +19714,7 @@ static int ecc_test_cert_gen(WC_RNG* rng) #else file = XFOPEN(eccCaKeyFile, "rb"); if (!file) { - ERROR_OUT(-8520, exit); + ERROR_OUT(-9820, exit); } bytes = XFREAD(der, 1, FOURK_BUF, file); XFCLOSE(file); @@ -19577,17 +19727,17 @@ static int ecc_test_cert_gen(WC_RNG* rng) /* Get CA Key */ ret = wc_ecc_init_ex(&caEccKey, HEAP_HINT, devId); if (ret != 0) { - ERROR_OUT(-8521, exit); + ERROR_OUT(-9821, exit); } ret = wc_EccPrivateKeyDecode(der, &idx, &caEccKey, (word32)bytes); if (ret != 0) { - ERROR_OUT(-8522, exit); + ERROR_OUT(-9822, exit); } /* Make a public key */ ret = wc_ecc_init_ex(&certPubKey, HEAP_HINT, devId); if (ret != 0) { - ERROR_OUT(-8523, exit); + ERROR_OUT(-9823, exit); } ret = wc_ecc_make_key(rng, 32, &certPubKey); @@ -19595,13 +19745,13 @@ static int ecc_test_cert_gen(WC_RNG* rng) ret = wc_AsyncWait(ret, &certPubKey.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0) { - ERROR_OUT(-8524, exit); + ERROR_OUT(-9824, exit); } TEST_SLEEP(); /* Setup Certificate */ if (wc_InitCert(&myCert)) { - ERROR_OUT(-8525, exit); + ERROR_OUT(-9825, exit); } #ifndef NO_SHA256 @@ -19621,17 +19771,17 @@ static int ecc_test_cert_gen(WC_RNG* rng) /* add SKID from the Public Key */ if (wc_SetSubjectKeyIdFromPublicKey(&myCert, NULL, &certPubKey) != 0) { - ERROR_OUT(-8526, exit); + ERROR_OUT(-9826, exit); } /* add AKID from the Public Key */ if (wc_SetAuthKeyIdFromPublicKey(&myCert, NULL, &caEccKey) != 0) { - ERROR_OUT(-8527, exit); + ERROR_OUT(-9827, exit); } /* add Key Usage */ if (wc_SetKeyUsage(&myCert, certKeyUsage) != 0) { - ERROR_OUT(-8528, exit); + ERROR_OUT(-9828, exit); } #endif /* WOLFSSL_CERT_EXT */ @@ -19655,12 +19805,12 @@ static int ecc_test_cert_gen(WC_RNG* rng) #endif #endif /* ENABLE_ECC384_CERT_GEN_TEST */ if (ret < 0) { - ERROR_OUT(-8529, exit); + ERROR_OUT(-9829, exit); } certSz = wc_MakeCert(&myCert, der, FOURK_BUF, NULL, &certPubKey, rng); if (certSz < 0) { - ERROR_OUT(-8530, exit); + ERROR_OUT(-9830, exit); } ret = 0; @@ -19674,7 +19824,7 @@ static int ecc_test_cert_gen(WC_RNG* rng) } } while (ret == WC_PENDING_E); if (ret < 0) { - ERROR_OUT(-8531, exit); + ERROR_OUT(-9831, exit); } certSz = ret; TEST_SLEEP(); @@ -19684,7 +19834,7 @@ static int ecc_test_cert_gen(WC_RNG* rng) ret = ParseCert(&decode, CERT_TYPE, NO_VERIFY, 0); if (ret != 0) { FreeDecodedCert(&decode); - ERROR_OUT(-8532, exit); + ERROR_OUT(-9832, exit); } FreeDecodedCert(&decode); @@ -19716,12 +19866,12 @@ static int ecc_test_allocator(WC_RNG* rng) key = wc_ecc_key_new(HEAP_HINT); if (key == NULL) { - ERROR_OUT(-8532, exit); + ERROR_OUT(-9833, exit); } ret = wc_ecc_make_key(rng, 32, key); if (ret != 0) { - ERROR_OUT(-8533, exit); + ERROR_OUT(-9834, exit); } exit: @@ -19747,7 +19897,7 @@ int ecc_test(void) ret = wc_InitRng(&rng); #endif if (ret != 0) - return -8600; + return -9900; #if defined(HAVE_ECC112) || defined(HAVE_ALL_CURVES) ret = ecc_test_curve(&rng, 14); @@ -19907,7 +20057,7 @@ int ecc_encrypt_test(void) ret = wc_InitRng(&rng); #endif if (ret != 0) - return -8700; + return -10000; XMEMSET(&userA, 0, sizeof(userA)); XMEMSET(&userB, 0, sizeof(userB)); @@ -19924,7 +20074,7 @@ int ecc_encrypt_test(void) ret = wc_AsyncWait(ret, &userA.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0){ - ret = -8701; goto done; + ret = -10001; goto done; } ret = wc_ecc_make_key(&rng, 32, &userB); @@ -19932,7 +20082,7 @@ int ecc_encrypt_test(void) ret = wc_AsyncWait(ret, &userB.asyncDev, WC_ASYNC_FLAG_NONE); #endif if (ret != 0){ - ret = -8702; goto done; + ret = -10002; goto done; } /* set message to incrementing 0,1,2,etc... */ @@ -19942,36 +20092,36 @@ int ecc_encrypt_test(void) /* encrypt msg to B */ ret = wc_ecc_encrypt(&userA, &userB, msg, sizeof(msg), out, &outSz, NULL); if (ret != 0) { - ret = -8703; goto done; + ret = -10003; goto done; } /* decrypt msg from A */ ret = wc_ecc_decrypt(&userB, &userA, out, outSz, plain, &plainSz, NULL); if (ret != 0) { - ret = -8704; goto done; + ret = -10004; goto done; } if (XMEMCMP(plain, msg, sizeof(msg)) != 0) { - ret = -8705; goto done; + ret = -10005; goto done; } /* let's verify message exchange works, A is client, B is server */ cliCtx = wc_ecc_ctx_new(REQ_RESP_CLIENT, &rng); srvCtx = wc_ecc_ctx_new(REQ_RESP_SERVER, &rng); if (cliCtx == NULL || srvCtx == NULL) { - ret = -8706; goto done; + ret = -10006; goto done; } /* get salt to send to peer */ tmpSalt = wc_ecc_ctx_get_own_salt(cliCtx); if (tmpSalt == NULL) { - ret = -8707; goto done; + ret = -10007; goto done; } XMEMCPY(cliSalt, tmpSalt, EXCHANGE_SALT_SZ); tmpSalt = wc_ecc_ctx_get_own_salt(srvCtx); if (tmpSalt == NULL) { - ret = -8708; goto done; + ret = -10008; goto done; } XMEMCPY(srvSalt, tmpSalt, EXCHANGE_SALT_SZ); @@ -20003,7 +20153,7 @@ int ecc_encrypt_test(void) goto done; if (XMEMCMP(plain, msg, sizeof(msg)) != 0) { - ret = -8709; goto done; + ret = -10009; goto done; } /* msg2 (response) from B to A */ @@ -20023,7 +20173,7 @@ int ecc_encrypt_test(void) goto done; if (XMEMCMP(plain2, msg2, sizeof(msg2)) != 0) { - ret = -8710; goto done; + ret = -10010; goto done; } done: @@ -20059,17 +20209,17 @@ int ecc_test_buffers(void) { ret = wc_ecc_init_ex(&cliKey, HEAP_HINT, devId); if (ret != 0) - return -8721; + return -10011; ret = wc_ecc_init_ex(&servKey, HEAP_HINT, devId); if (ret != 0) - return -8722; + return -10012; bytes = (size_t)sizeof_ecc_clikey_der_256; /* place client key into ecc_key struct cliKey */ ret = wc_EccPrivateKeyDecode(ecc_clikey_der_256, &idx, &cliKey, (word32)bytes); if (ret != 0) - return -8711; + return -10013; idx = 0; bytes = (size_t)sizeof_ecc_key_der_256; @@ -20078,7 +20228,7 @@ int ecc_test_buffers(void) { ret = wc_EccPrivateKeyDecode(ecc_key_der_256, &idx, &servKey, (word32)bytes); if (ret != 0) - return -8712; + return -10014; #ifndef HAVE_FIPS ret = wc_InitRng_ex(&rng, HEAP_HINT, devId); @@ -20086,7 +20236,7 @@ int ecc_test_buffers(void) { ret = wc_InitRng(&rng); #endif if (ret != 0) - return -8713; + return -10015; #if defined(HAVE_ECC_ENCRYPT) && defined(HAVE_HKDF) { @@ -20095,15 +20245,15 @@ int ecc_test_buffers(void) { x = sizeof(out); ret = wc_ecc_encrypt(&cliKey, &servKey, in, sizeof(in), out, &x, NULL); if (ret < 0) - return -8714; + return -10016; y = sizeof(plain); ret = wc_ecc_decrypt(&cliKey, &servKey, out, x, plain, &y, NULL); if (ret < 0) - return -8715; + return -10017; if (XMEMCMP(plain, in, inLen)) - return -8716; + return -10018; } #endif @@ -20116,7 +20266,7 @@ int ecc_test_buffers(void) { ret = wc_ecc_sign_hash(in, inLen, out, &x, &rng, &cliKey); } while (ret == WC_PENDING_E); if (ret < 0) - return -8717; + return -10019; TEST_SLEEP(); XMEMSET(plain, 0, sizeof(plain)); @@ -20130,10 +20280,10 @@ int ecc_test_buffers(void) { &cliKey); } while (ret == WC_PENDING_E); if (ret < 0) - return -8718; + return -10020; if (XMEMCMP(plain, in, (word32)ret)) - return -8719; + return -10021; TEST_SLEEP(); #ifdef WOLFSSL_CERT_EXT @@ -20144,7 +20294,7 @@ int ecc_test_buffers(void) { ret = wc_EccPublicKeyDecode(ecc_clikeypub_der_256, &idx, &cliKey, (word32) bytes); if (ret != 0) - return -8720; + return -10022; #endif wc_ecc_free(&cliKey); @@ -20286,16 +20436,16 @@ static int curve25519_overflow_test(void) for (i = 0; i < X25519_TEST_CNT; i++) { if (wc_curve25519_import_private_raw(sa[i], sizeof(sa[i]), pb[i], sizeof(pb[i]), &userA) != 0) - return -8750 - i; + return -10100 - i; /* test against known test vector */ XMEMSET(shared, 0, sizeof(shared)); y = sizeof(shared); if (wc_curve25519_shared_secret(&userA, &userA, shared, &y) != 0) - return -8755 - i; + return -10110 - i; if (XMEMCMP(ss[i], shared, y)) - return -8760 - i; + return -10120 - i; } return 0; @@ -20362,17 +20512,17 @@ static int curve25519_check_public_test(void) /* NULL pointer */ if (wc_curve25519_check_public(NULL, 0, EC25519_LITTLE_ENDIAN) != BAD_FUNC_ARG) { - return -10300; + return -10200; } if (wc_curve25519_check_public(NULL, 0, EC25519_BIG_ENDIAN) != BAD_FUNC_ARG) { - return -10301; + return -10201; } /* Length of 0 treated differently to other invalid lengths for TLS */ if (wc_curve25519_check_public(good, 0, EC25519_LITTLE_ENDIAN) != BUFFER_E) - return -10302; + return -10202; if (wc_curve25519_check_public(good, 0, EC25519_BIG_ENDIAN) != BUFFER_E) - return -10303; + return -10203; /* Length not CURVE25519_KEYSIZE */ for (i = 1; i < CURVE25519_KEYSIZE + 2; i++) { @@ -20380,11 +20530,11 @@ static int curve25519_check_public_test(void) continue; if (wc_curve25519_check_public(good, i, EC25519_LITTLE_ENDIAN) != ECC_BAD_ARG_E) { - return -10310 - i; + return -10204 - i; } if (wc_curve25519_check_public(good, i, EC25519_BIG_ENDIAN) != ECC_BAD_ARG_E) { - return -10350 - i; + return -10214 - i; } } @@ -20392,25 +20542,25 @@ static int curve25519_check_public_test(void) for (i = 0; i < (int)(sizeof(fail_le) / sizeof(*fail_le)); i++) { if (wc_curve25519_check_public(fail_le[i], CURVE25519_KEYSIZE, EC25519_LITTLE_ENDIAN) == 0) { - return -10390 - i; + return -10224 - i; } } /* Big-endian fail cases */ for (i = 0; i < (int)(sizeof(fail_be) / sizeof(*fail_be)); i++) { if (wc_curve25519_check_public(fail_be[i], CURVE25519_KEYSIZE, EC25519_BIG_ENDIAN) == 0) { - return -10394 - i; + return -10234 - i; } } /* Check a valid public value works! */ if (wc_curve25519_check_public(good, CURVE25519_KEYSIZE, EC25519_LITTLE_ENDIAN) != 0) { - return -10398; + return -10244; } if (wc_curve25519_check_public(good, CURVE25519_KEYSIZE, EC25519_BIG_ENDIAN) != 0) { - return -10399; + return -10245; } return 0; @@ -20488,7 +20638,7 @@ int curve25519_test(void) ret = wc_InitRng(&rng); #endif if (ret != 0) - return -8800; + return -10300; wc_curve25519_init(&userA); wc_curve25519_init(&userB); @@ -20496,38 +20646,38 @@ int curve25519_test(void) /* make curve25519 keys */ if (wc_curve25519_make_key(&rng, 32, &userA) != 0) - return -8801; + return -10301; if (wc_curve25519_make_key(&rng, 32, &userB) != 0) - return -8802; + return -10302; #ifdef HAVE_CURVE25519_SHARED_SECRET /* find shared secret key */ x = sizeof(sharedA); if (wc_curve25519_shared_secret(&userA, &userB, sharedA, &x) != 0) - return -8803; + return -10303; y = sizeof(sharedB); if (wc_curve25519_shared_secret(&userB, &userA, sharedB, &y) != 0) - return -8804; + return -10304; /* compare shared secret keys to test they are the same */ if (y != x) - return -8805; + return -10305; if (XMEMCMP(sharedA, sharedB, x)) - return -8806; + return -10306; #endif #ifdef HAVE_CURVE25519_KEY_EXPORT /* export a public key and import it for another user */ x = sizeof(exportBuf); if (wc_curve25519_export_public(&userA, exportBuf, &x) != 0) - return -8807; + return -10307; #ifdef HAVE_CURVE25519_KEY_IMPORT if (wc_curve25519_import_public(exportBuf, x, &pubKey) != 0) - return -8808; + return -10308; #endif #endif @@ -20537,60 +20687,60 @@ int curve25519_test(void) XMEMSET(sharedB, 0, sizeof(sharedB)); y = sizeof(sharedB); if (wc_curve25519_shared_secret(&userB, &pubKey, sharedB, &y) != 0) - return -8809; + return -10309; if (XMEMCMP(sharedA, sharedB, y)) - return -8810; + return -10310; /* import RFC test vectors and compare shared key */ if (wc_curve25519_import_private_raw(sa, sizeof(sa), pa, sizeof(pa), &userA) != 0) - return -8811; + return -10311; if (wc_curve25519_import_private_raw(sb, sizeof(sb), pb, sizeof(pb), &userB) != 0) - return -8812; + return -10312; /* test against known test vector */ XMEMSET(sharedB, 0, sizeof(sharedB)); y = sizeof(sharedB); if (wc_curve25519_shared_secret(&userA, &userB, sharedB, &y) != 0) - return -8813; + return -10313; if (XMEMCMP(ss, sharedB, y)) - return -8814; + return -10314; /* test swapping roles of keys and generating same shared key */ XMEMSET(sharedB, 0, sizeof(sharedB)); y = sizeof(sharedB); if (wc_curve25519_shared_secret(&userB, &userA, sharedB, &y) != 0) - return -8815; + return -10315; if (XMEMCMP(ss, sharedB, y)) - return -8816; + return -10316; /* test with 1 generated key and 1 from known test vector */ if (wc_curve25519_import_private_raw(sa, sizeof(sa), pa, sizeof(pa), &userA) != 0) - return -8817; + return -10317; if (wc_curve25519_make_key(&rng, 32, &userB) != 0) - return -8818; + return -10318; x = sizeof(sharedA); if (wc_curve25519_shared_secret(&userA, &userB, sharedA, &x) != 0) - return -8819; + return -10319; y = sizeof(sharedB); if (wc_curve25519_shared_secret(&userB, &userA, sharedB, &y) != 0) - return -8820; + return -10320; /* compare shared secret keys to test they are the same */ if (y != x) - return -8821; + return -10321; if (XMEMCMP(sharedA, sharedB, x)) - return -8822; + return -10322; ret = curve25519_overflow_test(); if (ret != 0) @@ -20631,7 +20781,7 @@ static int ed25519_test_cert(void) tmp = XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (tmp == NULL) { - ERROR_OUT(-8823, done); + ERROR_OUT(-10323, done); } #ifdef USE_CERT_BUFFERS_256 @@ -20640,20 +20790,20 @@ static int ed25519_test_cert(void) #elif !defined(NO_FILESYSTEM) file = XFOPEN(caEd25519Cert, "rb"); if (file == NULL) { - ERROR_OUT(-8824, done); + ERROR_OUT(-10324, done); } bytes = XFREAD(tmp, 1, FOURK_BUF, file); XFCLOSE(file); #else /* No certificate to use. */ - ERROR_OUT(-8825, done); + ERROR_OUT(-10325, done); #endif InitDecodedCert(&cert[0], tmp, (word32)bytes, 0); caCert = &cert[0]; ret = ParseCert(caCert, CERT_TYPE, NO_VERIFY, NULL); if (ret != 0) { - ERROR_OUT(-8826, done); + ERROR_OUT(-10326, done); } #ifdef USE_CERT_BUFFERS_256 @@ -20662,39 +20812,39 @@ static int ed25519_test_cert(void) #elif !defined(NO_FILESYSTEM) file = XFOPEN(serverEd25519Cert, "rb"); if (file == NULL) { - ERROR_OUT(-8827, done); + ERROR_OUT(-10327, done); } bytes = XFREAD(tmp, 1, FOURK_BUF, file); XFCLOSE(file); #else /* No certificate to use. */ - ERROR_OUT(-8828, done); + ERROR_OUT(-10328, done); #endif InitDecodedCert(&cert[1], tmp, (word32)bytes, 0); serverCert = &cert[1]; ret = ParseCert(serverCert, CERT_TYPE, NO_VERIFY, NULL); if (ret != 0) { - ERROR_OUT(-8829, done); + ERROR_OUT(-10329, done); } #ifdef HAVE_ED25519_VERIFY ret = wc_ed25519_init(&key); if (ret < 0) { - ERROR_OUT(-8830, done); + ERROR_OUT(-10330, done); } pubKey = &key; ret = wc_ed25519_import_public(caCert->publicKey, caCert->pubKeySize, pubKey); if (ret < 0) { - ERROR_OUT(-8831, done); + ERROR_OUT(-10331, done); } if (wc_ed25519_verify_msg(serverCert->signature, serverCert->sigLength, serverCert->source + serverCert->certBegin, serverCert->sigIndex - serverCert->certBegin, &verify, pubKey) < 0 || verify != 1) { - ERROR_OUT(-8832, done); + ERROR_OUT(-10332, done); } #endif /* HAVE_ED25519_VERIFY */ @@ -20730,7 +20880,7 @@ static int ed25519_test_make_cert(void) ret = wc_InitRng(&rng); #endif if (ret != 0) - return -8833; + return -10333; wc_ed25519_init(&key); privKey = &key; @@ -20744,38 +20894,38 @@ static int ed25519_test_make_cert(void) #ifdef WOLFSSL_CERT_EXT ret = wc_SetKeyUsage(&cert, certKeyUsage); if (ret < 0) { - ERROR_OUT(-8834, done); + ERROR_OUT(-10334, done); } ret = wc_SetSubjectKeyIdFromPublicKey_ex(&cert, ED25519_TYPE, privKey); if (ret < 0) { - ERROR_OUT(-8835, done); + ERROR_OUT(-10335, done); } ret = wc_SetAuthKeyIdFromPublicKey_ex(&cert, ED25519_TYPE, privKey); if (ret < 0) { - ERROR_OUT(-8836, done); + ERROR_OUT(-10336, done); } #endif tmp = XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (tmp == NULL) { - ERROR_OUT(-8837, done); + ERROR_OUT(-10337, done); } cert.sigType = CTC_ED25519; ret = wc_MakeCert_ex(&cert, tmp, FOURK_BUF, ED25519_TYPE, privKey, &rng); if (ret < 0) { - ERROR_OUT(-8838, done); + ERROR_OUT(-10338, done); } ret = wc_SignCert_ex(cert.bodySz, cert.sigType, tmp, FOURK_BUF, ED25519_TYPE, privKey, &rng); if (ret < 0) { - ERROR_OUT(-8839, done); + ERROR_OUT(-10339, done); } InitDecodedCert(&decode, tmp, ret, HEAP_HINT); ret = ParseCert(&decode, CERT_TYPE, NO_VERIFY, 0); FreeDecodedCert(&decode); if (ret != 0) { - ERROR_OUT(-8840, done); + ERROR_OUT(-10340, done); } done: @@ -20848,35 +20998,35 @@ static int ed25519ctx_test(void) if (wc_ed25519_import_private_key(sKeyCtx, ED25519_KEY_SIZE, pKeyCtx, sizeof(pKeyCtx), &key) != 0) - return -9020; + return -10400; if (wc_ed25519ctx_sign_msg(msgCtx, sizeof(msgCtx), out, &outlen, &key, contextCtx, sizeof(contextCtx)) != 0) - return -9021; + return -10401; if (XMEMCMP(out, sigCtx1, 64)) - return -9022; + return -10402; #if defined(HAVE_ED25519_VERIFY) /* test verify on good msg */ if (wc_ed25519ctx_verify_msg(out, outlen, msgCtx, sizeof(msgCtx), &verify, &key, contextCtx, sizeof(contextCtx)) != 0 || verify != 1) - return -9023; + return -10403; #endif if (wc_ed25519ctx_sign_msg(msgCtx, sizeof(msgCtx), out, &outlen, &key, NULL, 0) != 0) - return -9025; + return -10404; if (XMEMCMP(out, sigCtx2, 64)) - return -9026; + return -10405; #if defined(HAVE_ED25519_VERIFY) /* test verify on good msg */ if (wc_ed25519ctx_verify_msg(out, outlen, msgCtx, sizeof(msgCtx), &verify, &key, NULL, 0) != 0 || verify != 1) - return -9027; + return -10406; #endif wc_ed25519_free(&key); @@ -20954,72 +21104,72 @@ static int ed25519ph_test(void) if (wc_ed25519_import_private_key(sKeyPh, ED25519_KEY_SIZE, pKeyPh, sizeof(pKeyPh), &key) != 0) { - return -9030; + return -10500; } if (wc_ed25519ph_sign_msg(msgPh, sizeof(msgPh), out, &outlen, &key, NULL, 0) != 0) { - return -9031; + return -10501; } if (XMEMCMP(out, sigPh1, 64)) - return -9032; + return -10502; #if defined(HAVE_ED25519_VERIFY) /* test verify on good msg */ if (wc_ed25519ph_verify_msg(out, outlen, msgPh, sizeof(msgPh), &verify, &key, NULL, 0) != 0 || verify != 1) { - return -9033; + return -10503; } #endif if (wc_ed25519ph_sign_msg(msgPh, sizeof(msgPh), out, &outlen, &key, contextPh2, sizeof(contextPh2)) != 0) { - return -9035; + return -10504; } if (XMEMCMP(out, sigPh2, 64)) - return -9036; + return -10505; #if defined(HAVE_ED25519_VERIFY) /* test verify on good msg */ if (wc_ed25519ph_verify_msg(out, outlen, msgPh, sizeof(msgPh), &verify, &key, contextPh2, sizeof(contextPh2)) != 0 || verify != 1) { - return -9037; + return -10506; } #endif if (wc_ed25519ph_sign_hash(hashPh, sizeof(hashPh), out, &outlen, &key, NULL, 0) != 0) { - return -9041; + return -10507; } if (XMEMCMP(out, sigPh1, 64)) - return -9042; + return -10508; #if defined(HAVE_ED25519_VERIFY) if (wc_ed25519ph_verify_hash(out, outlen, hashPh, sizeof(hashPh), &verify, &key, NULL, 0) != 0 || verify != 1) { - return -9043; + return -10509; } #endif if (wc_ed25519ph_sign_hash(hashPh, sizeof(hashPh), out, &outlen, &key, contextPh2, sizeof(contextPh2)) != 0) { - return -9045; + return -10510; } if (XMEMCMP(out, sigPh2, 64)) - return -9046; + return -10511; #if defined(HAVE_ED25519_VERIFY) if (wc_ed25519ph_verify_hash(out, outlen, hashPh, sizeof(hashPh), &verify, &key, contextPh2, sizeof(contextPh2)) != 0 || verify != 1) { - return -9047; + return -10512; } #endif @@ -21412,7 +21562,7 @@ int ed25519_test(void) ret = wc_InitRng(&rng); #endif if (ret != 0) - return -8900; + return -10600; wc_ed25519_init(&key); wc_ed25519_init(&key2); @@ -21434,56 +21584,56 @@ int ed25519_test(void) if (wc_ed25519_import_private_key(sKeys[i], ED25519_KEY_SIZE, pKeys[i], pKeySz[i], &key) != 0) - return -8901 - i; + return -10601 - i; if (wc_ed25519_sign_msg(msgs[i], msgSz[i], out, &outlen, &key) != 0) - return -8911 - i; + return -10611 - i; if (XMEMCMP(out, sigs[i], 64)) - return -8921 - i; + return -10621 - i; #if defined(HAVE_ED25519_VERIFY) /* test verify on good msg */ if (wc_ed25519_verify_msg(out, outlen, msgs[i], msgSz[i], &verify, &key) != 0 || verify != 1) - return -8931 - i; + return -10631 - i; /* test verify on bad msg */ out[outlen-1] = out[outlen-1] + 1; if (wc_ed25519_verify_msg(out, outlen, msgs[i], msgSz[i], &verify, &key) == 0 || verify == 1) - return -8941 - i; + return -10641 - i; #endif /* HAVE_ED25519_VERIFY */ /* test api for import/exporting keys */ exportPSz = sizeof(exportPKey); exportSSz = sizeof(exportSKey); if (wc_ed25519_export_public(&key, exportPKey, &exportPSz) != 0) - return -8951 - i; + return -10651 - i; if (wc_ed25519_import_public(exportPKey, exportPSz, &key2) != 0) - return -8961 - i; + return -10661 - i; if (wc_ed25519_export_private_only(&key, exportSKey, &exportSSz) != 0) - return -8971 - i; + return -10671 - i; if (wc_ed25519_import_private_key(exportSKey, exportSSz, exportPKey, exportPSz, &key2) != 0) - return -8981 - i; + return -10681 - i; /* clear "out" buffer and test sign with imported keys */ outlen = sizeof(out); XMEMSET(out, 0, sizeof(out)); if (wc_ed25519_sign_msg(msgs[i], msgSz[i], out, &outlen, &key2) != 0) - return -8991 - i; + return -10691 - i; #if defined(HAVE_ED25519_VERIFY) if (wc_ed25519_verify_msg(out, outlen, msgs[i], msgSz[i], &verify, &key2) != 0 || verify != 1) - return -9001 - i; + return -10701 - i; if (XMEMCMP(out, sigs[i], 64)) - return -9011 - i; + return -10711 - i; #endif /* HAVE_ED25519_VERIFY */ } @@ -21500,28 +21650,28 @@ int ed25519_test(void) idx = 0; if (wc_Ed25519PrivateKeyDecode(privateEd25519, &idx, &key3, sizeof(privateEd25519)) != 0) - return -7230 - i; + return -10721 - i; if (wc_ed25519_sign_msg(msgs[0], msgSz[0], out, &outlen, &key3) != BAD_FUNC_ARG) - return -7231 - i; + return -10731 - i; idx = 0; if (wc_Ed25519PublicKeyDecode(publicEd25519, &idx, &key3, sizeof(publicEd25519)) != 0) - return -7232 - i; + return -10741 - i; if (wc_ed25519_sign_msg(msgs[0], msgSz[0], out, &outlen, &key3) != 0) - return -7233 - i; + return -10751 - i; if (XMEMCMP(out, sigs[0], 64)) - return -7234 - i; + return -10761 - i; #if defined(HAVE_ED25519_VERIFY) /* test verify on good msg */ if (wc_ed25519_verify_msg(out, outlen, msgs[0], msgSz[0], &verify, &key3) != 0 || verify != 1) - return -7233 - i; + return -10771 - i; #endif /* HAVE_ED25519_VERIFY */ wc_ed25519_free(&key3); @@ -21530,13 +21680,13 @@ int ed25519_test(void) idx = 0; if (wc_Ed25519PrivateKeyDecode(privPubEd25519, &idx, &key3, sizeof(privPubEd25519)) != 0) - return -7230 - i; + return -10781 - i; if (wc_ed25519_sign_msg(msgs[0], msgSz[0], out, &outlen, &key3) != 0) - return -7233 - i; + return -10791 - i; if (XMEMCMP(out, sigs[0], 64)) - return -7234 - i; + return -10801 - i; wc_ed25519_free(&key3); #endif /* NO_ASN */ @@ -21569,6 +21719,1399 @@ int ed25519_test(void) } #endif /* HAVE_ED25519 */ +#ifdef HAVE_CURVE448 +#if defined(HAVE_CURVE448_SHARED_SECRET) && \ + defined(HAVE_CURVE448_KEY_IMPORT) +/* Test the wc_curve448_check_public API. + * + * returns 0 on success and -ve on failure. + */ +static int curve448_check_public_test(void) +{ + /* Little-endian values that will fail */ + byte fail_le[][CURVE448_KEY_SIZE] = { + { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + }, + { + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + }, + }; + /* Big-endian values that will fail */ + byte fail_be[][CURVE448_KEY_SIZE] = { + { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 + }, + { + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01 + }, + }; + /* Good or valid public value */ + byte good[CURVE448_KEY_SIZE] = { + 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01 + }; + int i; + + /* Parameter checks */ + /* NULL pointer */ + if (wc_curve448_check_public(NULL, 0, EC448_LITTLE_ENDIAN) != + BAD_FUNC_ARG) { + return -10900; + } + if (wc_curve448_check_public(NULL, 0, EC448_BIG_ENDIAN) != BAD_FUNC_ARG) { + return -10901; + } + /* Length of 0 treated differently to other invalid lengths for TLS */ + if (wc_curve448_check_public(good, 0, EC448_LITTLE_ENDIAN) != BUFFER_E) + return -10902; + if (wc_curve448_check_public(good, 0, EC448_BIG_ENDIAN) != BUFFER_E) + return -10903; + + /* Length not CURVE448_KEY_SIZE */ + for (i = 1; i < CURVE448_KEY_SIZE + 2; i++) { + if (i == CURVE448_KEY_SIZE) + continue; + if (wc_curve448_check_public(good, i, EC448_LITTLE_ENDIAN) != + ECC_BAD_ARG_E) { + return -10904 - i; + } + if (wc_curve448_check_public(good, i, EC448_BIG_ENDIAN) != + ECC_BAD_ARG_E) { + return -10914 - i; + } + } + + /* Little-endian fail cases */ + for (i = 0; i < (int)(sizeof(fail_le) / sizeof(fail_le)); i++) { + if (wc_curve448_check_public(fail_le[i], CURVE448_KEY_SIZE, + EC448_LITTLE_ENDIAN) == 0) { + return -10924 - i; + } + } + /* Big-endian fail cases */ + for (i = 0; i < (int)(sizeof(fail_be) / sizeof(fail_be)); i++) { + if (wc_curve448_check_public(fail_be[i], CURVE448_KEY_SIZE, + EC448_BIG_ENDIAN) == 0) { + return -10934 - i; + } + } + + /* Check a valid public value works! */ + if (wc_curve448_check_public(good, CURVE448_KEY_SIZE, + EC448_LITTLE_ENDIAN) != 0) { + return -10944; + } + if (wc_curve448_check_public(good, CURVE448_KEY_SIZE, + EC448_BIG_ENDIAN) != 0) { + return -10945; + } + + return 0; +} + +#endif /* HAVE_CURVE448_SHARED_SECRET && HAVE_CURVE448_KEY_IMPORT */ + +int curve448_test(void) +{ + WC_RNG rng; + int ret; +#ifdef HAVE_CURVE448_SHARED_SECRET + byte sharedA[CURVE448_KEY_SIZE]; + byte sharedB[CURVE448_KEY_SIZE]; + word32 y; +#endif +#ifdef HAVE_CURVE448_KEY_EXPORT + byte exportBuf[CURVE448_KEY_SIZE]; +#endif + word32 x; + curve448_key userA, userB, pubKey; + +#if defined(HAVE_CURVE448_SHARED_SECRET) && \ + defined(HAVE_CURVE448_KEY_IMPORT) + /* test vectors from + https://www.rfc-editor.org/rfc/rfc7748.html + */ + + /* secret key for party a */ + byte sa[] = { + 0x6b, 0x72, 0x98, 0xa5, 0xc0, 0xd8, 0xc2, 0x9a, + 0x1d, 0xab, 0x27, 0xf1, 0xa6, 0x82, 0x63, 0x00, + 0x91, 0x73, 0x89, 0x44, 0x97, 0x41, 0xa9, 0x74, + 0xf5, 0xba, 0xc9, 0xd9, 0x8d, 0xc2, 0x98, 0xd4, + 0x65, 0x55, 0xbc, 0xe8, 0xba, 0xe8, 0x9e, 0xee, + 0xd4, 0x00, 0x58, 0x4b, 0xb0, 0x46, 0xcf, 0x75, + 0x57, 0x9f, 0x51, 0xd1, 0x25, 0x49, 0x8f, 0x9a, + }; + + /* public key for party a */ + byte pa[] = { + 0xa0, 0x1f, 0xc4, 0x32, 0xe5, 0x80, 0x7f, 0x17, + 0x53, 0x0d, 0x12, 0x88, 0xda, 0x12, 0x5b, 0x0c, + 0xd4, 0x53, 0xd9, 0x41, 0x72, 0x64, 0x36, 0xc8, + 0xbb, 0xd9, 0xc5, 0x22, 0x2c, 0x3d, 0xa7, 0xfa, + 0x63, 0x9c, 0xe0, 0x3d, 0xb8, 0xd2, 0x3b, 0x27, + 0x4a, 0x07, 0x21, 0xa1, 0xae, 0xd5, 0x22, 0x7d, + 0xe6, 0xe3, 0xb7, 0x31, 0xcc, 0xf7, 0x08, 0x9b, + }; + + /* secret key for party b */ + byte sb[] = { + 0x2d, 0x99, 0x73, 0x51, 0xb6, 0x10, 0x6f, 0x36, + 0xb0, 0xd1, 0x09, 0x1b, 0x92, 0x9c, 0x4c, 0x37, + 0x21, 0x3e, 0x0d, 0x2b, 0x97, 0xe8, 0x5e, 0xbb, + 0x20, 0xc1, 0x27, 0x69, 0x1d, 0x0d, 0xad, 0x8f, + 0x1d, 0x81, 0x75, 0xb0, 0x72, 0x37, 0x45, 0xe6, + 0x39, 0xa3, 0xcb, 0x70, 0x44, 0x29, 0x0b, 0x99, + 0xe0, 0xe2, 0xa0, 0xc2, 0x7a, 0x6a, 0x30, 0x1c, + }; + + /* public key for party b */ + byte pb[] = { + 0x09, 0x36, 0xf3, 0x7b, 0xc6, 0xc1, 0xbd, 0x07, + 0xae, 0x3d, 0xec, 0x7a, 0xb5, 0xdc, 0x06, 0xa7, + 0x3c, 0xa1, 0x32, 0x42, 0xfb, 0x34, 0x3e, 0xfc, + 0x72, 0xb9, 0xd8, 0x27, 0x30, 0xb4, 0x45, 0xf3, + 0xd4, 0xb0, 0xbd, 0x07, 0x71, 0x62, 0xa4, 0x6d, + 0xcf, 0xec, 0x6f, 0x9b, 0x59, 0x0b, 0xfc, 0xbc, + 0xf5, 0x20, 0xcd, 0xb0, 0x29, 0xa8, 0xb7, 0x3e, + }; + + /* expected shared key */ + byte ss[] = { + 0x9d, 0x87, 0x4a, 0x51, 0x37, 0x50, 0x9a, 0x44, + 0x9a, 0xd5, 0x85, 0x30, 0x40, 0x24, 0x1c, 0x52, + 0x36, 0x39, 0x54, 0x35, 0xc3, 0x64, 0x24, 0xfd, + 0x56, 0x0b, 0x0c, 0xb6, 0x2b, 0x28, 0x1d, 0x28, + 0x52, 0x75, 0xa7, 0x40, 0xce, 0x32, 0xa2, 0x2d, + 0xd1, 0x74, 0x0f, 0x4a, 0xa9, 0x16, 0x1c, 0xec, + 0x95, 0xcc, 0xc6, 0x1a, 0x18, 0xf4, 0xff, 0x07, + }; +#endif /* HAVE_CURVE448_SHARED_SECRET */ + +#ifndef HAVE_FIPS + ret = wc_InitRng_ex(&rng, HEAP_HINT, devId); +#else + ret = wc_InitRng(&rng); +#endif + if (ret != 0) + return -11000; + + wc_curve448_init(&userA); + wc_curve448_init(&userB); + wc_curve448_init(&pubKey); + + /* make curve448 keys */ + if (wc_curve448_make_key(&rng, CURVE448_KEY_SIZE, &userA) != 0) + return -11001; + + if (wc_curve448_make_key(&rng, CURVE448_KEY_SIZE, &userB) != 0) + return -11002; + +#ifdef HAVE_CURVE448_SHARED_SECRET + /* find shared secret key */ + x = sizeof(sharedA); + if (wc_curve448_shared_secret(&userA, &userB, sharedA, &x) != 0) + return -11003; + + y = sizeof(sharedB); + if (wc_curve448_shared_secret(&userB, &userA, sharedB, &y) != 0) + return -11004; + + /* compare shared secret keys to test they are the same */ + if (y != x) + return -11005; + + if (XMEMCMP(sharedA, sharedB, x)) + return -11006; +#endif + +#ifdef HAVE_CURVE448_KEY_EXPORT + /* export a public key and import it for another user */ + x = sizeof(exportBuf); + if (wc_curve448_export_public(&userA, exportBuf, &x) != 0) + return -11007; + +#ifdef HAVE_CURVE448_KEY_IMPORT + if (wc_curve448_import_public(exportBuf, x, &pubKey) != 0) + return -11008; +#endif +#endif + +#if defined(HAVE_CURVE448_SHARED_SECRET) && \ + defined(HAVE_CURVE448_KEY_IMPORT) + /* test shared key after importing a public key */ + XMEMSET(sharedB, 0, sizeof(sharedB)); + y = sizeof(sharedB); + if (wc_curve448_shared_secret(&userB, &pubKey, sharedB, &y) != 0) + return -11009; + + if (XMEMCMP(sharedA, sharedB, y)) + return -11010; + + /* import RFC test vectors and compare shared key */ + if (wc_curve448_import_private_raw(sa, sizeof(sa), pa, sizeof(pa), &userA) + != 0) + return -11011; + + if (wc_curve448_import_private_raw(sb, sizeof(sb), pb, sizeof(pb), &userB) + != 0) + return -11012; + + /* test against known test vector */ + XMEMSET(sharedB, 0, sizeof(sharedB)); + y = sizeof(sharedB); + if (wc_curve448_shared_secret(&userA, &userB, sharedB, &y) != 0) + return -11013; + + if (XMEMCMP(ss, sharedB, y)) + return -11014; + + /* test swapping roles of keys and generating same shared key */ + XMEMSET(sharedB, 0, sizeof(sharedB)); + y = sizeof(sharedB); + if (wc_curve448_shared_secret(&userB, &userA, sharedB, &y) != 0) + return -11015; + + if (XMEMCMP(ss, sharedB, y)) + return -11016; + + /* test with 1 generated key and 1 from known test vector */ + if (wc_curve448_import_private_raw(sa, sizeof(sa), pa, sizeof(pa), &userA) + != 0) + return -11017; + + if (wc_curve448_make_key(&rng, 56, &userB) != 0) + return -11018; + + x = sizeof(sharedA); + if (wc_curve448_shared_secret(&userA, &userB, sharedA, &x) != 0) + return -11019; + + y = sizeof(sharedB); + if (wc_curve448_shared_secret(&userB, &userA, sharedB, &y) != 0) + return -11020; + + /* compare shared secret keys to test they are the same */ + if (y != x) + return -11021; + + if (XMEMCMP(sharedA, sharedB, x)) + return -11022; + + ret = curve448_check_public_test(); + if (ret != 0) + return ret; +#endif /* HAVE_CURVE448_SHARED_SECRET && HAVE_CURVE448_KEY_IMPORT */ + + /* clean up keys when done */ + wc_curve448_free(&pubKey); + wc_curve448_free(&userB); + wc_curve448_free(&userA); + + wc_FreeRng(&rng); + + return 0; +} +#endif /* HAVE_CURVE448 */ + +#ifdef HAVE_ED448 +#ifdef WOLFSSL_TEST_CERT +static int ed448_test_cert(void) +{ + DecodedCert cert[2]; + DecodedCert* serverCert = NULL; + DecodedCert* caCert = NULL; +#ifdef HAVE_ED448_VERIFY + ed448_key key; + ed448_key* pubKey = NULL; + int verify; +#endif /* HAVE_ED448_VERIFY */ + int ret; + byte* tmp; + size_t bytes; + XFILE file; + + tmp = XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + if (tmp == NULL) { + ERROR_OUT(-11023, done); + } + +#ifdef USE_CERT_BUFFERS_256 + XMEMCPY(tmp, ca_ed448_cert, sizeof_ca_ed448_cert); + bytes = sizeof_ca_ed448_cert; +#elif !defined(NO_FILESYSTEM) + file = XFOPEN(caEd448Cert, "rb"); + if (file == NULL) { + ERROR_OUT(-11024, done); + } + bytes = XFREAD(tmp, 1, FOURK_BUF, file); + XFCLOSE(file); +#else + /* No certificate to use. */ + ERROR_OUT(-11025, done); +#endif + + InitDecodedCert(&cert[0], tmp, (word32)bytes, 0); + caCert = &cert[0]; + ret = ParseCert(caCert, CERT_TYPE, NO_VERIFY, NULL); + if (ret != 0) { + ERROR_OUT(-11026, done); + } + +#ifdef USE_CERT_BUFFERS_256 + XMEMCPY(tmp, server_ed448_cert, sizeof_server_ed448_cert); + bytes = sizeof_server_ed448_cert; +#elif !defined(NO_FILESYSTEM) + file = XFOPEN(serverEd448Cert, "rb"); + if (file == NULL) { + ERROR_OUT(-11027, done); + } + bytes = XFREAD(tmp, 1, FOURK_BUF, file); + XFCLOSE(file); +#else + /* No certificate to use. */ + ERROR_OUT(-11028, done); +#endif + + InitDecodedCert(&cert[1], tmp, (word32)bytes, 0); + serverCert = &cert[1]; + ret = ParseCert(serverCert, CERT_TYPE, NO_VERIFY, NULL); + if (ret != 0) { + ERROR_OUT(-11029, done); + } + +#ifdef HAVE_ED448_VERIFY + ret = wc_ed448_init(&key); + if (ret < 0) { + ERROR_OUT(-11030, done); + } + pubKey = &key; + ret = wc_ed448_import_public(caCert->publicKey, caCert->pubKeySize, pubKey); + if (ret < 0) { + ERROR_OUT(-11031, done); + } + + if (wc_ed448_verify_msg(serverCert->signature, serverCert->sigLength, + serverCert->source + serverCert->certBegin, + serverCert->sigIndex - serverCert->certBegin, + &verify, pubKey) < 0 || verify != 1) { + ERROR_OUT(-11032, done); + } +#endif /* HAVE_ED448_VERIFY */ + +done: + if (tmp != NULL) + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); +#ifdef HAVE_ED448_VERIFY + wc_ed448_free(pubKey); +#endif /* HAVE_ED448_VERIFY */ + if (caCert != NULL) + FreeDecodedCert(caCert); + if (serverCert != NULL) + FreeDecodedCert(serverCert); + + return ret; +} + +static int ed448_test_make_cert(void) +{ + WC_RNG rng; + Cert cert; + DecodedCert decode; + ed448_key key; + ed448_key* privKey = NULL; + int ret = 0; + byte* tmp = NULL; + + wc_InitCert(&cert); + +#ifndef HAVE_FIPS + ret = wc_InitRng_ex(&rng, HEAP_HINT, devId); +#else + ret = wc_InitRng(&rng); +#endif + if (ret != 0) + return -11033; + + wc_ed448_init(&key); + privKey = &key; + wc_ed448_make_key(&rng, ED448_KEY_SIZE, privKey); + + cert.daysValid = 365 * 2; + cert.selfSigned = 1; + XMEMCPY(&cert.issuer, &certDefaultName, sizeof(CertName)); + XMEMCPY(&cert.subject, &certDefaultName, sizeof(CertName)); + cert.isCA = 0; +#ifdef WOLFSSL_CERT_EXT + ret = wc_SetKeyUsage(&cert, certKeyUsage); + if (ret < 0) { + ERROR_OUT(-11034, done); + } + ret = wc_SetSubjectKeyIdFromPublicKey_ex(&cert, ED448_TYPE, privKey); + if (ret < 0) { + ERROR_OUT(-11035, done); + } + ret = wc_SetAuthKeyIdFromPublicKey_ex(&cert, ED448_TYPE, privKey); + if (ret < 0) { + ERROR_OUT(-11036, done); + } +#endif + tmp = XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + if (tmp == NULL) { + ERROR_OUT(-11037, done); + } + + cert.sigType = CTC_ED448; + ret = wc_MakeCert_ex(&cert, tmp, FOURK_BUF, ED448_TYPE, privKey, &rng); + if (ret < 0) { + ERROR_OUT(-11038, done); + } + ret = wc_SignCert_ex(cert.bodySz, cert.sigType, tmp, FOURK_BUF, ED448_TYPE, + privKey, &rng); + if (ret < 0) { + ERROR_OUT(-11039, done); + } + + InitDecodedCert(&decode, tmp, ret, HEAP_HINT); + ret = ParseCert(&decode, CERT_TYPE, NO_VERIFY, 0); + FreeDecodedCert(&decode); + if (ret != 0) { + ERROR_OUT(-11040, done); + } + +done: + if (tmp != NULL) + XFREE(tmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + wc_ed448_free(privKey); + wc_FreeRng(&rng); + return ret; +} +#endif /* WOLFSSL_TEST_CERT */ + +#if defined(HAVE_ED448_SIGN) && defined(HAVE_ED448_KEY_EXPORT) && \ + defined(HAVE_ED448_KEY_IMPORT) +static int ed448_ctx_test(void) +{ + byte out[ED448_SIG_SIZE]; + word32 outlen; +#ifdef HAVE_ED448_VERIFY + int verify; +#endif /* HAVE_ED448_VERIFY */ + ed448_key key; + + static const byte sKeyCtx[] = { + 0xc4, 0xea, 0xb0, 0x5d, 0x35, 0x70, 0x07, 0xc6, + 0x32, 0xf3, 0xdb, 0xb4, 0x84, 0x89, 0x92, 0x4d, + 0x55, 0x2b, 0x08, 0xfe, 0x0c, 0x35, 0x3a, 0x0d, + 0x4a, 0x1f, 0x00, 0xac, 0xda, 0x2c, 0x46, 0x3a, + 0xfb, 0xea, 0x67, 0xc5, 0xe8, 0xd2, 0x87, 0x7c, + 0x5e, 0x3b, 0xc3, 0x97, 0xa6, 0x59, 0x94, 0x9e, + 0xf8, 0x02, 0x1e, 0x95, 0x4e, 0x0a, 0x12, 0x27, + 0x4e + }; + + static const byte pKeyCtx[] = { + 0x43, 0xba, 0x28, 0xf4, 0x30, 0xcd, 0xff, 0x45, + 0x6a, 0xe5, 0x31, 0x54, 0x5f, 0x7e, 0xcd, 0x0a, + 0xc8, 0x34, 0xa5, 0x5d, 0x93, 0x58, 0xc0, 0x37, + 0x2b, 0xfa, 0x0c, 0x6c, 0x67, 0x98, 0xc0, 0x86, + 0x6a, 0xea, 0x01, 0xeb, 0x00, 0x74, 0x28, 0x02, + 0xb8, 0x43, 0x8e, 0xa4, 0xcb, 0x82, 0x16, 0x9c, + 0x23, 0x51, 0x60, 0x62, 0x7b, 0x4c, 0x3a, 0x94, + 0x80 + }; + + static const byte sigCtx[] = { + 0xd4, 0xf8, 0xf6, 0x13, 0x17, 0x70, 0xdd, 0x46, + 0xf4, 0x08, 0x67, 0xd6, 0xfd, 0x5d, 0x50, 0x55, + 0xde, 0x43, 0x54, 0x1f, 0x8c, 0x5e, 0x35, 0xab, + 0xbc, 0xd0, 0x01, 0xb3, 0x2a, 0x89, 0xf7, 0xd2, + 0x15, 0x1f, 0x76, 0x47, 0xf1, 0x1d, 0x8c, 0xa2, + 0xae, 0x27, 0x9f, 0xb8, 0x42, 0xd6, 0x07, 0x21, + 0x7f, 0xce, 0x6e, 0x04, 0x2f, 0x68, 0x15, 0xea, + 0x00, 0x0c, 0x85, 0x74, 0x1d, 0xe5, 0xc8, 0xda, + 0x11, 0x44, 0xa6, 0xa1, 0xab, 0xa7, 0xf9, 0x6d, + 0xe4, 0x25, 0x05, 0xd7, 0xa7, 0x29, 0x85, 0x24, + 0xfd, 0xa5, 0x38, 0xfc, 0xcb, 0xbb, 0x75, 0x4f, + 0x57, 0x8c, 0x1c, 0xad, 0x10, 0xd5, 0x4d, 0x0d, + 0x54, 0x28, 0x40, 0x7e, 0x85, 0xdc, 0xbc, 0x98, + 0xa4, 0x91, 0x55, 0xc1, 0x37, 0x64, 0xe6, 0x6c, + 0x3c, 0x00 + }; + + static const byte msgCtx[] = { + 0x03 + }; + + static const byte contextCtx[] = { + 0x66,0x6f,0x6f + }; + + outlen = sizeof(out); + XMEMSET(out, 0, sizeof(out)); + + if (wc_ed448_import_private_key(sKeyCtx, ED448_KEY_SIZE, pKeyCtx, + sizeof(pKeyCtx), &key) != 0) + return -11100; + + if (wc_ed448_sign_msg(msgCtx, sizeof(msgCtx), out, &outlen, &key, + contextCtx, sizeof(contextCtx)) != 0) + return -11101; + + if (XMEMCMP(out, sigCtx, sizeof(sigCtx))) + return -11102; + +#if defined(HAVE_ED448_VERIFY) + /* test verify on good msg */ + if (wc_ed448_verify_msg(out, outlen, msgCtx, sizeof(msgCtx), &verify, &key, + contextCtx, sizeof(contextCtx)) != 0 || verify != 1) + return -11103; +#endif + + wc_ed448_free(&key); + + return 0; +} + +static int ed448ph_test(void) +{ + byte out[ED448_SIG_SIZE]; + word32 outlen; +#ifdef HAVE_ED448_VERIFY + int verify; +#endif /* HAVE_ED448_VERIFY */ + ed448_key key; + + static const byte sKeyPh[] = { + 0x83, 0x3f, 0xe6, 0x24, 0x09, 0x23, 0x7b, 0x9d, + 0x62, 0xec, 0x77, 0x58, 0x75, 0x20, 0x91, 0x1e, + 0x9a, 0x75, 0x9c, 0xec, 0x1d, 0x19, 0x75, 0x5b, + 0x7d, 0xa9, 0x01, 0xb9, 0x6d, 0xca, 0x3d, 0x42, + 0xef, 0x78, 0x22, 0xe0, 0xd5, 0x10, 0x41, 0x27, + 0xdc, 0x05, 0xd6, 0xdb, 0xef, 0xde, 0x69, 0xe3, + 0xab, 0x2c, 0xec, 0x7c, 0x86, 0x7c, 0x6e, 0x2c, + 0x49 + }; + + static const byte pKeyPh[] = { + 0x25, 0x9b, 0x71, 0xc1, 0x9f, 0x83, 0xef, 0x77, + 0xa7, 0xab, 0xd2, 0x65, 0x24, 0xcb, 0xdb, 0x31, + 0x61, 0xb5, 0x90, 0xa4, 0x8f, 0x7d, 0x17, 0xde, + 0x3e, 0xe0, 0xba, 0x9c, 0x52, 0xbe, 0xb7, 0x43, + 0xc0, 0x94, 0x28, 0xa1, 0x31, 0xd6, 0xb1, 0xb5, + 0x73, 0x03, 0xd9, 0x0d, 0x81, 0x32, 0xc2, 0x76, + 0xd5, 0xed, 0x3d, 0x5d, 0x01, 0xc0, 0xf5, 0x38, + 0x80 + }; + + static const byte sigPh1[] = { + 0x82, 0x2f, 0x69, 0x01, 0xf7, 0x48, 0x0f, 0x3d, + 0x5f, 0x56, 0x2c, 0x59, 0x29, 0x94, 0xd9, 0x69, + 0x36, 0x02, 0x87, 0x56, 0x14, 0x48, 0x32, 0x56, + 0x50, 0x56, 0x00, 0xbb, 0xc2, 0x81, 0xae, 0x38, + 0x1f, 0x54, 0xd6, 0xbc, 0xe2, 0xea, 0x91, 0x15, + 0x74, 0x93, 0x2f, 0x52, 0xa4, 0xe6, 0xca, 0xdd, + 0x78, 0x76, 0x93, 0x75, 0xec, 0x3f, 0xfd, 0x1b, + 0x80, 0x1a, 0x0d, 0x9b, 0x3f, 0x40, 0x30, 0xcd, + 0x43, 0x39, 0x64, 0xb6, 0x45, 0x7e, 0xa3, 0x94, + 0x76, 0x51, 0x12, 0x14, 0xf9, 0x74, 0x69, 0xb5, + 0x7d, 0xd3, 0x2d, 0xbc, 0x56, 0x0a, 0x9a, 0x94, + 0xd0, 0x0b, 0xff, 0x07, 0x62, 0x04, 0x64, 0xa3, + 0xad, 0x20, 0x3d, 0xf7, 0xdc, 0x7c, 0xe3, 0x60, + 0xc3, 0xcd, 0x36, 0x96, 0xd9, 0xd9, 0xfa, 0xb9, + 0x0f, 0x00 + }; + + static const byte sigPh2[] = { + 0xc3, 0x22, 0x99, 0xd4, 0x6e, 0xc8, 0xff, 0x02, + 0xb5, 0x45, 0x40, 0x98, 0x28, 0x14, 0xdc, 0xe9, + 0xa0, 0x58, 0x12, 0xf8, 0x19, 0x62, 0xb6, 0x49, + 0xd5, 0x28, 0x09, 0x59, 0x16, 0xa2, 0xaa, 0x48, + 0x10, 0x65, 0xb1, 0x58, 0x04, 0x23, 0xef, 0x92, + 0x7e, 0xcf, 0x0a, 0xf5, 0x88, 0x8f, 0x90, 0xda, + 0x0f, 0x6a, 0x9a, 0x85, 0xad, 0x5d, 0xc3, 0xf2, + 0x80, 0xd9, 0x12, 0x24, 0xba, 0x99, 0x11, 0xa3, + 0x65, 0x3d, 0x00, 0xe4, 0x84, 0xe2, 0xce, 0x23, + 0x25, 0x21, 0x48, 0x1c, 0x86, 0x58, 0xdf, 0x30, + 0x4b, 0xb7, 0x74, 0x5a, 0x73, 0x51, 0x4c, 0xdb, + 0x9b, 0xf3, 0xe1, 0x57, 0x84, 0xab, 0x71, 0x28, + 0x4f, 0x8d, 0x07, 0x04, 0xa6, 0x08, 0xc5, 0x4a, + 0x6b, 0x62, 0xd9, 0x7b, 0xeb, 0x51, 0x1d, 0x13, + 0x21, 0x00 + }; + + static const byte msgPh[] = { + 0x61,0x62,0x63 + }; + + /* SHA-512 hash of msgPh */ + static const byte hashPh[] = { + 0x48, 0x33, 0x66, 0x60, 0x13, 0x60, 0xa8, 0x77, + 0x1c, 0x68, 0x63, 0x08, 0x0c, 0xc4, 0x11, 0x4d, + 0x8d, 0xb4, 0x45, 0x30, 0xf8, 0xf1, 0xe1, 0xee, + 0x4f, 0x94, 0xea, 0x37, 0xe7, 0x8b, 0x57, 0x39, + 0xd5, 0xa1, 0x5b, 0xef, 0x18, 0x6a, 0x53, 0x86, + 0xc7, 0x57, 0x44, 0xc0, 0x52, 0x7e, 0x1f, 0xaa, + 0x9f, 0x87, 0x26, 0xe4, 0x62, 0xa1, 0x2a, 0x4f, + 0xeb, 0x06, 0xbd, 0x88, 0x01, 0xe7, 0x51, 0xe4 + }; + + static const byte contextPh2[] = { + 0x66,0x6f,0x6f + }; + + outlen = sizeof(out); + XMEMSET(out, 0, sizeof(out)); + + if (wc_ed448_import_private_key(sKeyPh, ED448_KEY_SIZE, pKeyPh, + sizeof(pKeyPh), &key) != 0) { + return -11200; + } + + if (wc_ed448ph_sign_msg(msgPh, sizeof(msgPh), out, &outlen, &key, NULL, + 0) != 0) { + return -11201; + } + + if (XMEMCMP(out, sigPh1, sizeof(sigPh1))) + return -11202; + +#if defined(HAVE_ED448_VERIFY) + /* test verify on good msg */ + if (wc_ed448ph_verify_msg(out, outlen, msgPh, sizeof(msgPh), &verify, &key, + NULL, 0) != 0 || verify != 1) { + return -11203; + } +#endif + + if (wc_ed448ph_sign_msg(msgPh, sizeof(msgPh), out, &outlen, &key, + contextPh2, sizeof(contextPh2)) != 0) { + return -11204; + } + + if (XMEMCMP(out, sigPh2, sizeof(sigPh2))) + return -11205; + +#if defined(HAVE_ED448_VERIFY) + /* test verify on good msg */ + if (wc_ed448ph_verify_msg(out, outlen, msgPh, sizeof(msgPh), &verify, &key, + contextPh2, sizeof(contextPh2)) != 0 || + verify != 1) { + return -11206; + } +#endif + + if (wc_ed448ph_sign_hash(hashPh, sizeof(hashPh), out, &outlen, &key, NULL, + 0) != 0) { + return -11207; + } + + if (XMEMCMP(out, sigPh1, sizeof(sigPh1))) + return -11208; + +#if defined(HAVE_ED448_VERIFY) + if (wc_ed448ph_verify_hash(out, outlen, hashPh, sizeof(hashPh), &verify, + &key, NULL, 0) != 0 || verify != 1) { + return -11209; + } +#endif + + if (wc_ed448ph_sign_hash(hashPh, sizeof(hashPh), out, &outlen, &key, + contextPh2, sizeof(contextPh2)) != 0) { + return -11210; + } + + if (XMEMCMP(out, sigPh2, sizeof(sigPh2))) + return -11211; + +#if defined(HAVE_ED448_VERIFY) + if (wc_ed448ph_verify_hash(out, outlen, hashPh, sizeof(hashPh), &verify, + &key, contextPh2, sizeof(contextPh2)) != 0 || + verify != 1) { + return -11212; + } +#endif + + wc_ed448_free(&key); + + return 0; +} +#endif /* HAVE_ED448_SIGN && HAVE_ED448_KEY_EXPORT && HAVE_ED448_KEY_IMPORT */ + +int ed448_test(void) +{ + int ret; + WC_RNG rng; +#if defined(HAVE_ED448_SIGN) && defined(HAVE_ED448_KEY_EXPORT) &&\ + defined(HAVE_ED448_KEY_IMPORT) + byte out[ED448_SIG_SIZE]; + byte exportPKey[ED448_KEY_SIZE]; + byte exportSKey[ED448_KEY_SIZE]; + word32 exportPSz; + word32 exportSSz; + int i; + word32 outlen; +#ifdef HAVE_ED448_VERIFY + int verify; +#endif /* HAVE_ED448_VERIFY */ +#endif /* HAVE_ED448_SIGN && HAVE_ED448_KEY_EXPORT && HAVE_ED448_KEY_IMPORT */ + word32 keySz, sigSz; + ed448_key key; + ed448_key key2; + +#if defined(HAVE_ED448_SIGN) && defined(HAVE_ED448_KEY_EXPORT) && \ + defined(HAVE_ED448_KEY_IMPORT) + /* test vectors from + https://tools.ietf.org/html/rfc8032 + */ + + static const byte sKey1[] = { + 0x6c, 0x82, 0xa5, 0x62, 0xcb, 0x80, 0x8d, 0x10, + 0xd6, 0x32, 0xbe, 0x89, 0xc8, 0x51, 0x3e, 0xbf, + 0x6c, 0x92, 0x9f, 0x34, 0xdd, 0xfa, 0x8c, 0x9f, + 0x63, 0xc9, 0x96, 0x0e, 0xf6, 0xe3, 0x48, 0xa3, + 0x52, 0x8c, 0x8a, 0x3f, 0xcc, 0x2f, 0x04, 0x4e, + 0x39, 0xa3, 0xfc, 0x5b, 0x94, 0x49, 0x2f, 0x8f, + 0x03, 0x2e, 0x75, 0x49, 0xa2, 0x00, 0x98, 0xf9, + 0x5b + }; + + static const byte sKey2[] = { + 0xc4, 0xea, 0xb0, 0x5d, 0x35, 0x70, 0x07, 0xc6, + 0x32, 0xf3, 0xdb, 0xb4, 0x84, 0x89, 0x92, 0x4d, + 0x55, 0x2b, 0x08, 0xfe, 0x0c, 0x35, 0x3a, 0x0d, + 0x4a, 0x1f, 0x00, 0xac, 0xda, 0x2c, 0x46, 0x3a, + 0xfb, 0xea, 0x67, 0xc5, 0xe8, 0xd2, 0x87, 0x7c, + 0x5e, 0x3b, 0xc3, 0x97, 0xa6, 0x59, 0x94, 0x9e, + 0xf8, 0x02, 0x1e, 0x95, 0x4e, 0x0a, 0x12, 0x27, + 0x4e + }; + + static const byte sKey3[] = { + 0x25, 0x8c, 0xdd, 0x4a, 0xda, 0x32, 0xed, 0x9c, + 0x9f, 0xf5, 0x4e, 0x63, 0x75, 0x6a, 0xe5, 0x82, + 0xfb, 0x8f, 0xab, 0x2a, 0xc7, 0x21, 0xf2, 0xc8, + 0xe6, 0x76, 0xa7, 0x27, 0x68, 0x51, 0x3d, 0x93, + 0x9f, 0x63, 0xdd, 0xdb, 0x55, 0x60, 0x91, 0x33, + 0xf2, 0x9a, 0xdf, 0x86, 0xec, 0x99, 0x29, 0xdc, + 0xcb, 0x52, 0xc1, 0xc5, 0xfd, 0x2f, 0xf7, 0xe2, + 0x1b + }; + + /* uncompressed test */ + static const byte sKey4[] = { + 0x6c, 0x82, 0xa5, 0x62, 0xcb, 0x80, 0x8d, 0x10, + 0xd6, 0x32, 0xbe, 0x89, 0xc8, 0x51, 0x3e, 0xbf, + 0x6c, 0x92, 0x9f, 0x34, 0xdd, 0xfa, 0x8c, 0x9f, + 0x63, 0xc9, 0x96, 0x0e, 0xf6, 0xe3, 0x48, 0xa3, + 0x52, 0x8c, 0x8a, 0x3f, 0xcc, 0x2f, 0x04, 0x4e, + 0x39, 0xa3, 0xfc, 0x5b, 0x94, 0x49, 0x2f, 0x8f, + 0x03, 0x2e, 0x75, 0x49, 0xa2, 0x00, 0x98, 0xf9, + 0x5b + }; + + /* compressed prefix test */ + static const byte sKey5[] = { + 0x6c, 0x82, 0xa5, 0x62, 0xcb, 0x80, 0x8d, 0x10, + 0xd6, 0x32, 0xbe, 0x89, 0xc8, 0x51, 0x3e, 0xbf, + 0x6c, 0x92, 0x9f, 0x34, 0xdd, 0xfa, 0x8c, 0x9f, + 0x63, 0xc9, 0x96, 0x0e, 0xf6, 0xe3, 0x48, 0xa3, + 0x52, 0x8c, 0x8a, 0x3f, 0xcc, 0x2f, 0x04, 0x4e, + 0x39, 0xa3, 0xfc, 0x5b, 0x94, 0x49, 0x2f, 0x8f, + 0x03, 0x2e, 0x75, 0x49, 0xa2, 0x00, 0x98, 0xf9, + 0x5b + }; + + static const byte sKey6[] = { + 0x87, 0x2d, 0x09, 0x37, 0x80, 0xf5, 0xd3, 0x73, + 0x0d, 0xf7, 0xc2, 0x12, 0x66, 0x4b, 0x37, 0xb8, + 0xa0, 0xf2, 0x4f, 0x56, 0x81, 0x0d, 0xaa, 0x83, + 0x82, 0xcd, 0x4f, 0xa3, 0xf7, 0x76, 0x34, 0xec, + 0x44, 0xdc, 0x54, 0xf1, 0xc2, 0xed, 0x9b, 0xea, + 0x86, 0xfa, 0xfb, 0x76, 0x32, 0xd8, 0xbe, 0x19, + 0x9e, 0xa1, 0x65, 0xf5, 0xad, 0x55, 0xdd, 0x9c, + 0xe8 + }; + + static const byte* sKeys[] = {sKey1, sKey2, sKey3, sKey4, sKey5, sKey6}; + + static const byte pKey1[] = { + 0x5f, 0xd7, 0x44, 0x9b, 0x59, 0xb4, 0x61, 0xfd, + 0x2c, 0xe7, 0x87, 0xec, 0x61, 0x6a, 0xd4, 0x6a, + 0x1d, 0xa1, 0x34, 0x24, 0x85, 0xa7, 0x0e, 0x1f, + 0x8a, 0x0e, 0xa7, 0x5d, 0x80, 0xe9, 0x67, 0x78, + 0xed, 0xf1, 0x24, 0x76, 0x9b, 0x46, 0xc7, 0x06, + 0x1b, 0xd6, 0x78, 0x3d, 0xf1, 0xe5, 0x0f, 0x6c, + 0xd1, 0xfa, 0x1a, 0xbe, 0xaf, 0xe8, 0x25, 0x61, + 0x80 + }; + + static const byte pKey2[] = { + 0x43, 0xba, 0x28, 0xf4, 0x30, 0xcd, 0xff, 0x45, + 0x6a, 0xe5, 0x31, 0x54, 0x5f, 0x7e, 0xcd, 0x0a, + 0xc8, 0x34, 0xa5, 0x5d, 0x93, 0x58, 0xc0, 0x37, + 0x2b, 0xfa, 0x0c, 0x6c, 0x67, 0x98, 0xc0, 0x86, + 0x6a, 0xea, 0x01, 0xeb, 0x00, 0x74, 0x28, 0x02, + 0xb8, 0x43, 0x8e, 0xa4, 0xcb, 0x82, 0x16, 0x9c, + 0x23, 0x51, 0x60, 0x62, 0x7b, 0x4c, 0x3a, 0x94, + 0x80 + }; + + static const byte pKey3[] = { + 0x3b, 0xa1, 0x6d, 0xa0, 0xc6, 0xf2, 0xcc, 0x1f, + 0x30, 0x18, 0x77, 0x40, 0x75, 0x6f, 0x5e, 0x79, + 0x8d, 0x6b, 0xc5, 0xfc, 0x01, 0x5d, 0x7c, 0x63, + 0xcc, 0x95, 0x10, 0xee, 0x3f, 0xd4, 0x4a, 0xdc, + 0x24, 0xd8, 0xe9, 0x68, 0xb6, 0xe4, 0x6e, 0x6f, + 0x94, 0xd1, 0x9b, 0x94, 0x53, 0x61, 0x72, 0x6b, + 0xd7, 0x5e, 0x14, 0x9e, 0xf0, 0x98, 0x17, 0xf5, + 0x80 + }; + + /* uncompressed test */ + static const byte pKey4[] = { + 0x5f, 0xd7, 0x44, 0x9b, 0x59, 0xb4, 0x61, 0xfd, + 0x2c, 0xe7, 0x87, 0xec, 0x61, 0x6a, 0xd4, 0x6a, + 0x1d, 0xa1, 0x34, 0x24, 0x85, 0xa7, 0x0e, 0x1f, + 0x8a, 0x0e, 0xa7, 0x5d, 0x80, 0xe9, 0x67, 0x78, + 0xed, 0xf1, 0x24, 0x76, 0x9b, 0x46, 0xc7, 0x06, + 0x1b, 0xd6, 0x78, 0x3d, 0xf1, 0xe5, 0x0f, 0x6c, + 0xd1, 0xfa, 0x1a, 0xbe, 0xaf, 0xe8, 0x25, 0x61, + 0x80 + }; + + /* compressed prefix */ + static const byte pKey5[] = { + 0x5f, 0xd7, 0x44, 0x9b, 0x59, 0xb4, 0x61, 0xfd, + 0x2c, 0xe7, 0x87, 0xec, 0x61, 0x6a, 0xd4, 0x6a, + 0x1d, 0xa1, 0x34, 0x24, 0x85, 0xa7, 0x0e, 0x1f, + 0x8a, 0x0e, 0xa7, 0x5d, 0x80, 0xe9, 0x67, 0x78, + 0xed, 0xf1, 0x24, 0x76, 0x9b, 0x46, 0xc7, 0x06, + 0x1b, 0xd6, 0x78, 0x3d, 0xf1, 0xe5, 0x0f, 0x6c, + 0xd1, 0xfa, 0x1a, 0xbe, 0xaf, 0xe8, 0x25, 0x61, + 0x80 + }; + + static const byte pKey6[] = { + 0xa8, 0x1b, 0x2e, 0x8a, 0x70, 0xa5, 0xac, 0x94, + 0xff, 0xdb, 0xcc, 0x9b, 0xad, 0xfc, 0x3f, 0xeb, + 0x08, 0x01, 0xf2, 0x58, 0x57, 0x8b, 0xb1, 0x14, + 0xad, 0x44, 0xec, 0xe1, 0xec, 0x0e, 0x79, 0x9d, + 0xa0, 0x8e, 0xff, 0xb8, 0x1c, 0x5d, 0x68, 0x5c, + 0x0c, 0x56, 0xf6, 0x4e, 0xec, 0xae, 0xf8, 0xcd, + 0xf1, 0x1c, 0xc3, 0x87, 0x37, 0x83, 0x8c, 0xf4, + 0x00 + }; + + static const byte* pKeys[] = {pKey1, pKey2, pKey3, pKey4, pKey5, pKey6}; + static const byte pKeySz[] = {sizeof(pKey1), sizeof(pKey2), sizeof(pKey3), + sizeof(pKey4), sizeof(pKey5), sizeof(pKey6)}; + + static const byte sig1[] = { + 0x53, 0x3a, 0x37, 0xf6, 0xbb, 0xe4, 0x57, 0x25, + 0x1f, 0x02, 0x3c, 0x0d, 0x88, 0xf9, 0x76, 0xae, + 0x2d, 0xfb, 0x50, 0x4a, 0x84, 0x3e, 0x34, 0xd2, + 0x07, 0x4f, 0xd8, 0x23, 0xd4, 0x1a, 0x59, 0x1f, + 0x2b, 0x23, 0x3f, 0x03, 0x4f, 0x62, 0x82, 0x81, + 0xf2, 0xfd, 0x7a, 0x22, 0xdd, 0xd4, 0x7d, 0x78, + 0x28, 0xc5, 0x9b, 0xd0, 0xa2, 0x1b, 0xfd, 0x39, + 0x80, 0xff, 0x0d, 0x20, 0x28, 0xd4, 0xb1, 0x8a, + 0x9d, 0xf6, 0x3e, 0x00, 0x6c, 0x5d, 0x1c, 0x2d, + 0x34, 0x5b, 0x92, 0x5d, 0x8d, 0xc0, 0x0b, 0x41, + 0x04, 0x85, 0x2d, 0xb9, 0x9a, 0xc5, 0xc7, 0xcd, + 0xda, 0x85, 0x30, 0xa1, 0x13, 0xa0, 0xf4, 0xdb, + 0xb6, 0x11, 0x49, 0xf0, 0x5a, 0x73, 0x63, 0x26, + 0x8c, 0x71, 0xd9, 0x58, 0x08, 0xff, 0x2e, 0x65, + 0x26, 0x00 + }; + + static const byte sig2[] = { + 0x26, 0xb8, 0xf9, 0x17, 0x27, 0xbd, 0x62, 0x89, + 0x7a, 0xf1, 0x5e, 0x41, 0xeb, 0x43, 0xc3, 0x77, + 0xef, 0xb9, 0xc6, 0x10, 0xd4, 0x8f, 0x23, 0x35, + 0xcb, 0x0b, 0xd0, 0x08, 0x78, 0x10, 0xf4, 0x35, + 0x25, 0x41, 0xb1, 0x43, 0xc4, 0xb9, 0x81, 0xb7, + 0xe1, 0x8f, 0x62, 0xde, 0x8c, 0xcd, 0xf6, 0x33, + 0xfc, 0x1b, 0xf0, 0x37, 0xab, 0x7c, 0xd7, 0x79, + 0x80, 0x5e, 0x0d, 0xbc, 0xc0, 0xaa, 0xe1, 0xcb, + 0xce, 0xe1, 0xaf, 0xb2, 0xe0, 0x27, 0xdf, 0x36, + 0xbc, 0x04, 0xdc, 0xec, 0xbf, 0x15, 0x43, 0x36, + 0xc1, 0x9f, 0x0a, 0xf7, 0xe0, 0xa6, 0x47, 0x29, + 0x05, 0xe7, 0x99, 0xf1, 0x95, 0x3d, 0x2a, 0x0f, + 0xf3, 0x34, 0x8a, 0xb2, 0x1a, 0xa4, 0xad, 0xaf, + 0xd1, 0xd2, 0x34, 0x44, 0x1c, 0xf8, 0x07, 0xc0, + 0x3a, 0x00 + }; + + static const byte sig3[] = { + 0x7e, 0xee, 0xab, 0x7c, 0x4e, 0x50, 0xfb, 0x79, + 0x9b, 0x41, 0x8e, 0xe5, 0xe3, 0x19, 0x7f, 0xf6, + 0xbf, 0x15, 0xd4, 0x3a, 0x14, 0xc3, 0x43, 0x89, + 0xb5, 0x9d, 0xd1, 0xa7, 0xb1, 0xb8, 0x5b, 0x4a, + 0xe9, 0x04, 0x38, 0xac, 0xa6, 0x34, 0xbe, 0xa4, + 0x5e, 0x3a, 0x26, 0x95, 0xf1, 0x27, 0x0f, 0x07, + 0xfd, 0xcd, 0xf7, 0xc6, 0x2b, 0x8e, 0xfe, 0xaf, + 0x00, 0xb4, 0x5c, 0x2c, 0x96, 0xba, 0x45, 0x7e, + 0xb1, 0xa8, 0xbf, 0x07, 0x5a, 0x3d, 0xb2, 0x8e, + 0x5c, 0x24, 0xf6, 0xb9, 0x23, 0xed, 0x4a, 0xd7, + 0x47, 0xc3, 0xc9, 0xe0, 0x3c, 0x70, 0x79, 0xef, + 0xb8, 0x7c, 0xb1, 0x10, 0xd3, 0xa9, 0x98, 0x61, + 0xe7, 0x20, 0x03, 0xcb, 0xae, 0x6d, 0x6b, 0x8b, + 0x82, 0x7e, 0x4e, 0x6c, 0x14, 0x30, 0x64, 0xff, + 0x3c, 0x00 + }; + + /* uncompressed test */ + static const byte sig4[] = { + 0x53, 0x3a, 0x37, 0xf6, 0xbb, 0xe4, 0x57, 0x25, + 0x1f, 0x02, 0x3c, 0x0d, 0x88, 0xf9, 0x76, 0xae, + 0x2d, 0xfb, 0x50, 0x4a, 0x84, 0x3e, 0x34, 0xd2, + 0x07, 0x4f, 0xd8, 0x23, 0xd4, 0x1a, 0x59, 0x1f, + 0x2b, 0x23, 0x3f, 0x03, 0x4f, 0x62, 0x82, 0x81, + 0xf2, 0xfd, 0x7a, 0x22, 0xdd, 0xd4, 0x7d, 0x78, + 0x28, 0xc5, 0x9b, 0xd0, 0xa2, 0x1b, 0xfd, 0x39, + 0x80, 0xff, 0x0d, 0x20, 0x28, 0xd4, 0xb1, 0x8a, + 0x9d, 0xf6, 0x3e, 0x00, 0x6c, 0x5d, 0x1c, 0x2d, + 0x34, 0x5b, 0x92, 0x5d, 0x8d, 0xc0, 0x0b, 0x41, + 0x04, 0x85, 0x2d, 0xb9, 0x9a, 0xc5, 0xc7, 0xcd, + 0xda, 0x85, 0x30, 0xa1, 0x13, 0xa0, 0xf4, 0xdb, + 0xb6, 0x11, 0x49, 0xf0, 0x5a, 0x73, 0x63, 0x26, + 0x8c, 0x71, 0xd9, 0x58, 0x08, 0xff, 0x2e, 0x65, + 0x26, 0x00 + }; + + /* compressed prefix */ + static const byte sig5[] = { + 0x53, 0x3a, 0x37, 0xf6, 0xbb, 0xe4, 0x57, 0x25, + 0x1f, 0x02, 0x3c, 0x0d, 0x88, 0xf9, 0x76, 0xae, + 0x2d, 0xfb, 0x50, 0x4a, 0x84, 0x3e, 0x34, 0xd2, + 0x07, 0x4f, 0xd8, 0x23, 0xd4, 0x1a, 0x59, 0x1f, + 0x2b, 0x23, 0x3f, 0x03, 0x4f, 0x62, 0x82, 0x81, + 0xf2, 0xfd, 0x7a, 0x22, 0xdd, 0xd4, 0x7d, 0x78, + 0x28, 0xc5, 0x9b, 0xd0, 0xa2, 0x1b, 0xfd, 0x39, + 0x80, 0xff, 0x0d, 0x20, 0x28, 0xd4, 0xb1, 0x8a, + 0x9d, 0xf6, 0x3e, 0x00, 0x6c, 0x5d, 0x1c, 0x2d, + 0x34, 0x5b, 0x92, 0x5d, 0x8d, 0xc0, 0x0b, 0x41, + 0x04, 0x85, 0x2d, 0xb9, 0x9a, 0xc5, 0xc7, 0xcd, + 0xda, 0x85, 0x30, 0xa1, 0x13, 0xa0, 0xf4, 0xdb, + 0xb6, 0x11, 0x49, 0xf0, 0x5a, 0x73, 0x63, 0x26, + 0x8c, 0x71, 0xd9, 0x58, 0x08, 0xff, 0x2e, 0x65, + 0x26, 0x00 + }; + + static const byte sig6[] = { + 0xe3, 0x01, 0x34, 0x5a, 0x41, 0xa3, 0x9a, 0x4d, + 0x72, 0xff, 0xf8, 0xdf, 0x69, 0xc9, 0x80, 0x75, + 0xa0, 0xcc, 0x08, 0x2b, 0x80, 0x2f, 0xc9, 0xb2, + 0xb6, 0xbc, 0x50, 0x3f, 0x92, 0x6b, 0x65, 0xbd, + 0xdf, 0x7f, 0x4c, 0x8f, 0x1c, 0xb4, 0x9f, 0x63, + 0x96, 0xaf, 0xc8, 0xa7, 0x0a, 0xbe, 0x6d, 0x8a, + 0xef, 0x0d, 0xb4, 0x78, 0xd4, 0xc6, 0xb2, 0x97, + 0x00, 0x76, 0xc6, 0xa0, 0x48, 0x4f, 0xe7, 0x6d, + 0x76, 0xb3, 0xa9, 0x76, 0x25, 0xd7, 0x9f, 0x1c, + 0xe2, 0x40, 0xe7, 0xc5, 0x76, 0x75, 0x0d, 0x29, + 0x55, 0x28, 0x28, 0x6f, 0x71, 0x9b, 0x41, 0x3d, + 0xe9, 0xad, 0xa3, 0xe8, 0xeb, 0x78, 0xed, 0x57, + 0x36, 0x03, 0xce, 0x30, 0xd8, 0xbb, 0x76, 0x17, + 0x85, 0xdc, 0x30, 0xdb, 0xc3, 0x20, 0x86, 0x9e, + 0x1a, 0x00 + }; + + static const byte* sigs[] = {sig1, sig2, sig3, sig4, sig5, sig6}; + + static const byte msg1[] = { }; + static const byte msg2[] = { 0x03 }; + static const byte msg3[] = { 0x64, 0xa6, 0x5f, 0x3c, 0xde, 0xdc, 0xdd, + 0x66, 0x81, 0x1e, 0x29, 0x15 }; + + /* test of a 1023 byte long message */ + static const byte msg4[] = { + 0x6d, 0xdf, 0x80, 0x2e, 0x1a, 0xae, 0x49, 0x86, + 0x93, 0x5f, 0x7f, 0x98, 0x1b, 0xa3, 0xf0, 0x35, + 0x1d, 0x62, 0x73, 0xc0, 0xa0, 0xc2, 0x2c, 0x9c, + 0x0e, 0x83, 0x39, 0x16, 0x8e, 0x67, 0x54, 0x12, + 0xa3, 0xde, 0xbf, 0xaf, 0x43, 0x5e, 0xd6, 0x51, + 0x55, 0x80, 0x07, 0xdb, 0x43, 0x84, 0xb6, 0x50, + 0xfc, 0xc0, 0x7e, 0x3b, 0x58, 0x6a, 0x27, 0xa4, + 0xf7, 0xa0, 0x0a, 0xc8, 0xa6, 0xfe, 0xc2, 0xcd, + 0x86, 0xae, 0x4b, 0xf1, 0x57, 0x0c, 0x41, 0xe6, + 0xa4, 0x0c, 0x93, 0x1d, 0xb2, 0x7b, 0x2f, 0xaa, + 0x15, 0xa8, 0xce, 0xdd, 0x52, 0xcf, 0xf7, 0x36, + 0x2c, 0x4e, 0x6e, 0x23, 0xda, 0xec, 0x0f, 0xbc, + 0x3a, 0x79, 0xb6, 0x80, 0x6e, 0x31, 0x6e, 0xfc, + 0xc7, 0xb6, 0x81, 0x19, 0xbf, 0x46, 0xbc, 0x76, + 0xa2, 0x60, 0x67, 0xa5, 0x3f, 0x29, 0x6d, 0xaf, + 0xdb, 0xdc, 0x11, 0xc7, 0x7f, 0x77, 0x77, 0xe9, + 0x72, 0x66, 0x0c, 0xf4, 0xb6, 0xa9, 0xb3, 0x69, + 0xa6, 0x66, 0x5f, 0x02, 0xe0, 0xcc, 0x9b, 0x6e, + 0xdf, 0xad, 0x13, 0x6b, 0x4f, 0xab, 0xe7, 0x23, + 0xd2, 0x81, 0x3d, 0xb3, 0x13, 0x6c, 0xfd, 0xe9, + 0xb6, 0xd0, 0x44, 0x32, 0x2f, 0xee, 0x29, 0x47, + 0x95, 0x2e, 0x03, 0x1b, 0x73, 0xab, 0x5c, 0x60, + 0x33, 0x49, 0xb3, 0x07, 0xbd, 0xc2, 0x7b, 0xc6, + 0xcb, 0x8b, 0x8b, 0xbd, 0x7b, 0xd3, 0x23, 0x21, + 0x9b, 0x80, 0x33, 0xa5, 0x81, 0xb5, 0x9e, 0xad, + 0xeb, 0xb0, 0x9b, 0x3c, 0x4f, 0x3d, 0x22, 0x77, + 0xd4, 0xf0, 0x34, 0x36, 0x24, 0xac, 0xc8, 0x17, + 0x80, 0x47, 0x28, 0xb2, 0x5a, 0xb7, 0x97, 0x17, + 0x2b, 0x4c, 0x5c, 0x21, 0xa2, 0x2f, 0x9c, 0x78, + 0x39, 0xd6, 0x43, 0x00, 0x23, 0x2e, 0xb6, 0x6e, + 0x53, 0xf3, 0x1c, 0x72, 0x3f, 0xa3, 0x7f, 0xe3, + 0x87, 0xc7, 0xd3, 0xe5, 0x0b, 0xdf, 0x98, 0x13, + 0xa3, 0x0e, 0x5b, 0xb1, 0x2c, 0xf4, 0xcd, 0x93, + 0x0c, 0x40, 0xcf, 0xb4, 0xe1, 0xfc, 0x62, 0x25, + 0x92, 0xa4, 0x95, 0x88, 0x79, 0x44, 0x94, 0xd5, + 0x6d, 0x24, 0xea, 0x4b, 0x40, 0xc8, 0x9f, 0xc0, + 0x59, 0x6c, 0xc9, 0xeb, 0xb9, 0x61, 0xc8, 0xcb, + 0x10, 0xad, 0xde, 0x97, 0x6a, 0x5d, 0x60, 0x2b, + 0x1c, 0x3f, 0x85, 0xb9, 0xb9, 0xa0, 0x01, 0xed, + 0x3c, 0x6a, 0x4d, 0x3b, 0x14, 0x37, 0xf5, 0x20, + 0x96, 0xcd, 0x19, 0x56, 0xd0, 0x42, 0xa5, 0x97, + 0xd5, 0x61, 0xa5, 0x96, 0xec, 0xd3, 0xd1, 0x73, + 0x5a, 0x8d, 0x57, 0x0e, 0xa0, 0xec, 0x27, 0x22, + 0x5a, 0x2c, 0x4a, 0xaf, 0xf2, 0x63, 0x06, 0xd1, + 0x52, 0x6c, 0x1a, 0xf3, 0xca, 0x6d, 0x9c, 0xf5, + 0xa2, 0xc9, 0x8f, 0x47, 0xe1, 0xc4, 0x6d, 0xb9, + 0xa3, 0x32, 0x34, 0xcf, 0xd4, 0xd8, 0x1f, 0x2c, + 0x98, 0x53, 0x8a, 0x09, 0xeb, 0xe7, 0x69, 0x98, + 0xd0, 0xd8, 0xfd, 0x25, 0x99, 0x7c, 0x7d, 0x25, + 0x5c, 0x6d, 0x66, 0xec, 0xe6, 0xfa, 0x56, 0xf1, + 0x11, 0x44, 0x95, 0x0f, 0x02, 0x77, 0x95, 0xe6, + 0x53, 0x00, 0x8f, 0x4b, 0xd7, 0xca, 0x2d, 0xee, + 0x85, 0xd8, 0xe9, 0x0f, 0x3d, 0xc3, 0x15, 0x13, + 0x0c, 0xe2, 0xa0, 0x03, 0x75, 0xa3, 0x18, 0xc7, + 0xc3, 0xd9, 0x7b, 0xe2, 0xc8, 0xce, 0x5b, 0x6d, + 0xb4, 0x1a, 0x62, 0x54, 0xff, 0x26, 0x4f, 0xa6, + 0x15, 0x5b, 0xae, 0xe3, 0xb0, 0x77, 0x3c, 0x0f, + 0x49, 0x7c, 0x57, 0x3f, 0x19, 0xbb, 0x4f, 0x42, + 0x40, 0x28, 0x1f, 0x0b, 0x1f, 0x4f, 0x7b, 0xe8, + 0x57, 0xa4, 0xe5, 0x9d, 0x41, 0x6c, 0x06, 0xb4, + 0xc5, 0x0f, 0xa0, 0x9e, 0x18, 0x10, 0xdd, 0xc6, + 0xb1, 0x46, 0x7b, 0xae, 0xac, 0x5a, 0x36, 0x68, + 0xd1, 0x1b, 0x6e, 0xca, 0xa9, 0x01, 0x44, 0x00, + 0x16, 0xf3, 0x89, 0xf8, 0x0a, 0xcc, 0x4d, 0xb9, + 0x77, 0x02, 0x5e, 0x7f, 0x59, 0x24, 0x38, 0x8c, + 0x7e, 0x34, 0x0a, 0x73, 0x2e, 0x55, 0x44, 0x40, + 0xe7, 0x65, 0x70, 0xf8, 0xdd, 0x71, 0xb7, 0xd6, + 0x40, 0xb3, 0x45, 0x0d, 0x1f, 0xd5, 0xf0, 0x41, + 0x0a, 0x18, 0xf9, 0xa3, 0x49, 0x4f, 0x70, 0x7c, + 0x71, 0x7b, 0x79, 0xb4, 0xbf, 0x75, 0xc9, 0x84, + 0x00, 0xb0, 0x96, 0xb2, 0x16, 0x53, 0xb5, 0xd2, + 0x17, 0xcf, 0x35, 0x65, 0xc9, 0x59, 0x74, 0x56, + 0xf7, 0x07, 0x03, 0x49, 0x7a, 0x07, 0x87, 0x63, + 0x82, 0x9b, 0xc0, 0x1b, 0xb1, 0xcb, 0xc8, 0xfa, + 0x04, 0xea, 0xdc, 0x9a, 0x6e, 0x3f, 0x66, 0x99, + 0x58, 0x7a, 0x9e, 0x75, 0xc9, 0x4e, 0x5b, 0xab, + 0x00, 0x36, 0xe0, 0xb2, 0xe7, 0x11, 0x39, 0x2c, + 0xff, 0x00, 0x47, 0xd0, 0xd6, 0xb0, 0x5b, 0xd2, + 0xa5, 0x88, 0xbc, 0x10, 0x97, 0x18, 0x95, 0x42, + 0x59, 0xf1, 0xd8, 0x66, 0x78, 0xa5, 0x79, 0xa3, + 0x12, 0x0f, 0x19, 0xcf, 0xb2, 0x96, 0x3f, 0x17, + 0x7a, 0xeb, 0x70, 0xf2, 0xd4, 0x84, 0x48, 0x26, + 0x26, 0x2e, 0x51, 0xb8, 0x02, 0x71, 0x27, 0x20, + 0x68, 0xef, 0x5b, 0x38, 0x56, 0xfa, 0x85, 0x35, + 0xaa, 0x2a, 0x88, 0xb2, 0xd4, 0x1f, 0x2a, 0x0e, + 0x2f, 0xda, 0x76, 0x24, 0xc2, 0x85, 0x02, 0x72, + 0xac, 0x4a, 0x2f, 0x56, 0x1f, 0x8f, 0x2f, 0x7a, + 0x31, 0x8b, 0xfd, 0x5c, 0xaf, 0x96, 0x96, 0x14, + 0x9e, 0x4a, 0xc8, 0x24, 0xad, 0x34, 0x60, 0x53, + 0x8f, 0xdc, 0x25, 0x42, 0x1b, 0xee, 0xc2, 0xcc, + 0x68, 0x18, 0x16, 0x2d, 0x06, 0xbb, 0xed, 0x0c, + 0x40, 0xa3, 0x87, 0x19, 0x23, 0x49, 0xdb, 0x67, + 0xa1, 0x18, 0xba, 0xda, 0x6c, 0xd5, 0xab, 0x01, + 0x40, 0xee, 0x27, 0x32, 0x04, 0xf6, 0x28, 0xaa, + 0xd1, 0xc1, 0x35, 0xf7, 0x70, 0x27, 0x9a, 0x65, + 0x1e, 0x24, 0xd8, 0xc1, 0x4d, 0x75, 0xa6, 0x05, + 0x9d, 0x76, 0xb9, 0x6a, 0x6f, 0xd8, 0x57, 0xde, + 0xf5, 0xe0, 0xb3, 0x54, 0xb2, 0x7a, 0xb9, 0x37, + 0xa5, 0x81, 0x5d, 0x16, 0xb5, 0xfa, 0xe4, 0x07, + 0xff, 0x18, 0x22, 0x2c, 0x6d, 0x1e, 0xd2, 0x63, + 0xbe, 0x68, 0xc9, 0x5f, 0x32, 0xd9, 0x08, 0xbd, + 0x89, 0x5c, 0xd7, 0x62, 0x07, 0xae, 0x72, 0x64, + 0x87, 0x56, 0x7f, 0x9a, 0x67, 0xda, 0xd7, 0x9a, + 0xbe, 0xc3, 0x16, 0xf6, 0x83, 0xb1, 0x7f, 0x2d, + 0x02, 0xbf, 0x07, 0xe0, 0xac, 0x8b, 0x5b, 0xc6, + 0x16, 0x2c, 0xf9, 0x46, 0x97, 0xb3, 0xc2, 0x7c, + 0xd1, 0xfe, 0xa4, 0x9b, 0x27, 0xf2, 0x3b, 0xa2, + 0x90, 0x18, 0x71, 0x96, 0x25, 0x06, 0x52, 0x0c, + 0x39, 0x2d, 0xa8, 0xb6, 0xad, 0x0d, 0x99, 0xf7, + 0x01, 0x3f, 0xbc, 0x06, 0xc2, 0xc1, 0x7a, 0x56, + 0x95, 0x00, 0xc8, 0xa7, 0x69, 0x64, 0x81, 0xc1, + 0xcd, 0x33, 0xe9, 0xb1, 0x4e, 0x40, 0xb8, 0x2e, + 0x79, 0xa5, 0xf5, 0xdb, 0x82, 0x57, 0x1b, 0xa9, + 0x7b, 0xae, 0x3a, 0xd3, 0xe0, 0x47, 0x95, 0x15, + 0xbb, 0x0e, 0x2b, 0x0f, 0x3b, 0xfc, 0xd1, 0xfd, + 0x33, 0x03, 0x4e, 0xfc, 0x62, 0x45, 0xed, 0xdd, + 0x7e, 0xe2, 0x08, 0x6d, 0xda, 0xe2, 0x60, 0x0d, + 0x8c, 0xa7, 0x3e, 0x21, 0x4e, 0x8c, 0x2b, 0x0b, + 0xdb, 0x2b, 0x04, 0x7c, 0x6a, 0x46, 0x4a, 0x56, + 0x2e, 0xd7, 0x7b, 0x73, 0xd2, 0xd8, 0x41, 0xc4, + 0xb3, 0x49, 0x73, 0x55, 0x12, 0x57, 0x71, 0x3b, + 0x75, 0x36, 0x32, 0xef, 0xba, 0x34, 0x81, 0x69, + 0xab, 0xc9, 0x0a, 0x68, 0xf4, 0x26, 0x11, 0xa4, + 0x01, 0x26, 0xd7, 0xcb, 0x21, 0xb5, 0x86, 0x95, + 0x56, 0x81, 0x86, 0xf7, 0xe5, 0x69, 0xd2, 0xff, + 0x0f, 0x9e, 0x74, 0x5d, 0x04, 0x87, 0xdd, 0x2e, + 0xb9, 0x97, 0xca, 0xfc, 0x5a, 0xbf, 0x9d, 0xd1, + 0x02, 0xe6, 0x2f, 0xf6, 0x6c, 0xba, 0x87 + }; + + static const byte* msgs[] = {msg1, msg2, msg3, msg1, msg1, msg4}; + static const word16 msgSz[] = {0 /*sizeof(msg1)*/, + sizeof(msg2), + sizeof(msg3), + 0 /*sizeof(msg1)*/, + 0 /*sizeof(msg1)*/, + sizeof(msg4) + }; +#ifndef NO_ASN + static byte privateEd448[] = { + 0x30, 0x47, 0x02, 0x01, 0x00, 0x30, 0x05, 0x06, + 0x03, 0x2b, 0x65, 0x71, 0x04, 0x3b, 0x04, 0x39, + 0x6c, 0x82, 0xa5, 0x62, 0xcb, 0x80, 0x8d, 0x10, + 0xd6, 0x32, 0xbe, 0x89, 0xc8, 0x51, 0x3e, 0xbf, + 0x6c, 0x92, 0x9f, 0x34, 0xdd, 0xfa, 0x8c, 0x9f, + 0x63, 0xc9, 0x96, 0x0e, 0xf6, 0xe3, 0x48, 0xa3, + 0x52, 0x8c, 0x8a, 0x3f, 0xcc, 0x2f, 0x04, 0x4e, + 0x39, 0xa3, 0xfc, 0x5b, 0x94, 0x49, 0x2f, 0x8f, + 0x03, 0x2e, 0x75, 0x49, 0xa2, 0x00, 0x98, 0xf9, + 0x5b + }; + static byte publicEd448[] = { + 0x30, 0x43, 0x30, 0x05, 0x06, 0x03, 0x2b, 0x65, + 0x71, 0x03, 0x3a, 0x00, 0x5f, 0xd7, 0x44, 0x9b, + 0x59, 0xb4, 0x61, 0xfd, 0x2c, 0xe7, 0x87, 0xec, + 0x61, 0x6a, 0xd4, 0x6a, 0x1d, 0xa1, 0x34, 0x24, + 0x85, 0xa7, 0x0e, 0x1f, 0x8a, 0x0e, 0xa7, 0x5d, + 0x80, 0xe9, 0x67, 0x78, 0xed, 0xf1, 0x24, 0x76, + 0x9b, 0x46, 0xc7, 0x06, 0x1b, 0xd6, 0x78, 0x3d, + 0xf1, 0xe5, 0x0f, 0x6c, 0xd1, 0xfa, 0x1a, 0xbe, + 0xaf, 0xe8, 0x25, 0x61, 0x80 + }; + static byte privPubEd448[] = { + 0x30, 0x81, 0x84, 0x02, 0x01, 0x00, 0x30, 0x05, + 0x06, 0x03, 0x2b, 0x65, 0x71, 0x04, 0x3b, 0x04, + 0x39, 0x6c, 0x82, 0xa5, 0x62, 0xcb, 0x80, 0x8d, + 0x10, 0xd6, 0x32, 0xbe, 0x89, 0xc8, 0x51, 0x3e, + 0xbf, 0x6c, 0x92, 0x9f, 0x34, 0xdd, 0xfa, 0x8c, + 0x9f, 0x63, 0xc9, 0x96, 0x0e, 0xf6, 0xe3, 0x48, + 0xa3, 0x52, 0x8c, 0x8a, 0x3f, 0xcc, 0x2f, 0x04, + 0x4e, 0x39, 0xa3, 0xfc, 0x5b, 0x94, 0x49, 0x2f, + 0x8f, 0x03, 0x2e, 0x75, 0x49, 0xa2, 0x00, 0x98, + 0xf9, 0x5b, 0xa1, 0x3b, 0x04, 0x39, 0x5f, 0xd7, + 0x44, 0x9b, 0x59, 0xb4, 0x61, 0xfd, 0x2c, 0xe7, + 0x87, 0xec, 0x61, 0x6a, 0xd4, 0x6a, 0x1d, 0xa1, + 0x34, 0x24, 0x85, 0xa7, 0x0e, 0x1f, 0x8a, 0x0e, + 0xa7, 0x5d, 0x80, 0xe9, 0x67, 0x78, 0xed, 0xf1, + 0x24, 0x76, 0x9b, 0x46, 0xc7, 0x06, 0x1b, 0xd6, + 0x78, 0x3d, 0xf1, 0xe5, 0x0f, 0x6c, 0xd1, 0xfa, + 0x1a, 0xbe, 0xaf, 0xe8, 0x25, 0x61, 0x80 + }; + + word32 idx; + ed448_key key3; +#endif /* NO_ASN */ +#endif /* HAVE_ED448_SIGN && HAVE_ED448_KEY_EXPORT && HAVE_ED448_KEY_IMPORT */ + + /* create ed448 keys */ +#ifndef HAVE_FIPS + ret = wc_InitRng_ex(&rng, HEAP_HINT, devId); +#else + ret = wc_InitRng(&rng); +#endif + if (ret != 0) + return -11300; + + wc_ed448_init(&key); + wc_ed448_init(&key2); +#ifndef NO_ASN + wc_ed448_init(&key3); +#endif + wc_ed448_make_key(&rng, ED448_KEY_SIZE, &key); + wc_ed448_make_key(&rng, ED448_KEY_SIZE, &key2); + + /* helper functions for signature and key size */ + keySz = wc_ed448_size(&key); + sigSz = wc_ed448_sig_size(&key); + +#if defined(HAVE_ED448_SIGN) && defined(HAVE_ED448_KEY_EXPORT) &&\ + defined(HAVE_ED448_KEY_IMPORT) + for (i = 0; i < 6; i++) { + outlen = sizeof(out); + XMEMSET(out, 0, sizeof(out)); + + if (wc_ed448_import_private_key(sKeys[i], ED448_KEY_SIZE, pKeys[i], + pKeySz[i], &key) != 0) + return -11301 - i; + + if (wc_ed448_sign_msg(msgs[i], msgSz[i], out, &outlen, &key, NULL, + 0) != 0) { + return -11311 - i; + } + + if (XMEMCMP(out, sigs[i], 114)) + return -11321 - i; + +#if defined(HAVE_ED448_VERIFY) + /* test verify on good msg */ + if (wc_ed448_verify_msg(out, outlen, msgs[i], msgSz[i], &verify, &key, + NULL, 0) != 0 || verify != 1) { + return -11331 - i; + } + + /* test verify on bad msg */ + out[outlen-2] = out[outlen-2] + 1; + if (wc_ed448_verify_msg(out, outlen, msgs[i], msgSz[i], &verify, &key, + NULL, 0) == 0 || verify == 1) { + return -11341 - i; + } +#endif /* HAVE_ED448_VERIFY */ + + /* test api for import/exporting keys */ + exportPSz = sizeof(exportPKey); + exportSSz = sizeof(exportSKey); + if (wc_ed448_export_public(&key, exportPKey, &exportPSz) != 0) + return -11351 - i; + + if (wc_ed448_import_public(exportPKey, exportPSz, &key2) != 0) + return -11361 - i; + + if (wc_ed448_export_private_only(&key, exportSKey, &exportSSz) != 0) + return -11371 - i; + + if (wc_ed448_import_private_key(exportSKey, exportSSz, + exportPKey, exportPSz, &key2) != 0) + return -11381 - i; + + /* clear "out" buffer and test sign with imported keys */ + outlen = sizeof(out); + XMEMSET(out, 0, sizeof(out)); + if (wc_ed448_sign_msg(msgs[i], msgSz[i], out, &outlen, &key2, NULL, + 0) != 0) { + return -11391 - i; + } + +#if defined(HAVE_ED448_VERIFY) + if (wc_ed448_verify_msg(out, outlen, msgs[i], msgSz[i], &verify, &key2, + NULL, 0) != 0 || verify != 1) + return -11401 - i; + + if (XMEMCMP(out, sigs[i], sizeof(sigs[i]))) + return -11411 - i; +#endif /* HAVE_ED448_VERIFY */ + } + + ret = ed448_ctx_test(); + if (ret != 0) + return ret; + + ret = ed448ph_test(); + if (ret != 0) + return ret; + +#ifndef NO_ASN + /* Try ASN.1 encoded private-only key and public key. */ + idx = 0; + if (wc_Ed448PrivateKeyDecode(privateEd448, &idx, &key3, + sizeof(privateEd448)) != 0) + return -11421 - i; + + if (wc_ed448_sign_msg(msgs[0], msgSz[0], out, &outlen, &key3, NULL, 0) + != BAD_FUNC_ARG) + return -11431 - i; + + idx = 0; + if (wc_Ed448PublicKeyDecode(publicEd448, &idx, &key3, + sizeof(publicEd448)) != 0) + return -11441 - i; + + if (wc_ed448_sign_msg(msgs[0], msgSz[0], out, &outlen, &key3, NULL, 0) != 0) + return -11451 - i; + + if (XMEMCMP(out, sigs[0], sizeof(sigs[0]))) + return -11461 - i; + +#if defined(HAVE_ED448_VERIFY) + /* test verify on good msg */ + if (wc_ed448_verify_msg(out, outlen, msgs[0], msgSz[0], &verify, &key3, + NULL, 0) != 0 || verify != 1) + return -11471 - i; +#endif /* HAVE_ED448_VERIFY */ + + wc_ed448_free(&key3); + wc_ed448_init(&key3); + + idx = 0; + if (wc_Ed448PrivateKeyDecode(privPubEd448, &idx, &key3, + sizeof(privPubEd448)) != 0) + return -11481 - i; + + if (wc_ed448_sign_msg(msgs[0], msgSz[0], out, &outlen, &key3, NULL, 0) != 0) + return -11491 - i; + + if (XMEMCMP(out, sigs[0], sizeof(sigs[0]))) + return -11501 - i; + + wc_ed448_free(&key3); +#endif /* NO_ASN */ +#endif /* HAVE_ED448_SIGN && HAVE_ED448_KEY_EXPORT && HAVE_ED448_KEY_IMPORT */ + + /* clean up keys when done */ + wc_ed448_free(&key); + wc_ed448_free(&key2); + +#if defined(HAVE_HASHDRBG) || defined(NO_RC4) + wc_FreeRng(&rng); +#endif + + /* hush warnings of unused keySz and sigSz */ + (void)keySz; + (void)sigSz; + +#ifdef WOLFSSL_TEST_CERT + ret = ed448_test_cert(); + if (ret < 0) + return ret; +#ifdef WOLFSSL_CERT_GEN + ret = ed448_test_make_cert(); + if (ret < 0) + return ret; +#endif /* WOLFSSL_CERT_GEN */ +#endif /* WOLFSSL_TEST_CERT */ + + return 0; +} +#endif /* HAVE_ED448 */ #if defined(WOLFSSL_CMAC) && !defined(NO_AES) @@ -21739,34 +23282,34 @@ int cmac_test(void) XMEMSET(tag, 0, sizeof(tag)); tagSz = AES_BLOCK_SIZE; if (wc_InitCmac(&cmac, tc->k, tc->kSz, tc->type, NULL) != 0) - return -9100; + return -11600; if (tc->partial) { if (wc_CmacUpdate(&cmac, tc->m, tc->mSz/2 - tc->partial) != 0) - return -9101; + return -11601; if (wc_CmacUpdate(&cmac, tc->m + tc->mSz/2 - tc->partial, tc->mSz/2 + tc->partial) != 0) - return -9102; + return -11602; } else { if (wc_CmacUpdate(&cmac, tc->m, tc->mSz) != 0) - return -9103; + return -11603; } if (wc_CmacFinal(&cmac, tag, &tagSz) != 0) - return -9104; + return -11604; if (XMEMCMP(tag, tc->t, AES_BLOCK_SIZE) != 0) - return -9105; + return -11605; XMEMSET(tag, 0, sizeof(tag)); tagSz = sizeof(tag); if (wc_AesCmacGenerate(tag, &tagSz, tc->m, tc->mSz, tc->k, tc->kSz) != 0) - return -9106; + return -11606; if (XMEMCMP(tag, tc->t, AES_BLOCK_SIZE) != 0) - return -9107; + return -11607; if (wc_AesCmacVerify(tc->t, tc->tSz, tc->m, tc->mSz, tc->k, tc->kSz) != 0) - return -9108; + return -11608; } return 0; @@ -22017,7 +23560,7 @@ int compress_test(void) c = XMALLOC(cSz * sizeof(byte), HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); d = XMALLOC(dSz * sizeof(byte), HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (c == NULL || d == NULL) { - ERROR_OUT(-9200, exit); + ERROR_OUT(-11700, exit); } /* follow calloc and initialize to 0 */ @@ -22025,16 +23568,16 @@ int compress_test(void) XMEMSET(d, 0, dSz); if ((ret = wc_Compress(c, cSz, sample_text, dSz, 0)) < 0) { - ERROR_OUT(-9201, exit); + ERROR_OUT(-11701, exit); } cSz = (word32)ret; if ((ret = wc_DeCompress(d, dSz, c, cSz)) != (int)dSz) { - ERROR_OUT(-9202, exit); + ERROR_OUT(-11702, exit); } if (XMEMCMP(d, sample_text, dSz) != 0) { - ERROR_OUT(-9203, exit); + ERROR_OUT(-11703, exit); } /* GZIP tests */ @@ -22044,17 +23587,17 @@ int compress_test(void) ret = wc_Compress_ex(c, cSz, sample_text, dSz, 0, LIBZ_WINBITS_GZIP); if (ret < 0) { - ERROR_OUT(-9204, exit); + ERROR_OUT(-11704, exit); } cSz = (word32)ret; ret = wc_DeCompress_ex(d, dSz, c, cSz, LIBZ_WINBITS_GZIP); if (ret < 0) { - ERROR_OUT(-9206, exit); + ERROR_OUT(-11705, exit); } if (XMEMCMP(d, sample_text, dSz) != 0) { - ERROR_OUT(-9207, exit); + ERROR_OUT(-11706, exit); } /* Try with gzip generated output */ @@ -22062,12 +23605,12 @@ int compress_test(void) ret = wc_DeCompress_ex(d, dSz, sample_text_gz, sizeof(sample_text_gz), LIBZ_WINBITS_GZIP); if (ret < 0) { - ERROR_OUT(-9208, exit); + ERROR_OUT(-11707, exit); } dSz = (word32)ret; if (XMEMCMP(d, sample_text, dSz) != 0) { - ERROR_OUT(-9209, exit); + ERROR_OUT(-11708, exit); } ret = 0; /* success */ @@ -22153,7 +23696,7 @@ static int pkcs7_load_certs_keys( #ifdef USE_CERT_BUFFERS_1024 if (*rsaClientCertBufSz < (word32)sizeof_client_cert_der_1024) - return -9204; + return -11709; XMEMCPY(rsaClientCertBuf, client_cert_der_1024, sizeof_client_cert_der_1024); @@ -22161,7 +23704,7 @@ static int pkcs7_load_certs_keys( if (rsaServerCertBuf != NULL) { if (*rsaServerCertBufSz < (word32)sizeof_server_cert_der_1024) - return -9205; + return -11710; XMEMCPY(rsaServerCertBuf, server_cert_der_1024, sizeof_server_cert_der_1024); @@ -22170,14 +23713,14 @@ static int pkcs7_load_certs_keys( if (rsaCaCertBuf != NULL) { if (*rsaCaCertBufSz < (word32)sizeof_ca_cert_der_1024) - return -9206; + return -11711; XMEMCPY(rsaCaCertBuf, ca_cert_der_1024, sizeof_ca_cert_der_1024); *rsaCaCertBufSz = sizeof_ca_cert_der_1024; } #elif defined(USE_CERT_BUFFERS_2048) if (*rsaClientCertBufSz < (word32)sizeof_client_cert_der_2048) - return -9207; + return -11712; XMEMCPY(rsaClientCertBuf, client_cert_der_2048, sizeof_client_cert_der_2048); @@ -22185,7 +23728,7 @@ static int pkcs7_load_certs_keys( if (rsaServerCertBuf != NULL) { if (*rsaServerCertBufSz < (word32)sizeof_server_cert_der_2048) - return -9208; + return -11713; XMEMCPY(rsaServerCertBuf, server_cert_der_2048, sizeof_server_cert_der_2048); @@ -22194,7 +23737,7 @@ static int pkcs7_load_certs_keys( if (rsaCaCertBuf != NULL) { if (*rsaCaCertBufSz < (word32)sizeof_ca_cert_der_2048) - return -9209; + return -11714; XMEMCPY(rsaCaCertBuf, ca_cert_der_2048, sizeof_ca_cert_der_2048); *rsaCaCertBufSz = sizeof_ca_cert_der_2048; @@ -22202,7 +23745,7 @@ static int pkcs7_load_certs_keys( #else certFile = XFOPEN(clientCert, "rb"); if (!certFile) - return -9210; + return -11715; *rsaClientCertBufSz = (word32)XFREAD(rsaClientCertBuf, 1, *rsaClientCertBufSz, certFile); @@ -22211,7 +23754,7 @@ static int pkcs7_load_certs_keys( if (rsaServerCertBuf != NULL) { certFile = XFOPEN(rsaServerCertDerFile, "rb"); if (!certFile) - return -9211; + return -11716; *rsaServerCertBufSz = (word32)XFREAD(rsaServerCertBuf, 1, *rsaServerCertBufSz, certFile); @@ -22221,7 +23764,7 @@ static int pkcs7_load_certs_keys( if (rsaCaCertBuf != NULL) { certFile = XFOPEN(rsaCaCertDerFile, "rb"); if (!certFile) - return -9212; + return -11717; *rsaCaCertBufSz = (word32)XFREAD(rsaCaCertBuf, 1, *rsaCaCertBufSz, certFile); @@ -22231,7 +23774,7 @@ static int pkcs7_load_certs_keys( #ifdef USE_CERT_BUFFERS_1024 if (*rsaClientPrivKeyBufSz < (word32)sizeof_client_key_der_1024) - return -9213; + return -11718; XMEMCPY(rsaClientPrivKeyBuf, client_key_der_1024, sizeof_client_key_der_1024); @@ -22239,7 +23782,7 @@ static int pkcs7_load_certs_keys( if (rsaServerPrivKeyBuf != NULL) { if (*rsaServerPrivKeyBufSz < (word32)sizeof_server_key_der_1024) - return -9214; + return -11719; XMEMCPY(rsaServerPrivKeyBuf, server_key_der_1024, sizeof_server_key_der_1024); @@ -22248,14 +23791,14 @@ static int pkcs7_load_certs_keys( if (rsaCaPrivKeyBuf != NULL) { if (*rsaCaPrivKeyBufSz < (word32)sizeof_ca_key_der_1024) - return -9215; + return -11720; XMEMCPY(rsaCaPrivKeyBuf, ca_key_der_1024, sizeof_ca_key_der_1024); *rsaCaPrivKeyBufSz = sizeof_ca_key_der_1024; } #elif defined(USE_CERT_BUFFERS_2048) if (*rsaClientPrivKeyBufSz < (word32)sizeof_client_key_der_2048) - return -9216; + return -11721; XMEMCPY(rsaClientPrivKeyBuf, client_key_der_2048, sizeof_client_key_der_2048); @@ -22263,7 +23806,7 @@ static int pkcs7_load_certs_keys( if (rsaServerPrivKeyBuf != NULL) { if (*rsaServerPrivKeyBufSz < (word32)sizeof_server_key_der_2048) - return -9217; + return -11722; XMEMCPY(rsaServerPrivKeyBuf, server_key_der_2048, sizeof_server_key_der_2048); @@ -22272,7 +23815,7 @@ static int pkcs7_load_certs_keys( if (rsaCaPrivKeyBuf != NULL) { if (*rsaCaPrivKeyBufSz < (word32)sizeof_ca_key_der_2048) - return -9218; + return -11723; XMEMCPY(rsaCaPrivKeyBuf, ca_key_der_2048, sizeof_ca_key_der_2048); *rsaCaPrivKeyBufSz = sizeof_ca_key_der_2048; @@ -22280,7 +23823,7 @@ static int pkcs7_load_certs_keys( #else keyFile = XFOPEN(clientKey, "rb"); if (!keyFile) - return -9219; + return -11724; *rsaClientPrivKeyBufSz = (word32)XFREAD(rsaClientPrivKeyBuf, 1, *rsaClientPrivKeyBufSz, keyFile); @@ -22289,7 +23832,7 @@ static int pkcs7_load_certs_keys( if (rsaServerPrivKeyBuf != NULL) { keyFile = XFOPEN(rsaServerKeyDerFile, "rb"); if (!keyFile) - return -9220; + return -11725; *rsaServerPrivKeyBufSz = (word32)XFREAD(rsaServerPrivKeyBuf, 1, *rsaServerPrivKeyBufSz, keyFile); @@ -22299,7 +23842,7 @@ static int pkcs7_load_certs_keys( if (rsaCaPrivKeyBuf != NULL) { keyFile = XFOPEN(rsaCaKeyFile, "rb"); if (!keyFile) - return -9221; + return -11726; *rsaCaPrivKeyBufSz = (word32)XFREAD(rsaCaPrivKeyBuf, 1, *rsaCaPrivKeyBufSz, keyFile); @@ -22314,14 +23857,14 @@ static int pkcs7_load_certs_keys( #ifdef USE_CERT_BUFFERS_256 if (*eccClientCertBufSz < (word32)sizeof_cliecc_cert_der_256) - return -9210; + return -11727; XMEMCPY(eccClientCertBuf, cliecc_cert_der_256, sizeof_cliecc_cert_der_256); *eccClientCertBufSz = sizeof_cliecc_cert_der_256; #else certFile = XFOPEN(eccClientCert, "rb"); if (!certFile) - return -9211; + return -11728; *eccClientCertBufSz = (word32)XFREAD(eccClientCertBuf, 1, *eccClientCertBufSz, certFile); @@ -22330,14 +23873,14 @@ static int pkcs7_load_certs_keys( #ifdef USE_CERT_BUFFERS_256 if (*eccClientPrivKeyBufSz < (word32)sizeof_ecc_clikey_der_256) - return -9212; + return -11729; XMEMCPY(eccClientPrivKeyBuf, ecc_clikey_der_256, sizeof_ecc_clikey_der_256); *eccClientPrivKeyBufSz = sizeof_ecc_clikey_der_256; #else keyFile = XFOPEN(eccClientKey, "rb"); if (!keyFile) - return -9213; + return -11730; *eccClientPrivKeyBufSz = (word32)XFREAD(eccClientPrivKeyBuf, 1, *eccClientPrivKeyBufSz, keyFile); @@ -22436,7 +23979,7 @@ static int myOriEncryptCb(PKCS7* pkcs7, byte* cek, word32 cekSz, byte* oriType, /* make sure buffers are large enough */ if ((*oriValueSz < (2 + cekSz)) || (*oriTypeSz < sizeof(oriType))) - return -1; + return -11731; /* our simple encryption algorithm will be take the bitwise complement */ oriValue[0] = 0x04; /*ASN OCTET STRING */ @@ -22471,14 +24014,14 @@ static int myOriDecryptCb(PKCS7* pkcs7, byte* oriType, word32 oriTypeSz, /* make sure oriType matches what we expect */ if (oriTypeSz != sizeof(asnDataOid)) - return -1; + return -11732; if (XMEMCMP(oriType, asnDataOid, sizeof(asnDataOid)) != 0) - return -1; + return -11733; /* make sure decrypted buffer is large enough */ if (*decryptedKeySz < oriValueSz) - return -1; + return -11734; /* decrypt encrypted CEK using simple bitwise complement, only for example */ @@ -22530,7 +24073,7 @@ static int myDecryptionFunc(PKCS7* pkcs7, int encryptOID, byte* iv, int ivSz, /* test user context passed in */ if (usrCtx == NULL || *(int*)usrCtx != 1) { - return -1; + return -11735; } /* if needing to find keyIdSz can call with NULL */ @@ -22539,7 +24082,7 @@ static int myDecryptionFunc(PKCS7* pkcs7, int encryptOID, byte* iv, int ivSz, if (ret != LENGTH_ONLY_E) { printf("Unexpected error %d when getting keyIdSz\n", ret); printf("Possibly no KEY ID attribute set\n"); - return -1; + return -11736; } else { XMEMSET(keyIdRaw, 0, sizeof(keyIdRaw)); @@ -22551,11 +24094,11 @@ static int myDecryptionFunc(PKCS7* pkcs7, int encryptOID, byte* iv, int ivSz, if (keyIdSz < 3) { printf("keyIdSz is smaller than expected\n"); - return -1; + return -11737; } if (keyIdSz > 2 + sizeof(int)) { printf("example case was only expecting a keyId of int size\n"); - return -1; + return -11738; } /* keyIdRaw[0] OCTET TAG */ @@ -22786,14 +24329,14 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, #endif ); if (pkcs7 == NULL) - return -9310; + return -11739; if (testVectors[i].secretKey != NULL) { /* KEKRI recipient type */ ret = wc_PKCS7_Init(pkcs7, pkcs7->heap, pkcs7->devId); if (ret != 0) { - return -9311; + return -11740; } pkcs7->content = (byte*)testVectors[i].content; @@ -22812,7 +24355,7 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, if (ret < 0) { wc_PKCS7_Free(pkcs7); - return -9313; + return -11741; } /* set key, for decryption */ @@ -22821,7 +24364,7 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, if (ret != 0) { wc_PKCS7_Free(pkcs7); - return -9314; + return -11742; } } else if (testVectors[i].password != NULL) { @@ -22830,7 +24373,7 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, ret = wc_PKCS7_Init(pkcs7, pkcs7->heap, pkcs7->devId); if (ret != 0) { - return -9315; + return -11743; } pkcs7->content = (byte*)testVectors[i].content; @@ -22849,7 +24392,7 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, if (ret < 0) { wc_PKCS7_Free(pkcs7); - return -9316; + return -11744; } /* set password, for decryption */ @@ -22858,7 +24401,7 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, if (ret < 0) { wc_PKCS7_Free(pkcs7); - return -9317; + return -11745; } #endif /* NO_PWDBASED */ @@ -22867,7 +24410,7 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, ret = wc_PKCS7_Init(pkcs7, pkcs7->heap, pkcs7->devId); if (ret != 0) { - return -9318; + return -11746; } pkcs7->content = (byte*)testVectors[i].content; @@ -22880,7 +24423,7 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, if (ret < 0) { wc_PKCS7_Free(pkcs7); - return -9319; + return -11747; } /* set decrypt callback for decryption */ @@ -22888,7 +24431,7 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, if (ret < 0) { wc_PKCS7_Free(pkcs7); - return -9320; + return -11748; } } else { @@ -22896,14 +24439,14 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, ret = wc_PKCS7_Init(pkcs7, pkcs7->heap, pkcs7->devId); if (ret != 0) { - return -9321; + return -11749; } ret = wc_PKCS7_InitWithCert(pkcs7, testVectors[i].cert, (word32)testVectors[i].certSz); if (ret != 0) { wc_PKCS7_Free(pkcs7); - return -9321; + return -11750; } pkcs7->keyWrapOID = testVectors[i].keyWrapOID; @@ -22923,7 +24466,7 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, ret = wc_PKCS7_SetSignerIdentifierType(pkcs7, CMS_SKID); if (ret != 0) { wc_PKCS7_Free(pkcs7); - return -9322; + return -11751; } } else if (testVectors[i].ktriOptions & CMS_ISSUER_AND_SERIAL_NUMBER) { @@ -22932,7 +24475,7 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, CMS_ISSUER_AND_SERIAL_NUMBER); if (ret != 0) { wc_PKCS7_Free(pkcs7); - return -9323; + return -11752; } } } @@ -22942,7 +24485,7 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, sizeof(enveloped)); if (envelopedSz <= 0) { wc_PKCS7_Free(pkcs7); - return -9324; + return -11753; } /* decode envelopedData */ @@ -22950,13 +24493,13 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, decoded, sizeof(decoded)); if (decodedSz <= 0) { wc_PKCS7_Free(pkcs7); - return -9325; + return -11754; } /* test decode result */ if (XMEMCMP(decoded, data, sizeof(data)) != 0){ wc_PKCS7_Free(pkcs7); - return -9326; + return -11755; } #ifndef NO_PKCS7_STREAM @@ -22967,14 +24510,14 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, decoded, sizeof(decoded)); if (decodedSz <= 0 && decodedSz != WC_PKCS7_WANT_READ_E) { printf("unexpected error %d\n", decodedSz); - return -9325; + return -11756; } } /* test decode result */ if (XMEMCMP(decoded, data, sizeof(data)) != 0) { printf("stream read compare failed\n"); wc_PKCS7_Free(pkcs7); - return -9326; + return -11757; } } #endif @@ -22983,14 +24526,14 @@ static int pkcs7enveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, pkcs7File = XFOPEN(testVectors[i].outFileName, "wb"); if (!pkcs7File) { wc_PKCS7_Free(pkcs7); - return -9327; + return -11758; } ret = (int)XFWRITE(enveloped, 1, envelopedSz, pkcs7File); XFCLOSE(pkcs7File); if (ret != envelopedSz) { wc_PKCS7_Free(pkcs7); - return -9328; + return -11759; } #endif /* PKCS7_OUTPUT_TEST_BUNDLES */ @@ -23029,12 +24572,12 @@ int pkcs7enveloped_test(void) /* read client RSA cert and key in DER format */ rsaCert = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (rsaCert == NULL) - return -9300; + return -11800; rsaPrivKey = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (rsaPrivKey == NULL) { XFREE(rsaCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - return -9301; + return -11801; } rsaCertSz = FOURK_BUF; @@ -23049,7 +24592,7 @@ int pkcs7enveloped_test(void) XFREE(rsaCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); XFREE(rsaPrivKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); #endif - return -9302; + return -11802; } eccPrivKey =(byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); @@ -23059,7 +24602,7 @@ int pkcs7enveloped_test(void) XFREE(rsaPrivKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); #endif XFREE(eccCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - return -9303; + return -11803; } eccCertSz = FOURK_BUF; @@ -23079,7 +24622,7 @@ int pkcs7enveloped_test(void) XFREE(eccCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); XFREE(eccPrivKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); #endif - return -9304; + return -11804; } ret = pkcs7enveloped_run_vectors(rsaCert, (word32)rsaCertSz, @@ -23381,7 +24924,7 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, ret = wc_InitRng(&rng); #endif if (ret != 0) { - return -9370; + return -11805; } senderNonce[0] = 0x04; @@ -23390,7 +24933,7 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, ret = wc_RNG_GenerateBlock(&rng, &senderNonce[2], PKCS7_NONCE_SZ); if (ret != 0) { wc_FreeRng(&rng); - return -9371; + return -11806; } wc_FreeRng(&rng); @@ -23405,14 +24948,14 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, #endif ); if (pkcs7 == NULL) - return -9372; + return -11807; if (testVectors[i].secretKey != NULL) { /* KEKRI recipient type */ ret = wc_PKCS7_Init(pkcs7, pkcs7->heap, pkcs7->devId); if (ret != 0) { - return -9373; + return -11808; } pkcs7->content = (byte*)testVectors[i].content; @@ -23435,7 +24978,7 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, if (ret < 0) { wc_PKCS7_Free(pkcs7); - return -9374; + return -11809; } /* set key, for decryption */ @@ -23444,7 +24987,7 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, if (ret != 0) { wc_PKCS7_Free(pkcs7); - return -9375; + return -11810; } } else if (testVectors[i].password != NULL) { @@ -23453,7 +24996,7 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, ret = wc_PKCS7_Init(pkcs7, pkcs7->heap, pkcs7->devId); if (ret != 0) { - return -9376; + return -11811; } pkcs7->content = (byte*)testVectors[i].content; @@ -23476,7 +25019,7 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, if (ret < 0) { wc_PKCS7_Free(pkcs7); - return -9377; + return -11812; } /* set password, for decryption */ @@ -23485,7 +25028,7 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, if (ret < 0) { wc_PKCS7_Free(pkcs7); - return -9378; + return -11813; } #endif /* NO_PWDBASED */ @@ -23494,7 +25037,7 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, ret = wc_PKCS7_Init(pkcs7, pkcs7->heap, pkcs7->devId); if (ret != 0) { - return -9379; + return -11814; } pkcs7->content = (byte*)testVectors[i].content; @@ -23511,7 +25054,7 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, if (ret < 0) { wc_PKCS7_Free(pkcs7); - return -9380; + return -11815; } /* set decrypt callback for decryption */ @@ -23519,7 +25062,7 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, if (ret < 0) { wc_PKCS7_Free(pkcs7); - return -9381; + return -11816; } } else { @@ -23529,7 +25072,7 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, (word32)testVectors[i].certSz); if (ret != 0) { wc_PKCS7_Free(pkcs7); - return -9382; + return -11817; } pkcs7->keyWrapOID = testVectors[i].keyWrapOID; @@ -23553,7 +25096,7 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, ret = wc_PKCS7_SetSignerIdentifierType(pkcs7, CMS_SKID); if (ret != 0) { wc_PKCS7_Free(pkcs7); - return -9383; + return -11818; } } else if (testVectors[i].ktriOptions & CMS_ISSUER_AND_SERIAL_NUMBER) { @@ -23562,7 +25105,7 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, CMS_ISSUER_AND_SERIAL_NUMBER); if (ret != 0) { wc_PKCS7_Free(pkcs7); - return -9384; + return -11819; } } } @@ -23572,7 +25115,7 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, sizeof(enveloped)); if (envelopedSz <= 0) { wc_PKCS7_Free(pkcs7); - return -9385; + return -11820; } #ifndef NO_PKCS7_STREAM { /* test reading byte by byte */ @@ -23582,14 +25125,14 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, enveloped + z, 1, decoded, sizeof(decoded)); if (decodedSz <= 0 && decodedSz != WC_PKCS7_WANT_READ_E) { printf("unexpected error %d\n", decodedSz); - return -9386; + return -11821; } } /* test decode result */ if (XMEMCMP(decoded, data, sizeof(data)) != 0) { printf("stream read compare failed\n"); wc_PKCS7_Free(pkcs7); - return -9387; + return -11822; } } #endif @@ -23599,13 +25142,13 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, sizeof(decoded)); if (decodedSz <= 0) { wc_PKCS7_Free(pkcs7); - return -9386; + return -11823; } /* test decode result */ if (XMEMCMP(decoded, data, sizeof(data)) != 0){ wc_PKCS7_Free(pkcs7); - return -9387; + return -11824; } #ifdef PKCS7_OUTPUT_TEST_BUNDLES @@ -23613,14 +25156,14 @@ static int pkcs7authenveloped_run_vectors(byte* rsaCert, word32 rsaCertSz, pkcs7File = XFOPEN(testVectors[i].outFileName, "wb"); if (!pkcs7File) { wc_PKCS7_Free(pkcs7); - return -9388; + return -11825; } ret = (int)XFWRITE(enveloped, 1, envelopedSz, pkcs7File); XFCLOSE(pkcs7File); if (ret != envelopedSz) { wc_PKCS7_Free(pkcs7); - return -9389; + return -11826; } #endif /* PKCS7_OUTPUT_TEST_BUNDLES */ @@ -23664,12 +25207,12 @@ int pkcs7authenveloped_test(void) /* read client RSA cert and key in DER format */ rsaCert = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (rsaCert == NULL) - return -9360; + return -11900; rsaPrivKey = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (rsaPrivKey == NULL) { XFREE(rsaCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - return -9361; + return -11901; } rsaCertSz = FOURK_BUF; @@ -23684,7 +25227,7 @@ int pkcs7authenveloped_test(void) XFREE(rsaCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); XFREE(rsaPrivKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); #endif - return -9362; + return -11902; } eccPrivKey =(byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); @@ -23694,7 +25237,7 @@ int pkcs7authenveloped_test(void) XFREE(rsaPrivKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); #endif XFREE(eccCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - return -9363; + return -11903; } eccCertSz = FOURK_BUF; @@ -23714,7 +25257,7 @@ int pkcs7authenveloped_test(void) XFREE(eccCert, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); XFREE(eccPrivKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); #endif - return -9364; + return -11904; } ret = pkcs7authenveloped_run_vectors(rsaCert, (word32)rsaCertSz, @@ -23759,15 +25302,15 @@ static int myCEKwrapFunc(PKCS7* pkcs7, byte* cek, word32 cekSz, byte* keyId, /* test case sanity checks */ if (keyIdSz != 1) { - return -1; + return -11905; } if (keyId[0] != 0x00) { - return -1; + return -11906; } if (type != (int)PKCS7_KEKRI) { - return -1; + return -11907; } switch (keyWrapAlgo) { @@ -23851,7 +25394,7 @@ static int envelopedData_encrypt(byte* in, word32 inSz, byte* out, pkcs7 = wc_PKCS7_New(NULL, INVALID_DEVID); if (pkcs7 == NULL) - return -1; + return -11908; pkcs7->content = in; pkcs7->contentSz = inSz; @@ -23867,7 +25410,7 @@ static int envelopedData_encrypt(byte* in, word32 inSz, byte* out, if (ret < 0) { printf("wc_PKCS7_AddRecipient_KEKRI() failed, ret = %d\n", ret); wc_PKCS7_Free(pkcs7); - return -1; + return -11909; } /* encode envelopedData, returns size */ @@ -23875,7 +25418,7 @@ static int envelopedData_encrypt(byte* in, word32 inSz, byte* out, if (ret <= 0) { printf("wc_PKCS7_EncodeEnvelopedData() failed, ret = %d\n", ret); wc_PKCS7_Free(pkcs7); - return -1; + return -11910; } @@ -23937,19 +25480,19 @@ static int generateBundle(byte* out, word32 *outSz, const byte* encryptKey, /* init PKCS7 */ pkcs7 = wc_PKCS7_New(NULL, INVALID_DEVID); if (pkcs7 == NULL) - return -1; + return -11911; ret = wc_PKCS7_InitWithCert(pkcs7, cert, certSz); if (ret != 0) { printf("ERROR: wc_PKCS7_InitWithCert() failed, ret = %d\n", ret); wc_PKCS7_Free(pkcs7); - return -1; + return -11912; } ret = wc_PKCS7_SetSignerIdentifierType(pkcs7, CMS_SKID); if (ret != 0) { wc_PKCS7_Free(pkcs7); - return -1; + return -11913; } /* encode Signed Encrypted FirmwarePkgData */ @@ -23969,7 +25512,7 @@ static int generateBundle(byte* out, word32 *outSz, const byte* encryptKey, printf("ERROR: wc_PKCS7_EncodeSignedEncryptedFPD() failed, " "ret = %d\n", ret); wc_PKCS7_Free(pkcs7); - return -1; + return -11914; } else { *outSz = ret; @@ -24100,12 +25643,12 @@ int pkcs7callback_test(byte* cert, word32 certSz, byte* key, word32 keySz) ret = generateBundle(derBuf, &derSz, defKey, sizeof(defKey), 0, cert, certSz, key, keySz); if (ret <= 0) { - return -10000; + return -11915; } ret = verifyBundle(derBuf, derSz, 0); if (ret != 0) { - return -10001; + return -11916; } /* test choosing other key with keyID */ @@ -24113,12 +25656,12 @@ int pkcs7callback_test(byte* cert, word32 certSz, byte* key, word32 keySz) ret = generateBundle(derBuf, &derSz, altKey, sizeof(altKey), 1, cert, certSz, key, keySz); if (ret <= 0) { - return -10002; + return -11917; } ret = verifyBundle(derBuf, derSz, 1); if (ret != 0) { - return -10003; + return -11918; } /* test fail case with wrong keyID */ @@ -24126,12 +25669,12 @@ int pkcs7callback_test(byte* cert, word32 certSz, byte* key, word32 keySz) ret = generateBundle(derBuf, &derSz, defKey, sizeof(defKey), 1, cert, certSz, key, keySz); if (ret <= 0) { - return -10004; + return -11919; } ret = verifyBundle(derBuf, derSz, 1); if (ret == 0) { - return -10005; + return -11920; } return 0; @@ -24289,7 +25832,7 @@ int pkcs7encrypted_test(void) for (i = 0; i < testSz; i++) { pkcs7 = wc_PKCS7_New(HEAP_HINT, devId); if (pkcs7 == NULL) - return -9407; + return -12000; pkcs7->content = (byte*)testVectors[i].content; pkcs7->contentSz = testVectors[i].contentSz; @@ -24305,7 +25848,7 @@ int pkcs7encrypted_test(void) sizeof(encrypted)); if (encryptedSz <= 0) { wc_PKCS7_Free(pkcs7); - return -9401; + return -12001; } /* decode encryptedData */ @@ -24317,14 +25860,14 @@ int pkcs7encrypted_test(void) decoded, sizeof(decoded)); if (decodedSz <= 0 && decodedSz != WC_PKCS7_WANT_READ_E) { printf("unexpected error %d\n", decodedSz); - return -9402; + return -12002; } } /* test decode result */ if (XMEMCMP(decoded, data, sizeof(data)) != 0) { printf("stream read failed\n"); wc_PKCS7_Free(pkcs7); - return -9403; + return -12003; } } #endif @@ -24332,13 +25875,13 @@ int pkcs7encrypted_test(void) decoded, sizeof(decoded)); if (decodedSz <= 0){ wc_PKCS7_Free(pkcs7); - return -9402; + return -12004; } /* test decode result */ if (XMEMCMP(decoded, data, sizeof(data)) != 0) { wc_PKCS7_Free(pkcs7); - return -9403; + return -12005; } /* verify decoded unprotected attributes */ @@ -24356,14 +25899,14 @@ int pkcs7encrypted_test(void) if (XMEMCMP(decodedAttrib->oid, expectedAttrib->oid, decodedAttrib->oidSz) != 0) { wc_PKCS7_Free(pkcs7); - return -9404; + return -12006; } /* verify value */ if (XMEMCMP(decodedAttrib->value, expectedAttrib->value, decodedAttrib->valueSz) != 0) { wc_PKCS7_Free(pkcs7); - return -9405; + return -12007; } decodedAttrib = decodedAttrib->next; @@ -24376,7 +25919,7 @@ int pkcs7encrypted_test(void) pkcs7File = XFOPEN(testVectors[i].outFileName, "wb"); if (!pkcs7File) { wc_PKCS7_Free(pkcs7); - return -9406; + return -12008; } ret = (int)XFWRITE(encrypted, encryptedSz, 1, pkcs7File); @@ -24435,7 +25978,7 @@ int pkcs7compressed_test(void) for (i = 0; i < testSz; i++) { pkcs7 = wc_PKCS7_New(HEAP_HINT, devId); if (pkcs7 == NULL) - return -9450; + return -12100; pkcs7->content = (byte*)testVectors[i].content; pkcs7->contentSz = testVectors[i].contentSz; @@ -24446,7 +25989,7 @@ int pkcs7compressed_test(void) sizeof(compressed)); if (compressedSz <= 0) { wc_PKCS7_Free(pkcs7); - return -9451; + return -12101; } /* decode compressedData */ @@ -24455,26 +25998,26 @@ int pkcs7compressed_test(void) sizeof(decoded)); if (decodedSz <= 0){ wc_PKCS7_Free(pkcs7); - return -9452; + return -12102; } /* test decode result */ if (XMEMCMP(decoded, testVectors[i].content, testVectors[i].contentSz) != 0) { wc_PKCS7_Free(pkcs7); - return -9453; + return -12103; } /* make sure content type is the same */ if (testVectors[i].contentOID != pkcs7->contentOID) - return -9454; + return -12104; #ifdef PKCS7_OUTPUT_TEST_BUNDLES /* output pkcs7 compressedData for external testing */ pkcs7File = XFOPEN(testVectors[i].outFileName, "wb"); if (!pkcs7File) { wc_PKCS7_Free(pkcs7); - return -9455; + return -12105; } ret = (int)XFWRITE(compressed, compressedSz, 1, pkcs7File); @@ -24745,14 +26288,14 @@ static int pkcs7signed_run_vectors( outSz = FOURK_BUF; out = (byte*)XMALLOC(outSz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (out == NULL) - return -9510; + return -12106; XMEMSET(out, 0, outSz); ret = wc_PKCS7_PadData((byte*)data, sizeof(data), out, outSz, 16); if (ret < 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - return -9511; + return -12107; } #ifndef HAVE_FIPS @@ -24762,13 +26305,13 @@ static int pkcs7signed_run_vectors( #endif if (ret != 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - return -9512; + return -12108; } for (i = 0; i < testSz; i++) { pkcs7 = wc_PKCS7_New(HEAP_HINT, devId); if (pkcs7 == NULL) - return -9513; + return -12109; ret = wc_PKCS7_InitWithCert(pkcs7, testVectors[i].cert, (word32)testVectors[i].certSz); @@ -24776,7 +26319,7 @@ static int pkcs7signed_run_vectors( if (ret != 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9514; + return -12110; } /* load CA certificate, if present */ @@ -24786,7 +26329,7 @@ static int pkcs7signed_run_vectors( if (ret != 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9515; + return -12111; } } @@ -24809,7 +26352,7 @@ static int pkcs7signed_run_vectors( if (ret != 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9516; + return -12112; } } @@ -24820,7 +26363,7 @@ static int pkcs7signed_run_vectors( if (ret != 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9517; + return -12113; } } @@ -24833,7 +26376,7 @@ static int pkcs7signed_run_vectors( if (ret != 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9518; + return -12114; } } @@ -24856,7 +26399,7 @@ static int pkcs7signed_run_vectors( if (ret != 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9519; + return -12115; } wc_ShaUpdate(&sha, pkcs7->publicKey, pkcs7->publicKeySz); wc_ShaFinal(&sha, digest); @@ -24866,7 +26409,7 @@ static int pkcs7signed_run_vectors( if (ret != 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9520; + return -12116; } wc_Sha256Update(&sha, pkcs7->publicKey, pkcs7->publicKeySz); wc_Sha256Final(&sha, digest); @@ -24884,7 +26427,7 @@ static int pkcs7signed_run_vectors( if (ret != 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9521; + return -12117; } } @@ -24892,7 +26435,7 @@ static int pkcs7signed_run_vectors( if (encodedSz < 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9522; + return -12118; } #ifdef PKCS7_OUTPUT_TEST_BUNDLES @@ -24901,14 +26444,14 @@ static int pkcs7signed_run_vectors( if (!file) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9523; + return -12119; } ret = (int)XFWRITE(out, 1, encodedSz, file); XFCLOSE(file); if (ret != (int)encodedSz) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9524; + return -12120; } #endif /* PKCS7_OUTPUT_TEST_BUNDLES */ @@ -24916,7 +26459,7 @@ static int pkcs7signed_run_vectors( pkcs7 = wc_PKCS7_New(HEAP_HINT, devId); if (pkcs7 == NULL) - return -9525; + return -12121; wc_PKCS7_InitWithCert(pkcs7, NULL, 0); if (testVectors[i].detachedSignature == 1) { @@ -24929,23 +26472,23 @@ static int pkcs7signed_run_vectors( if (ret < 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9526; + return -12122; } /* verify contentType extracted successfully for custom content types */ if (testVectors[i].contentTypeSz > 0) { if (pkcs7->contentTypeSz != testVectors[i].contentTypeSz) { - return -9527; + return -12123; } else if (XMEMCMP(pkcs7->contentType, testVectors[i].contentType, pkcs7->contentTypeSz) != 0) { - return -9528; + return -12124; } } if (pkcs7->singleCert == NULL || pkcs7->singleCertSz == 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9529; + return -12125; } { @@ -24964,13 +26507,13 @@ static int pkcs7signed_run_vectors( NULL, (word32*)&bufSz) != LENGTH_ONLY_E) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9530; + return -12126; } if (bufSz > (int)sizeof(buf)) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9531; + return -12127; } bufSz = wc_PKCS7_GetAttributeValue(pkcs7, oidPt, oidSz, @@ -24979,7 +26522,7 @@ static int pkcs7signed_run_vectors( (testVectors[i].signedAttribs == NULL && bufSz > 0)) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9532; + return -12128; } } @@ -24988,7 +26531,7 @@ static int pkcs7signed_run_vectors( if (!file) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9533; + return -12129; } ret = (int)XFWRITE(pkcs7->singleCert, 1, pkcs7->singleCertSz, file); XFCLOSE(file); @@ -25245,14 +26788,14 @@ static int pkcs7signed_run_SingleShotVectors( outSz = FOURK_BUF; out = (byte*)XMALLOC(outSz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (out == NULL) - return -9550; + return -12130; XMEMSET(out, 0, outSz); ret = wc_PKCS7_PadData((byte*)data, sizeof(data), out, outSz, 16); if (ret < 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - return -9551; + return -12131; } #ifndef HAVE_FIPS @@ -25262,13 +26805,13 @@ static int pkcs7signed_run_SingleShotVectors( #endif if (ret != 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - return -9552; + return -12132; } for (i = 0; i < testSz; i++) { pkcs7 = wc_PKCS7_New(HEAP_HINT, devId); if (pkcs7 == NULL) - return -9553; + return -12133; ret = wc_PKCS7_InitWithCert(pkcs7, testVectors[i].cert, (word32)testVectors[i].certSz); @@ -25276,7 +26819,7 @@ static int pkcs7signed_run_SingleShotVectors( if (ret != 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9554; + return -12134; } /* load CA certificate, if present */ @@ -25286,7 +26829,7 @@ static int pkcs7signed_run_SingleShotVectors( if (ret != 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9555; + return -12135; } } @@ -25297,7 +26840,7 @@ static int pkcs7signed_run_SingleShotVectors( if (ret != 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9556; + return -12136; } } @@ -25314,7 +26857,7 @@ static int pkcs7signed_run_SingleShotVectors( if (encodedSz < 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9557; + return -12137; } #ifndef NO_PKCS7_ENCRYPTED_DATA @@ -25335,7 +26878,7 @@ static int pkcs7signed_run_SingleShotVectors( if (encodedSz <= 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9558; + return -12138; } #endif @@ -25353,7 +26896,7 @@ static int pkcs7signed_run_SingleShotVectors( if (encodedSz <= 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9559; + return -12139; } #ifndef NO_PKCS7_ENCRYPTED_DATA @@ -25373,7 +26916,7 @@ static int pkcs7signed_run_SingleShotVectors( if (encodedSz <= 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9560; + return -12140; } #endif /* NO_PKCS7_ENCRYPTED_DATA */ @@ -25383,7 +26926,7 @@ static int pkcs7signed_run_SingleShotVectors( /* unsupported SignedData single-shot combination */ XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9561; + return -12141; } #ifdef PKCS7_OUTPUT_TEST_BUNDLES @@ -25392,14 +26935,14 @@ static int pkcs7signed_run_SingleShotVectors( if (!file) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9562; + return -12142; } ret = (int)XFWRITE(out, 1, encodedSz, file); XFCLOSE(file); if (ret != (int)encodedSz) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9563; + return -12143; } #endif /* PKCS7_OUTPUT_TEST_BUNDLES */ @@ -25407,14 +26950,14 @@ static int pkcs7signed_run_SingleShotVectors( pkcs7 = wc_PKCS7_New(HEAP_HINT, devId); if (pkcs7 == NULL) - return -9564; + return -12144; wc_PKCS7_InitWithCert(pkcs7, NULL, 0); ret = wc_PKCS7_VerifySignedData(pkcs7, out, outSz); if (ret < 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9565; + return -12145; } #ifndef NO_PKCS7_STREAM { @@ -25425,7 +26968,7 @@ static int pkcs7signed_run_SingleShotVectors( XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); printf("unexpected error %d\n", ret); - return -9565; + return -12146; } } } @@ -25434,7 +26977,7 @@ static int pkcs7signed_run_SingleShotVectors( if (pkcs7->singleCert == NULL || pkcs7->singleCertSz == 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9566; + return -12147; } if (testVectors[i].encCompFlag == 0) { @@ -25444,7 +26987,7 @@ static int pkcs7signed_run_SingleShotVectors( pkcs7->contentSz)) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9567; + return -12148; } } @@ -25460,7 +27003,7 @@ static int pkcs7signed_run_SingleShotVectors( if (ret < 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9568; + return -12149; } /* compare decrypted to expected */ @@ -25468,7 +27011,7 @@ static int pkcs7signed_run_SingleShotVectors( XMEMCMP(out, testVectors[i].content, ret)) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9569; + return -12150; } } #endif @@ -25481,7 +27024,7 @@ static int pkcs7signed_run_SingleShotVectors( if (ret < 0) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9570; + return -12151; } /* compare decompressed to expected */ @@ -25489,7 +27032,7 @@ static int pkcs7signed_run_SingleShotVectors( XMEMCMP(out, testVectors[i].content, ret)) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9571; + return -12152; } } #ifndef NO_PKCS7_ENCRYPTED_DATA @@ -25504,7 +27047,7 @@ static int pkcs7signed_run_SingleShotVectors( if (encryptedTmp == NULL) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9572; + return -12153; } XMEMSET(encryptedTmp, 0, encryptedTmpSz); @@ -25521,7 +27064,7 @@ static int pkcs7signed_run_SingleShotVectors( XFREE(encryptedTmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9573; + return -12154; } /* decompress inner compressedData */ @@ -25531,7 +27074,7 @@ static int pkcs7signed_run_SingleShotVectors( XFREE(encryptedTmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9574; + return -12155; } XFREE(encryptedTmp, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); @@ -25541,7 +27084,7 @@ static int pkcs7signed_run_SingleShotVectors( XMEMCMP(out, testVectors[i].content, ret)) { XFREE(out, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_PKCS7_Free(pkcs7); - return -9575; + return -12156; } } #endif /* NO_PKCS7_ENCRYPTED_DATA */ @@ -25605,12 +27148,12 @@ int pkcs7signed_test(void) rsaClientCertBuf = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (rsaClientCertBuf == NULL) - ret = -9500; + ret = -12200; rsaClientPrivKeyBuf = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (ret == 0 && rsaClientPrivKeyBuf == NULL) { - ret = -9501; + ret = -12201; } rsaClientCertBufSz = FOURK_BUF; @@ -25620,12 +27163,12 @@ int pkcs7signed_test(void) rsaServerCertBuf = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (ret == 0 && rsaServerCertBuf == NULL) - ret = -9502; + ret = -12202; rsaServerPrivKeyBuf = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (ret == 0 && rsaServerPrivKeyBuf == NULL) { - ret = -9503; + ret = -12203; } rsaServerCertBufSz = FOURK_BUF; @@ -25635,12 +27178,12 @@ int pkcs7signed_test(void) rsaCaCertBuf = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (ret == 0 && rsaCaCertBuf == NULL) - ret = -9504; + ret = -12204; rsaCaPrivKeyBuf = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (ret == 0 && rsaCaPrivKeyBuf == NULL) { - ret = -9505; + ret = -12205; } rsaCaCertBufSz = FOURK_BUF; @@ -25652,13 +27195,13 @@ int pkcs7signed_test(void) eccClientCertBuf = (byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (ret == 0 && eccClientCertBuf == NULL) { - ret = -9506; + ret = -12206; } eccClientPrivKeyBuf =(byte*)XMALLOC(FOURK_BUF, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (ret == 0 && eccClientPrivKeyBuf == NULL) { - ret = -9507; + ret = -12207; } eccClientCertBufSz = FOURK_BUF; @@ -25675,7 +27218,7 @@ int pkcs7signed_test(void) eccClientCertBuf, &eccClientCertBufSz, eccClientPrivKeyBuf, &eccClientPrivKeyBufSz); if (ret < 0) { - ret = -9508; + ret = -12208; } if (ret >= 0) @@ -25759,7 +27302,7 @@ int mp_test(void) ret = mp_init_multi(&a, &b, &r1, &r2, NULL, NULL); if (ret != 0) - return -9600; + return -12300; mp_init_copy(&p, &a); @@ -25774,62 +27317,62 @@ int mp_test(void) #if defined(HAVE_ECC) || defined(WOLFSSL_KEY_GEN) mp_set_int(&a, 0); if (a.used != 0 || a.dp[0] != 0) - return -9601; + return -12301; for (j = 1; j <= MP_MAX_TEST_BYTE_LEN; j++) { for (i = 0; i < 4 * j; i++) { /* New values to use. */ ret = randNum(&p, j, &rng, NULL); if (ret != 0) - return -9602; + return -12302; ret = randNum(&a, j, &rng, NULL); if (ret != 0) - return -9603; + return -12303; ret = randNum(&b, j, &rng, NULL); if (ret != 0) - return -9604; + return -12304; ret = wc_RNG_GenerateBlock(&rng, (byte*)&d, sizeof(d)); if (ret != 0) - return -9605; + return -12305; d &= MP_MASK; /* Ensure sqrmod produce same result as mulmod. */ ret = mp_sqrmod(&a, &p, &r1); if (ret != 0) - return -9606; + return -12306; ret = mp_mulmod(&a, &a, &p, &r2); if (ret != 0) - return -9607; + return -12307; if (mp_cmp(&r1, &r2) != 0) - return -9608; + return -12308; /* Ensure add with mod produce same result as sub with mod. */ ret = mp_addmod(&a, &b, &p, &r1); if (ret != 0) - return -9609; + return -12309; b.sign ^= 1; ret = mp_submod(&a, &b, &p, &r2); if (ret != 0) - return -9610; + return -12310; if (mp_cmp(&r1, &r2) != 0) - return -9611; + return -12311; /* Ensure add digit produce same result as sub digit. */ ret = mp_add_d(&a, d, &r1); if (ret != 0) - return -9612; + return -12312; ret = mp_sub_d(&r1, d, &r2); if (ret != 0) - return -9613; + return -12313; if (mp_cmp(&a, &r2) != 0) - return -9614; + return -12314; /* Invert - if p is even it will use the slow impl. * - if p and a are even it will fail. */ ret = mp_invmod(&a, &p, &r1); if (ret != 0 && ret != MP_VAL) - return -9615; + return -12315; ret = 0; /* Shift up and down number all bits in a digit. */ @@ -25837,12 +27380,12 @@ int mp_test(void) mp_mul_2d(&a, k, &r1); mp_div_2d(&r1, k, &r2, &p); if (mp_cmp(&a, &r2) != 0) - return -9616; + return -12316; if (!mp_iszero(&p)) - return -9617; + return -12317; mp_rshb(&r1, k); if (mp_cmp(&a, &r1) != 0) - return -9618; + return -12318; } } } @@ -25851,14 +27394,14 @@ int mp_test(void) d &= 0xffffffff; mp_set_int(&a, d); if (a.used != 1 || a.dp[0] != d) - return -9619; + return -12319; /* Check setting a bit and testing a bit works. */ for (i = 0; i < MP_MAX_TEST_BYTE_LEN * 8; i++) { mp_zero(&a); mp_set_bit(&a, i); if (!mp_is_bit_set(&a, i)) - return -9620; + return -12320; } #endif @@ -26009,65 +27552,65 @@ int prime_test(void) if (ret == 0) ret = mp_mul(&n, &p3, &n); if (ret != 0) - return -9650; + return -12400; /* Check the old prime test using the number that false positives. * This test result should indicate as not prime. */ ret = mp_prime_is_prime(&n, 40, &isPrime); if (ret != 0) - return -9651; + return -12401; if (isPrime) - return -9652; + return -12402; /* This test result should fail. It should indicate the value as prime. */ ret = mp_prime_is_prime(&n, 8, &isPrime); if (ret != 0) - return -9653; + return -12403; if (!isPrime) - return -9654; + return -12404; /* This test result should indicate the value as not prime. */ ret = mp_prime_is_prime_ex(&n, 8, &isPrime, &rng); if (ret != 0) - return -9655; + return -12405; if (isPrime) - return -9656; + return -12406; ret = mp_read_unsigned_bin(&n, controlPrime, sizeof(controlPrime)); if (ret != 0) - return -9657; + return -12407; /* This test result should indicate the value as prime. */ ret = mp_prime_is_prime_ex(&n, 8, &isPrime, &rng); if (ret != 0) - return -9658; + return -12408; if (!isPrime) - return -9659; + return -12409; /* This test result should indicate the value as prime. */ isPrime = -1; ret = mp_prime_is_prime(&n, 8, &isPrime); if (ret != 0) - return -9660; + return -12410; if (!isPrime) - return -9661; + return -12411; ret = mp_read_unsigned_bin(&n, testOne, sizeof(testOne)); if (ret != 0) - return -9662; + return -12412; /* This test result should indicate the value as not prime. */ ret = mp_prime_is_prime_ex(&n, 8, &isPrime, &rng); if (ret != 0) - return -9663; + return -12413; if (isPrime) - return -9664; + return -12414; ret = mp_prime_is_prime(&n, 8, &isPrime); if (ret != 0) - return -9665; + return -12415; if (isPrime) - return -9666; + return -12416; mp_clear(&p3); mp_clear(&p2); @@ -26143,57 +27686,57 @@ int berder_test(void) for (i = 0; i < (int)(sizeof(testData) / sizeof(*testData)); i++) { ret = wc_BerToDer(testData[i].in, testData[i].inSz, NULL, &len); if (ret != LENGTH_ONLY_E) - return -9700 - i; + return -12500 - i; if (len != testData[i].outSz) - return -9710 - i; + return -12510 - i; len = testData[i].outSz; ret = wc_BerToDer(testData[i].in, testData[i].inSz, out, &len); if (ret != 0) - return -9720 - i; + return -12520 - i; if (XMEMCMP(out, testData[i].out, len) != 0) - return -9730 - i; + return -12530 - i; for (l = 1; l < testData[i].inSz; l++) { ret = wc_BerToDer(testData[i].in, l, NULL, &len); if (ret != ASN_PARSE_E) - return -9740; + return -12540; len = testData[i].outSz; ret = wc_BerToDer(testData[i].in, l, out, &len); if (ret != ASN_PARSE_E) - return -9741; + return -12541; } for (l = 0; l < testData[i].outSz-1; l++) { ret = wc_BerToDer(testData[i].in, testData[i].inSz, out, &l); if (ret != BUFFER_E) - return -9742; + return -12542; } } ret = wc_BerToDer(NULL, 4, NULL, NULL); if (ret != BAD_FUNC_ARG) - return -9743; + return -12543; ret = wc_BerToDer(out, 4, NULL, NULL); if (ret != BAD_FUNC_ARG) - return -9744; + return -12544; ret = wc_BerToDer(NULL, 4, NULL, &len); if (ret != BAD_FUNC_ARG) - return -9745; + return -12545; ret = wc_BerToDer(NULL, 4, out, NULL); if (ret != BAD_FUNC_ARG) - return -9746; + return -12546; ret = wc_BerToDer(out, 4, out, NULL); if (ret != BAD_FUNC_ARG) - return -9747; + return -12547; ret = wc_BerToDer(NULL, 4, out, &len); if (ret != BAD_FUNC_ARG) - return -9748; + return -12548; for (l = 1; l < sizeof(good4_out); l++) { len = l; ret = wc_BerToDer(good4_in, sizeof(good4_in), out, &len); if (ret != BUFFER_E) - return -9749; + return -12549; } return 0; @@ -26222,10 +27765,10 @@ int logging_test(void) b[i] = i; if (wolfSSL_Debugging_ON() != 0) - return -9800; + return -12600; if (wolfSSL_SetLoggingCb(my_Logging_cb) != 0) - return -9801; + return -12601; WOLFSSL_MSG(msg); WOLFSSL_BUFFER(a, sizeof(a)); @@ -26250,7 +27793,7 @@ int logging_test(void) /* check the logs were disabled */ if (i != log_cnt) - return -9802; + return -12602; /* restore callback and leave logging enabled */ wolfSSL_SetLoggingCb(NULL); @@ -26262,10 +27805,10 @@ int logging_test(void) #else if (wolfSSL_Debugging_ON() != NOT_COMPILED_IN) - return -9803; + return -12603; wolfSSL_Debugging_OFF(); if (wolfSSL_SetLoggingCb(NULL) != NOT_COMPILED_IN) - return -9804; + return -12604; #endif /* DEBUG_WOLFSSL */ return 0; } @@ -26279,27 +27822,27 @@ int mutex_test(void) #ifndef WOLFSSL_NO_MALLOC wolfSSL_Mutex *mm = wc_InitAndAllocMutex(); if (mm == NULL) - return -9900; + return -12700; wc_FreeMutex(mm); XFREE(mm, NULL, DYNAMIC_TYPE_MUTEX); #endif #ifdef WOLFSSL_PTHREADS if (wc_InitMutex(&m) != 0) - return -9901; + return -12701; if (wc_LockMutex(&m) != 0) - return -9902; + return -12702; if (wc_FreeMutex(&m) != BAD_MUTEX_E) - return -9903; + return -12703; if (wc_UnLockMutex(&m) != 0) - return -9904; + return -12704; if (wc_FreeMutex(&m) != 0) - return -9905; + return -12705; #ifndef WOLFSSL_NO_MUTEXLOCK_AFTER_FREE if (wc_LockMutex(&m) != BAD_MUTEX_E) - return -9906; + return -12706; if (wc_UnLockMutex(&m) != BAD_MUTEX_E) - return -9907; + return -12707; #endif #endif @@ -26351,13 +27894,13 @@ int memcb_test(void) /* Save existing memory callbacks */ if (wolfSSL_GetAllocators(&mc, &fc, &rc) != 0) - return -10000; + return -12800; #ifndef WOLFSSL_NO_MALLOC /* test realloc */ b = (byte*)XREALLOC(b, 1024, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (b == NULL) { - ERROR_OUT(-10001, exit_memcb); + ERROR_OUT(-12801, exit_memcb); } XFREE(b, NULL, DYNAMIC_TYPE_TMP_BUFFER); b = NULL; @@ -26366,7 +27909,7 @@ int memcb_test(void) if (wolfSSL_SetAllocators((wolfSSL_Malloc_cb)(void*)&my_Malloc_cb, (wolfSSL_Free_cb)(void*)&my_Free_cb, (wolfSSL_Realloc_cb)(void*)&my_Realloc_cb) != 0) { - ERROR_OUT(-10005, exit_memcb); + ERROR_OUT(-12802, exit_memcb); } b = (byte*)XMALLOC(1024, NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -26378,7 +27921,7 @@ int memcb_test(void) #else if (malloc_cnt != 0 || free_cnt != 0 || realloc_cnt != 0) #endif - ret = -10006; + ret = -12803; #endif /* !WOLFSSL_NO_MALLOC */ #ifndef WOLFSSL_NO_MALLOC @@ -26424,45 +27967,45 @@ int blob_test(void) outSz = sizeof(blob); ret = wc_caamCreateBlob((byte*)iv, sizeof(iv), blob, &outSz); if (ret != 0) { - ERROR_OUT(-10100, exit_blob); + ERROR_OUT(-12900, exit_blob); } blob[outSz - 2] += 1; ret = wc_caamOpenBlob(blob, outSz, out, &outSz); if (ret == 0) { /* should fail with altered blob */ - ERROR_OUT(-10101, exit_blob); + ERROR_OUT(-12901, exit_blob); } XMEMSET(blob, 0, sizeof(blob)); outSz = sizeof(blob); ret = wc_caamCreateBlob((byte*)iv, sizeof(iv), blob, &outSz); if (ret != 0) { - ERROR_OUT(-10102, exit_blob); + ERROR_OUT(-12902, exit_blob); } ret = wc_caamOpenBlob(blob, outSz, out, &outSz); if (ret != 0) { - ERROR_OUT(-10103, exit_blob); + ERROR_OUT(-12903, exit_blob); } if (XMEMCMP(out, iv, sizeof(iv))) { - ERROR_OUT(-10104, exit_blob); + ERROR_OUT(-12904, exit_blob); } XMEMSET(blob, 0, sizeof(blob)); outSz = sizeof(blob); ret = wc_caamCreateBlob((byte*)text, sizeof(text), blob, &outSz); if (ret != 0) { - ERROR_OUT(-10105, exit_blob); + ERROR_OUT(-12905, exit_blob); } ret = wc_caamOpenBlob(blob, outSz, out, &outSz); if (ret != 0) { - ERROR_OUT(-10106, exit_blob); + ERROR_OUT(-12906, exit_blob); } if (XMEMCMP(out, text, sizeof(text))) { - ERROR_OUT(-10107, exit_blob); + ERROR_OUT(-12907, exit_blob); } exit_blob: diff --git a/wolfssl/internal.h b/wolfssl/internal.h index ec054c0ee..262d8b6b6 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -105,6 +105,12 @@ #ifdef HAVE_CURVE25519 #include #endif +#ifdef HAVE_ED448 + #include +#endif +#ifdef HAVE_CURVE448 + #include +#endif #include #include @@ -513,7 +519,8 @@ #endif #endif - #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519)) && !defined(NO_TLS) + #if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \ + defined(HAVE_CURVE448)) && !defined(NO_TLS) #if !defined(NO_AES) #if !defined(NO_SHA) && defined(HAVE_AES_CBC) #if !defined(NO_RSA) @@ -533,8 +540,9 @@ #endif #endif - #if defined(HAVE_ECC) || (defined(HAVE_CURVE25519) && \ - defined(HAVE_ED25519)) + #if defined(HAVE_ECC) || \ + (defined(HAVE_CURVE25519) && defined(HAVE_ED25519)) || \ + (defined(HAVE_CURVE448) && defined(HAVE_ED448)) #ifdef WOLFSSL_AES_128 #define BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA #endif @@ -560,8 +568,9 @@ #define BUILD_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 #endif #endif - #if defined(HAVE_ECC) || (defined(HAVE_CURVE25519) && \ - defined(HAVE_ED25519)) + #if defined(HAVE_ECC) || \ + (defined(HAVE_CURVE25519) && defined(HAVE_ED25519)) || \ + (defined(HAVE_CURVE448) && defined(HAVE_ED448)) #define BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 #endif #if defined(WOLFSSL_STATIC_DH) && defined(HAVE_ECC) @@ -577,8 +586,9 @@ #define BUILD_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 #endif #endif - #if defined(HAVE_ECC) || (defined(HAVE_CURVE25519) && \ - defined(HAVE_ED25519)) + #if defined(HAVE_ECC) || \ + (defined(HAVE_CURVE25519) && defined(HAVE_ED25519)) || \ + (defined(HAVE_CURVE448) && defined(HAVE_ED448)) #define BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 #endif #if defined(WOLFSSL_STATIC_DH) && defined(HAVE_ECC) @@ -626,8 +636,9 @@ #endif #endif - #if defined(HAVE_ECC) || (defined(HAVE_CURVE25519) && \ - defined(HAVE_ED25519)) + #if defined(HAVE_ECC) || \ + (defined(HAVE_CURVE25519) && defined(HAVE_ED25519)) || \ + (defined(HAVE_CURVE448) && defined(HAVE_ED448)) #ifndef WOLFSSL_AEAD_ONLY #define BUILD_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA #endif @@ -646,8 +657,9 @@ #endif #endif - #if defined(HAVE_ECC) || (defined(HAVE_CURVE25519) && \ - defined(HAVE_ED25519)) + #if defined(HAVE_ECC) || \ + (defined(HAVE_CURVE25519) && defined(HAVE_ED25519)) || \ + (defined(HAVE_CURVE448) && defined(HAVE_ED448)) #define BUILD_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA #endif #if defined(WOLFSSL_STATIC_DH) && defined(HAVE_ECC) @@ -657,8 +669,9 @@ #endif #if defined(HAVE_NULL_CIPHER) #if !defined(NO_SHA) - #if defined(HAVE_ECC) || (defined(HAVE_CURVE25519) && \ - defined(HAVE_ED25519)) + #if defined(HAVE_ECC) || \ + (defined(HAVE_CURVE25519) && defined(HAVE_ED25519)) || \ + (defined(HAVE_CURVE448) && defined(HAVE_ED448)) #define BUILD_TLS_ECDHE_ECDSA_WITH_NULL_SHA #endif #endif @@ -673,8 +686,9 @@ #endif #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) && !defined(NO_SHA256) #if !defined(NO_OLD_POLY1305) - #if defined(HAVE_ECC) || (defined(HAVE_CURVE25519) && \ - defined(HAVE_ED25519)) + #if defined(HAVE_ECC) || \ + (defined(HAVE_CURVE25519) && defined(HAVE_ED25519)) || \ + (defined(HAVE_CURVE448) && defined(HAVE_ED448)) #define BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_OLD_POLY1305_SHA256 #endif #if !defined(NO_RSA) && defined(HAVE_ECC) @@ -686,7 +700,8 @@ #endif /* NO_OLD_POLY1305 */ #if !defined(NO_PSK) #define BUILD_TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 - #if defined(HAVE_ECC) || defined(HAVE_ED25519) + #if defined(HAVE_ECC) || defined(HAVE_ED25519) || \ + defined(HAVE_ED448) #define BUILD_TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 #endif #ifndef NO_DH @@ -729,12 +744,13 @@ #endif #endif -#if (defined(HAVE_ECC) || defined(HAVE_CURVE25519)) && !defined(NO_TLS) && \ - !defined(NO_AES) +#if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)) \ + && !defined(NO_TLS) && !defined(NO_AES) #ifdef HAVE_AESGCM #if !defined(NO_SHA256) && defined(WOLFSSL_AES_128) - #if defined(HAVE_ECC) || (defined(HAVE_CURVE25519) && \ - defined(HAVE_ED25519)) + #if defined(HAVE_ECC) || \ + (defined(HAVE_CURVE25519) && defined(HAVE_ED25519)) || \ + (defined(HAVE_CURVE448) && defined(HAVE_ED448)) #define BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 #endif #ifndef NO_RSA @@ -742,8 +758,9 @@ #endif #endif #if defined(WOLFSSL_SHA384) && defined(WOLFSSL_AES_256) - #if defined(HAVE_ECC) || (defined(HAVE_CURVE25519) && \ - defined(HAVE_ED25519)) + #if defined(HAVE_ECC) || \ + (defined(HAVE_CURVE25519) && defined(HAVE_ED25519)) || \ + (defined(HAVE_CURVE448) && defined(HAVE_ED448)) #define BUILD_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 #endif #ifndef NO_RSA @@ -752,8 +769,9 @@ #endif #endif #if defined(HAVE_AESCCM) && !defined(NO_SHA256) - #if defined(HAVE_ECC) || (defined(HAVE_CURVE25519) && \ - defined(HAVE_ED25519)) + #if defined(HAVE_ECC) || \ + (defined(HAVE_CURVE25519) && defined(HAVE_ED25519)) || \ + (defined(HAVE_CURVE448) && defined(HAVE_ED448)) #ifdef WOLFSSL_AES_128 #define BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM #define BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 @@ -766,9 +784,10 @@ #endif #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) && !defined(NO_SHA256) - #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) - #if defined(HAVE_ECC) || (defined(HAVE_CURVE25519) && \ - defined(HAVE_ED25519)) + #if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) + #if defined(HAVE_ECC) || \ + (defined(HAVE_CURVE25519) && defined(HAVE_ED25519)) || \ + (defined(HAVE_CURVE448) && defined(HAVE_ED448)) #define BUILD_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 #endif #ifndef NO_RSA @@ -1402,6 +1421,8 @@ enum Misc { MAX_CERT_VERIFY_SZ = 4096 / 8, /* max RSA - default 4096-bits */ #elif defined(HAVE_ECC) MAX_CERT_VERIFY_SZ = ECC_MAX_SIG_SIZE, /* max ECC */ +#elif defined(HAVE_ED448) + MAX_CERT_VERIFY_SZ = ED448_SIG_SIZE, /* max Ed448 */ #elif defined(HAVE_ED25519) MAX_CERT_VERIFY_SZ = ED25519_SIG_SIZE, /* max Ed25519 */ #else @@ -1968,7 +1989,7 @@ struct WOLFSSL_CERT_MANAGER { #ifndef NO_RSA short minRsaKeySz; /* minimum allowed RSA key size */ #endif -#if defined(HAVE_ECC) || defined(HAVE_ED25519) +#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) short minEccKeySz; /* minimum allowed ECC key size */ #endif }; @@ -2671,7 +2692,7 @@ struct WOLFSSL_CTX { #ifndef NO_RSA short minRsaKeySz; /* minimum RSA key size */ #endif -#if defined(HAVE_ECC) || defined(HAVE_ED25519) +#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) short minEccKeySz; /* minimum ECC key size */ #endif #if defined(OPENSSL_EXTRA) || defined(HAVE_WEBSERVER) @@ -2702,13 +2723,13 @@ struct WOLFSSL_CTX { void* verifyCertCbArg; #endif /* OPENSSL_ALL */ word32 timeout; /* session timeout */ -#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) +#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_ED448) word32 ecdhCurveOID; /* curve Ecc_Sum */ #endif #ifdef HAVE_ECC word16 eccTempKeySz; /* in octets 20 - 66 */ #endif -#if defined(HAVE_ECC) || defined(HAVE_ED25519) +#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) word32 pkCurveOID; /* curve Ecc_Sum */ #endif #if defined(HAVE_SESSION_TICKET) || !defined(NO_PSK) @@ -2810,6 +2831,18 @@ struct WOLFSSL_CTX { /* User X25519 SharedSecret Callback handler */ CallbackX25519SharedSecret X25519SharedSecretCb; #endif + #ifdef HAVE_ED448 + /* User Ed448Sign Callback handler */ + CallbackEd448Sign Ed448SignCb; + /* User Ed448Verify Callback handler */ + CallbackEd448Verify Ed448VerifyCb; + #endif + #ifdef HAVE_CURVE448 + /* User X448 KeyGen Callback Handler */ + CallbackX448KeyGen X448KeyGenCb; + /* User X448 SharedSecret Callback handler */ + CallbackX448SharedSecret X448SharedSecretCb; + #endif #endif /* HAVE_ECC */ #ifndef NO_DH CallbackDhAgree DhAgreeCb; /* User DH Agree Callback handler */ @@ -2911,7 +2944,8 @@ enum SignatureAlgorithm { ecc_dsa_sa_algo = 3, rsa_pss_sa_algo = 8, ed25519_sa_algo = 9, - rsa_pss_pss_algo = 10 + rsa_pss_pss_algo = 10, + ed448_sa_algo = 11 }; #define PSS_RSAE_TO_PSS_PSS(macAlgo) \ @@ -3253,6 +3287,9 @@ typedef struct Buffers { #ifdef HAVE_ED25519 buffer peerEd25519Key; /* for Ed25519 Verify Callbacks */ #endif /* HAVE_ED25519 */ + #ifdef HAVE_ED448 + buffer peerEd448Key; /* for Ed448 Verify Callbacks */ + #endif /* HAVE_ED448 */ #ifndef NO_RSA buffer peerRsaKey; /* we own for Rsa Verify Callbacks */ #endif /* NO_RSA */ @@ -3387,8 +3424,9 @@ typedef struct Options { #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_TLS13_MIDDLEBOX_COMPAT) word16 sentChangeCipher:1; /* Change Cipher Spec sent */ #endif -#if !defined(WOLFSSL_NO_CLIENT_AUTH) && defined(HAVE_ED25519) && \ - !defined(NO_ED25519_CLIENT_AUTH) +#if !defined(WOLFSSL_NO_CLIENT_AUTH) && \ + ((defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \ + (defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH))) word16 cacheMessages:1; /* Cache messages for sign/verify */ #endif #ifndef NO_DH @@ -3433,7 +3471,7 @@ typedef struct Options { #ifndef NO_RSA short minRsaKeySz; /* minimum RSA key size */ #endif -#if defined(HAVE_ECC) || defined(HAVE_ED25519) +#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) short minEccKeySz; /* minimum ECC key size */ #endif #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) @@ -3583,7 +3621,7 @@ struct WOLFSSL_X509 { buffer pubKey; int pubKeyOID; DNS_entry* altNamesNext; /* hint for retrieval */ -#if defined(HAVE_ECC) || defined(HAVE_ED25519) +#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) word32 pkCurveOID; #endif /* HAVE_ECC */ #ifndef NO_CERTS @@ -3747,7 +3785,8 @@ typedef struct HS_Hashes { #ifdef WOLFSSL_SHA512 wc_Sha512 hashSha512; /* sha512 hash of handshake msgs */ #endif -#if defined(HAVE_ED25519) && !defined(WOLFSSL_NO_CLIENT_AUTH) +#if (defined(HAVE_ED25519) || defined(HAVE_ED448)) && \ + !defined(WOLFSSL_NO_CLIENT_AUTH) byte* messages; /* handshake messages */ int length; /* length of handshake messages' data */ int prevLen; /* length of messages but last */ @@ -3927,10 +3966,10 @@ struct WOLFSSL { byte peerNtruKey[MAX_NTRU_PUB_KEY_SZ]; byte peerNtruKeyPresent; #endif -#if defined(HAVE_ECC) || defined(HAVE_ED25519) +#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) int eccVerifyRes; #endif -#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) +#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) word32 ecdhCurveOID; /* curve Ecc_Sum */ ecc_key* eccTempKey; /* private ECDHE key */ byte eccTempKeyPresent; /* also holds type */ @@ -3942,7 +3981,7 @@ struct WOLFSSL { word16 eccTempKeySz; /* in octets 20 - 66 */ byte peerEccDsaKeyPresent; #endif -#if defined(HAVE_ECC) || defined(HAVE_ED25519) +#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_CURVE448) word32 pkCurveOID; /* curve Ecc_Sum */ #endif #ifdef HAVE_ED25519 @@ -3953,6 +3992,14 @@ struct WOLFSSL { curve25519_key* peerX25519Key; byte peerX25519KeyPresent; #endif +#ifdef HAVE_ED448 + ed448_key* peerEd448Key; + byte peerEd448KeyPresent; +#endif +#ifdef HAVE_CURVE448 + curve448_key* peerX448Key; + byte peerX448KeyPresent; +#endif #ifdef HAVE_LIBZ z_stream c_stream; /* compression stream */ z_stream d_stream; /* decompression stream */ @@ -4094,6 +4141,14 @@ struct WOLFSSL { void* X25519KeyGenCtx; /* X25519 KeyGen Callback Context */ void* X25519SharedSecretCtx; /* X25519 Pms Callback Context */ #endif + #ifdef HAVE_ED448 + void* Ed448SignCtx; /* ED448 Sign Callback Context */ + void* Ed448VerifyCtx; /* ED448 Verify Callback Context */ + #endif + #ifdef HAVE_CURVE448 + void* X448KeyGenCtx; /* X448 KeyGen Callback Context */ + void* X448SharedSecretCtx; /* X448 Pms Callback Context */ + #endif #endif /* HAVE_ECC */ #ifndef NO_DH void* DhAgreeCtx; /* DH Pms Callback Context */ @@ -4346,6 +4401,14 @@ WOLFSSL_LOCAL int wolfSSL_GetMaxRecordSize(WOLFSSL* ssl, int maxFragment); word32 inSz, const byte* msg, word32 msgSz, ed25519_key* key, buffer* keyBufInfo); #endif /* HAVE_ED25519 */ + #ifdef HAVE_ED448 + WOLFSSL_LOCAL int Ed448CheckPubKey(WOLFSSL* ssl); + WOLFSSL_LOCAL int Ed448Sign(WOLFSSL* ssl, const byte* in, word32 inSz, + byte* out, word32* outSz, ed448_key* key, DerBuffer* keyBufInfo); + WOLFSSL_LOCAL int Ed448Verify(WOLFSSL* ssl, const byte* in, + word32 inSz, const byte* msg, word32 msgSz, ed448_key* key, + buffer* keyBufInfo); + #endif /* HAVE_ED448 */ #ifdef WOLFSSL_TRUST_PEER_CERT diff --git a/wolfssl/openssl/ec448.h b/wolfssl/openssl/ec448.h new file mode 100644 index 000000000..fb3b9005d --- /dev/null +++ b/wolfssl/openssl/ec448.h @@ -0,0 +1,44 @@ +/* ec448.h + * + * 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 + */ + +/* ec448.h */ + +#ifndef WOLFSSL_EC448_H_ +#define WOLFSSL_EC448_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +WOLFSSL_API +int wolfSSL_EC448_generate_key(unsigned char *priv, unsigned int *privSz, + unsigned char *pub, unsigned int *pubSz); + +WOLFSSL_API +int wolfSSL_EC448_shared_key(unsigned char *shared, unsigned int *sharedSz, + const unsigned char *priv, unsigned int privSz, + const unsigned char *pub, unsigned int pubSz); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* header */ diff --git a/wolfssl/openssl/ed448.h b/wolfssl/openssl/ed448.h new file mode 100644 index 000000000..b9411e92c --- /dev/null +++ b/wolfssl/openssl/ed448.h @@ -0,0 +1,47 @@ +/* ed448.h + * + * 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 + */ + +/* ed448.h */ + +#ifndef WOLFSSL_ED448_H_ +#define WOLFSSL_ED448_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +WOLFSSL_API +int wolfSSL_ED448_generate_key(unsigned char *priv, unsigned int *privSz, + unsigned char *pub, unsigned int *pubSz); +WOLFSSL_API +int wolfSSL_ED448_sign(const unsigned char *msg, unsigned int msgSz, + const unsigned char *priv, unsigned int privSz, + unsigned char *sig, unsigned int *sigSz); +WOLFSSL_API +int wolfSSL_ED448_verify(const unsigned char *msg, unsigned int msgSz, + const unsigned char *pub, unsigned int pubSz, + const unsigned char *sig, unsigned int sigSz); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* header */ diff --git a/wolfssl/openssl/include.am b/wolfssl/openssl/include.am index 3b77bcc08..2444a6865 100644 --- a/wolfssl/openssl/include.am +++ b/wolfssl/openssl/include.am @@ -17,6 +17,8 @@ nobase_include_HEADERS+= \ wolfssl/openssl/ec.h \ wolfssl/openssl/ec25519.h \ wolfssl/openssl/ed25519.h \ + wolfssl/openssl/ec448.h \ + wolfssl/openssl/ed448.h \ wolfssl/openssl/engine.h \ wolfssl/openssl/err.h \ wolfssl/openssl/evp.h \ diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 42fdb6ea8..6397fa177 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -2567,6 +2567,50 @@ WOLFSSL_API void wolfSSL_SetX25519SharedSecretCtx(WOLFSSL* ssl, void *ctx); WOLFSSL_API void* wolfSSL_GetX25519SharedSecretCtx(WOLFSSL* ssl); #endif +#ifdef HAVE_ED448 +struct ed448_key; +typedef int (*CallbackEd448Sign)(WOLFSSL* ssl, + const unsigned char* in, unsigned int inSz, + unsigned char* out, unsigned int* outSz, + const unsigned char* keyDer, unsigned int keySz, + void* ctx); +WOLFSSL_API void wolfSSL_CTX_SetEd448SignCb(WOLFSSL_CTX*, + CallbackEd448Sign); +WOLFSSL_API void wolfSSL_SetEd448SignCtx(WOLFSSL* ssl, void *ctx); +WOLFSSL_API void* wolfSSL_GetEd448SignCtx(WOLFSSL* ssl); + +typedef int (*CallbackEd448Verify)(WOLFSSL* ssl, + const unsigned char* sig, unsigned int sigSz, + const unsigned char* msg, unsigned int msgSz, + const unsigned char* keyDer, unsigned int keySz, + int* result, void* ctx); +WOLFSSL_API void wolfSSL_CTX_SetEd448VerifyCb(WOLFSSL_CTX*, + CallbackEd448Verify); +WOLFSSL_API void wolfSSL_SetEd448VerifyCtx(WOLFSSL* ssl, void *ctx); +WOLFSSL_API void* wolfSSL_GetEd448VerifyCtx(WOLFSSL* ssl); +#endif + +#ifdef HAVE_CURVE448 +struct curve448_key; + +typedef int (*CallbackX448KeyGen)(WOLFSSL* ssl, struct curve448_key* key, + unsigned int keySz, void* ctx); +WOLFSSL_API void wolfSSL_CTX_SetX448KeyGenCb(WOLFSSL_CTX*, CallbackX448KeyGen); +WOLFSSL_API void wolfSSL_SetX448KeyGenCtx(WOLFSSL* ssl, void *ctx); +WOLFSSL_API void* wolfSSL_GetX448KeyGenCtx(WOLFSSL* ssl); + +typedef int (*CallbackX448SharedSecret)(WOLFSSL* ssl, + struct curve448_key* otherKey, + unsigned char* pubKeyDer, unsigned int* pubKeySz, + unsigned char* out, unsigned int* outlen, + int side, void* ctx); + /* side is WOLFSSL_CLIENT_END or WOLFSSL_SERVER_END */ +WOLFSSL_API void wolfSSL_CTX_SetX448SharedSecretCb(WOLFSSL_CTX*, + CallbackX448SharedSecret); +WOLFSSL_API void wolfSSL_SetX448SharedSecretCtx(WOLFSSL* ssl, void *ctx); +WOLFSSL_API void* wolfSSL_GetX448SharedSecretCtx(WOLFSSL* ssl); +#endif + #ifndef NO_RSA typedef int (*CallbackRsaSign)(WOLFSSL* ssl, const unsigned char* in, unsigned int inSz, @@ -2975,7 +3019,6 @@ enum { WOLFSSL_ECC_BRAINPOOLP384R1 = 27, WOLFSSL_ECC_BRAINPOOLP512R1 = 28, WOLFSSL_ECC_X25519 = 29, - /* Not implemented. */ WOLFSSL_ECC_X448 = 30, WOLFSSL_FFDHE_2048 = 256, diff --git a/wolfssl/test.h b/wolfssl/test.h index b669f4359..e521c3a11 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -38,6 +38,12 @@ #ifdef HAVE_CURVE25519 #include #endif /* HAVE_ECC */ + #ifdef HAVE_ED448 + #include + #endif /* HAVE_ED448 */ + #ifdef HAVE_CURVE448 + #include + #endif /* HAVE_ECC */ #endif /*HAVE_PK_CALLBACKS */ #ifdef USE_WINDOWS_API @@ -290,60 +296,70 @@ /* all certs relative to wolfSSL home directory now */ #if defined(WOLFSSL_NO_CURRDIR) || defined(WOLFSSL_MDK_SHELL) -#define caCertFile "certs/ca-cert.pem" -#define eccCertFile "certs/server-ecc.pem" -#define eccKeyFile "certs/ecc-key.pem" -#define eccRsaCertFile "certs/server-ecc-rsa.pem" -#define svrCertFile "certs/server-cert.pem" -#define svrKeyFile "certs/server-key.pem" -#define cliCertFile "certs/client-cert.pem" -#define cliCertDerFile "certs/client-cert.der" -#define cliCertFileExt "certs/client-cert-ext.pem" +#define caCertFile "certs/ca-cert.pem" +#define eccCertFile "certs/server-ecc.pem" +#define eccKeyFile "certs/ecc-key.pem" +#define eccRsaCertFile "certs/server-ecc-rsa.pem" +#define svrCertFile "certs/server-cert.pem" +#define svrKeyFile "certs/server-key.pem" +#define cliCertFile "certs/client-cert.pem" +#define cliCertDerFile "certs/client-cert.der" +#define cliCertFileExt "certs/client-cert-ext.pem" #define cliCertDerFileExt "certs/client-cert-ext.der" -#define cliKeyFile "certs/client-key.pem" -#define ntruCertFile "certs/ntru-cert.pem" -#define ntruKeyFile "certs/ntru-key.raw" -#define dhParamFile "certs/dh2048.pem" -#define cliEccKeyFile "certs/ecc-client-key.pem" -#define cliEccCertFile "certs/client-ecc-cert.pem" -#define caEccCertFile "certs/ca-ecc-cert.pem" -#define crlPemDir "certs/crl" -#define edCertFile "certs/ed25519/server-ed25519-cert.pem" -#define edKeyFile "certs/ed25519/server-ed25519-priv.pem" -#define cliEdCertFile "certs/ed25519/client-ed25519.pem" -#define cliEdKeyFile "certs/ed25519/client-ed25519-priv.pem" -#define caEdCertFile "certs/ed25519/ca-ed25519.pem" +#define cliKeyFile "certs/client-key.pem" +#define ntruCertFile "certs/ntru-cert.pem" +#define ntruKeyFile "certs/ntru-key.raw" +#define dhParamFile "certs/dh2048.pem" +#define cliEccKeyFile "certs/ecc-client-key.pem" +#define cliEccCertFile "certs/client-ecc-cert.pem" +#define caEccCertFile "certs/ca-ecc-cert.pem" +#define crlPemDir "certs/crl" +#define edCertFile "certs/ed25519/server-ed25519-cert.pem" +#define edKeyFile "certs/ed25519/server-ed25519-priv.pem" +#define cliEdCertFile "certs/ed25519/client-ed25519.pem" +#define cliEdKeyFile "certs/ed25519/client-ed25519-priv.pem" +#define caEdCertFile "certs/ed25519/ca-ed25519.pem" +#define ed448CertFile "certs/ed448/server-ed448-cert.pem" +#define ed448KeyFile "certs/ed448/server-ed448-priv.pem" +#define cliEd448CertFile "certs/ed448/client-ed448.pem" +#define cliEd448KeyFile "certs/ed448/client-ed448-priv.pem" +#define caEd448CertFile "certs/ed448/ca-ed448.pem" #ifdef HAVE_WNR /* Whitewood netRandom default config file */ - #define wnrConfig "wnr-example.conf" + #define wnrConfig "wnr-example.conf" #endif #else -#define caCertFile "./certs/ca-cert.pem" -#define eccCertFile "./certs/server-ecc.pem" -#define eccKeyFile "./certs/ecc-key.pem" -#define eccRsaCertFile "./certs/server-ecc-rsa.pem" -#define svrCertFile "./certs/server-cert.pem" -#define svrKeyFile "./certs/server-key.pem" -#define cliCertFile "./certs/client-cert.pem" -#define cliCertDerFile "./certs/client-cert.der" -#define cliCertFileExt "./certs/client-cert-ext.pem" +#define caCertFile "./certs/ca-cert.pem" +#define eccCertFile "./certs/server-ecc.pem" +#define eccKeyFile "./certs/ecc-key.pem" +#define eccRsaCertFile "./certs/server-ecc-rsa.pem" +#define svrCertFile "./certs/server-cert.pem" +#define svrKeyFile "./certs/server-key.pem" +#define cliCertFile "./certs/client-cert.pem" +#define cliCertDerFile "./certs/client-cert.der" +#define cliCertFileExt "./certs/client-cert-ext.pem" #define cliCertDerFileExt "./certs/client-cert-ext.der" -#define cliKeyFile "./certs/client-key.pem" -#define ntruCertFile "./certs/ntru-cert.pem" -#define ntruKeyFile "./certs/ntru-key.raw" -#define dhParamFile "./certs/dh2048.pem" -#define cliEccKeyFile "./certs/ecc-client-key.pem" -#define cliEccCertFile "./certs/client-ecc-cert.pem" -#define caEccCertFile "./certs/ca-ecc-cert.pem" -#define crlPemDir "./certs/crl" -#define edCertFile "./certs/ed25519/server-ed25519-cert.pem" -#define edKeyFile "./certs/ed25519/server-ed25519-priv.pem" -#define cliEdCertFile "./certs/ed25519/client-ed25519.pem" -#define cliEdKeyFile "./certs/ed25519/client-ed25519-priv.pem" -#define caEdCertFile "./certs/ed25519/ca-ed25519.pem" +#define cliKeyFile "./certs/client-key.pem" +#define ntruCertFile "./certs/ntru-cert.pem" +#define ntruKeyFile "./certs/ntru-key.raw" +#define dhParamFile "./certs/dh2048.pem" +#define cliEccKeyFile "./certs/ecc-client-key.pem" +#define cliEccCertFile "./certs/client-ecc-cert.pem" +#define caEccCertFile "./certs/ca-ecc-cert.pem" +#define crlPemDir "./certs/crl" +#define edCertFile "./certs/ed25519/server-ed25519-cert.pem" +#define edKeyFile "./certs/ed25519/server-ed25519-priv.pem" +#define cliEdCertFile "./certs/ed25519/client-ed25519.pem" +#define cliEdKeyFile "./certs/ed25519/client-ed25519-priv.pem" +#define caEdCertFile "./certs/ed25519/ca-ed25519.pem" +#define ed448CertFile "./certs/ed448/server-ed448-cert.pem" +#define ed448KeyFile "./certs/ed448/server-ed448-priv.pem" +#define cliEd448CertFile "./certs/ed448/client-ed448.pem" +#define cliEd448KeyFile "./certs/ed448/client-ed448-priv.pem" +#define caEd448CertFile "./certs/ed448/ca-ed448.pem" #ifdef HAVE_WNR /* Whitewood netRandom default config file */ - #define wnrConfig "./wnr-example.conf" + #define wnrConfig "./wnr-example.conf" #endif #endif @@ -714,7 +730,8 @@ static WC_INLINE void showPeerEx(WOLFSSL* ssl, int lng_index) WOLFSSL_CIPHER* cipher; const char** words = client_showpeer_msg[lng_index]; -#if defined(HAVE_ECC) || !defined(NO_DH) +#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) || \ + !defined(NO_DH) const char *name; #endif #ifndef NO_DH @@ -742,7 +759,8 @@ static WC_INLINE void showPeerEx(WOLFSSL* ssl, int lng_index) #else printf("%s %s\n", words[1], wolfSSL_CIPHER_get_name(cipher)); #endif -#if defined(HAVE_ECC) || !defined(NO_DH) +#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) || \ + !defined(NO_DH) if ((name = wolfSSL_get_curve_name(ssl)) != NULL) printf("%s %s\n", words[2], name); #endif @@ -1927,7 +1945,7 @@ static WC_INLINE int StackSizeCheck(func_args* args, thread_func tf) int ret, i, used; void* status; unsigned char* myStack = NULL; - int stackSize = 1024*128; + int stackSize = 1024*152; pthread_attr_t myAttr; pthread_t threadId; @@ -2441,6 +2459,9 @@ typedef struct PkCbInfo { #ifdef HAVE_CURVE25519 curve25519_key curve; #endif + #ifdef HAVE_CURVE448 + curve448_key curve; + #endif } keyGen; #endif } PkCbInfo; @@ -2820,6 +2841,167 @@ static WC_INLINE int myX25519SharedSecret(WOLFSSL* ssl, curve25519_key* otherKey } #endif /* HAVE_CURVE25519 */ +#ifdef HAVE_ED448 +static WC_INLINE int myEd448Sign(WOLFSSL* ssl, const byte* in, word32 inSz, + byte* out, word32* outSz, const byte* key, word32 keySz, void* ctx) +{ + int ret; + word32 idx = 0; + ed448_key myKey; + byte* keyBuf = (byte*)key; + PkCbInfo* cbInfo = (PkCbInfo*)ctx; + + (void)ssl; + (void)cbInfo; + + WOLFSSL_PKMSG("PK 448 Sign: inSz %d, keySz %d\n", inSz, keySz); + +#ifdef TEST_PK_PRIVKEY + ret = load_key_file(cbInfo->ourKey, &keyBuf, &keySz); + if (ret != 0) + return ret; +#endif + + ret = wc_ed448_init(&myKey); + if (ret == 0) { + ret = wc_Ed448PrivateKeyDecode(keyBuf, &idx, &myKey, keySz); + if (ret == 0) + ret = wc_ed448_sign_msg(in, inSz, out, outSz, &myKey); + wc_ed448_free(&myKey); + } + +#ifdef TEST_PK_PRIVKEY + free(keyBuf); +#endif + + WOLFSSL_PKMSG("PK 448 Sign: ret %d, outSz %d\n", ret, *outSz); + + return ret; +} + + +static WC_INLINE int myEd448Verify(WOLFSSL* ssl, const byte* sig, word32 sigSz, + const byte* msg, word32 msgSz, const byte* key, word32 keySz, + int* result, void* ctx) +{ + int ret; + ed448_key myKey; + PkCbInfo* cbInfo = (PkCbInfo*)ctx; + + (void)ssl; + (void)cbInfo; + + WOLFSSL_PKMSG("PK 448 Verify: sigSz %d, msgSz %d, keySz %d\n", sigSz, msgSz, + keySz); + + ret = wc_ed448_init(&myKey); + if (ret == 0) { + ret = wc_ed448_import_public(key, keySz, &myKey); + if (ret == 0) { + ret = wc_ed448_verify_msg(sig, sigSz, msg, msgSz, result, &myKey); + } + wc_ed448_free(&myKey); + } + + WOLFSSL_PKMSG("PK 448 Verify: ret %d, result %d\n", ret, *result); + + return ret; +} +#endif /* HAVE_ED448 */ + +#ifdef HAVE_CURVE448 +static WC_INLINE int myX448KeyGen(WOLFSSL* ssl, curve448_key* key, + unsigned int keySz, void* ctx) +{ + int ret; + WC_RNG rng; + PkCbInfo* cbInfo = (PkCbInfo*)ctx; + + (void)ssl; + (void)cbInfo; + + WOLFSSL_PKMSG("PK 448 KeyGen: keySz %d\n", keySz); + + ret = wc_InitRng(&rng); + if (ret != 0) + return ret; + + ret = wc_curve448_make_key(&rng, keySz, key); + + wc_FreeRng(&rng); + + WOLFSSL_PKMSG("PK 448 KeyGen: ret %d\n", ret); + + return ret; +} + +static WC_INLINE int myX448SharedSecret(WOLFSSL* ssl, curve448_key* otherKey, + unsigned char* pubKeyDer, unsigned int* pubKeySz, + unsigned char* out, unsigned int* outlen, + int side, void* ctx) +{ + int ret; + curve448_key* privKey = NULL; + curve448_key* pubKey = NULL; + curve448_key tmpKey; + PkCbInfo* cbInfo = (PkCbInfo*)ctx; + + (void)ssl; + (void)cbInfo; + + WOLFSSL_PKMSG("PK 448 PMS: side %s\n", + side == WOLFSSL_CLIENT_END ? "client" : "server"); + + ret = wc_curve448_init(&tmpKey); + if (ret != 0) { + return ret; + } + + /* for client: create and export public key */ + if (side == WOLFSSL_CLIENT_END) { + WC_RNG rng; + + privKey = &tmpKey; + pubKey = otherKey; + + ret = wc_InitRng(&rng); + if (ret == 0) { + ret = wc_curve448_make_key(&rng, CURVE448_KEY_SIZE, privKey); + if (ret == 0) { + ret = wc_curve448_export_public_ex(privKey, pubKeyDer, + pubKeySz, EC448_LITTLE_ENDIAN); + } + wc_FreeRng(&rng); + } + } + + /* for server: import public key */ + else if (side == WOLFSSL_SERVER_END) { + privKey = otherKey; + pubKey = &tmpKey; + + ret = wc_curve448_import_public_ex(pubKeyDer, *pubKeySz, pubKey, + EC448_LITTLE_ENDIAN); + } + else { + ret = BAD_FUNC_ARG; + } + + /* generate shared secret and return it */ + if (ret == 0) { + ret = wc_curve448_shared_secret_ex(privKey, pubKey, out, outlen, + EC448_LITTLE_ENDIAN); + } + + wc_curve448_free(&tmpKey); + + WOLFSSL_PKMSG("PK 448 PMS: ret %d, pubKeySz %d, outLen %d\n", + ret, *pubKeySz, *outlen); + + return ret; +} +#endif /* HAVE_CURVE448 */ + #endif /* HAVE_ECC */ #ifndef NO_DH @@ -3246,6 +3428,14 @@ static WC_INLINE void SetupPkCallbacks(WOLFSSL_CTX* ctx) wolfSSL_CTX_SetX25519KeyGenCb(ctx, myX25519KeyGen); wolfSSL_CTX_SetX25519SharedSecretCb(ctx, myX25519SharedSecret); #endif + #ifdef HAVE_ED448 + wolfSSL_CTX_SetEd448SignCb(ctx, myEd448Sign); + wolfSSL_CTX_SetEd448VerifyCb(ctx, myEd448Verify); + #endif + #ifdef HAVE_CURVE448 + wolfSSL_CTX_SetX448KeyGenCb(ctx, myX448KeyGen); + wolfSSL_CTX_SetX448SharedSecretCb(ctx, myX448SharedSecret); + #endif #ifndef NO_RSA wolfSSL_CTX_SetRsaSignCb(ctx, myRsaSign); wolfSSL_CTX_SetRsaVerifyCb(ctx, myRsaVerify); @@ -3279,6 +3469,14 @@ static WC_INLINE void SetupPkCallbackContexts(WOLFSSL* ssl, void* myCtx) wolfSSL_SetX25519KeyGenCtx(ssl, myCtx); wolfSSL_SetX25519SharedSecretCtx(ssl, myCtx); #endif + #ifdef HAVE_ED448 + wolfSSL_SetEd448SignCtx(ssl, myCtx); + wolfSSL_SetEd448VerifyCtx(ssl, myCtx); + #endif + #ifdef HAVE_CURVE448 + wolfSSL_SetX448KeyGenCtx(ssl, myCtx); + wolfSSL_SetX448SharedSecretCtx(ssl, myCtx); + #endif #ifndef NO_RSA wolfSSL_SetRsaSignCtx(ssl, myCtx); wolfSSL_SetRsaVerifyCtx(ssl, myCtx); diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 29cd9d703..bef803dd3 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -283,6 +283,8 @@ enum Misc_ASN { MAX_ENCODED_SIG_SZ = 512, #elif defined(HAVE_ECC) MAX_ENCODED_SIG_SZ = 140, +#elif defined(HAVE_CURVE448) + MAX_ENCODED_SIG_SZ = 114, #else MAX_ENCODED_SIG_SZ = 64, #endif @@ -435,6 +437,7 @@ enum Key_Sum { NTRUk = 274, ECDSAk = 518, ED25519k = 256, + ED448k = 257, DHk = 647, /* dhKeyAgreement OID: 1.2.840.113549.1.3.1 */ }; @@ -679,7 +682,7 @@ struct SignatureCtx { byte* out; byte* plain; #endif -#if defined(HAVE_ECC) || defined(HAVE_ED25519) +#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) int verify; #endif union { @@ -691,6 +694,9 @@ struct SignatureCtx { #endif #ifdef HAVE_ED25519 struct ed25519_key* ed25519; + #endif + #ifdef HAVE_ED448 + struct ed448_key* ed448; #endif void* ptr; } key; @@ -833,7 +839,7 @@ struct DecodedCert { word32 extSubjKeyIdSz; #endif -#if defined(HAVE_ECC) || defined(HAVE_ED25519) +#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448) word32 pkCurveOID; /* Public Key's curve OID */ #endif /* HAVE_ECC */ const byte* beforeDate; @@ -1207,7 +1213,8 @@ enum cert_enums { RSA_KEY = 10, NTRU_KEY = 11, ECC_KEY = 12, - ED25519_KEY = 13 + ED25519_KEY = 13, + ED448_KEY = 14 }; #endif /* WOLFSSL_CERT_GEN */ diff --git a/wolfssl/wolfcrypt/asn_public.h b/wolfssl/wolfcrypt/asn_public.h index 77dc38012..393780036 100644 --- a/wolfssl/wolfcrypt/asn_public.h +++ b/wolfssl/wolfcrypt/asn_public.h @@ -41,6 +41,10 @@ typedef struct ed25519_key ed25519_key; #define WC_ED25519KEY_TYPE_DEFINED #endif +#ifndef WC_ED448KEY_TYPE_DEFINED + typedef struct ed448_key ed448_key; + #define WC_ED448KEY_TYPE_DEFINED +#endif #ifndef WC_RSAKEY_TYPE_DEFINED typedef struct RsaKey RsaKey; #define WC_RSAKEY_TYPE_DEFINED @@ -76,6 +80,8 @@ enum Ecc_Sum { ECC_X25519_OID = 365, ECC_ED25519_OID = 256, ECC_BRAINPOOLP320R1_OID = 106, + ECC_X448_OID = 362, + ECC_ED448_OID = 257, ECC_SECP384R1_OID = 210, ECC_BRAINPOOLP384R1_OID = 108, ECC_BRAINPOOLP512R1_OID = 110, @@ -103,6 +109,7 @@ enum CertType { TRUSTED_PEER_TYPE, EDDSA_PRIVATEKEY_TYPE, ED25519_TYPE, + ED448_TYPE, PKCS12_TYPE, PKCS8_PRIVATEKEY_TYPE, PKCS8_ENC_PRIVATEKEY_TYPE, @@ -126,7 +133,8 @@ enum Ctc_SigType { CTC_SHA384wECDSA = 525, CTC_SHA512wRSA = 657, CTC_SHA512wECDSA = 526, - CTC_ED25519 = 256 + CTC_ED25519 = 256, + CTC_ED448 = 257 }; enum Ctc_Encoding { @@ -528,6 +536,24 @@ WOLFSSL_API void wc_FreeDer(DerBuffer** pDer); #endif #endif +#ifdef HAVE_ED448 + /* private key helpers */ + WOLFSSL_API int wc_Ed448PrivateKeyDecode(const byte*, word32*, + ed448_key*, word32); + WOLFSSL_API int wc_Ed448KeyToDer(ed448_key* key, byte* output, + word32 inLen); + WOLFSSL_API int wc_Ed448PrivateKeyToDer(ed448_key* key, byte* output, + word32 inLen); + + /* public key helper */ + WOLFSSL_API int wc_Ed448PublicKeyDecode(const byte*, word32*, + ed448_key*, word32); + #if (defined(WOLFSSL_CERT_GEN) || defined(WOLFSSL_KEY_GEN)) + WOLFSSL_API int wc_Ed448PublicKeyToDer(ed448_key*, byte* output, + word32 inLen, int with_AlgCurve); + #endif +#endif + /* DER encode signature */ WOLFSSL_API word32 wc_EncodeSignature(byte* out, const byte* digest, word32 digSz, int hashOID); diff --git a/wolfssl/wolfcrypt/curve448.h b/wolfssl/wolfcrypt/curve448.h new file mode 100644 index 000000000..6a9c495e2 --- /dev/null +++ b/wolfssl/wolfcrypt/curve448.h @@ -0,0 +1,139 @@ +/* curve448.h + * + * 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 + */ + +/* Implemented to: RFC 7748 */ + + +#ifndef WOLF_CRYPT_CURVE448_H +#define WOLF_CRYPT_CURVE448_H + +#include + +#ifdef HAVE_CURVE448 + +#include +#include + +#ifdef WOLFSSL_ASYNC_CRYPT + #include +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +#define CURVE448_KEY_SIZE 56 +#define CURVE448_PUB_KEY_SIZE 56 + + +/* A CURVE448 Key */ +typedef struct curve448_key { + byte p[CURVE448_PUB_KEY_SIZE]; /* public key */ + byte k[CURVE448_KEY_SIZE]; /* private key */ + +#ifdef WOLFSSL_ASYNC_CRYPT + WC_ASYNC_DEV asyncDev; +#endif +} curve448_key; + +enum { + EC448_LITTLE_ENDIAN = 0, + EC448_BIG_ENDIAN = 1 +}; + +WOLFSSL_API +int wc_curve448_make_key(WC_RNG* rng, int keysize, curve448_key* key); + +WOLFSSL_API +int wc_curve448_shared_secret(curve448_key* private_key, + curve448_key* public_key, + byte* out, word32* outlen); + +WOLFSSL_API +int wc_curve448_shared_secret_ex(curve448_key* private_key, + curve448_key* public_key, + byte* out, word32* outlen, int endian); + +WOLFSSL_API +int wc_curve448_init(curve448_key* key); + +WOLFSSL_API +void wc_curve448_free(curve448_key* key); + + +/* raw key helpers */ +WOLFSSL_API +int wc_curve448_import_private(const byte* priv, word32 privSz, + curve448_key* key); +WOLFSSL_API +int wc_curve448_import_private_ex(const byte* priv, word32 privSz, + curve448_key* key, int endian); + +WOLFSSL_API +int wc_curve448_import_private_raw(const byte* priv, word32 privSz, + const byte* pub, word32 pubSz, + curve448_key* key); +WOLFSSL_API +int wc_curve448_import_private_raw_ex(const byte* priv, word32 privSz, + const byte* pub, word32 pubSz, + curve448_key* key, int endian); +WOLFSSL_API +int wc_curve448_export_private_raw(curve448_key* key, byte* out, + word32* outLen); +WOLFSSL_API +int wc_curve448_export_private_raw_ex(curve448_key* key, byte* out, + word32* outLen, int endian); + +WOLFSSL_API +int wc_curve448_import_public(const byte* in, word32 inLen, + curve448_key* key); +WOLFSSL_API +int wc_curve448_import_public_ex(const byte* in, word32 inLen, + curve448_key* key, int endian); +WOLFSSL_API +int wc_curve448_check_public(const byte* pub, word32 pubSz, int endian); + +WOLFSSL_API +int wc_curve448_export_public(curve448_key* key, byte* out, word32* outLen); +WOLFSSL_API +int wc_curve448_export_public_ex(curve448_key* key, byte* out, + word32* outLen, int endian); + +WOLFSSL_API +int wc_curve448_export_key_raw(curve448_key* key, + byte* priv, word32 *privSz, + byte* pub, word32 *pubSz); +WOLFSSL_API +int wc_curve448_export_key_raw_ex(curve448_key* key, + byte* priv, word32 *privSz, + byte* pub, word32 *pubSz, + int endian); +/* size helper */ +WOLFSSL_API +int wc_curve448_size(curve448_key* key); + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* HAVE_CURVE448 */ +#endif /* WOLF_CRYPT_CURVE448_H */ + diff --git a/wolfssl/wolfcrypt/ecc.h b/wolfssl/wolfcrypt/ecc.h index f15ba9746..8741a6d6a 100644 --- a/wolfssl/wolfcrypt/ecc.h +++ b/wolfssl/wolfcrypt/ecc.h @@ -196,7 +196,7 @@ typedef enum ecc_curve_id { #ifdef HAVE_CURVE25519 ECC_X25519, #endif -#ifdef HAVE_X448 +#ifdef HAVE_CURVE448 ECC_X448, #endif diff --git a/wolfssl/wolfcrypt/ed448.h b/wolfssl/wolfcrypt/ed448.h new file mode 100644 index 000000000..4f868b53d --- /dev/null +++ b/wolfssl/wolfcrypt/ed448.h @@ -0,0 +1,160 @@ +/* ed448.h + * + * 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 + */ + +/*! + \file wolfssl/wolfcrypt/ed448.h +*/ + + +#ifndef WOLF_CRYPT_ED448_H +#define WOLF_CRYPT_ED448_H + +#include + +#ifdef HAVE_ED448 + +#include +#include +#include +#include + +#ifdef WOLFSSL_ASYNC_CRYPT + #include +#endif + +#ifdef __cplusplus + extern "C" { +#endif + + +/* info about EdDSA curve specifically ed448, defined as an elliptic curve + * over GF(p) + * + * 56 key size + * "ED448" curve name + * "2^448-2^224-1" prime number + * "-39081" value of d + * "SHAKE256" hash function + */ + +#define ED448_KEY_SIZE 57 /* private key only */ +#define ED448_SIG_SIZE 114 /* two elements */ + +#define ED448_PUB_KEY_SIZE 57 /* compressed */ +/* both private and public key */ +#define ED448_PRV_KEY_SIZE (ED448_PUB_KEY_SIZE+ED448_KEY_SIZE) + + +enum { + Ed448 = 0, + Ed448ph = 1, +}; + +#ifndef WC_ED448KEY_TYPE_DEFINED + typedef struct ed448_key ed448_key; + #define WC_ED448KEY_TYPE_DEFINED +#endif + +/* An ED448 Key */ +struct ed448_key { + byte p[ED448_PUB_KEY_SIZE]; /* compressed public key */ + byte k[ED448_PRV_KEY_SIZE]; /* private key : 56 secret -- 56 public */ +#ifdef FREESCALE_LTC_ECC + /* uncompressed point coordinates */ + byte pointX[ED448_KEY_SIZE]; /* recovered X coordinate */ + byte pointY[ED448_KEY_SIZE]; /* Y coordinate is the public key with The most significant bit of the final octet always zero. */ +#endif + word16 pubKeySet:1; +#ifdef WOLFSSL_ASYNC_CRYPT + WC_ASYNC_DEV asyncDev; +#endif +}; + + +WOLFSSL_API +int wc_ed448_make_public(ed448_key* key, unsigned char* pubKey, + word32 pubKeySz); +WOLFSSL_API +int wc_ed448_make_key(WC_RNG* rng, int keysize, ed448_key* key); +WOLFSSL_API +int wc_ed448_sign_msg(const byte* in, word32 inLen, byte* out, word32 *outLen, + ed448_key* key, const byte* context, byte contextLen); +WOLFSSL_API +int wc_ed448ph_sign_hash(const byte* hash, word32 hashLen, byte* out, + word32 *outLen, ed448_key* key, + const byte* context, byte contextLen); +WOLFSSL_API +int wc_ed448ph_sign_msg(const byte* in, word32 inLen, byte* out, + word32 *outLen, ed448_key* key, const byte* context, + byte contextLen); +WOLFSSL_API +int wc_ed448_verify_msg(const byte* sig, word32 sigLen, const byte* msg, + word32 msgLen, int* stat, ed448_key* key, + const byte* context, byte contextLen); +WOLFSSL_API +int wc_ed448ph_verify_hash(const byte* sig, word32 sigLen, const byte* hash, + word32 hashLen, int* stat, ed448_key* key, + const byte* context, byte contextLen); +WOLFSSL_API +int wc_ed448ph_verify_msg(const byte* sig, word32 sigLen, const byte* msg, + word32 msgLen, int* stat, ed448_key* key, + const byte* context, byte contextLen); +WOLFSSL_API +int wc_ed448_init(ed448_key* key); +WOLFSSL_API +void wc_ed448_free(ed448_key* key); +WOLFSSL_API +int wc_ed448_import_public(const byte* in, word32 inLen, ed448_key* key); +WOLFSSL_API +int wc_ed448_import_private_only(const byte* priv, word32 privSz, + ed448_key* key); +WOLFSSL_API +int wc_ed448_import_private_key(const byte* priv, word32 privSz, + const byte* pub, word32 pubSz, ed448_key* key); +WOLFSSL_API +int wc_ed448_export_public(ed448_key*, byte* out, word32* outLen); +WOLFSSL_API +int wc_ed448_export_private_only(ed448_key* key, byte* out, word32* outLen); +WOLFSSL_API +int wc_ed448_export_private(ed448_key* key, byte* out, word32* outLen); +WOLFSSL_API +int wc_ed448_export_key(ed448_key* key, byte* priv, word32 *privSz, + byte* pub, word32 *pubSz); + +WOLFSSL_API +int wc_ed448_check_key(ed448_key* key); + +/* size helper */ +WOLFSSL_API +int wc_ed448_size(ed448_key* key); +WOLFSSL_API +int wc_ed448_priv_size(ed448_key* key); +WOLFSSL_API +int wc_ed448_pub_size(ed448_key* key); +WOLFSSL_API +int wc_ed448_sig_size(ed448_key* key); + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* HAVE_ED448 */ +#endif /* WOLF_CRYPT_ED448_H */ diff --git a/wolfssl/wolfcrypt/fe_448.h b/wolfssl/wolfcrypt/fe_448.h new file mode 100644 index 000000000..6bcd87d29 --- /dev/null +++ b/wolfssl/wolfcrypt/fe_448.h @@ -0,0 +1,116 @@ +/* fe448_448.h + * + * 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 + */ + + +#ifndef WOLF_CRYPT_FE_448_H +#define WOLF_CRYPT_FE_448_H + +#include + +#if defined(HAVE_CURVE448) || defined(HAVE_ED448) + +#include + +#include + +#if defined(HAVE___UINT128_T) && !defined(NO_CURVED448_128BIT) + #define CURVED448_128BIT +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +/* default to be faster but take more memory */ +#if !defined(CURVE448_SMALL) || !defined(ED448_SMALL) + +#if defined(CURVED448_128BIT) + typedef int64_t fe448; + #ifdef __SIZEOF_INT128__ + typedef __uint128_t uint128_t; + typedef __int128_t int128_t; + #else + typedef unsigned long uint128_t __attribute__ ((mode(TI))); + typedef long int128_t __attribute__ ((mode(TI))); + #endif +#else + typedef int32_t fe448; +#endif + +WOLFSSL_LOCAL void fe448_init(void); +WOLFSSL_LOCAL int curve448(byte* r, const byte* n, const byte* a); + +#if !defined(CURVED448_128BIT) +WOLFSSL_LOCAL void fe448_reduce(fe448*); +#else +#define fe448_reduce(a) +#endif +WOLFSSL_LOCAL void fe448_neg(fe448*,const fe448*); +WOLFSSL_LOCAL void fe448_add(fe448*, const fe448*, const fe448*); +WOLFSSL_LOCAL void fe448_sub(fe448*, const fe448*, const fe448*); +WOLFSSL_LOCAL void fe448_mul(fe448*,const fe448*,const fe448*); +WOLFSSL_LOCAL void fe448_sqr(fe448*, const fe448*); +WOLFSSL_LOCAL void fe448_mul39081(fe448*, const fe448*); +WOLFSSL_LOCAL void fe448_invert(fe448*, const fe448*); + +WOLFSSL_LOCAL void fe448_0(fe448*); +WOLFSSL_LOCAL void fe448_1(fe448*); +WOLFSSL_LOCAL void fe448_copy(fe448*, const fe448*); +WOLFSSL_LOCAL int fe448_isnonzero(const fe448*); +WOLFSSL_LOCAL int fe448_isnegative(const fe448*); + +WOLFSSL_LOCAL void fe448_from_bytes(fe448*,const unsigned char *); +WOLFSSL_LOCAL void fe448_to_bytes(unsigned char *, const fe448*); + +WOLFSSL_LOCAL void fe448_cmov(fe448*,const fe448*, int); +WOLFSSL_LOCAL void fe448_pow_2_446_222_1(fe448*,const fe448*); + +#else + +WOLFSSL_LOCAL void fe448_init(void); +WOLFSSL_LOCAL int curve448(byte* r, const byte* n, const byte* a); + +#define fe448_reduce(a) +WOLFSSL_LOCAL void fe448_neg(uint8_t*,const uint8_t*); +WOLFSSL_LOCAL void fe448_add(uint8_t*, const uint8_t*, const uint8_t*); +WOLFSSL_LOCAL void fe448_sub(uint8_t*, const uint8_t*, const uint8_t*); +WOLFSSL_LOCAL void fe448_mul(uint8_t*,const uint8_t*,const uint8_t*); +WOLFSSL_LOCAL void fe448_sqr(uint8_t*, const uint8_t*); +WOLFSSL_LOCAL void fe448_mul39081(uint8_t*, const uint8_t*); +WOLFSSL_LOCAL void fe448_invert(uint8_t*, const uint8_t*); + +WOLFSSL_LOCAL void fe448_copy(uint8_t*, const uint8_t*); +WOLFSSL_LOCAL int fe448_isnonzero(const uint8_t*); + +WOLFSSL_LOCAL void fe448_norm(byte *a); + +WOLFSSL_LOCAL void fe448_cmov(uint8_t*,const uint8_t*, int); +WOLFSSL_LOCAL void fe448_pow_2_446_222_1(uint8_t*,const uint8_t*); + +#endif /* !CURVE448_SMALL || !ED448_SMALL */ + +#ifdef __cplusplus + } /* extern "C" */ +#endif + +#endif /* HAVE_CURVE448 || HAVE_ED448 */ + +#endif /* WOLF_CRYPT_FE_448_H */ diff --git a/wolfssl/wolfcrypt/ge_448.h b/wolfssl/wolfcrypt/ge_448.h new file mode 100644 index 000000000..51cb02af6 --- /dev/null +++ b/wolfssl/wolfcrypt/ge_448.h @@ -0,0 +1,86 @@ +/* ge_448.h + * + * 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 + */ + + +#ifndef WOLF_CRYPT_GE_448_H +#define WOLF_CRYPT_GE_448_H + +#include + +#ifdef HAVE_ED448 + +#include + +/* +ge448 means group element. + +Here the group is the set of pairs (x,y) of field elements (see fe.h) +satisfying -x^2 + y^2 = 1 + d x^2y^2 +where d = -39081. + +Representations: + ge448_p2 (projective) : (X:Y:Z) satisfying x=X/Z, y=Y/Z + ge448_precomp (affine): (x,y) +*/ + +#ifdef ED448_SMALL + typedef byte ge448; + #define GE448_WORDS 56 +#elif defined(CURVED448_128BIT) + typedef int64_t ge448; + #define GE448_WORDS 8 +#else + typedef int32_t ge448; + #define GE448_WORDS 16 +#endif + +typedef struct { + ge448 X[GE448_WORDS]; + ge448 Y[GE448_WORDS]; + ge448 Z[GE448_WORDS]; +} ge448_p2; + + +WOLFSSL_LOCAL int ge448_compress_key(byte*, const byte*, const byte*); +WOLFSSL_LOCAL int ge448_from_bytes_negate_vartime(ge448_p2 *, + const unsigned char *); + +WOLFSSL_LOCAL int ge448_double_scalarmult_vartime(ge448_p2 *, + const unsigned char *, + const ge448_p2 *, + const unsigned char *); +WOLFSSL_LOCAL void ge448_scalarmult_base(ge448_p2 *, const unsigned char *); +WOLFSSL_LOCAL void sc448_reduce(byte*); +WOLFSSL_LOCAL void sc448_muladd(byte*, const byte*, const byte*, const byte*); +WOLFSSL_LOCAL void ge448_to_bytes(unsigned char *, const ge448_p2 *); + + +#ifndef ED448_SMALL +typedef struct { + ge448 x[GE448_WORDS]; + ge448 y[GE448_WORDS]; +} ge448_precomp; + +#endif /* !ED448_SMALL */ + +#endif /* HAVE_ED448 */ + +#endif /* WOLF_CRYPT_GE_448_H */ diff --git a/wolfssl/wolfcrypt/hash.h b/wolfssl/wolfcrypt/hash.h index 29c5c0bde..73222cab9 100644 --- a/wolfssl/wolfcrypt/hash.h +++ b/wolfssl/wolfcrypt/hash.h @@ -210,6 +210,9 @@ WOLFSSL_API int wc_Sha3_224Hash(const byte*, word32, byte*); WOLFSSL_API int wc_Sha3_256Hash(const byte*, word32, byte*); WOLFSSL_API int wc_Sha3_384Hash(const byte*, word32, byte*); WOLFSSL_API int wc_Sha3_512Hash(const byte*, word32, byte*); +#ifdef WOLFSSL_SHAKE256 +WOLFSSL_API int wc_Shake256Hash(const byte*, word32, byte*, word32); +#endif #endif /* WOLFSSL_SHA3 */ enum max_prf { diff --git a/wolfssl/wolfcrypt/include.am b/wolfssl/wolfcrypt/include.am index 56f5efe96..0df704636 100644 --- a/wolfssl/wolfcrypt/include.am +++ b/wolfssl/wolfcrypt/include.am @@ -19,6 +19,10 @@ nobase_include_HEADERS+= \ wolfssl/wolfcrypt/ed25519.h \ wolfssl/wolfcrypt/fe_operations.h \ wolfssl/wolfcrypt/ge_operations.h \ + wolfssl/wolfcrypt/curve448.h \ + wolfssl/wolfcrypt/ed448.h \ + wolfssl/wolfcrypt/fe_448.h \ + wolfssl/wolfcrypt/ge_448.h \ wolfssl/wolfcrypt/error-crypt.h \ wolfssl/wolfcrypt/fips_test.h \ wolfssl/wolfcrypt/hash.h \ diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index be71f3bcd..594e73f91 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -694,7 +694,7 @@ extern void uITRON4_free(void *p) ; #endif /* FreeRTOS pvPortRealloc() implementation can be found here: https://github.com/wolfSSL/wolfssl-freertos/pull/3/files */ - #if !defined(USE_FAST_MATH) || defined(HAVE_ED25519) + #if !defined(USE_FAST_MATH) || defined(HAVE_ED25519) || defined(HAVE_ED448) #if defined(WOLFSSL_ESPIDF) /*In IDF, realloc(p, n) is equivalent to heap_caps_realloc(p, s, MALLOC_CAP_8BIT) */ @@ -879,7 +879,7 @@ extern void uITRON4_free(void *p) ; #endif /* FreeRTOS pvPortRealloc() implementation can be found here: https://github.com/wolfSSL/wolfssl-freertos/pull/3/files */ - #if !defined(USE_FAST_MATH) || defined(HAVE_ED25519) + #if !defined(USE_FAST_MATH) || defined(HAVE_ED25519) || defined(HAVE_ED448) #define XREALLOC(p, n, h, t) pvPortRealloc((p), (n)) #endif #endif @@ -1674,7 +1674,7 @@ extern void uITRON4_free(void *p) ; #endif #endif /* HAVE_ECC */ -/* Curve255519 Configs */ +/* Curve25519 Configs */ #ifdef HAVE_CURVE25519 /* By default enable shared secret, key export and import */ #ifndef NO_CURVE25519_SHARED_SECRET @@ -1691,7 +1691,7 @@ extern void uITRON4_free(void *p) ; #endif #endif /* HAVE_CURVE25519 */ -/* Ed255519 Configs */ +/* Ed25519 Configs */ #ifdef HAVE_ED25519 /* By default enable sign, verify, key export and import */ #ifndef NO_ED25519_SIGN @@ -1712,6 +1712,44 @@ extern void uITRON4_free(void *p) ; #endif #endif /* HAVE_ED25519 */ +/* Curve448 Configs */ +#ifdef HAVE_CURVE448 + /* By default enable shared secret, key export and import */ + #ifndef NO_CURVE448_SHARED_SECRET + #undef HAVE_CURVE448_SHARED_SECRET + #define HAVE_CURVE448_SHARED_SECRET + #endif + #ifndef NO_CURVE448_KEY_EXPORT + #undef HAVE_CURVE448_KEY_EXPORT + #define HAVE_CURVE448_KEY_EXPORT + #endif + #ifndef NO_CURVE448_KEY_IMPORT + #undef HAVE_CURVE448_KEY_IMPORT + #define HAVE_CURVE448_KEY_IMPORT + #endif +#endif /* HAVE_CURVE448 */ + +/* Ed448 Configs */ +#ifdef HAVE_ED448 + /* By default enable sign, verify, key export and import */ + #ifndef NO_ED448_SIGN + #undef HAVE_ED448_SIGN + #define HAVE_ED448_SIGN + #endif + #ifndef NO_ED448_VERIFY + #undef HAVE_ED448_VERIFY + #define HAVE_ED448_VERIFY + #endif + #ifndef NO_ED448_KEY_EXPORT + #undef HAVE_ED448_KEY_EXPORT + #define HAVE_ED448_KEY_EXPORT + #endif + #ifndef NO_ED448_KEY_IMPORT + #undef HAVE_ED448_KEY_IMPORT + #define HAVE_ED448_KEY_IMPORT + #endif +#endif /* HAVE_ED448 */ + /* AES Config */ #ifndef NO_AES /* By default enable all AES key sizes, decryption and CBC */ @@ -1993,6 +2031,12 @@ extern void uITRON4_free(void *p) ; #define ED25519_SMALL #endif +/* both CURVE and ED small math should be enabled */ +#ifdef CURVED448_SMALL + #define CURVE448_SMALL + #define ED448_SMALL +#endif + #ifndef WOLFSSL_ALERT_COUNT_MAX #define WOLFSSL_ALERT_COUNT_MAX 5 @@ -2091,7 +2135,7 @@ extern void uITRON4_free(void *p) ; #endif #if defined(WOLFCRYPT_ONLY) && defined(NO_AES) && !defined(HAVE_CURVE25519) && \ - defined(WC_NO_RNG) && defined(WC_NO_RSA_OAEP) + !defined(HAVE_CURVE448) && defined(WC_NO_RNG) && defined(WC_NO_RSA_OAEP) #undef WOLFSSL_NO_CONST_CMP #define WOLFSSL_NO_CONST_CMP #endif diff --git a/wolfssl/wolfcrypt/sha3.h b/wolfssl/wolfcrypt/sha3.h index 1663fbc6f..47e2e2c9c 100644 --- a/wolfssl/wolfcrypt/sha3.h +++ b/wolfssl/wolfcrypt/sha3.h @@ -114,6 +114,8 @@ struct Sha3 { #endif +typedef wc_Sha3 wc_Shake; + WOLFSSL_API int wc_InitSha3_224(wc_Sha3*, void*, int); WOLFSSL_API int wc_Sha3_224_Update(wc_Sha3*, const byte*, word32); @@ -143,6 +145,12 @@ WOLFSSL_API void wc_Sha3_512_Free(wc_Sha3*); WOLFSSL_API int wc_Sha3_512_GetHash(wc_Sha3*, byte*); WOLFSSL_API int wc_Sha3_512_Copy(wc_Sha3* src, wc_Sha3* dst); +WOLFSSL_API int wc_InitShake256(wc_Shake*, void*, int); +WOLFSSL_API int wc_Shake256_Update(wc_Shake*, const byte*, word32); +WOLFSSL_API int wc_Shake256_Final(wc_Shake*, byte*, word32); +WOLFSSL_API void wc_Shake256_Free(wc_Shake*); +WOLFSSL_API int wc_Shake256_Copy(wc_Shake* src, wc_Sha3* dst); + #if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB) WOLFSSL_API int wc_Sha3_SetFlags(wc_Sha3* sha3, word32 flags); WOLFSSL_API int wc_Sha3_GetFlags(wc_Sha3* sha3, word32* flags); diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index a248e26c1..66bd0c8b5 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -661,6 +661,8 @@ DYNAMIC_TYPE_HASH_TMP = 88, DYNAMIC_TYPE_BLOB = 89, DYNAMIC_TYPE_NAME_ENTRY = 90, + DYNAMIC_TYPE_CURVE448 = 91, + DYNAMIC_TYPE_ED448 = 92, DYNAMIC_TYPE_SNIFFER_SERVER = 1000, DYNAMIC_TYPE_SNIFFER_SESSION = 1001, DYNAMIC_TYPE_SNIFFER_PB = 1002, From 441027a5025a75c87d86cb1ac29a7034e88d167e Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Fri, 28 Feb 2020 10:42:37 +1000 Subject: [PATCH 166/649] Improve performance of RSA/DH ops on x64 Focus on 3072-bit ops but others improved as well. --- wolfcrypt/src/sp_x86_64.c | 1094 +- wolfcrypt/src/sp_x86_64_asm.S | 32116 +++++++++++++++++++------------- 2 files changed, 19556 insertions(+), 13654 deletions(-) diff --git a/wolfcrypt/src/sp_x86_64.c b/wolfcrypt/src/sp_x86_64.c index c1ec7a3a0..b73db77c4 100644 --- a/wolfcrypt/src/sp_x86_64.c +++ b/wolfcrypt/src/sp_x86_64.c @@ -140,159 +140,17 @@ extern void sp_2048_sqr_avx2_16(sp_digit* r, const sp_digit* a); extern sp_digit sp_2048_add_16(sp_digit* r, const sp_digit* a, const sp_digit* b); extern sp_digit sp_2048_sub_in_place_32(sp_digit* a, const sp_digit* b); extern sp_digit sp_2048_add_32(sp_digit* r, const sp_digit* a, const sp_digit* b); -/* 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_2048_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_2048_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 o, ca, cb; - - ca = sp_2048_add_16(a1, a, a + 16); - cb = sp_2048_add_16(b1, b, b + 16); - o = ca & cb; - sp_2048_mul_16(z1, a1, b1); - sp_2048_mul_16(z2, a + 16, b + 16); - sp_2048_mul_16(z0, a, b); - sp_2048_mask_16(r + 32, a1, 0 - cb); - sp_2048_mask_16(b1, b1, 0 - ca); - o += sp_2048_add_16(r + 32, r + 32, b1); - o += sp_2048_sub_in_place_32(z1, z2); - o += sp_2048_sub_in_place_32(z1, z0); - o += sp_2048_add_32(r + 16, r + 16, z1); - r[48] = o; - XMEMSET(r + 48 + 1, 0, sizeof(sp_digit) * (16 - 1)); - sp_2048_add_32(r + 32, r + 32, z2); -} +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); -/* 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_2048_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 o; - - o = sp_2048_add_16(a1, a, a + 16); - sp_2048_sqr_16(z1, a1); - sp_2048_sqr_16(z2, a + 16); - sp_2048_sqr_16(z0, a); - sp_2048_mask_16(r + 32, a1, 0 - o); - o += sp_2048_dbl_16(r + 32, r + 32); - o += sp_2048_sub_in_place_32(z1, z2); - o += sp_2048_sub_in_place_32(z1, z0); - o += sp_2048_add_32(r + 16, r + 16, z1); - r[48] = o; - XMEMSET(r + 48 + 1, 0, sizeof(sp_digit) * (16 - 1)); - sp_2048_add_32(r + 32, r + 32, z2); -} +extern void sp_2048_sqr_32(sp_digit* r, const sp_digit* a); #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. - */ -SP_NOINLINE static void sp_2048_mul_avx2_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 o, ca, cb; - - ca = sp_2048_add_16(a1, a, a + 16); - cb = sp_2048_add_16(b1, b, b + 16); - o = ca & cb; - sp_2048_mul_avx2_16(z1, a1, b1); - sp_2048_mul_avx2_16(z2, a + 16, b + 16); - sp_2048_mul_avx2_16(z0, a, b); - sp_2048_mask_16(r + 32, a1, 0 - cb); - sp_2048_mask_16(b1, b1, 0 - ca); - o += sp_2048_add_16(r + 32, r + 32, b1); - o += sp_2048_sub_in_place_32(z1, z2); - o += sp_2048_sub_in_place_32(z1, z0); - o += sp_2048_add_32(r + 16, r + 16, z1); - r[48] = o; - XMEMSET(r + 48 + 1, 0, sizeof(sp_digit) * (16 - 1)); - sp_2048_add_32(r + 32, r + 32, z2); -} +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 -/* 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_2048_sqr_avx2_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 o; - - o = sp_2048_add_16(a1, a, a + 16); - sp_2048_sqr_avx2_16(z1, a1); - sp_2048_sqr_avx2_16(z2, a + 16); - sp_2048_sqr_avx2_16(z0, a); - sp_2048_mask_16(r + 32, a1, 0 - o); - o += sp_2048_dbl_16(r + 32, r + 32); - o += sp_2048_sub_in_place_32(z1, z2); - o += sp_2048_sub_in_place_32(z1, z0); - o += sp_2048_add_32(r + 16, r + 16, z1); - r[48] = o; - XMEMSET(r + 48 + 1, 0, sizeof(sp_digit) * (16 - 1)); - sp_2048_add_32(r + 32, r + 32, z2); -} +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_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) @@ -389,6 +247,36 @@ static WC_INLINE sp_digit div_2048_word_16(sp_digit d1, sp_digit d0, ); 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_2048_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_2048_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. @@ -413,6 +301,13 @@ static WC_INLINE int sp_2048_div_16(const sp_digit* a, const sp_digit* d, sp_dig div = d[15]; XMEMCPY(t1, a, sizeof(*t1) * 2 * 16); + r1 = sp_2048_cmp_16(&t1[16], d) >= 0; +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_2048_cond_sub_avx2_16(&t1[16], &t1[16], d, (sp_digit)0 - r1); + else +#endif + sp_2048_cond_sub_16(&t1[16], &t1[16], d, (sp_digit)0 - r1); for (i=15; i>=0; i--) { r1 = div_2048_word_16(t1[16 + i], t1[16 + i - 1], div); @@ -547,20 +442,31 @@ static int sp_2048_mod_exp_16(sp_digit* r, const sp_digit* a, const sp_digit* e, i = (bits - 1) / 64; n = e[i--]; c = bits & 63; - if (c == 0) + if (c == 0) { c = 64; - c -= bits % 5; + } + if ((bits % 5) == 0) { + c -= 5; + } + else { + c -= bits % 5; + } y = (int)(n >> c); n <<= 64 - c; XMEMCPY(r, t[y], sizeof(sp_digit) * 16); for (; i>=0 || c>=5; ) { - if (c == 0) { + if (c >= 5) { + y = (n >> 59) & 0x1f; + n <<= 5; + c -= 5; + } + else if (c == 0) { n = e[i--]; y = (int)(n >> 59); n <<= 5; c = 59; } - else if (c < 5) { + else { y = (int)(n >> 59); n = e[i--]; c = 5 - c; @@ -568,19 +474,20 @@ static int sp_2048_mod_exp_16(sp_digit* r, const sp_digit* a, const sp_digit* e, n <<= c; c = 64 - c; } - else { - y = (n >> 59) & 0x1f; - n <<= 5; - c -= 5; - } - sp_2048_mont_sqr_16(rt, r, m, mp); - sp_2048_mont_sqr_16(r, rt, m, mp); - sp_2048_mont_sqr_16(rt, r, m, mp); - sp_2048_mont_sqr_16(r, rt, m, mp); - sp_2048_mont_sqr_16(r, r, m, mp); + sp_2048_sqr_16(rt, r); + sp_2048_mont_reduce_16(rt, m, mp); + sp_2048_sqr_16(r, rt); + sp_2048_mont_reduce_16(r, m, mp); + sp_2048_sqr_16(rt, r); + sp_2048_mont_reduce_16(rt, m, mp); + sp_2048_sqr_16(r, rt); + sp_2048_mont_reduce_16(r, m, mp); + sp_2048_sqr_16(rt, r); + sp_2048_mont_reduce_16(rt, m, mp); - sp_2048_mont_mul_16(r, r, t[y], m, mp); + sp_2048_mul_16(r, rt, t[y]); + sp_2048_mont_reduce_16(r, m, mp); } XMEMSET(&r[16], 0, sizeof(sp_digit) * 16); @@ -728,20 +635,31 @@ static int sp_2048_mod_exp_avx2_16(sp_digit* r, const sp_digit* a, const sp_digi i = (bits - 1) / 64; n = e[i--]; c = bits & 63; - if (c == 0) + if (c == 0) { c = 64; - c -= bits % 5; + } + if ((bits % 5) == 0) { + c -= 5; + } + else { + c -= bits % 5; + } y = (int)(n >> c); n <<= 64 - c; XMEMCPY(r, t[y], sizeof(sp_digit) * 16); for (; i>=0 || c>=5; ) { - if (c == 0) { + if (c >= 5) { + y = (n >> 59) & 0x1f; + n <<= 5; + c -= 5; + } + else if (c == 0) { n = e[i--]; y = (int)(n >> 59); n <<= 5; c = 59; } - else if (c < 5) { + else { y = (int)(n >> 59); n = e[i--]; c = 5 - c; @@ -749,19 +667,20 @@ static int sp_2048_mod_exp_avx2_16(sp_digit* r, const sp_digit* a, const sp_digi n <<= c; c = 64 - c; } - else { - y = (n >> 59) & 0x1f; - n <<= 5; - c -= 5; - } - sp_2048_mont_sqr_avx2_16(rt, r, m, mp); - sp_2048_mont_sqr_avx2_16(r, rt, m, mp); - sp_2048_mont_sqr_avx2_16(rt, r, m, mp); - sp_2048_mont_sqr_avx2_16(r, rt, m, mp); - sp_2048_mont_sqr_avx2_16(r, r, m, mp); + sp_2048_sqr_avx2_16(rt, r); + sp_2048_mont_reduce_avx2_16(rt, m, mp); + sp_2048_sqr_avx2_16(r, rt); + sp_2048_mont_reduce_avx2_16(r, m, mp); + sp_2048_sqr_avx2_16(rt, r); + sp_2048_mont_reduce_avx2_16(rt, m, mp); + sp_2048_sqr_avx2_16(r, rt); + sp_2048_mont_reduce_avx2_16(r, m, mp); + sp_2048_sqr_avx2_16(rt, r); + sp_2048_mont_reduce_avx2_16(rt, m, mp); - sp_2048_mont_mul_avx2_16(r, r, t[y], m, mp); + sp_2048_mul_avx2_16(r, rt, t[y]); + sp_2048_mont_reduce_avx2_16(r, m, mp); } XMEMSET(&r[16], 0, sizeof(sp_digit) * 16); @@ -906,6 +825,13 @@ static WC_INLINE int sp_2048_div_32(const sp_digit* a, const sp_digit* d, sp_dig div = d[31]; XMEMCPY(t1, a, sizeof(*t1) * 2 * 32); + r1 = sp_2048_cmp_32(&t1[32], d) >= 0; +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_2048_cond_sub_avx2_32(&t1[32], &t1[32], d, (sp_digit)0 - r1); + else +#endif + sp_2048_cond_sub_32(&t1[32], &t1[32], d, (sp_digit)0 - r1); for (i=31; i>=0; i--) { r1 = div_2048_word_32(t1[32 + i], t1[32 + i - 1], div); @@ -971,6 +897,13 @@ static WC_INLINE int sp_2048_div_32_cond(const sp_digit* a, const sp_digit* d, s div = d[31]; XMEMCPY(t1, a, sizeof(*t1) * 2 * 32); + for (i = 31; i > 0; i--) { + if (t1[i + 32] != d[i]) + break; + } + if (t1[i + 32] >= d[i]) { + sp_2048_sub_in_place_32(&t1[32], d); + } for (i=31; i>=0; i--) { r1 = div_2048_word_32(t1[32 + i], t1[32 + i - 1], div); @@ -1110,20 +1043,31 @@ static int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e, i = (bits - 1) / 64; n = e[i--]; c = bits & 63; - if (c == 0) + if (c == 0) { c = 64; - c -= bits % 5; + } + if ((bits % 5) == 0) { + c -= 5; + } + else { + c -= bits % 5; + } y = (int)(n >> c); n <<= 64 - c; XMEMCPY(r, t[y], sizeof(sp_digit) * 32); for (; i>=0 || c>=5; ) { - if (c == 0) { + if (c >= 5) { + y = (n >> 59) & 0x1f; + n <<= 5; + c -= 5; + } + else if (c == 0) { n = e[i--]; y = (int)(n >> 59); n <<= 5; c = 59; } - else if (c < 5) { + else { y = (int)(n >> 59); n = e[i--]; c = 5 - c; @@ -1131,19 +1075,20 @@ static int sp_2048_mod_exp_32(sp_digit* r, const sp_digit* a, const sp_digit* e, n <<= c; c = 64 - c; } - else { - y = (n >> 59) & 0x1f; - n <<= 5; - c -= 5; - } - sp_2048_mont_sqr_32(rt, r, m, mp); - sp_2048_mont_sqr_32(r, rt, m, mp); - sp_2048_mont_sqr_32(rt, r, m, mp); - sp_2048_mont_sqr_32(r, rt, m, mp); - sp_2048_mont_sqr_32(r, r, m, mp); + sp_2048_sqr_32(rt, r); + sp_2048_mont_reduce_32(rt, m, mp); + sp_2048_sqr_32(r, rt); + sp_2048_mont_reduce_32(r, m, mp); + sp_2048_sqr_32(rt, r); + sp_2048_mont_reduce_32(rt, m, mp); + sp_2048_sqr_32(r, rt); + sp_2048_mont_reduce_32(r, m, mp); + sp_2048_sqr_32(rt, r); + sp_2048_mont_reduce_32(rt, m, mp); - sp_2048_mont_mul_32(r, r, t[y], m, mp); + sp_2048_mul_32(r, rt, t[y]); + sp_2048_mont_reduce_32(r, m, mp); } XMEMSET(&r[32], 0, sizeof(sp_digit) * 32); @@ -1293,20 +1238,31 @@ static int sp_2048_mod_exp_avx2_32(sp_digit* r, const sp_digit* a, const sp_digi i = (bits - 1) / 64; n = e[i--]; c = bits & 63; - if (c == 0) + if (c == 0) { c = 64; - c -= bits % 5; + } + if ((bits % 5) == 0) { + c -= 5; + } + else { + c -= bits % 5; + } y = (int)(n >> c); n <<= 64 - c; XMEMCPY(r, t[y], sizeof(sp_digit) * 32); for (; i>=0 || c>=5; ) { - if (c == 0) { + if (c >= 5) { + y = (n >> 59) & 0x1f; + n <<= 5; + c -= 5; + } + else if (c == 0) { n = e[i--]; y = (int)(n >> 59); n <<= 5; c = 59; } - else if (c < 5) { + else { y = (int)(n >> 59); n = e[i--]; c = 5 - c; @@ -1314,19 +1270,20 @@ static int sp_2048_mod_exp_avx2_32(sp_digit* r, const sp_digit* a, const sp_digi n <<= c; c = 64 - c; } - else { - y = (n >> 59) & 0x1f; - n <<= 5; - c -= 5; - } - sp_2048_mont_sqr_avx2_32(rt, r, m, mp); - sp_2048_mont_sqr_avx2_32(r, rt, m, mp); - sp_2048_mont_sqr_avx2_32(rt, r, m, mp); - sp_2048_mont_sqr_avx2_32(r, rt, m, mp); - sp_2048_mont_sqr_avx2_32(r, r, m, mp); + sp_2048_sqr_avx2_32(rt, r); + sp_2048_mont_reduce_avx2_32(rt, m, mp); + sp_2048_sqr_avx2_32(r, rt); + sp_2048_mont_reduce_avx2_32(r, m, mp); + sp_2048_sqr_avx2_32(rt, r); + sp_2048_mont_reduce_avx2_32(rt, m, mp); + sp_2048_sqr_avx2_32(r, rt); + sp_2048_mont_reduce_avx2_32(r, m, mp); + sp_2048_sqr_avx2_32(rt, r); + sp_2048_mont_reduce_avx2_32(rt, m, mp); - sp_2048_mont_mul_avx2_32(r, r, t[y], m, mp); + sp_2048_mul_avx2_32(r, rt, t[y]); + sp_2048_mont_reduce_avx2_32(r, m, mp); } XMEMSET(&r[32], 0, sizeof(sp_digit) * 32); @@ -1828,9 +1785,15 @@ static int sp_2048_mod_exp_2_avx2_32(sp_digit* r, const sp_digit* e, int bits, i = (bits - 1) / 64; n = e[i--]; c = bits & 63; - if (c == 0) + if (c == 0) { c = 64; - c -= bits % 6; + } + if ((bits % 6) == 0) { + c -= 6; + } + else { + c -= bits % 6; + } y = (int)(n >> c); n <<= 64 - c; sp_2048_lshift_32(r, norm, y); @@ -1934,9 +1897,15 @@ static int sp_2048_mod_exp_2_32(sp_digit* r, const sp_digit* e, int bits, i = (bits - 1) / 64; n = e[i--]; c = bits & 63; - if (c == 0) + if (c == 0) { c = 64; - c -= bits % 6; + } + if ((bits % 6) == 0) { + c -= 6; + } + else { + c -= bits % 6; + } y = (int)(n >> c); n <<= 64 - c; sp_2048_lshift_32(r, norm, y); @@ -2196,166 +2165,39 @@ static void sp_3072_from_mp(sp_digit* r, int size, const mp_int* a) } extern void sp_3072_to_bin(sp_digit* r, byte* a); -extern void sp_3072_mul_24(sp_digit* r, const sp_digit* a, const sp_digit* b); -extern void sp_3072_sqr_24(sp_digit* r, const sp_digit* a); -extern void sp_3072_mul_avx2_24(sp_digit* r, const sp_digit* a, const sp_digit* b); -extern void sp_3072_sqr_avx2_24(sp_digit* r, const sp_digit* a); +extern void sp_3072_mul_12(sp_digit* r, const sp_digit* a, const sp_digit* b); +extern void sp_3072_sqr_12(sp_digit* r, const sp_digit* a); +extern void sp_3072_mul_avx2_12(sp_digit* r, const sp_digit* a, const sp_digit* b); +extern void sp_3072_sqr_avx2_12(sp_digit* r, const sp_digit* a); +extern sp_digit sp_3072_add_12(sp_digit* r, const sp_digit* a, const sp_digit* b); +extern sp_digit sp_3072_sub_in_place_24(sp_digit* a, const sp_digit* b); extern sp_digit sp_3072_add_24(sp_digit* r, const sp_digit* a, const sp_digit* b); -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); -/* 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_3072_mask_24(sp_digit* r, const sp_digit* a, sp_digit m) -{ -#ifdef WOLFSSL_SP_SMALL - int i; +extern void sp_3072_mul_24(sp_digit* r, const sp_digit* a, const sp_digit* b); - for (i=0; i<24; i++) { - r[i] = a[i] & m; - } -#else - int i; - - for (i = 0; i < 24; 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_3072_mul_48(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - sp_digit* z0 = r; - sp_digit z1[48]; - sp_digit a1[24]; - sp_digit b1[24]; - sp_digit z2[48]; - sp_digit o, ca, cb; - - ca = sp_3072_add_24(a1, a, a + 24); - cb = sp_3072_add_24(b1, b, b + 24); - o = ca & cb; - sp_3072_mul_24(z1, a1, b1); - sp_3072_mul_24(z2, a + 24, b + 24); - sp_3072_mul_24(z0, a, b); - sp_3072_mask_24(r + 48, a1, 0 - cb); - sp_3072_mask_24(b1, b1, 0 - ca); - o += sp_3072_add_24(r + 48, r + 48, b1); - o += sp_3072_sub_in_place_48(z1, z2); - o += sp_3072_sub_in_place_48(z1, z0); - o += sp_3072_add_48(r + 24, r + 24, z1); - r[72] = o; - XMEMSET(r + 72 + 1, 0, sizeof(sp_digit) * (24 - 1)); - sp_3072_add_48(r + 48, r + 48, z2); -} - -extern sp_digit sp_3072_dbl_24(sp_digit* r, const sp_digit* a); -/* 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_3072_sqr_48(sp_digit* r, const sp_digit* a) -{ - sp_digit* z0 = r; - sp_digit z2[48]; - sp_digit z1[48]; - sp_digit a1[24]; - sp_digit o; - - o = sp_3072_add_24(a1, a, a + 24); - sp_3072_sqr_24(z1, a1); - sp_3072_sqr_24(z2, a + 24); - sp_3072_sqr_24(z0, a); - sp_3072_mask_24(r + 48, a1, 0 - o); - o += sp_3072_dbl_24(r + 48, r + 48); - o += sp_3072_sub_in_place_48(z1, z2); - o += sp_3072_sub_in_place_48(z1, z0); - o += sp_3072_add_48(r + 24, r + 24, z1); - r[72] = o; - XMEMSET(r + 72 + 1, 0, sizeof(sp_digit) * (24 - 1)); - sp_3072_add_48(r + 48, r + 48, z2); -} +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 -/* 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_3072_mul_avx2_48(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - sp_digit* z0 = r; - sp_digit z1[48]; - sp_digit a1[24]; - sp_digit b1[24]; - sp_digit z2[48]; - sp_digit o, ca, cb; - - ca = sp_3072_add_24(a1, a, a + 24); - cb = sp_3072_add_24(b1, b, b + 24); - o = ca & cb; - sp_3072_mul_avx2_24(z1, a1, b1); - sp_3072_mul_avx2_24(z2, a + 24, b + 24); - sp_3072_mul_avx2_24(z0, a, b); - sp_3072_mask_24(r + 48, a1, 0 - cb); - sp_3072_mask_24(b1, b1, 0 - ca); - o += sp_3072_add_24(r + 48, r + 48, b1); - o += sp_3072_sub_in_place_48(z1, z2); - o += sp_3072_sub_in_place_48(z1, z0); - o += sp_3072_add_48(r + 24, r + 24, z1); - r[72] = o; - XMEMSET(r + 72 + 1, 0, sizeof(sp_digit) * (24 - 1)); - sp_3072_add_48(r + 48, r + 48, z2); -} +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 -/* 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_3072_sqr_avx2_48(sp_digit* r, const sp_digit* a) -{ - sp_digit* z0 = r; - sp_digit z2[48]; - sp_digit z1[48]; - sp_digit a1[24]; - sp_digit o; +extern void sp_3072_sqr_avx2_24(sp_digit* r, const sp_digit* a); +#endif /* HAVE_INTEL_AVX2 */ - o = sp_3072_add_24(a1, a, a + 24); - sp_3072_sqr_avx2_24(z1, a1); - sp_3072_sqr_avx2_24(z2, a + 24); - sp_3072_sqr_avx2_24(z0, a); - sp_3072_mask_24(r + 48, a1, 0 - o); - o += sp_3072_dbl_24(r + 48, r + 48); - o += sp_3072_sub_in_place_48(z1, z2); - o += sp_3072_sub_in_place_48(z1, z0); - o += sp_3072_add_48(r + 24, r + 24, z1); - r[72] = o; - XMEMSET(r + 72 + 1, 0, sizeof(sp_digit) * (24 - 1)); - sp_3072_add_48(r + 48, r + 48, z2); -} +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); +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_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) @@ -2383,7 +2225,6 @@ static void sp_3072_mont_setup(const sp_digit* a, sp_digit* rho) extern void sp_3072_mul_d_48(sp_digit* r, const sp_digit* a, sp_digit b); #if (defined(WOLFSSL_HAVE_SP_RSA) || defined(WOLFSSL_HAVE_SP_DH)) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) -extern sp_digit sp_3072_sub_in_place_24(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 3072 bits, just need to subtract. * @@ -2452,6 +2293,36 @@ static WC_INLINE sp_digit div_3072_word_24(sp_digit d1, sp_digit d0, ); 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_3072_mask_24(sp_digit* r, const sp_digit* a, sp_digit m) +{ +#ifdef WOLFSSL_SP_SMALL + int i; + + for (i=0; i<24; i++) { + r[i] = a[i] & m; + } +#else + int i; + + for (i = 0; i < 24; 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_3072_cmp_24(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. @@ -2476,6 +2347,13 @@ static WC_INLINE int sp_3072_div_24(const sp_digit* a, const sp_digit* d, sp_dig div = d[23]; XMEMCPY(t1, a, sizeof(*t1) * 2 * 24); + r1 = sp_3072_cmp_24(&t1[24], d) >= 0; +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_3072_cond_sub_avx2_24(&t1[24], &t1[24], d, (sp_digit)0 - r1); + else +#endif + sp_3072_cond_sub_24(&t1[24], &t1[24], d, (sp_digit)0 - r1); for (i=23; i>=0; i--) { r1 = div_3072_word_24(t1[24 + i], t1[24 + i - 1], div); @@ -2610,20 +2488,31 @@ static int sp_3072_mod_exp_24(sp_digit* r, const sp_digit* a, const sp_digit* e, i = (bits - 1) / 64; n = e[i--]; c = bits & 63; - if (c == 0) + if (c == 0) { c = 64; - c -= bits % 5; + } + if ((bits % 5) == 0) { + c -= 5; + } + else { + c -= bits % 5; + } y = (int)(n >> c); n <<= 64 - c; XMEMCPY(r, t[y], sizeof(sp_digit) * 24); for (; i>=0 || c>=5; ) { - if (c == 0) { + if (c >= 5) { + y = (n >> 59) & 0x1f; + n <<= 5; + c -= 5; + } + else if (c == 0) { n = e[i--]; y = (int)(n >> 59); n <<= 5; c = 59; } - else if (c < 5) { + else { y = (int)(n >> 59); n = e[i--]; c = 5 - c; @@ -2631,19 +2520,20 @@ static int sp_3072_mod_exp_24(sp_digit* r, const sp_digit* a, const sp_digit* e, n <<= c; c = 64 - c; } - else { - y = (n >> 59) & 0x1f; - n <<= 5; - c -= 5; - } - sp_3072_mont_sqr_24(rt, r, m, mp); - sp_3072_mont_sqr_24(r, rt, m, mp); - sp_3072_mont_sqr_24(rt, r, m, mp); - sp_3072_mont_sqr_24(r, rt, m, mp); - sp_3072_mont_sqr_24(r, r, m, mp); + sp_3072_sqr_24(rt, r); + sp_3072_mont_reduce_24(rt, m, mp); + sp_3072_sqr_24(r, rt); + sp_3072_mont_reduce_24(r, m, mp); + sp_3072_sqr_24(rt, r); + sp_3072_mont_reduce_24(rt, m, mp); + sp_3072_sqr_24(r, rt); + sp_3072_mont_reduce_24(r, m, mp); + sp_3072_sqr_24(rt, r); + sp_3072_mont_reduce_24(rt, m, mp); - sp_3072_mont_mul_24(r, r, t[y], m, mp); + sp_3072_mul_24(r, rt, t[y]); + sp_3072_mont_reduce_24(r, m, mp); } XMEMSET(&r[24], 0, sizeof(sp_digit) * 24); @@ -2791,20 +2681,31 @@ static int sp_3072_mod_exp_avx2_24(sp_digit* r, const sp_digit* a, const sp_digi i = (bits - 1) / 64; n = e[i--]; c = bits & 63; - if (c == 0) + if (c == 0) { c = 64; - c -= bits % 5; + } + if ((bits % 5) == 0) { + c -= 5; + } + else { + c -= bits % 5; + } y = (int)(n >> c); n <<= 64 - c; XMEMCPY(r, t[y], sizeof(sp_digit) * 24); for (; i>=0 || c>=5; ) { - if (c == 0) { + if (c >= 5) { + y = (n >> 59) & 0x1f; + n <<= 5; + c -= 5; + } + else if (c == 0) { n = e[i--]; y = (int)(n >> 59); n <<= 5; c = 59; } - else if (c < 5) { + else { y = (int)(n >> 59); n = e[i--]; c = 5 - c; @@ -2812,19 +2713,20 @@ static int sp_3072_mod_exp_avx2_24(sp_digit* r, const sp_digit* a, const sp_digi n <<= c; c = 64 - c; } - else { - y = (n >> 59) & 0x1f; - n <<= 5; - c -= 5; - } - sp_3072_mont_sqr_avx2_24(rt, r, m, mp); - sp_3072_mont_sqr_avx2_24(r, rt, m, mp); - sp_3072_mont_sqr_avx2_24(rt, r, m, mp); - sp_3072_mont_sqr_avx2_24(r, rt, m, mp); - sp_3072_mont_sqr_avx2_24(r, r, m, mp); + sp_3072_sqr_avx2_24(rt, r); + sp_3072_mont_reduce_avx2_24(rt, m, mp); + sp_3072_sqr_avx2_24(r, rt); + sp_3072_mont_reduce_avx2_24(r, m, mp); + sp_3072_sqr_avx2_24(rt, r); + sp_3072_mont_reduce_avx2_24(rt, m, mp); + sp_3072_sqr_avx2_24(r, rt); + sp_3072_mont_reduce_avx2_24(r, m, mp); + sp_3072_sqr_avx2_24(rt, r); + sp_3072_mont_reduce_avx2_24(rt, m, mp); - sp_3072_mont_mul_avx2_24(r, r, t[y], m, mp); + sp_3072_mul_avx2_24(r, rt, t[y]); + sp_3072_mont_reduce_avx2_24(r, m, mp); } XMEMSET(&r[24], 0, sizeof(sp_digit) * 24); @@ -2969,6 +2871,13 @@ static WC_INLINE int sp_3072_div_48(const sp_digit* a, const sp_digit* d, sp_dig div = d[47]; XMEMCPY(t1, a, sizeof(*t1) * 2 * 48); + r1 = sp_3072_cmp_48(&t1[48], d) >= 0; +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_3072_cond_sub_avx2_48(&t1[48], &t1[48], d, (sp_digit)0 - r1); + else +#endif + sp_3072_cond_sub_48(&t1[48], &t1[48], d, (sp_digit)0 - r1); for (i=47; i>=0; i--) { r1 = div_3072_word_48(t1[48 + i], t1[48 + i - 1], div); @@ -3034,6 +2943,13 @@ static WC_INLINE int sp_3072_div_48_cond(const sp_digit* a, const sp_digit* d, s div = d[47]; XMEMCPY(t1, a, sizeof(*t1) * 2 * 48); + for (i = 47; i > 0; i--) { + if (t1[i + 48] != d[i]) + break; + } + if (t1[i + 48] >= d[i]) { + sp_3072_sub_in_place_48(&t1[48], d); + } for (i=47; i>=0; i--) { r1 = div_3072_word_48(t1[48 + i], t1[48 + i - 1], div); @@ -3173,20 +3089,31 @@ static int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e, i = (bits - 1) / 64; n = e[i--]; c = bits & 63; - if (c == 0) + if (c == 0) { c = 64; - c -= bits % 5; + } + if ((bits % 5) == 0) { + c -= 5; + } + else { + c -= bits % 5; + } y = (int)(n >> c); n <<= 64 - c; XMEMCPY(r, t[y], sizeof(sp_digit) * 48); for (; i>=0 || c>=5; ) { - if (c == 0) { + if (c >= 5) { + y = (n >> 59) & 0x1f; + n <<= 5; + c -= 5; + } + else if (c == 0) { n = e[i--]; y = (int)(n >> 59); n <<= 5; c = 59; } - else if (c < 5) { + else { y = (int)(n >> 59); n = e[i--]; c = 5 - c; @@ -3194,19 +3121,20 @@ static int sp_3072_mod_exp_48(sp_digit* r, const sp_digit* a, const sp_digit* e, n <<= c; c = 64 - c; } - else { - y = (n >> 59) & 0x1f; - n <<= 5; - c -= 5; - } - sp_3072_mont_sqr_48(rt, r, m, mp); - sp_3072_mont_sqr_48(r, rt, m, mp); - sp_3072_mont_sqr_48(rt, r, m, mp); - sp_3072_mont_sqr_48(r, rt, m, mp); - sp_3072_mont_sqr_48(r, r, m, mp); + sp_3072_sqr_48(rt, r); + sp_3072_mont_reduce_48(rt, m, mp); + sp_3072_sqr_48(r, rt); + sp_3072_mont_reduce_48(r, m, mp); + sp_3072_sqr_48(rt, r); + sp_3072_mont_reduce_48(rt, m, mp); + sp_3072_sqr_48(r, rt); + sp_3072_mont_reduce_48(r, m, mp); + sp_3072_sqr_48(rt, r); + sp_3072_mont_reduce_48(rt, m, mp); - sp_3072_mont_mul_48(r, r, t[y], m, mp); + sp_3072_mul_48(r, rt, t[y]); + sp_3072_mont_reduce_48(r, m, mp); } XMEMSET(&r[48], 0, sizeof(sp_digit) * 48); @@ -3356,20 +3284,31 @@ static int sp_3072_mod_exp_avx2_48(sp_digit* r, const sp_digit* a, const sp_digi i = (bits - 1) / 64; n = e[i--]; c = bits & 63; - if (c == 0) + if (c == 0) { c = 64; - c -= bits % 5; + } + if ((bits % 5) == 0) { + c -= 5; + } + else { + c -= bits % 5; + } y = (int)(n >> c); n <<= 64 - c; XMEMCPY(r, t[y], sizeof(sp_digit) * 48); for (; i>=0 || c>=5; ) { - if (c == 0) { + if (c >= 5) { + y = (n >> 59) & 0x1f; + n <<= 5; + c -= 5; + } + else if (c == 0) { n = e[i--]; y = (int)(n >> 59); n <<= 5; c = 59; } - else if (c < 5) { + else { y = (int)(n >> 59); n = e[i--]; c = 5 - c; @@ -3377,19 +3316,20 @@ static int sp_3072_mod_exp_avx2_48(sp_digit* r, const sp_digit* a, const sp_digi n <<= c; c = 64 - c; } - else { - y = (n >> 59) & 0x1f; - n <<= 5; - c -= 5; - } - sp_3072_mont_sqr_avx2_48(rt, r, m, mp); - sp_3072_mont_sqr_avx2_48(r, rt, m, mp); - sp_3072_mont_sqr_avx2_48(rt, r, m, mp); - sp_3072_mont_sqr_avx2_48(r, rt, m, mp); - sp_3072_mont_sqr_avx2_48(r, r, m, mp); + sp_3072_sqr_avx2_48(rt, r); + sp_3072_mont_reduce_avx2_48(rt, m, mp); + sp_3072_sqr_avx2_48(r, rt); + sp_3072_mont_reduce_avx2_48(r, m, mp); + sp_3072_sqr_avx2_48(rt, r); + sp_3072_mont_reduce_avx2_48(rt, m, mp); + sp_3072_sqr_avx2_48(r, rt); + sp_3072_mont_reduce_avx2_48(r, m, mp); + sp_3072_sqr_avx2_48(rt, r); + sp_3072_mont_reduce_avx2_48(rt, m, mp); - sp_3072_mont_mul_avx2_48(r, r, t[y], m, mp); + sp_3072_mul_avx2_48(r, rt, t[y]); + sp_3072_mont_reduce_avx2_48(r, m, mp); } XMEMSET(&r[48], 0, sizeof(sp_digit) * 48); @@ -3891,9 +3831,15 @@ static int sp_3072_mod_exp_2_avx2_48(sp_digit* r, const sp_digit* e, int bits, i = (bits - 1) / 64; n = e[i--]; c = bits & 63; - if (c == 0) + if (c == 0) { c = 64; - c -= bits % 6; + } + if ((bits % 6) == 0) { + c -= 6; + } + else { + c -= bits % 6; + } y = (int)(n >> c); n <<= 64 - c; sp_3072_lshift_48(r, norm, y); @@ -3997,9 +3943,15 @@ static int sp_3072_mod_exp_2_48(sp_digit* r, const sp_digit* e, int bits, i = (bits - 1) / 64; n = e[i--]; c = bits & 63; - if (c == 0) + if (c == 0) { c = 64; - c -= bits % 6; + } + if ((bits % 6) == 0) { + c -= 6; + } + else { + c -= bits % 6; + } y = (int)(n >> c); n <<= 64 - c; sp_3072_lshift_48(r, norm, y); @@ -4261,129 +4213,17 @@ static void sp_4096_from_mp(sp_digit* r, int size, const mp_int* a) extern void sp_4096_to_bin(sp_digit* r, byte* a); extern sp_digit sp_4096_sub_in_place_64(sp_digit* a, const sp_digit* b); extern sp_digit sp_4096_add_64(sp_digit* r, const sp_digit* a, const sp_digit* b); -/* 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_4096_mul_64(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - sp_digit* z0 = r; - sp_digit z1[64]; - sp_digit a1[32]; - sp_digit b1[32]; - sp_digit z2[64]; - sp_digit o, ca, cb; - - ca = sp_2048_add_32(a1, a, a + 32); - cb = sp_2048_add_32(b1, b, b + 32); - o = ca & cb; - sp_2048_mul_32(z1, a1, b1); - sp_2048_mul_32(z2, a + 32, b + 32); - sp_2048_mul_32(z0, a, b); - sp_2048_mask_32(r + 64, a1, 0 - cb); - sp_2048_mask_32(b1, b1, 0 - ca); - o += sp_2048_add_32(r + 64, r + 64, b1); - o += sp_4096_sub_in_place_64(z1, z2); - o += sp_4096_sub_in_place_64(z1, z0); - o += sp_4096_add_64(r + 32, r + 32, z1); - r[96] = o; - XMEMSET(r + 96 + 1, 0, sizeof(sp_digit) * (32 - 1)); - sp_4096_add_64(r + 64, r + 64, z2); -} +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); -/* 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_4096_sqr_64(sp_digit* r, const sp_digit* a) -{ - sp_digit* z0 = r; - sp_digit z2[64]; - sp_digit z1[64]; - sp_digit a1[32]; - sp_digit o; - - o = sp_2048_add_32(a1, a, a + 32); - sp_2048_sqr_32(z1, a1); - sp_2048_sqr_32(z2, a + 32); - sp_2048_sqr_32(z0, a); - sp_2048_mask_32(r + 64, a1, 0 - o); - o += sp_2048_dbl_32(r + 64, r + 64); - o += sp_4096_sub_in_place_64(z1, z2); - o += sp_4096_sub_in_place_64(z1, z0); - o += sp_4096_add_64(r + 32, r + 32, z1); - r[96] = o; - XMEMSET(r + 96 + 1, 0, sizeof(sp_digit) * (32 - 1)); - sp_4096_add_64(r + 64, r + 64, z2); -} +extern void sp_4096_sqr_64(sp_digit* r, const sp_digit* a); #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. - */ -SP_NOINLINE static void sp_4096_mul_avx2_64(sp_digit* r, const sp_digit* a, - const sp_digit* b) -{ - sp_digit* z0 = r; - sp_digit z1[64]; - sp_digit a1[32]; - sp_digit b1[32]; - sp_digit z2[64]; - sp_digit o, ca, cb; - - ca = sp_2048_add_32(a1, a, a + 32); - cb = sp_2048_add_32(b1, b, b + 32); - o = ca & cb; - sp_2048_mul_avx2_32(z1, a1, b1); - sp_2048_mul_avx2_32(z2, a + 32, b + 32); - sp_2048_mul_avx2_32(z0, a, b); - sp_2048_mask_32(r + 64, a1, 0 - cb); - sp_2048_mask_32(b1, b1, 0 - ca); - o += sp_2048_add_32(r + 64, r + 64, b1); - o += sp_4096_sub_in_place_64(z1, z2); - o += sp_4096_sub_in_place_64(z1, z0); - o += sp_4096_add_64(r + 32, r + 32, z1); - r[96] = o; - XMEMSET(r + 96 + 1, 0, sizeof(sp_digit) * (32 - 1)); - sp_4096_add_64(r + 64, r + 64, z2); -} +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 -/* 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_4096_sqr_avx2_64(sp_digit* r, const sp_digit* a) -{ - sp_digit* z0 = r; - sp_digit z2[64]; - sp_digit z1[64]; - sp_digit a1[32]; - sp_digit o; - - o = sp_2048_add_32(a1, a, a + 32); - sp_2048_sqr_avx2_32(z1, a1); - sp_2048_sqr_avx2_32(z2, a + 32); - sp_2048_sqr_avx2_32(z0, a); - sp_2048_mask_32(r + 64, a1, 0 - o); - o += sp_2048_dbl_32(r + 64, r + 64); - o += sp_4096_sub_in_place_64(z1, z2); - o += sp_4096_sub_in_place_64(z1, z0); - o += sp_4096_add_64(r + 32, r + 32, z1); - r[96] = o; - XMEMSET(r + 96 + 1, 0, sizeof(sp_digit) * (32 - 1)); - sp_4096_add_64(r + 64, r + 64, z2); -} +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. @@ -4531,6 +4371,13 @@ static WC_INLINE int sp_4096_div_64(const sp_digit* a, const sp_digit* d, sp_dig div = d[63]; XMEMCPY(t1, a, sizeof(*t1) * 2 * 64); + r1 = sp_4096_cmp_64(&t1[64], d) >= 0; +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_4096_cond_sub_avx2_64(&t1[64], &t1[64], d, (sp_digit)0 - r1); + else +#endif + sp_4096_cond_sub_64(&t1[64], &t1[64], d, (sp_digit)0 - r1); for (i=63; i>=0; i--) { r1 = div_4096_word_64(t1[64 + i], t1[64 + i - 1], div); @@ -4596,6 +4443,13 @@ static WC_INLINE int sp_4096_div_64_cond(const sp_digit* a, const sp_digit* d, s div = d[63]; XMEMCPY(t1, a, sizeof(*t1) * 2 * 64); + for (i = 63; i > 0; i--) { + if (t1[i + 64] != d[i]) + break; + } + if (t1[i + 64] >= d[i]) { + sp_4096_sub_in_place_64(&t1[64], d); + } for (i=63; i>=0; i--) { r1 = div_4096_word_64(t1[64 + i], t1[64 + i - 1], div); @@ -4735,20 +4589,31 @@ static int sp_4096_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e, i = (bits - 1) / 64; n = e[i--]; c = bits & 63; - if (c == 0) + if (c == 0) { c = 64; - c -= bits % 5; + } + if ((bits % 5) == 0) { + c -= 5; + } + else { + c -= bits % 5; + } y = (int)(n >> c); n <<= 64 - c; XMEMCPY(r, t[y], sizeof(sp_digit) * 64); for (; i>=0 || c>=5; ) { - if (c == 0) { + if (c >= 5) { + y = (n >> 59) & 0x1f; + n <<= 5; + c -= 5; + } + else if (c == 0) { n = e[i--]; y = (int)(n >> 59); n <<= 5; c = 59; } - else if (c < 5) { + else { y = (int)(n >> 59); n = e[i--]; c = 5 - c; @@ -4756,19 +4621,20 @@ static int sp_4096_mod_exp_64(sp_digit* r, const sp_digit* a, const sp_digit* e, n <<= c; c = 64 - c; } - else { - y = (n >> 59) & 0x1f; - n <<= 5; - c -= 5; - } - sp_4096_mont_sqr_64(rt, r, m, mp); - sp_4096_mont_sqr_64(r, rt, m, mp); - sp_4096_mont_sqr_64(rt, r, m, mp); - sp_4096_mont_sqr_64(r, rt, m, mp); - sp_4096_mont_sqr_64(r, r, m, mp); + sp_4096_sqr_64(rt, r); + sp_4096_mont_reduce_64(rt, m, mp); + sp_4096_sqr_64(r, rt); + sp_4096_mont_reduce_64(r, m, mp); + sp_4096_sqr_64(rt, r); + sp_4096_mont_reduce_64(rt, m, mp); + sp_4096_sqr_64(r, rt); + sp_4096_mont_reduce_64(r, m, mp); + sp_4096_sqr_64(rt, r); + sp_4096_mont_reduce_64(rt, m, mp); - sp_4096_mont_mul_64(r, r, t[y], m, mp); + sp_4096_mul_64(r, rt, t[y]); + sp_4096_mont_reduce_64(r, m, mp); } XMEMSET(&r[64], 0, sizeof(sp_digit) * 64); @@ -4918,20 +4784,31 @@ static int sp_4096_mod_exp_avx2_64(sp_digit* r, const sp_digit* a, const sp_digi i = (bits - 1) / 64; n = e[i--]; c = bits & 63; - if (c == 0) + if (c == 0) { c = 64; - c -= bits % 5; + } + if ((bits % 5) == 0) { + c -= 5; + } + else { + c -= bits % 5; + } y = (int)(n >> c); n <<= 64 - c; XMEMCPY(r, t[y], sizeof(sp_digit) * 64); for (; i>=0 || c>=5; ) { - if (c == 0) { + if (c >= 5) { + y = (n >> 59) & 0x1f; + n <<= 5; + c -= 5; + } + else if (c == 0) { n = e[i--]; y = (int)(n >> 59); n <<= 5; c = 59; } - else if (c < 5) { + else { y = (int)(n >> 59); n = e[i--]; c = 5 - c; @@ -4939,19 +4816,20 @@ static int sp_4096_mod_exp_avx2_64(sp_digit* r, const sp_digit* a, const sp_digi n <<= c; c = 64 - c; } - else { - y = (n >> 59) & 0x1f; - n <<= 5; - c -= 5; - } - sp_4096_mont_sqr_avx2_64(rt, r, m, mp); - sp_4096_mont_sqr_avx2_64(r, rt, m, mp); - sp_4096_mont_sqr_avx2_64(rt, r, m, mp); - sp_4096_mont_sqr_avx2_64(r, rt, m, mp); - sp_4096_mont_sqr_avx2_64(r, r, m, mp); + sp_4096_sqr_avx2_64(rt, r); + sp_4096_mont_reduce_avx2_64(rt, m, mp); + sp_4096_sqr_avx2_64(r, rt); + sp_4096_mont_reduce_avx2_64(r, m, mp); + sp_4096_sqr_avx2_64(rt, r); + sp_4096_mont_reduce_avx2_64(rt, m, mp); + sp_4096_sqr_avx2_64(r, rt); + sp_4096_mont_reduce_avx2_64(r, m, mp); + sp_4096_sqr_avx2_64(rt, r); + sp_4096_mont_reduce_avx2_64(rt, m, mp); - sp_4096_mont_mul_avx2_64(r, r, t[y], m, mp); + sp_4096_mul_avx2_64(r, rt, t[y]); + sp_4096_mont_reduce_avx2_64(r, m, mp); } XMEMSET(&r[64], 0, sizeof(sp_digit) * 64); @@ -5453,9 +5331,15 @@ static int sp_4096_mod_exp_2_avx2_64(sp_digit* r, const sp_digit* e, int bits, i = (bits - 1) / 64; n = e[i--]; c = bits & 63; - if (c == 0) + if (c == 0) { c = 64; - c -= bits % 6; + } + if ((bits % 6) == 0) { + c -= 6; + } + else { + c -= bits % 6; + } y = (int)(n >> c); n <<= 64 - c; sp_4096_lshift_64(r, norm, y); @@ -5559,9 +5443,15 @@ static int sp_4096_mod_exp_2_64(sp_digit* r, const sp_digit* e, int bits, i = (bits - 1) / 64; n = e[i--]; c = bits & 63; - if (c == 0) + if (c == 0) { c = 64; - c -= bits % 6; + } + if ((bits % 6) == 0) { + c -= 6; + } + else { + c -= bits % 6; + } y = (int)(n >> c); n <<= 64 - c; sp_4096_lshift_64(r, norm, y); @@ -22156,6 +22046,13 @@ static WC_INLINE int sp_256_div_4(const sp_digit* a, const sp_digit* d, sp_digit div = d[3]; XMEMCPY(t1, a, sizeof(*t1) * 2 * 4); + r1 = sp_256_cmp_4(&t1[4], d) >= 0; +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_256_cond_sub_avx2_4(&t1[4], &t1[4], d, (sp_digit)0 - r1); + else +#endif + sp_256_cond_sub_4(&t1[4], &t1[4], d, (sp_digit)0 - r1); for (i=3; i>=0; i--) { r1 = div_256_word_4(t1[4 + i], t1[4 + i - 1], div); @@ -24826,7 +24723,6 @@ static int sp_384_ecc_mulmod_win_add_sub_6(sp_point_384* r, const sp_point_384* #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 -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_mont_reduce_order_avx2_6(sp_digit* a, const sp_digit* m, sp_digit mp); /* Multiply two Montogmery form numbers mod the modulus (prime). * (r = a * b mod m) @@ -24967,40 +24863,6 @@ static void sp_384_mont_inv_avx2_6(sp_digit* r, const sp_digit* a, sp_digit* td) #endif /* WOLFSSL_SP_SMALL */ } -#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. - */ -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); -} - -#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_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); -} - -#endif /* HAVE_INTEL_AVX2_ */ /* Map the Montgomery form projective coordinate point to an affine point. * * r Resulting affine coordinate point. @@ -27947,6 +27809,7 @@ 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); /* Divide the double width number (d1|d0) by the dividend. (d1|d0 / div) @@ -28015,6 +27878,13 @@ static WC_INLINE int sp_384_div_6(const sp_digit* a, const sp_digit* d, sp_digit div = d[5]; XMEMCPY(t1, a, sizeof(*t1) * 2 * 6); + r1 = sp_384_cmp_6(&t1[6], d) >= 0; +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) + sp_384_cond_sub_avx2_6(&t1[6], &t1[6], d, (sp_digit)0 - r1); + else +#endif + sp_384_cond_sub_6(&t1[6], &t1[6], d, (sp_digit)0 - r1); for (i=5; i>=0; i--) { r1 = div_384_word_6(t1[6 + i], t1[6 + i - 1], div); diff --git a/wolfcrypt/src/sp_x86_64_asm.S b/wolfcrypt/src/sp_x86_64_asm.S index e73399f21..4d9b51f1d 100644 --- a/wolfcrypt/src/sp_x86_64_asm.S +++ b/wolfcrypt/src/sp_x86_64_asm.S @@ -2947,159 +2947,163 @@ sp_2048_mul_avx2_16: .p2align 4 _sp_2048_mul_avx2_16: #endif /* __APPLE__ */ + push %rbx push %rbp push %r12 push %r13 push %r14 - push %r15 - push %rbx movq %rdx, %rbp subq $128, %rsp - movq $0, %r14 + cmpq %rdi, %rsi + movq %rsp, %rbx + cmovne %rdi, %rbx + cmpq %rdi, %rbp + cmove %rsp, %rbx + 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, (%rsp) + movq %r8, (%rbx) adcxq %rax, %r9 # A[0] * B[2] mulx 16(%rbp), %rax, %r11 - movq %r9, 8(%rsp) + movq %r9, 8(%rbx) adcxq %rax, %r10 # A[0] * B[3] mulx 24(%rbp), %rax, %r12 - movq %r10, 16(%rsp) + movq %r10, 16(%rbx) adcxq %rax, %r11 - movq %r11, 24(%rsp) + 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(%rsp) + movq %r12, 32(%rbx) adcxq %rax, %r8 # A[0] * B[6] mulx 48(%rbp), %rax, %r10 - movq %r8, 40(%rsp) + movq %r8, 40(%rbx) adcxq %rax, %r9 # A[0] * B[7] mulx 56(%rbp), %rax, %r11 - movq %r9, 48(%rsp) + movq %r9, 48(%rbx) adcxq %rax, %r10 - movq %r10, 56(%rsp) + 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(%rsp) + movq %r11, 64(%rbx) adcxq %rax, %r12 # A[0] * B[10] mulx 80(%rbp), %rax, %r9 - movq %r12, 72(%rsp) + movq %r12, 72(%rbx) adcxq %rax, %r8 # A[0] * B[11] mulx 88(%rbp), %rax, %r10 - movq %r8, 80(%rsp) + movq %r8, 80(%rbx) adcxq %rax, %r9 - movq %r9, 88(%rsp) + 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(%rsp) + movq %r10, 96(%rbx) adcxq %rax, %r11 # A[0] * B[14] mulx 112(%rbp), %rax, %r8 - movq %r11, 104(%rsp) + movq %r11, 104(%rbx) adcxq %rax, %r12 # A[0] * B[15] mulx 120(%rbp), %rax, %r9 - movq %r12, %r15 + movq %r12, 112(%rbx) adcxq %rax, %r8 adcxq %r14, %r9 movq %r14, %r13 adcxq %r14, %r13 - movq %r8, %rbx + movq %r8, 120(%rbx) movq %r9, 128(%rdi) movq 8(%rsi), %rdx - movq 8(%rsp), %r9 - movq 16(%rsp), %r10 - movq 24(%rsp), %r11 - movq 32(%rsp), %r12 - movq 40(%rsp), %r8 + 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(%rsp) + movq %r9, 8(%rbx) adcxq %rax, %r10 adoxq %rcx, %r11 # A[1] * B[2] mulx 16(%rbp), %rax, %rcx - movq %r10, 16(%rsp) + movq %r10, 16(%rbx) adcxq %rax, %r11 adoxq %rcx, %r12 # A[1] * B[3] mulx 24(%rbp), %rax, %rcx - movq %r11, 24(%rsp) + movq %r11, 24(%rbx) adcxq %rax, %r12 adoxq %rcx, %r8 - movq %r12, 32(%rsp) - movq 48(%rsp), %r9 - movq 56(%rsp), %r10 - movq 64(%rsp), %r11 - movq 72(%rsp), %r12 + 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(%rsp) + movq %r8, 40(%rbx) adcxq %rax, %r9 adoxq %rcx, %r10 # A[1] * B[6] mulx 48(%rbp), %rax, %rcx - movq %r9, 48(%rsp) + movq %r9, 48(%rbx) adcxq %rax, %r10 adoxq %rcx, %r11 # A[1] * B[7] mulx 56(%rbp), %rax, %rcx - movq %r10, 56(%rsp) + movq %r10, 56(%rbx) adcxq %rax, %r11 adoxq %rcx, %r12 - movq %r11, 64(%rsp) - movq 80(%rsp), %r8 - movq 88(%rsp), %r9 - movq 96(%rsp), %r10 - movq 104(%rsp), %r11 + 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(%rsp) + movq %r12, 72(%rbx) adcxq %rax, %r8 adoxq %rcx, %r9 # A[1] * B[10] mulx 80(%rbp), %rax, %rcx - movq %r8, 80(%rsp) + movq %r8, 80(%rbx) adcxq %rax, %r9 adoxq %rcx, %r10 # A[1] * B[11] mulx 88(%rbp), %rax, %rcx - movq %r9, 88(%rsp) + movq %r9, 88(%rbx) adcxq %rax, %r10 adoxq %rcx, %r11 - movq %r10, 96(%rsp) - movq %r15, %r12 - movq %rbx, %r8 + movq %r10, 96(%rbx) + movq 112(%rbx), %r12 + movq 120(%rbx), %r8 movq 128(%rdi), %r9 # A[1] * B[12] mulx 96(%rbp), %rax, %rcx @@ -3107,17 +3111,17 @@ _sp_2048_mul_avx2_16: adoxq %rcx, %r12 # A[1] * B[13] mulx 104(%rbp), %rax, %rcx - movq %r11, 104(%rsp) + movq %r11, 104(%rbx) adcxq %rax, %r12 adoxq %rcx, %r8 # A[1] * B[14] mulx 112(%rbp), %rax, %rcx - movq %r12, %r15 + movq %r12, 112(%rbx) adcxq %rax, %r8 adoxq %rcx, %r9 # A[1] * B[15] mulx 120(%rbp), %rax, %rcx - movq %r8, %rbx + movq %r8, 120(%rbx) movq %r14, %r10 adcxq %rax, %r9 adoxq %rcx, %r10 @@ -3128,80 +3132,80 @@ _sp_2048_mul_avx2_16: movq %r9, 128(%rdi) movq %r10, 136(%rdi) movq 16(%rsi), %rdx - movq 16(%rsp), %r10 - movq 24(%rsp), %r11 - movq 32(%rsp), %r12 - movq 40(%rsp), %r8 - movq 48(%rsp), %r9 + 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(%rsp) + movq %r10, 16(%rbx) adcxq %rax, %r11 adoxq %rcx, %r12 # A[2] * B[2] mulx 16(%rbp), %rax, %rcx - movq %r11, 24(%rsp) + movq %r11, 24(%rbx) adcxq %rax, %r12 adoxq %rcx, %r8 # A[2] * B[3] mulx 24(%rbp), %rax, %rcx - movq %r12, 32(%rsp) + movq %r12, 32(%rbx) adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r8, 40(%rsp) - movq 56(%rsp), %r10 - movq 64(%rsp), %r11 - movq 72(%rsp), %r12 - movq 80(%rsp), %r8 + 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(%rsp) + movq %r9, 48(%rbx) adcxq %rax, %r10 adoxq %rcx, %r11 # A[2] * B[6] mulx 48(%rbp), %rax, %rcx - movq %r10, 56(%rsp) + movq %r10, 56(%rbx) adcxq %rax, %r11 adoxq %rcx, %r12 # A[2] * B[7] mulx 56(%rbp), %rax, %rcx - movq %r11, 64(%rsp) + movq %r11, 64(%rbx) adcxq %rax, %r12 adoxq %rcx, %r8 - movq %r12, 72(%rsp) - movq 88(%rsp), %r9 - movq 96(%rsp), %r10 - movq 104(%rsp), %r11 - movq %r15, %r12 + 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(%rsp) + movq %r8, 80(%rbx) adcxq %rax, %r9 adoxq %rcx, %r10 # A[2] * B[10] mulx 80(%rbp), %rax, %rcx - movq %r9, 88(%rsp) + movq %r9, 88(%rbx) adcxq %rax, %r10 adoxq %rcx, %r11 # A[2] * B[11] mulx 88(%rbp), %rax, %rcx - movq %r10, 96(%rsp) + movq %r10, 96(%rbx) adcxq %rax, %r11 adoxq %rcx, %r12 - movq %r11, 104(%rsp) - movq %rbx, %r8 + movq %r11, 104(%rbx) + movq 120(%rbx), %r8 movq 128(%rdi), %r9 movq 136(%rdi), %r10 # A[2] * B[12] @@ -3210,12 +3214,12 @@ _sp_2048_mul_avx2_16: adoxq %rcx, %r8 # A[2] * B[13] mulx 104(%rbp), %rax, %rcx - movq %r12, %r15 + movq %r12, 112(%rbx) adcxq %rax, %r8 adoxq %rcx, %r9 # A[2] * B[14] mulx 112(%rbp), %rax, %rcx - movq %r8, %rbx + movq %r8, 120(%rbx) adcxq %rax, %r9 adoxq %rcx, %r10 # A[2] * B[15] @@ -3231,79 +3235,79 @@ _sp_2048_mul_avx2_16: movq %r10, 136(%rdi) movq %r11, 144(%rdi) movq 24(%rsi), %rdx - movq 24(%rsp), %r11 - movq 32(%rsp), %r12 - movq 40(%rsp), %r8 - movq 48(%rsp), %r9 - movq 56(%rsp), %r10 + 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(%rsp) + movq %r11, 24(%rbx) adcxq %rax, %r12 adoxq %rcx, %r8 # A[3] * B[2] mulx 16(%rbp), %rax, %rcx - movq %r12, 32(%rsp) + movq %r12, 32(%rbx) adcxq %rax, %r8 adoxq %rcx, %r9 # A[3] * B[3] mulx 24(%rbp), %rax, %rcx - movq %r8, 40(%rsp) + movq %r8, 40(%rbx) adcxq %rax, %r9 adoxq %rcx, %r10 - movq %r9, 48(%rsp) - movq 64(%rsp), %r11 - movq 72(%rsp), %r12 - movq 80(%rsp), %r8 - movq 88(%rsp), %r9 + 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(%rsp) + movq %r10, 56(%rbx) adcxq %rax, %r11 adoxq %rcx, %r12 # A[3] * B[6] mulx 48(%rbp), %rax, %rcx - movq %r11, 64(%rsp) + movq %r11, 64(%rbx) adcxq %rax, %r12 adoxq %rcx, %r8 # A[3] * B[7] mulx 56(%rbp), %rax, %rcx - movq %r12, 72(%rsp) + movq %r12, 72(%rbx) adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r8, 80(%rsp) - movq 96(%rsp), %r10 - movq 104(%rsp), %r11 - movq %r15, %r12 - movq %rbx, %r8 + 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(%rsp) + movq %r9, 88(%rbx) adcxq %rax, %r10 adoxq %rcx, %r11 # A[3] * B[10] mulx 80(%rbp), %rax, %rcx - movq %r10, 96(%rsp) + movq %r10, 96(%rbx) adcxq %rax, %r11 adoxq %rcx, %r12 # A[3] * B[11] mulx 88(%rbp), %rax, %rcx - movq %r11, 104(%rsp) + movq %r11, 104(%rbx) adcxq %rax, %r12 adoxq %rcx, %r8 - movq %r12, %r15 + movq %r12, 112(%rbx) movq 128(%rdi), %r9 movq 136(%rdi), %r10 movq 144(%rdi), %r11 @@ -3313,7 +3317,7 @@ _sp_2048_mul_avx2_16: adoxq %rcx, %r9 # A[3] * B[13] mulx 104(%rbp), %rax, %rcx - movq %r8, %rbx + movq %r8, 120(%rbx) adcxq %rax, %r9 adoxq %rcx, %r10 # A[3] * B[14] @@ -3334,58 +3338,58 @@ _sp_2048_mul_avx2_16: movq %r11, 144(%rdi) movq %r12, 152(%rdi) movq 32(%rsi), %rdx - movq 32(%rsp), %r12 - movq 40(%rsp), %r8 - movq 48(%rsp), %r9 - movq 56(%rsp), %r10 - movq 64(%rsp), %r11 + 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(%rsp) + movq %r12, 32(%rbx) adcxq %rax, %r8 adoxq %rcx, %r9 # A[4] * B[2] mulx 16(%rbp), %rax, %rcx - movq %r8, 40(%rsp) + movq %r8, 40(%rbx) adcxq %rax, %r9 adoxq %rcx, %r10 # A[4] * B[3] mulx 24(%rbp), %rax, %rcx - movq %r9, 48(%rsp) + movq %r9, 48(%rbx) adcxq %rax, %r10 adoxq %rcx, %r11 - movq %r10, 56(%rsp) - movq 72(%rsp), %r12 - movq 80(%rsp), %r8 - movq 88(%rsp), %r9 - movq 96(%rsp), %r10 + 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(%rsp) + movq %r11, 64(%rbx) adcxq %rax, %r12 adoxq %rcx, %r8 # A[4] * B[6] mulx 48(%rbp), %rax, %rcx - movq %r12, 72(%rsp) + movq %r12, 72(%rbx) adcxq %rax, %r8 adoxq %rcx, %r9 # A[4] * B[7] mulx 56(%rbp), %rax, %rcx - movq %r8, 80(%rsp) + movq %r8, 80(%rbx) adcxq %rax, %r9 adoxq %rcx, %r10 - movq %r9, 88(%rsp) - movq 104(%rsp), %r11 - movq %r15, %r12 - movq %rbx, %r8 + movq %r9, 88(%rbx) + movq 104(%rbx), %r11 + movq 112(%rbx), %r12 + movq 120(%rbx), %r8 movq 128(%rdi), %r9 # A[4] * B[8] mulx 64(%rbp), %rax, %rcx @@ -3393,20 +3397,20 @@ _sp_2048_mul_avx2_16: adoxq %rcx, %r11 # A[4] * B[9] mulx 72(%rbp), %rax, %rcx - movq %r10, 96(%rsp) + movq %r10, 96(%rbx) adcxq %rax, %r11 adoxq %rcx, %r12 # A[4] * B[10] mulx 80(%rbp), %rax, %rcx - movq %r11, 104(%rsp) + movq %r11, 104(%rbx) adcxq %rax, %r12 adoxq %rcx, %r8 # A[4] * B[11] mulx 88(%rbp), %rax, %rcx - movq %r12, %r15 + movq %r12, 112(%rbx) adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r8, %rbx + movq %r8, 120(%rbx) movq 136(%rdi), %r10 movq 144(%rdi), %r11 movq 152(%rdi), %r12 @@ -3437,57 +3441,57 @@ _sp_2048_mul_avx2_16: movq %r12, 152(%rdi) movq %r8, 160(%rdi) movq 40(%rsi), %rdx - movq 40(%rsp), %r8 - movq 48(%rsp), %r9 - movq 56(%rsp), %r10 - movq 64(%rsp), %r11 - movq 72(%rsp), %r12 + 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(%rsp) + movq %r8, 40(%rbx) adcxq %rax, %r9 adoxq %rcx, %r10 # A[5] * B[2] mulx 16(%rbp), %rax, %rcx - movq %r9, 48(%rsp) + movq %r9, 48(%rbx) adcxq %rax, %r10 adoxq %rcx, %r11 # A[5] * B[3] mulx 24(%rbp), %rax, %rcx - movq %r10, 56(%rsp) + movq %r10, 56(%rbx) adcxq %rax, %r11 adoxq %rcx, %r12 - movq %r11, 64(%rsp) - movq 80(%rsp), %r8 - movq 88(%rsp), %r9 - movq 96(%rsp), %r10 - movq 104(%rsp), %r11 + 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(%rsp) + movq %r12, 72(%rbx) adcxq %rax, %r8 adoxq %rcx, %r9 # A[5] * B[6] mulx 48(%rbp), %rax, %rcx - movq %r8, 80(%rsp) + movq %r8, 80(%rbx) adcxq %rax, %r9 adoxq %rcx, %r10 # A[5] * B[7] mulx 56(%rbp), %rax, %rcx - movq %r9, 88(%rsp) + movq %r9, 88(%rbx) adcxq %rax, %r10 adoxq %rcx, %r11 - movq %r10, 96(%rsp) - movq %r15, %r12 - movq %rbx, %r8 + movq %r10, 96(%rbx) + movq 112(%rbx), %r12 + movq 120(%rbx), %r8 movq 128(%rdi), %r9 movq 136(%rdi), %r10 # A[5] * B[8] @@ -3496,17 +3500,17 @@ _sp_2048_mul_avx2_16: adoxq %rcx, %r12 # A[5] * B[9] mulx 72(%rbp), %rax, %rcx - movq %r11, 104(%rsp) + movq %r11, 104(%rbx) adcxq %rax, %r12 adoxq %rcx, %r8 # A[5] * B[10] mulx 80(%rbp), %rax, %rcx - movq %r12, %r15 + movq %r12, 112(%rbx) adcxq %rax, %r8 adoxq %rcx, %r9 # A[5] * B[11] mulx 88(%rbp), %rax, %rcx - movq %r8, %rbx + movq %r8, 120(%rbx) adcxq %rax, %r9 adoxq %rcx, %r10 movq %r9, 128(%rdi) @@ -3540,56 +3544,56 @@ _sp_2048_mul_avx2_16: movq %r8, 160(%rdi) movq %r9, 168(%rdi) movq 48(%rsi), %rdx - movq 48(%rsp), %r9 - movq 56(%rsp), %r10 - movq 64(%rsp), %r11 - movq 72(%rsp), %r12 - movq 80(%rsp), %r8 + 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(%rsp) + movq %r9, 48(%rbx) adcxq %rax, %r10 adoxq %rcx, %r11 # A[6] * B[2] mulx 16(%rbp), %rax, %rcx - movq %r10, 56(%rsp) + movq %r10, 56(%rbx) adcxq %rax, %r11 adoxq %rcx, %r12 # A[6] * B[3] mulx 24(%rbp), %rax, %rcx - movq %r11, 64(%rsp) + movq %r11, 64(%rbx) adcxq %rax, %r12 adoxq %rcx, %r8 - movq %r12, 72(%rsp) - movq 88(%rsp), %r9 - movq 96(%rsp), %r10 - movq 104(%rsp), %r11 - movq %r15, %r12 + 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(%rsp) + movq %r8, 80(%rbx) adcxq %rax, %r9 adoxq %rcx, %r10 # A[6] * B[6] mulx 48(%rbp), %rax, %rcx - movq %r9, 88(%rsp) + movq %r9, 88(%rbx) adcxq %rax, %r10 adoxq %rcx, %r11 # A[6] * B[7] mulx 56(%rbp), %rax, %rcx - movq %r10, 96(%rsp) + movq %r10, 96(%rbx) adcxq %rax, %r11 adoxq %rcx, %r12 - movq %r11, 104(%rsp) - movq %rbx, %r8 + movq %r11, 104(%rbx) + movq 120(%rbx), %r8 movq 128(%rdi), %r9 movq 136(%rdi), %r10 movq 144(%rdi), %r11 @@ -3599,12 +3603,12 @@ _sp_2048_mul_avx2_16: adoxq %rcx, %r8 # A[6] * B[9] mulx 72(%rbp), %rax, %rcx - movq %r12, %r15 + movq %r12, 112(%rbx) adcxq %rax, %r8 adoxq %rcx, %r9 # A[6] * B[10] mulx 80(%rbp), %rax, %rcx - movq %r8, %rbx + movq %r8, 120(%rbx) adcxq %rax, %r9 adoxq %rcx, %r10 # A[6] * B[11] @@ -3643,55 +3647,55 @@ _sp_2048_mul_avx2_16: movq %r9, 168(%rdi) movq %r10, 176(%rdi) movq 56(%rsi), %rdx - movq 56(%rsp), %r10 - movq 64(%rsp), %r11 - movq 72(%rsp), %r12 - movq 80(%rsp), %r8 - movq 88(%rsp), %r9 + 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(%rsp) + movq %r10, 56(%rbx) adcxq %rax, %r11 adoxq %rcx, %r12 # A[7] * B[2] mulx 16(%rbp), %rax, %rcx - movq %r11, 64(%rsp) + movq %r11, 64(%rbx) adcxq %rax, %r12 adoxq %rcx, %r8 # A[7] * B[3] mulx 24(%rbp), %rax, %rcx - movq %r12, 72(%rsp) + movq %r12, 72(%rbx) adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r8, 80(%rsp) - movq 96(%rsp), %r10 - movq 104(%rsp), %r11 - movq %r15, %r12 - movq %rbx, %r8 + 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(%rsp) + movq %r9, 88(%rbx) adcxq %rax, %r10 adoxq %rcx, %r11 # A[7] * B[6] mulx 48(%rbp), %rax, %rcx - movq %r10, 96(%rsp) + movq %r10, 96(%rbx) adcxq %rax, %r11 adoxq %rcx, %r12 # A[7] * B[7] mulx 56(%rbp), %rax, %rcx - movq %r11, 104(%rsp) + movq %r11, 104(%rbx) adcxq %rax, %r12 adoxq %rcx, %r8 - movq %r12, %r15 + movq %r12, 112(%rbx) movq 128(%rdi), %r9 movq 136(%rdi), %r10 movq 144(%rdi), %r11 @@ -3702,7 +3706,7 @@ _sp_2048_mul_avx2_16: adoxq %rcx, %r9 # A[7] * B[9] mulx 72(%rbp), %rax, %rcx - movq %r8, %rbx + movq %r8, 120(%rbx) adcxq %rax, %r9 adoxq %rcx, %r10 # A[7] * B[10] @@ -3746,34 +3750,34 @@ _sp_2048_mul_avx2_16: movq %r10, 176(%rdi) movq %r11, 184(%rdi) movq 64(%rsi), %rdx - movq 64(%rsp), %r11 - movq 72(%rsp), %r12 - movq 80(%rsp), %r8 - movq 88(%rsp), %r9 - movq 96(%rsp), %r10 + 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(%rsp) + movq %r11, 64(%rbx) adcxq %rax, %r12 adoxq %rcx, %r8 # A[8] * B[2] mulx 16(%rbp), %rax, %rcx - movq %r12, 72(%rsp) + movq %r12, 72(%rbx) adcxq %rax, %r8 adoxq %rcx, %r9 # A[8] * B[3] mulx 24(%rbp), %rax, %rcx - movq %r8, 80(%rsp) + movq %r8, 80(%rbx) adcxq %rax, %r9 adoxq %rcx, %r10 - movq %r9, 88(%rsp) - movq 104(%rsp), %r11 - movq %r15, %r12 - movq %rbx, %r8 + movq %r9, 88(%rbx) + movq 104(%rbx), %r11 + movq 112(%rbx), %r12 + movq 120(%rbx), %r8 movq 128(%rdi), %r9 # A[8] * B[4] mulx 32(%rbp), %rax, %rcx @@ -3781,20 +3785,20 @@ _sp_2048_mul_avx2_16: adoxq %rcx, %r11 # A[8] * B[5] mulx 40(%rbp), %rax, %rcx - movq %r10, 96(%rsp) + movq %r10, 96(%rbx) adcxq %rax, %r11 adoxq %rcx, %r12 # A[8] * B[6] mulx 48(%rbp), %rax, %rcx - movq %r11, 104(%rsp) + movq %r11, 104(%rbx) adcxq %rax, %r12 adoxq %rcx, %r8 # A[8] * B[7] mulx 56(%rbp), %rax, %rcx - movq %r12, %r15 + movq %r12, 112(%rbx) adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r8, %rbx + movq %r8, 120(%rbx) movq 136(%rdi), %r10 movq 144(%rdi), %r11 movq 152(%rdi), %r12 @@ -3849,33 +3853,33 @@ _sp_2048_mul_avx2_16: movq %r11, 184(%rdi) movq %r12, 192(%rdi) movq 72(%rsi), %rdx - movq 72(%rsp), %r12 - movq 80(%rsp), %r8 - movq 88(%rsp), %r9 - movq 96(%rsp), %r10 - movq 104(%rsp), %r11 + 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(%rsp) + movq %r12, 72(%rbx) adcxq %rax, %r8 adoxq %rcx, %r9 # A[9] * B[2] mulx 16(%rbp), %rax, %rcx - movq %r8, 80(%rsp) + movq %r8, 80(%rbx) adcxq %rax, %r9 adoxq %rcx, %r10 # A[9] * B[3] mulx 24(%rbp), %rax, %rcx - movq %r9, 88(%rsp) + movq %r9, 88(%rbx) adcxq %rax, %r10 adoxq %rcx, %r11 - movq %r10, 96(%rsp) - movq %r15, %r12 - movq %rbx, %r8 + movq %r10, 96(%rbx) + movq 112(%rbx), %r12 + movq 120(%rbx), %r8 movq 128(%rdi), %r9 movq 136(%rdi), %r10 # A[9] * B[4] @@ -3884,17 +3888,17 @@ _sp_2048_mul_avx2_16: adoxq %rcx, %r12 # A[9] * B[5] mulx 40(%rbp), %rax, %rcx - movq %r11, 104(%rsp) + movq %r11, 104(%rbx) adcxq %rax, %r12 adoxq %rcx, %r8 # A[9] * B[6] mulx 48(%rbp), %rax, %rcx - movq %r12, %r15 + movq %r12, 112(%rbx) adcxq %rax, %r8 adoxq %rcx, %r9 # A[9] * B[7] mulx 56(%rbp), %rax, %rcx - movq %r8, %rbx + movq %r8, 120(%rbx) adcxq %rax, %r9 adoxq %rcx, %r10 movq %r9, 128(%rdi) @@ -3952,32 +3956,32 @@ _sp_2048_mul_avx2_16: movq %r12, 192(%rdi) movq %r8, 200(%rdi) movq 80(%rsi), %rdx - movq 80(%rsp), %r8 - movq 88(%rsp), %r9 - movq 96(%rsp), %r10 - movq 104(%rsp), %r11 - movq %r15, %r12 + 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(%rsp) + movq %r8, 80(%rbx) adcxq %rax, %r9 adoxq %rcx, %r10 # A[10] * B[2] mulx 16(%rbp), %rax, %rcx - movq %r9, 88(%rsp) + movq %r9, 88(%rbx) adcxq %rax, %r10 adoxq %rcx, %r11 # A[10] * B[3] mulx 24(%rbp), %rax, %rcx - movq %r10, 96(%rsp) + movq %r10, 96(%rbx) adcxq %rax, %r11 adoxq %rcx, %r12 - movq %r11, 104(%rsp) - movq %rbx, %r8 + movq %r11, 104(%rbx) + movq 120(%rbx), %r8 movq 128(%rdi), %r9 movq 136(%rdi), %r10 movq 144(%rdi), %r11 @@ -3987,12 +3991,12 @@ _sp_2048_mul_avx2_16: adoxq %rcx, %r8 # A[10] * B[5] mulx 40(%rbp), %rax, %rcx - movq %r12, %r15 + movq %r12, 112(%rbx) adcxq %rax, %r8 adoxq %rcx, %r9 # A[10] * B[6] mulx 48(%rbp), %rax, %rcx - movq %r8, %rbx + movq %r8, 120(%rbx) adcxq %rax, %r9 adoxq %rcx, %r10 # A[10] * B[7] @@ -4055,31 +4059,31 @@ _sp_2048_mul_avx2_16: movq %r8, 200(%rdi) movq %r9, 208(%rdi) movq 88(%rsi), %rdx - movq 88(%rsp), %r9 - movq 96(%rsp), %r10 - movq 104(%rsp), %r11 - movq %r15, %r12 - movq %rbx, %r8 + 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(%rsp) + movq %r9, 88(%rbx) adcxq %rax, %r10 adoxq %rcx, %r11 # A[11] * B[2] mulx 16(%rbp), %rax, %rcx - movq %r10, 96(%rsp) + movq %r10, 96(%rbx) adcxq %rax, %r11 adoxq %rcx, %r12 # A[11] * B[3] mulx 24(%rbp), %rax, %rcx - movq %r11, 104(%rsp) + movq %r11, 104(%rbx) adcxq %rax, %r12 adoxq %rcx, %r8 - movq %r12, %r15 + movq %r12, 112(%rbx) movq 128(%rdi), %r9 movq 136(%rdi), %r10 movq 144(%rdi), %r11 @@ -4090,7 +4094,7 @@ _sp_2048_mul_avx2_16: adoxq %rcx, %r9 # A[11] * B[5] mulx 40(%rbp), %rax, %rcx - movq %r8, %rbx + movq %r8, 120(%rbx) adcxq %rax, %r9 adoxq %rcx, %r10 # A[11] * B[6] @@ -4158,10 +4162,10 @@ _sp_2048_mul_avx2_16: movq %r9, 208(%rdi) movq %r10, 216(%rdi) movq 96(%rsi), %rdx - movq 96(%rsp), %r10 - movq 104(%rsp), %r11 - movq %r15, %r12 - movq %rbx, %r8 + movq 96(%rbx), %r10 + movq 104(%rbx), %r11 + movq 112(%rbx), %r12 + movq 120(%rbx), %r8 movq 128(%rdi), %r9 # A[12] * B[0] mulx (%rbp), %rax, %rcx @@ -4169,20 +4173,20 @@ _sp_2048_mul_avx2_16: adoxq %rcx, %r11 # A[12] * B[1] mulx 8(%rbp), %rax, %rcx - movq %r10, 96(%rsp) + movq %r10, 96(%rbx) adcxq %rax, %r11 adoxq %rcx, %r12 # A[12] * B[2] mulx 16(%rbp), %rax, %rcx - movq %r11, 104(%rsp) + movq %r11, 104(%rbx) adcxq %rax, %r12 adoxq %rcx, %r8 # A[12] * B[3] mulx 24(%rbp), %rax, %rcx - movq %r12, %r15 + movq %r12, 112(%rbx) adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r8, %rbx + movq %r8, 120(%rbx) movq 136(%rdi), %r10 movq 144(%rdi), %r11 movq 152(%rdi), %r12 @@ -4261,9 +4265,9 @@ _sp_2048_mul_avx2_16: movq %r10, 216(%rdi) movq %r11, 224(%rdi) movq 104(%rsi), %rdx - movq 104(%rsp), %r11 - movq %r15, %r12 - movq %rbx, %r8 + movq 104(%rbx), %r11 + movq 112(%rbx), %r12 + movq 120(%rbx), %r8 movq 128(%rdi), %r9 movq 136(%rdi), %r10 # A[13] * B[0] @@ -4272,17 +4276,17 @@ _sp_2048_mul_avx2_16: adoxq %rcx, %r12 # A[13] * B[1] mulx 8(%rbp), %rax, %rcx - movq %r11, 104(%rsp) + movq %r11, 104(%rbx) adcxq %rax, %r12 adoxq %rcx, %r8 # A[13] * B[2] mulx 16(%rbp), %rax, %rcx - movq %r12, %r15 + movq %r12, 112(%rbx) adcxq %rax, %r8 adoxq %rcx, %r9 # A[13] * B[3] mulx 24(%rbp), %rax, %rcx - movq %r8, %rbx + movq %r8, 120(%rbx) adcxq %rax, %r9 adoxq %rcx, %r10 movq %r9, 128(%rdi) @@ -4364,8 +4368,8 @@ _sp_2048_mul_avx2_16: movq %r11, 224(%rdi) movq %r12, 232(%rdi) movq 112(%rsi), %rdx - movq %r15, %r12 - movq %rbx, %r8 + movq 112(%rbx), %r12 + movq 120(%rbx), %r8 movq 128(%rdi), %r9 movq 136(%rdi), %r10 movq 144(%rdi), %r11 @@ -4375,12 +4379,12 @@ _sp_2048_mul_avx2_16: adoxq %rcx, %r8 # A[14] * B[1] mulx 8(%rbp), %rax, %rcx - movq %r12, %r15 + movq %r12, 112(%rbx) adcxq %rax, %r8 adoxq %rcx, %r9 # A[14] * B[2] mulx 16(%rbp), %rax, %rcx - movq %r8, %rbx + movq %r8, 120(%rbx) adcxq %rax, %r9 adoxq %rcx, %r10 # A[14] * B[3] @@ -4467,7 +4471,7 @@ _sp_2048_mul_avx2_16: movq %r12, 232(%rdi) movq %r8, 240(%rdi) movq 120(%rsi), %rdx - movq %rbx, %r8 + movq 120(%rbx), %r8 movq 128(%rdi), %r9 movq 136(%rdi), %r10 movq 144(%rdi), %r11 @@ -4478,7 +4482,7 @@ _sp_2048_mul_avx2_16: adoxq %rcx, %r9 # A[15] * B[1] mulx 8(%rbp), %rax, %rcx - movq %r8, %rbx + movq %r8, 120(%rbx) adcxq %rax, %r9 adoxq %rcx, %r10 # A[15] * B[2] @@ -4566,23 +4570,34 @@ _sp_2048_mul_avx2_16: adcxq %r13, %r9 movq %r8, 240(%rdi) movq %r9, 248(%rdi) - vmovdqu (%rsp), %ymm0 - vmovdqu 32(%rsp), %ymm1 - vmovdqu 64(%rsp), %ymm2 - vmovdqu 96(%rsp), %xmm3 - vmovdqu %ymm0, (%rdi) - vmovdqu %ymm1, 32(%rdi) - vmovdqu %ymm2, 64(%rdi) - vmovdqu %xmm3, 96(%rdi) - movq %r15, 112(%rdi) - movq %rbx, 120(%rdi) + cmpq %rdi, %rsi + je L_start_2048_mul_avx2_16 + cmpq %rdi, %rbp + jne L_end_2048_mul_avx2_16 +L_start_2048_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_2048_mul_avx2_16: addq $128, %rsp - pop %rbx - pop %r15 pop %r14 pop %r13 pop %r12 pop %rbp + pop %rbx repz retq #ifndef __APPLE__ .size sp_2048_mul_avx2_16,.-sp_2048_mul_avx2_16 @@ -4607,16 +4622,16 @@ _sp_2048_sqr_avx2_16: push %rbp push %r12 push %r13 + push %r14 + push %r15 + push %rbx subq $128, %rsp cmpq %rdi, %rsi movq %rsp, %rbp cmovne %rdi, %rbp - xorq %r12, %r12 - # Diagonal 1 - xorq %r8, %r8 - xorq %r9, %r9 - xorq %r10, %r10 xorq %r11, %r11 + # Diagonal 1 + xorq %r10, %r10 # A[1] x A[0] movq (%rsi), %rdx mulxq 8(%rsi), %r8, %r9 @@ -4624,70 +4639,70 @@ _sp_2048_sqr_avx2_16: 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, %r11 - movq %r8, 8(%rbp) - movq %r9, 16(%rbp) - movq %r10, 24(%rbp) - movq %r12, %r8 - movq %r12, %r9 - movq %r12, %r10 + adoxq %rcx, %r8 # A[4] x A[0] mulxq 32(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 + 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, %r8 - adoxq %rcx, %r9 + adcxq %rax, %r9 + adoxq %rcx, %r10 # A[6] x A[0] mulxq 48(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r11, 32(%rbp) - movq %r8, 40(%rbp) - movq %r9, 48(%rbp) - movq %r12, %r11 - movq %r12, %r8 - movq %r12, %r9 + 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, %r10 - adoxq %rcx, %r11 - # A[8] x A[0] - mulxq 64(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[9] x A[0] - mulxq 72(%rsi), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r10, 56(%rbp) - movq %r11, 64(%rbp) - movq %r8, 72(%rbp) - movq %r12, %r10 - movq %r12, %r11 - movq %r12, %r8 - # A[10] x A[0] - mulxq 80(%rsi), %rax, %rcx + # 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, %r10 - adoxq %rcx, %r11 + adcxq %rax, %r9 + adoxq %rcx, %r10 # A[12] x A[0] mulxq 96(%rsi), %rax, %rcx - adcxq %rax, %r11 + adcxq %rax, %r10 adoxq %rcx, %r8 - movq %r9, 80(%rbp) - movq %r10, 88(%rbp) - movq %r11, 96(%rbp) - movq %r12, %r9 - movq %r12, %r10 - movq %r12, %r11 + 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 @@ -4696,323 +4711,323 @@ _sp_2048_sqr_avx2_16: 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, %r11 - movq %r8, 104(%rbp) - movq %r9, 112(%rbp) - movq %r10, 120(%rbp) + adoxq %rcx, %r8 + movq %r10, %rbx # Carry - adcxq %r12, %r11 - movq %r12, %r13 - adcxq %r12, %r13 - adoxq %r12, %r13 - movq %r11, 128(%rdi) + adcxq %r11, %r8 + movq %r11, %r12 + adcxq %r11, %r12 + adoxq %r11, %r12 + movq %r8, 128(%rdi) # Diagonal 2 - movq 24(%rbp), %r11 - movq 32(%rbp), %r8 - movq 40(%rbp), %r9 - movq 48(%rbp), %r10 + 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, %r11 - adoxq %rcx, %r8 + adcxq %rax, %r8 + adoxq %rcx, %r9 # A[3] x A[1] mulxq 24(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 + 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, %r9 - adoxq %rcx, %r10 - movq %r11, 24(%rbp) - movq %r8, 32(%rbp) - movq %r9, 40(%rbp) - movq 56(%rbp), %r11 - movq 64(%rbp), %r8 - movq 72(%rbp), %r9 + adcxq %rax, %r10 + adoxq %rcx, %r8 # A[5] x A[1] mulxq 40(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[6] x A[1] - mulxq 48(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[7] x A[1] - mulxq 56(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r10, 48(%rbp) - movq %r11, 56(%rbp) - movq %r8, 64(%rbp) - movq 80(%rbp), %r10 - movq 88(%rbp), %r11 - movq 96(%rbp), %r8 - # A[8] x A[1] - mulxq 64(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[9] x A[1] - mulxq 72(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[10] x A[1] - mulxq 80(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - movq %r9, 72(%rbp) - movq %r10, 80(%rbp) - movq %r11, 88(%rbp) - movq 104(%rbp), %r9 - movq 112(%rbp), %r10 - movq 120(%rbp), %r11 - # A[11] x A[1] - mulxq 88(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[12] x A[1] - mulxq 96(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[13] x A[1] - mulxq 104(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r8, 96(%rbp) - movq %r9, 104(%rbp) - movq %r10, 112(%rbp) - movq 128(%rdi), %r8 - movq %r12, %r9 - movq %r12, %r10 - # A[14] x A[1] - mulxq 112(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[15] x A[1] - mulxq 120(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[15] x A[2] - movq 16(%rsi), %rdx - mulxq 120(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r11, 120(%rbp) - movq %r8, 128(%rdi) - movq %r9, 136(%rdi) - # Carry - adcxq %r13, %r10 - movq %r12, %r13 - adcxq %r12, %r13 - adoxq %r12, %r13 - movq %r10, 144(%rdi) - # Diagonal 3 - movq 40(%rbp), %r10 - movq 48(%rbp), %r11 - movq 56(%rbp), %r8 - movq 64(%rbp), %r9 - # A[3] x A[2] - mulxq 24(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[4] x A[2] - mulxq 32(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[5] x A[2] - mulxq 40(%rsi), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 movq %r10, 40(%rbp) - movq %r11, 48(%rbp) - movq %r8, 56(%rbp) - movq 72(%rbp), %r10 - movq 80(%rbp), %r11 - movq 88(%rbp), %r8 - # A[6] x A[2] + 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[2] + # A[7] x A[1] mulxq 56(%rsi), %rax, %rcx adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[8] x A[2] - mulxq 64(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - movq %r9, 64(%rbp) - movq %r10, 72(%rbp) - movq %r11, 80(%rbp) - movq 96(%rbp), %r9 - movq 104(%rbp), %r10 - movq 112(%rbp), %r11 - # A[9] x A[2] - mulxq 72(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[10] x A[2] - mulxq 80(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[11] x A[2] - mulxq 88(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r8, 88(%rbp) - movq %r9, 96(%rbp) - movq %r10, 104(%rbp) - movq 120(%rbp), %r8 - movq 128(%rdi), %r9 - movq 136(%rdi), %r10 - # A[12] x A[2] - mulxq 96(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[13] x A[2] - mulxq 104(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[14] x A[2] - mulxq 112(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r11, 112(%rbp) - movq %r8, 120(%rbp) - movq %r9, 128(%rdi) - movq 144(%rdi), %r11 - movq %r12, %r8 - movq %r12, %r9 - # A[14] x A[3] - movq 112(%rsi), %rdx - mulxq 24(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[14] x A[4] - mulxq 32(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[14] x A[5] - mulxq 40(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r10, 136(%rdi) - movq %r11, 144(%rdi) - movq %r8, 152(%rdi) - # Carry - adcxq %r13, %r9 - movq %r12, %r13 - adcxq %r12, %r13 - adoxq %r12, %r13 - movq %r9, 160(%rdi) - # Diagonal 4 - movq 56(%rbp), %r9 - movq 64(%rbp), %r10 - movq 72(%rbp), %r11 - movq 80(%rbp), %r8 - # A[4] x A[3] - movq 24(%rsi), %rdx - mulxq 32(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[5] x A[3] - mulxq 40(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[6] x A[3] - mulxq 48(%rsi), %rax, %rcx - adcxq %rax, %r11 adoxq %rcx, %r8 movq %r9, 56(%rbp) movq %r10, 64(%rbp) - movq %r11, 72(%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 128(%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, 128(%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) + # Carry + adcxq %r12, %r8 + movq %r11, %r12 + adcxq %r11, %r12 + adoxq %r11, %r12 + movq %r8, 144(%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 128(%rdi), %r10 + movq 136(%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, 128(%rdi) + movq 144(%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, 136(%rdi) + movq %r9, 144(%rdi) + movq %r11, %r8 + # A[14] x A[5] + mulxq 40(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 + movq %r10, 152(%rdi) + # Carry + adcxq %r12, %r8 + movq %r11, %r12 + adcxq %r11, %r12 + adoxq %r11, %r12 + movq %r8, 160(%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 - movq 96(%rbp), %r10 - movq 104(%rbp), %r11 + # 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, %r10 + adoxq %rcx, %r13 # A[9] x A[3] mulxq 72(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r8, 80(%rbp) + adcxq %rax, %r13 + adoxq %rcx, %r14 movq %r9, 88(%rbp) - movq %r10, 96(%rbp) - movq 112(%rbp), %r8 - movq 120(%rbp), %r9 - movq 128(%rdi), %r10 + # No store %r13 + # No load %r15 - %r9 + # No load %rbx - %r10 # A[10] x A[3] mulxq 80(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 + adcxq %rax, %r14 + adoxq %rcx, %r15 # A[11] x A[3] mulxq 88(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 + adcxq %rax, %r15 + adoxq %rcx, %rbx + # No store %r14 + # No store %r15 + movq 128(%rdi), %r8 + movq 136(%rdi), %r9 # A[12] x A[3] mulxq 96(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r11, 104(%rbp) - movq %r8, 112(%rbp) - movq %r9, 120(%rbp) - movq 136(%rdi), %r11 - movq 144(%rdi), %r8 - movq 152(%rdi), %r9 + adcxq %rax, %rbx + adoxq %rcx, %r8 # A[13] x A[3] mulxq 104(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 + adcxq %rax, %r8 + adoxq %rcx, %r9 + # No store %rbx + movq %r8, 128(%rdi) + movq 144(%rdi), %r10 + movq 152(%rdi), %r8 # A[13] x A[4] movq 104(%rsi), %rdx mulxq 32(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[13] x A[5] - mulxq 40(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r10, 128(%rdi) - movq %r11, 136(%rdi) - movq %r8, 144(%rdi) - movq 160(%rdi), %r10 - movq %r12, %r11 - movq %r12, %r8 - # A[13] x A[6] - mulxq 48(%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, 136(%rdi) + movq %r10, 144(%rdi) + movq 160(%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, %r10 - adoxq %rcx, %r11 + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r8, 152(%rdi) + movq %r9, 160(%rdi) + movq %r11, %r8 # A[13] x A[8] mulxq 64(%rsi), %rax, %rcx - adcxq %rax, %r11 + adcxq %rax, %r10 adoxq %rcx, %r8 - movq %r9, 152(%rdi) - movq %r10, 160(%rdi) - movq %r11, 168(%rdi) + movq %r10, 168(%rdi) # Carry - adcxq %r13, %r8 - movq %r12, %r13 - adcxq %r12, %r13 - adoxq %r12, %r13 + adcxq %r12, %r8 + movq %r11, %r12 + adcxq %r11, %r12 + adoxq %r11, %r12 movq %r8, 176(%rdi) # Diagonal 5 movq 72(%rbp), %r8 movq 80(%rbp), %r9 movq 88(%rbp), %r10 - movq 96(%rbp), %r11 # A[5] x A[4] movq 32(%rsi), %rdx mulxq 40(%rsi), %rax, %rcx @@ -5022,71 +5037,71 @@ _sp_2048_sqr_avx2_16: 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, %r11 - movq %r8, 72(%rbp) - movq %r9, 80(%rbp) - movq %r10, 88(%rbp) - movq 104(%rbp), %r8 - movq 112(%rbp), %r9 - movq 120(%rbp), %r10 + adoxq %rcx, %r13 # A[8] x A[4] mulxq 64(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 + 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, %r8 - adoxq %rcx, %r9 + adcxq %rax, %r14 + adoxq %rcx, %r15 # A[10] x A[4] mulxq 80(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r11, 96(%rbp) - movq %r8, 104(%rbp) - movq %r9, 112(%rbp) - movq 128(%rdi), %r11 - movq 136(%rdi), %r8 - movq 144(%rdi), %r9 + adcxq %rax, %r15 + adoxq %rcx, %rbx + # No store %r14 + # No store %r15 + movq 128(%rdi), %r9 + movq 136(%rdi), %r10 # A[11] x A[4] mulxq 88(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 + adcxq %rax, %rbx + adoxq %rcx, %r9 # A[12] x A[4] mulxq 96(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 + adcxq %rax, %r9 + adoxq %rcx, %r10 + # No store %rbx + movq %r9, 128(%rdi) + movq 144(%rdi), %r8 + movq 152(%rdi), %r9 # A[12] x A[5] movq 96(%rsi), %rdx mulxq 40(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r10, 120(%rbp) - movq %r11, 128(%rdi) - movq %r8, 136(%rdi) - movq 152(%rdi), %r10 - movq 160(%rdi), %r11 - movq 168(%rdi), %r8 + adcxq %rax, %r10 + adoxq %rcx, %r8 # A[12] x A[6] mulxq 48(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r10, 136(%rdi) + movq %r8, 144(%rdi) + movq 160(%rdi), %r10 + movq 168(%rdi), %r8 # A[12] x A[7] mulxq 56(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 + adcxq %rax, %r9 + adoxq %rcx, %r10 # A[12] x A[8] mulxq 64(%rsi), %rax, %rcx - adcxq %rax, %r11 + adcxq %rax, %r10 adoxq %rcx, %r8 - movq %r9, 144(%rdi) - movq %r10, 152(%rdi) - movq %r11, 160(%rdi) + movq %r9, 152(%rdi) + movq %r10, 160(%rdi) movq 176(%rdi), %r9 - movq %r12, %r10 - movq %r12, %r11 + movq %r11, %r10 # A[12] x A[9] mulxq 72(%rsi), %rax, %rcx adcxq %rax, %r8 @@ -5095,84 +5110,86 @@ _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 %r11, %r8 # A[12] x A[11] mulxq 88(%rsi), %rax, %rcx adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r8, 168(%rdi) - movq %r9, 176(%rdi) + adoxq %rcx, %r8 movq %r10, 184(%rdi) # Carry - adcxq %r13, %r11 - movq %r12, %r13 - adcxq %r12, %r13 - adoxq %r12, %r13 - movq %r11, 192(%rdi) + adcxq %r12, %r8 + movq %r11, %r12 + adcxq %r11, %r12 + adoxq %r11, %r12 + movq %r8, 192(%rdi) # Diagonal 6 - movq 88(%rbp), %r11 - movq 96(%rbp), %r8 - movq 104(%rbp), %r9 - movq 112(%rbp), %r10 + 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, %r11 - adoxq %rcx, %r8 + adcxq %rax, %r8 + adoxq %rcx, %r13 # A[7] x A[5] mulxq 56(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 + 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, %r9 - adoxq %rcx, %r10 - movq %r11, 88(%rbp) - movq %r8, 96(%rbp) - movq %r9, 104(%rbp) - movq 120(%rbp), %r11 - movq 128(%rdi), %r8 - movq 136(%rdi), %r9 + adcxq %rax, %r14 + adoxq %rcx, %r15 # A[9] x A[5] mulxq 72(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 + adcxq %rax, %r15 + adoxq %rcx, %rbx + # No store %r14 + # No store %r15 + movq 128(%rdi), %r10 + movq 136(%rdi), %r8 # A[10] x A[5] mulxq 80(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 + adcxq %rax, %rbx + adoxq %rcx, %r10 # A[11] x A[5] mulxq 88(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r10, 112(%rbp) - movq %r11, 120(%rbp) - movq %r8, 128(%rdi) - movq 144(%rdi), %r10 - movq 152(%rdi), %r11 - movq 160(%rdi), %r8 + adcxq %rax, %r10 + adoxq %rcx, %r8 + # No store %rbx + movq %r10, 128(%rdi) + movq 144(%rdi), %r9 + movq 152(%rdi), %r10 # A[11] x A[6] movq 88(%rsi), %rdx mulxq 48(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 + adcxq %rax, %r8 + adoxq %rcx, %r9 # A[11] x A[7] mulxq 56(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r8, 136(%rdi) + movq %r9, 144(%rdi) + movq 160(%rdi), %r8 + movq 168(%rdi), %r9 # A[11] x A[8] mulxq 64(%rsi), %rax, %rcx - adcxq %rax, %r11 + adcxq %rax, %r10 adoxq %rcx, %r8 - movq %r9, 136(%rdi) - movq %r10, 144(%rdi) - movq %r11, 152(%rdi) - movq 168(%rdi), %r9 - movq 176(%rdi), %r10 - movq 184(%rdi), %r11 # A[11] x A[9] 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 # A[11] x A[10] mulxq 80(%rsi), %rax, %rcx adcxq %rax, %r9 @@ -5181,77 +5198,75 @@ _sp_2048_sqr_avx2_16: movq 104(%rsi), %rdx mulxq 72(%rsi), %rax, %rcx adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r8, 160(%rdi) + adoxq %rcx, %r8 movq %r9, 168(%rdi) movq %r10, 176(%rdi) - movq 192(%rdi), %r8 - movq %r12, %r9 - movq %r12, %r10 + movq 192(%rdi), %r9 + movq %r11, %r10 # A[13] x A[10] mulxq 80(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[13] x A[11] - mulxq 88(%rsi), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 - # A[13] x A[12] - mulxq 96(%rsi), %rax, %rcx + # A[13] x A[11] + mulxq 88(%rsi), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r10 - movq %r11, 184(%rdi) - movq %r8, 192(%rdi) - movq %r9, 200(%rdi) + movq %r8, 184(%rdi) + movq %r9, 192(%rdi) + movq %r11, %r8 + # A[13] x A[12] + mulxq 96(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 + movq %r10, 200(%rdi) # Carry - adcxq %r13, %r10 - movq %r12, %r13 - adcxq %r12, %r13 - adoxq %r12, %r13 - movq %r10, 208(%rdi) + adcxq %r12, %r8 + movq %r11, %r12 + adcxq %r11, %r12 + adoxq %r11, %r12 + movq %r8, 208(%rdi) # Diagonal 7 - movq 104(%rbp), %r10 - movq 112(%rbp), %r11 - movq 120(%rbp), %r8 - movq 128(%rdi), %r9 + # 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, %r10 - adoxq %rcx, %r11 + adcxq %rax, %r14 + adoxq %rcx, %r15 # A[8] x A[6] mulxq 64(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 + adcxq %rax, %r15 + adoxq %rcx, %rbx + # No store %r14 + # No store %r15 + movq 128(%rdi), %r8 + movq 136(%rdi), %r9 # A[9] x A[6] mulxq 72(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r10, 104(%rbp) - movq %r11, 112(%rbp) - movq %r8, 120(%rbp) - movq 136(%rdi), %r10 - movq 144(%rdi), %r11 - movq 152(%rdi), %r8 + adcxq %rax, %rbx + adoxq %rcx, %r8 # A[10] x A[6] mulxq 80(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 + adcxq %rax, %r8 + adoxq %rcx, %r9 + # No store %rbx + movq %r8, 128(%rdi) + movq 144(%rdi), %r10 + movq 152(%rdi), %r8 # A[10] x A[7] movq 80(%rsi), %rdx mulxq 56(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 + adcxq %rax, %r9 + adoxq %rcx, %r10 # A[10] x A[8] mulxq 64(%rsi), %rax, %rcx - adcxq %rax, %r11 + adcxq %rax, %r10 adoxq %rcx, %r8 - movq %r9, 128(%rdi) - movq %r10, 136(%rdi) - movq %r11, 144(%rdi) + movq %r9, 136(%rdi) + movq %r10, 144(%rdi) movq 160(%rdi), %r9 movq 168(%rdi), %r10 - movq 176(%rdi), %r11 # A[10] x A[9] mulxq 72(%rsi), %rax, %rcx adcxq %rax, %r8 @@ -5261,85 +5276,87 @@ _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 # A[14] x A[7] mulxq 56(%rsi), %rax, %rcx adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r8, 152(%rdi) - movq %r9, 160(%rdi) - movq %r10, 168(%rdi) - movq 184(%rdi), %r8 - movq 192(%rdi), %r9 - movq 200(%rdi), %r10 + adoxq %rcx, %r8 # A[14] x A[8] mulxq 64(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r10, 168(%rdi) + movq %r8, 176(%rdi) + movq 192(%rdi), %r10 + movq 200(%rdi), %r8 # A[14] x A[9] mulxq 72(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[14] x A[10] - mulxq 80(%rsi), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r10 - movq %r11, 176(%rdi) - movq %r8, 184(%rdi) - movq %r9, 192(%rdi) - movq 208(%rdi), %r11 - movq %r12, %r8 - movq %r12, %r9 + # A[14] x A[10] + mulxq 80(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 + movq %r9, 184(%rdi) + movq %r10, 192(%rdi) + movq 208(%rdi), %r9 + movq %r11, %r10 # A[14] x A[11] mulxq 88(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[14] x A[12] - mulxq 96(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[14] x A[13] - mulxq 104(%rsi), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r10, 200(%rdi) - movq %r11, 208(%rdi) - movq %r8, 216(%rdi) + # A[14] x A[12] + mulxq 96(%rsi), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r8, 200(%rdi) + movq %r9, 208(%rdi) + movq %r11, %r8 + # A[14] x A[13] + mulxq 104(%rsi), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 + movq %r10, 216(%rdi) # Carry - adcxq %r13, %r9 - movq %r12, %r13 - adcxq %r12, %r13 - adoxq %r12, %r13 - movq %r9, 224(%rdi) + adcxq %r12, %r8 + movq %r11, %r12 + adcxq %r11, %r12 + adoxq %r11, %r12 + movq %r8, 224(%rdi) # Diagonal 8 - movq 120(%rbp), %r9 - movq 128(%rdi), %r10 - movq 136(%rdi), %r11 - movq 144(%rdi), %r8 + # No load %rbx - %r8 + movq 128(%rdi), %r9 + movq 136(%rdi), %r10 # A[8] x A[7] movq 56(%rsi), %rdx mulxq 64(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 + adcxq %rax, %rbx + adoxq %rcx, %r9 # A[9] x A[7] mulxq 72(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 + adcxq %rax, %r9 + adoxq %rcx, %r10 + # No store %rbx + movq %r9, 128(%rdi) + movq 144(%rdi), %r8 + movq 152(%rdi), %r9 # A[9] x A[8] movq 64(%rsi), %rdx mulxq 72(%rsi), %rax, %rcx - adcxq %rax, %r11 + adcxq %rax, %r10 adoxq %rcx, %r8 - movq %r9, 120(%rbp) - movq %r10, 128(%rdi) - movq %r11, 136(%rdi) - movq 152(%rdi), %r9 - movq 160(%rdi), %r10 - movq 168(%rdi), %r11 # A[15] x A[3] movq 120(%rsi), %rdx 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 # A[15] x A[4] mulxq 32(%rsi), %rax, %rcx adcxq %rax, %r9 @@ -5347,71 +5364,70 @@ _sp_2048_sqr_avx2_16: # A[15] x A[5] mulxq 40(%rsi), %rax, %rcx adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r8, 144(%rdi) + adoxq %rcx, %r8 movq %r9, 152(%rdi) movq %r10, 160(%rdi) - movq 176(%rdi), %r8 - movq 184(%rdi), %r9 - movq 192(%rdi), %r10 + movq 176(%rdi), %r9 + movq 184(%rdi), %r10 # A[15] x A[6] mulxq 48(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 + adcxq %rax, %r8 + adoxq %rcx, %r9 # A[15] x A[7] mulxq 56(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r8, 168(%rdi) + movq %r9, 176(%rdi) + movq 192(%rdi), %r8 + movq 200(%rdi), %r9 # A[15] x A[8] mulxq 64(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r11, 168(%rdi) - movq %r8, 176(%rdi) - movq %r9, 184(%rdi) - movq 200(%rdi), %r11 - movq 208(%rdi), %r8 - movq 216(%rdi), %r9 + adcxq %rax, %r10 + adoxq %rcx, %r8 # A[15] x A[9] mulxq 72(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[15] x A[10] - mulxq 80(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[15] x A[11] - mulxq 88(%rsi), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r10, 192(%rdi) - movq %r11, 200(%rdi) - movq %r8, 208(%rdi) - movq 224(%rdi), %r10 - movq %r12, %r11 - movq %r12, %r8 - # A[15] x A[12] - mulxq 96(%rsi), %rax, %rcx + movq %r10, 184(%rdi) + movq %r8, 192(%rdi) + movq 208(%rdi), %r10 + movq 216(%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, 200(%rdi) + movq %r10, 208(%rdi) + movq 224(%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, %r10 - adoxq %rcx, %r11 + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r8, 216(%rdi) + movq %r9, 224(%rdi) + movq %r11, %r8 # A[15] x A[14] mulxq 112(%rsi), %rax, %rcx - adcxq %rax, %r11 + adcxq %rax, %r10 adoxq %rcx, %r8 - movq %r9, 216(%rdi) - movq %r10, 224(%rdi) - movq %r11, 232(%rdi) + movq %r10, 232(%rdi) # Carry - adcxq %r13, %r8 - movq %r12, %r13 - adcxq %r12, %r13 - adoxq %r12, %r13 + adcxq %r12, %r8 + movq %r11, %r12 + adcxq %r11, %r12 + adoxq %r11, %r12 movq %r8, 240(%rdi) - movq %r13, 248(%rdi) + movq %r12, 248(%rdi) # Double and Add in A[i] x A[i] movq 8(%rbp), %r9 # A[0] x A[0] @@ -5427,8 +5443,8 @@ _sp_2048_sqr_avx2_16: movq 8(%rsi), %rdx mulxq %rdx, %rax, %rcx adoxq %r8, %r8 - adcxq %rax, %r8 adoxq %r9, %r9 + adcxq %rax, %r8 adcxq %rcx, %r9 movq %r8, 16(%rbp) movq %r9, 24(%rbp) @@ -5438,8 +5454,8 @@ _sp_2048_sqr_avx2_16: movq 16(%rsi), %rdx mulxq %rdx, %rax, %rcx adoxq %r8, %r8 - adcxq %rax, %r8 adoxq %r9, %r9 + adcxq %rax, %r8 adcxq %rcx, %r9 movq %r8, 32(%rbp) movq %r9, 40(%rbp) @@ -5449,8 +5465,8 @@ _sp_2048_sqr_avx2_16: movq 24(%rsi), %rdx mulxq %rdx, %rax, %rcx adoxq %r8, %r8 - adcxq %rax, %r8 adoxq %r9, %r9 + adcxq %rax, %r8 adcxq %rcx, %r9 movq %r8, 48(%rbp) movq %r9, 56(%rbp) @@ -5460,8 +5476,8 @@ _sp_2048_sqr_avx2_16: movq 32(%rsi), %rdx mulxq %rdx, %rax, %rcx adoxq %r8, %r8 - adcxq %rax, %r8 adoxq %r9, %r9 + adcxq %rax, %r8 adcxq %rcx, %r9 movq %r8, 64(%rbp) movq %r9, 72(%rbp) @@ -5471,41 +5487,33 @@ _sp_2048_sqr_avx2_16: movq 40(%rsi), %rdx mulxq %rdx, %rax, %rcx adoxq %r8, %r8 - adcxq %rax, %r8 adoxq %r9, %r9 + adcxq %rax, %r8 adcxq %rcx, %r9 movq %r8, 80(%rbp) movq %r9, 88(%rbp) - movq 96(%rbp), %r8 - movq 104(%rbp), %r9 # A[6] x A[6] movq 48(%rsi), %rdx mulxq %rdx, %rax, %rcx - adoxq %r8, %r8 - adcxq %rax, %r8 - adoxq %r9, %r9 - adcxq %rcx, %r9 - movq %r8, 96(%rbp) - movq %r9, 104(%rbp) - movq 112(%rbp), %r8 - movq 120(%rbp), %r9 + 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 %r8, %r8 - adcxq %rax, %r8 - adoxq %r9, %r9 - adcxq %rcx, %r9 - movq %r8, 112(%rbp) - movq %r9, 120(%rbp) + adoxq %r15, %r15 + adoxq %rbx, %rbx + adcxq %rax, %r15 + adcxq %rcx, %rbx movq 128(%rdi), %r8 movq 136(%rdi), %r9 # A[8] x A[8] movq 64(%rsi), %rdx mulxq %rdx, %rax, %rcx adoxq %r8, %r8 - adcxq %rax, %r8 adoxq %r9, %r9 + adcxq %rax, %r8 adcxq %rcx, %r9 movq %r8, 128(%rdi) movq %r9, 136(%rdi) @@ -5515,8 +5523,8 @@ _sp_2048_sqr_avx2_16: movq 72(%rsi), %rdx mulxq %rdx, %rax, %rcx adoxq %r8, %r8 - adcxq %rax, %r8 adoxq %r9, %r9 + adcxq %rax, %r8 adcxq %rcx, %r9 movq %r8, 144(%rdi) movq %r9, 152(%rdi) @@ -5526,8 +5534,8 @@ _sp_2048_sqr_avx2_16: movq 80(%rsi), %rdx mulxq %rdx, %rax, %rcx adoxq %r8, %r8 - adcxq %rax, %r8 adoxq %r9, %r9 + adcxq %rax, %r8 adcxq %rcx, %r9 movq %r8, 160(%rdi) movq %r9, 168(%rdi) @@ -5537,8 +5545,8 @@ _sp_2048_sqr_avx2_16: movq 88(%rsi), %rdx mulxq %rdx, %rax, %rcx adoxq %r8, %r8 - adcxq %rax, %r8 adoxq %r9, %r9 + adcxq %rax, %r8 adcxq %rcx, %r9 movq %r8, 176(%rdi) movq %r9, 184(%rdi) @@ -5548,8 +5556,8 @@ _sp_2048_sqr_avx2_16: movq 96(%rsi), %rdx mulxq %rdx, %rax, %rcx adoxq %r8, %r8 - adcxq %rax, %r8 adoxq %r9, %r9 + adcxq %rax, %r8 adcxq %rcx, %r9 movq %r8, 192(%rdi) movq %r9, 200(%rdi) @@ -5559,8 +5567,8 @@ _sp_2048_sqr_avx2_16: movq 104(%rsi), %rdx mulxq %rdx, %rax, %rcx adoxq %r8, %r8 - adcxq %rax, %r8 adoxq %r9, %r9 + adcxq %rax, %r8 adcxq %rcx, %r9 movq %r8, 208(%rdi) movq %r9, 216(%rdi) @@ -5570,8 +5578,8 @@ _sp_2048_sqr_avx2_16: movq 112(%rsi), %rdx mulxq %rdx, %rax, %rcx adoxq %r8, %r8 - adcxq %rax, %r8 adoxq %r9, %r9 + adcxq %rax, %r8 adcxq %rcx, %r9 movq %r8, 224(%rdi) movq %r9, 232(%rdi) @@ -5581,25 +5589,34 @@ _sp_2048_sqr_avx2_16: movq 120(%rsi), %rdx mulxq %rdx, %rax, %rcx adoxq %r8, %r8 - adcxq %rax, %r8 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) cmpq %rdi, %rsi jne L_end_2048_sqr_avx2_16 - vmovdqu (%rbp), %ymm0 - vmovdqu 32(%rbp), %ymm1 - vmovdqu 64(%rbp), %ymm2 - vmovdqu 96(%rbp), %ymm3 - vmovdqu 128(%rdi), %ymm4 - vmovdqu %ymm0, (%rdi) - vmovdqu %ymm1, 32(%rdi) - vmovdqu %ymm2, 64(%rdi) - vmovdqu %ymm3, 96(%rdi) - vmovdqu %ymm4, 128(%rdi) + 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_2048_sqr_avx2_16: addq $128, %rsp + pop %rbx + pop %r15 + pop %r14 pop %r13 pop %r12 pop %rbp @@ -5624,6 +5641,7 @@ sp_2048_add_16: .p2align 4 _sp_2048_add_16: #endif /* __APPLE__ */ + # Add movq (%rsi), %rcx xorq %rax, %rax addq (%rdx), %rcx @@ -5811,6 +5829,7 @@ sp_2048_add_32: .p2align 4 _sp_2048_add_32: #endif /* __APPLE__ */ + # Add movq (%rsi), %rcx xorq %rax, %rax addq (%rdx), %rcx @@ -5913,6 +5932,725 @@ _sp_2048_add_32: #ifndef __APPLE__ .size sp_2048_add_32,.-sp_2048_add_32 #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__ +.globl sp_2048_mul_32 +.type sp_2048_mul_32,@function +.align 16 +sp_2048_mul_32: +#else +.globl _sp_2048_mul_32 +.p2align 4 +_sp_2048_mul_32: +#endif /* __APPLE__ */ + push %r12 + push %r13 + push %r14 + push %r15 + subq $808, %rsp + movq %rdi, 768(%rsp) + movq %rsi, 776(%rsp) + movq %rdx, 784(%rsp) + leaq 512(%rsp), %r10 + leaq 128(%rsi), %r12 + # Add + movq (%rsi), %rax + xorq %r13, %r13 + addq (%r12), %rax + movq 8(%rsi), %rcx + movq %rax, (%r10) + adcq 8(%r12), %rcx + movq 16(%rsi), %r8 + movq %rcx, 8(%r10) + adcq 16(%r12), %r8 + movq 24(%rsi), %rax + movq %r8, 16(%r10) + adcq 24(%r12), %rax + movq 32(%rsi), %rcx + movq %rax, 24(%r10) + adcq 32(%r12), %rcx + movq 40(%rsi), %r8 + movq %rcx, 32(%r10) + adcq 40(%r12), %r8 + movq 48(%rsi), %rax + movq %r8, 40(%r10) + adcq 48(%r12), %rax + movq 56(%rsi), %rcx + movq %rax, 48(%r10) + adcq 56(%r12), %rcx + movq 64(%rsi), %r8 + movq %rcx, 56(%r10) + adcq 64(%r12), %r8 + movq 72(%rsi), %rax + movq %r8, 64(%r10) + adcq 72(%r12), %rax + movq 80(%rsi), %rcx + movq %rax, 72(%r10) + adcq 80(%r12), %rcx + movq 88(%rsi), %r8 + movq %rcx, 80(%r10) + adcq 88(%r12), %r8 + movq 96(%rsi), %rax + movq %r8, 88(%r10) + adcq 96(%r12), %rax + movq 104(%rsi), %rcx + movq %rax, 96(%r10) + adcq 104(%r12), %rcx + movq 112(%rsi), %r8 + movq %rcx, 104(%r10) + adcq 112(%r12), %r8 + movq 120(%rsi), %rax + movq %r8, 112(%r10) + adcq 120(%r12), %rax + movq %rax, 120(%r10) + adcq $0, %r13 + movq %r13, 792(%rsp) + leaq 640(%rsp), %r11 + leaq 128(%rdx), %r12 + # Add + movq (%rdx), %rax + xorq %r14, %r14 + addq (%r12), %rax + movq 8(%rdx), %rcx + movq %rax, (%r11) + adcq 8(%r12), %rcx + movq 16(%rdx), %r8 + movq %rcx, 8(%r11) + adcq 16(%r12), %r8 + movq 24(%rdx), %rax + movq %r8, 16(%r11) + adcq 24(%r12), %rax + movq 32(%rdx), %rcx + movq %rax, 24(%r11) + adcq 32(%r12), %rcx + movq 40(%rdx), %r8 + movq %rcx, 32(%r11) + adcq 40(%r12), %r8 + movq 48(%rdx), %rax + movq %r8, 40(%r11) + adcq 48(%r12), %rax + movq 56(%rdx), %rcx + movq %rax, 48(%r11) + adcq 56(%r12), %rcx + movq 64(%rdx), %r8 + movq %rcx, 56(%r11) + adcq 64(%r12), %r8 + movq 72(%rdx), %rax + movq %r8, 64(%r11) + adcq 72(%r12), %rax + movq 80(%rdx), %rcx + movq %rax, 72(%r11) + adcq 80(%r12), %rcx + movq 88(%rdx), %r8 + movq %rcx, 80(%r11) + adcq 88(%r12), %r8 + movq 96(%rdx), %rax + movq %r8, 88(%r11) + adcq 96(%r12), %rax + movq 104(%rdx), %rcx + movq %rax, 96(%r11) + adcq 104(%r12), %rcx + movq 112(%rdx), %r8 + movq %rcx, 104(%r11) + adcq 112(%r12), %r8 + movq 120(%rdx), %rax + movq %r8, 112(%r11) + adcq 120(%r12), %rax + movq %rax, 120(%r11) + adcq $0, %r14 + movq %r14, 800(%rsp) + movq %r11, %rdx + movq %r10, %rsi + movq %rsp, %rdi +#ifndef __APPLE__ + callq sp_2048_mul_16@plt +#else + callq _sp_2048_mul_16 +#endif /* __APPLE__ */ + movq 784(%rsp), %rdx + movq 776(%rsp), %rsi + leaq 256(%rsp), %rdi + addq $128, %rdx + addq $128, %rsi +#ifndef __APPLE__ + callq sp_2048_mul_16@plt +#else + callq _sp_2048_mul_16 +#endif /* __APPLE__ */ + movq 784(%rsp), %rdx + movq 776(%rsp), %rsi + movq 768(%rsp), %rdi +#ifndef __APPLE__ + callq sp_2048_mul_16@plt +#else + callq _sp_2048_mul_16 +#endif /* __APPLE__ */ + movq 792(%rsp), %r13 + movq 800(%rsp), %r14 + movq 768(%rsp), %r15 + movq %r13, %r9 + leaq 512(%rsp), %r10 + leaq 640(%rsp), %r11 + andq %r14, %r9 + negq %r13 + negq %r14 + addq $256, %r15 + movq (%r10), %rax + movq (%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, (%r10) + movq %rcx, (%r11) + movq 8(%r10), %rax + movq 8(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 8(%r10) + movq %rcx, 8(%r11) + movq 16(%r10), %rax + movq 16(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 16(%r10) + movq %rcx, 16(%r11) + movq 24(%r10), %rax + movq 24(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 24(%r10) + movq %rcx, 24(%r11) + movq 32(%r10), %rax + movq 32(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 32(%r10) + movq %rcx, 32(%r11) + movq 40(%r10), %rax + movq 40(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 40(%r10) + movq %rcx, 40(%r11) + movq 48(%r10), %rax + movq 48(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 48(%r10) + movq %rcx, 48(%r11) + movq 56(%r10), %rax + movq 56(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 56(%r10) + movq %rcx, 56(%r11) + movq 64(%r10), %rax + movq 64(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 64(%r10) + movq %rcx, 64(%r11) + movq 72(%r10), %rax + movq 72(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 72(%r10) + movq %rcx, 72(%r11) + movq 80(%r10), %rax + movq 80(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 80(%r10) + movq %rcx, 80(%r11) + movq 88(%r10), %rax + movq 88(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 88(%r10) + movq %rcx, 88(%r11) + movq 96(%r10), %rax + movq 96(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 96(%r10) + movq %rcx, 96(%r11) + movq 104(%r10), %rax + movq 104(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 104(%r10) + movq %rcx, 104(%r11) + movq 112(%r10), %rax + movq 112(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 112(%r10) + movq %rcx, 112(%r11) + movq 120(%r10), %rax + movq 120(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 120(%r10) + movq %rcx, 120(%r11) + movq (%r10), %rax + addq (%r11), %rax + movq 8(%r10), %rcx + movq %rax, (%r15) + adcq 8(%r11), %rcx + movq 16(%r10), %r8 + movq %rcx, 8(%r15) + adcq 16(%r11), %r8 + movq 24(%r10), %rax + movq %r8, 16(%r15) + adcq 24(%r11), %rax + movq 32(%r10), %rcx + movq %rax, 24(%r15) + adcq 32(%r11), %rcx + movq 40(%r10), %r8 + movq %rcx, 32(%r15) + adcq 40(%r11), %r8 + movq 48(%r10), %rax + movq %r8, 40(%r15) + adcq 48(%r11), %rax + movq 56(%r10), %rcx + movq %rax, 48(%r15) + adcq 56(%r11), %rcx + movq 64(%r10), %r8 + movq %rcx, 56(%r15) + adcq 64(%r11), %r8 + movq 72(%r10), %rax + movq %r8, 64(%r15) + adcq 72(%r11), %rax + movq 80(%r10), %rcx + movq %rax, 72(%r15) + adcq 80(%r11), %rcx + movq 88(%r10), %r8 + movq %rcx, 80(%r15) + adcq 88(%r11), %r8 + movq 96(%r10), %rax + movq %r8, 88(%r15) + adcq 96(%r11), %rax + movq 104(%r10), %rcx + movq %rax, 96(%r15) + adcq 104(%r11), %rcx + movq 112(%r10), %r8 + movq %rcx, 104(%r15) + adcq 112(%r11), %r8 + movq 120(%r10), %rax + movq %r8, 112(%r15) + adcq 120(%r11), %rax + movq %rax, 120(%r15) + adcq $0, %r9 + leaq 256(%rsp), %r11 + movq %rsp, %r10 + movq (%r10), %rax + subq (%r11), %rax + movq 8(%r10), %rcx + movq %rax, (%r10) + sbbq 8(%r11), %rcx + movq 16(%r10), %r8 + movq %rcx, 8(%r10) + sbbq 16(%r11), %r8 + movq 24(%r10), %rax + movq %r8, 16(%r10) + sbbq 24(%r11), %rax + movq 32(%r10), %rcx + movq %rax, 24(%r10) + sbbq 32(%r11), %rcx + movq 40(%r10), %r8 + movq %rcx, 32(%r10) + sbbq 40(%r11), %r8 + movq 48(%r10), %rax + movq %r8, 40(%r10) + sbbq 48(%r11), %rax + movq 56(%r10), %rcx + movq %rax, 48(%r10) + sbbq 56(%r11), %rcx + movq 64(%r10), %r8 + movq %rcx, 56(%r10) + sbbq 64(%r11), %r8 + movq 72(%r10), %rax + movq %r8, 64(%r10) + sbbq 72(%r11), %rax + movq 80(%r10), %rcx + movq %rax, 72(%r10) + sbbq 80(%r11), %rcx + movq 88(%r10), %r8 + movq %rcx, 80(%r10) + sbbq 88(%r11), %r8 + movq 96(%r10), %rax + movq %r8, 88(%r10) + sbbq 96(%r11), %rax + movq 104(%r10), %rcx + movq %rax, 96(%r10) + sbbq 104(%r11), %rcx + movq 112(%r10), %r8 + movq %rcx, 104(%r10) + sbbq 112(%r11), %r8 + movq 120(%r10), %rax + movq %r8, 112(%r10) + sbbq 120(%r11), %rax + movq 128(%r10), %rcx + movq %rax, 120(%r10) + sbbq 128(%r11), %rcx + movq 136(%r10), %r8 + movq %rcx, 128(%r10) + sbbq 136(%r11), %r8 + movq 144(%r10), %rax + movq %r8, 136(%r10) + sbbq 144(%r11), %rax + movq 152(%r10), %rcx + movq %rax, 144(%r10) + sbbq 152(%r11), %rcx + movq 160(%r10), %r8 + movq %rcx, 152(%r10) + sbbq 160(%r11), %r8 + movq 168(%r10), %rax + movq %r8, 160(%r10) + sbbq 168(%r11), %rax + movq 176(%r10), %rcx + movq %rax, 168(%r10) + sbbq 176(%r11), %rcx + movq 184(%r10), %r8 + movq %rcx, 176(%r10) + sbbq 184(%r11), %r8 + movq 192(%r10), %rax + movq %r8, 184(%r10) + sbbq 192(%r11), %rax + movq 200(%r10), %rcx + movq %rax, 192(%r10) + sbbq 200(%r11), %rcx + movq 208(%r10), %r8 + movq %rcx, 200(%r10) + sbbq 208(%r11), %r8 + movq 216(%r10), %rax + movq %r8, 208(%r10) + sbbq 216(%r11), %rax + movq 224(%r10), %rcx + movq %rax, 216(%r10) + sbbq 224(%r11), %rcx + movq 232(%r10), %r8 + movq %rcx, 224(%r10) + sbbq 232(%r11), %r8 + movq 240(%r10), %rax + movq %r8, 232(%r10) + sbbq 240(%r11), %rax + movq 248(%r10), %rcx + movq %rax, 240(%r10) + sbbq 248(%r11), %rcx + movq %rcx, 248(%r10) + sbbq $0, %r9 + movq (%r10), %rax + subq (%rdi), %rax + movq 8(%r10), %rcx + movq %rax, (%r10) + sbbq 8(%rdi), %rcx + movq 16(%r10), %r8 + movq %rcx, 8(%r10) + sbbq 16(%rdi), %r8 + movq 24(%r10), %rax + movq %r8, 16(%r10) + sbbq 24(%rdi), %rax + movq 32(%r10), %rcx + movq %rax, 24(%r10) + sbbq 32(%rdi), %rcx + movq 40(%r10), %r8 + movq %rcx, 32(%r10) + sbbq 40(%rdi), %r8 + movq 48(%r10), %rax + movq %r8, 40(%r10) + sbbq 48(%rdi), %rax + movq 56(%r10), %rcx + movq %rax, 48(%r10) + sbbq 56(%rdi), %rcx + movq 64(%r10), %r8 + movq %rcx, 56(%r10) + sbbq 64(%rdi), %r8 + movq 72(%r10), %rax + movq %r8, 64(%r10) + sbbq 72(%rdi), %rax + movq 80(%r10), %rcx + movq %rax, 72(%r10) + sbbq 80(%rdi), %rcx + movq 88(%r10), %r8 + movq %rcx, 80(%r10) + sbbq 88(%rdi), %r8 + movq 96(%r10), %rax + movq %r8, 88(%r10) + sbbq 96(%rdi), %rax + movq 104(%r10), %rcx + movq %rax, 96(%r10) + sbbq 104(%rdi), %rcx + movq 112(%r10), %r8 + movq %rcx, 104(%r10) + sbbq 112(%rdi), %r8 + movq 120(%r10), %rax + movq %r8, 112(%r10) + sbbq 120(%rdi), %rax + movq 128(%r10), %rcx + movq %rax, 120(%r10) + sbbq 128(%rdi), %rcx + movq 136(%r10), %r8 + movq %rcx, 128(%r10) + sbbq 136(%rdi), %r8 + movq 144(%r10), %rax + movq %r8, 136(%r10) + sbbq 144(%rdi), %rax + movq 152(%r10), %rcx + movq %rax, 144(%r10) + sbbq 152(%rdi), %rcx + movq 160(%r10), %r8 + movq %rcx, 152(%r10) + sbbq 160(%rdi), %r8 + movq 168(%r10), %rax + movq %r8, 160(%r10) + sbbq 168(%rdi), %rax + movq 176(%r10), %rcx + movq %rax, 168(%r10) + sbbq 176(%rdi), %rcx + movq 184(%r10), %r8 + movq %rcx, 176(%r10) + sbbq 184(%rdi), %r8 + movq 192(%r10), %rax + movq %r8, 184(%r10) + sbbq 192(%rdi), %rax + movq 200(%r10), %rcx + movq %rax, 192(%r10) + sbbq 200(%rdi), %rcx + movq 208(%r10), %r8 + movq %rcx, 200(%r10) + sbbq 208(%rdi), %r8 + movq 216(%r10), %rax + movq %r8, 208(%r10) + sbbq 216(%rdi), %rax + movq 224(%r10), %rcx + movq %rax, 216(%r10) + sbbq 224(%rdi), %rcx + movq 232(%r10), %r8 + movq %rcx, 224(%r10) + sbbq 232(%rdi), %r8 + movq 240(%r10), %rax + movq %r8, 232(%r10) + sbbq 240(%rdi), %rax + movq 248(%r10), %rcx + movq %rax, 240(%r10) + sbbq 248(%rdi), %rcx + movq %rcx, 248(%r10) + sbbq $0, %r9 + subq $128, %r15 + # Add + movq (%r15), %rax + addq (%r10), %rax + movq 8(%r15), %rcx + movq %rax, (%r15) + adcq 8(%r10), %rcx + movq 16(%r15), %r8 + movq %rcx, 8(%r15) + adcq 16(%r10), %r8 + movq 24(%r15), %rax + movq %r8, 16(%r15) + adcq 24(%r10), %rax + movq 32(%r15), %rcx + movq %rax, 24(%r15) + adcq 32(%r10), %rcx + movq 40(%r15), %r8 + movq %rcx, 32(%r15) + adcq 40(%r10), %r8 + movq 48(%r15), %rax + movq %r8, 40(%r15) + adcq 48(%r10), %rax + movq 56(%r15), %rcx + movq %rax, 48(%r15) + adcq 56(%r10), %rcx + movq 64(%r15), %r8 + movq %rcx, 56(%r15) + adcq 64(%r10), %r8 + movq 72(%r15), %rax + movq %r8, 64(%r15) + adcq 72(%r10), %rax + movq 80(%r15), %rcx + movq %rax, 72(%r15) + adcq 80(%r10), %rcx + movq 88(%r15), %r8 + movq %rcx, 80(%r15) + adcq 88(%r10), %r8 + movq 96(%r15), %rax + movq %r8, 88(%r15) + adcq 96(%r10), %rax + movq 104(%r15), %rcx + movq %rax, 96(%r15) + adcq 104(%r10), %rcx + movq 112(%r15), %r8 + movq %rcx, 104(%r15) + adcq 112(%r10), %r8 + movq 120(%r15), %rax + movq %r8, 112(%r15) + adcq 120(%r10), %rax + movq 128(%r15), %rcx + movq %rax, 120(%r15) + adcq 128(%r10), %rcx + movq 136(%r15), %r8 + movq %rcx, 128(%r15) + adcq 136(%r10), %r8 + movq 144(%r15), %rax + movq %r8, 136(%r15) + adcq 144(%r10), %rax + movq 152(%r15), %rcx + movq %rax, 144(%r15) + adcq 152(%r10), %rcx + movq 160(%r15), %r8 + movq %rcx, 152(%r15) + adcq 160(%r10), %r8 + movq 168(%r15), %rax + movq %r8, 160(%r15) + adcq 168(%r10), %rax + movq 176(%r15), %rcx + movq %rax, 168(%r15) + adcq 176(%r10), %rcx + movq 184(%r15), %r8 + movq %rcx, 176(%r15) + adcq 184(%r10), %r8 + movq 192(%r15), %rax + movq %r8, 184(%r15) + adcq 192(%r10), %rax + movq 200(%r15), %rcx + movq %rax, 192(%r15) + adcq 200(%r10), %rcx + movq 208(%r15), %r8 + movq %rcx, 200(%r15) + adcq 208(%r10), %r8 + movq 216(%r15), %rax + movq %r8, 208(%r15) + adcq 216(%r10), %rax + movq 224(%r15), %rcx + movq %rax, 216(%r15) + adcq 224(%r10), %rcx + movq 232(%r15), %r8 + movq %rcx, 224(%r15) + adcq 232(%r10), %r8 + movq 240(%r15), %rax + movq %r8, 232(%r15) + adcq 240(%r10), %rax + movq 248(%r15), %rcx + movq %rax, 240(%r15) + adcq 248(%r10), %rcx + movq %rcx, 248(%r15) + adcq $0, %r9 + movq %r9, 384(%rdi) + addq $128, %r15 + # Add + movq (%r15), %rax + xorq %r9, %r9 + addq (%r11), %rax + movq 8(%r15), %rcx + movq %rax, (%r15) + adcq 8(%r11), %rcx + movq 16(%r15), %r8 + movq %rcx, 8(%r15) + adcq 16(%r11), %r8 + movq 24(%r15), %rax + movq %r8, 16(%r15) + adcq 24(%r11), %rax + movq 32(%r15), %rcx + movq %rax, 24(%r15) + adcq 32(%r11), %rcx + movq 40(%r15), %r8 + movq %rcx, 32(%r15) + adcq 40(%r11), %r8 + movq 48(%r15), %rax + movq %r8, 40(%r15) + adcq 48(%r11), %rax + movq 56(%r15), %rcx + movq %rax, 48(%r15) + adcq 56(%r11), %rcx + movq 64(%r15), %r8 + movq %rcx, 56(%r15) + adcq 64(%r11), %r8 + movq 72(%r15), %rax + movq %r8, 64(%r15) + adcq 72(%r11), %rax + movq 80(%r15), %rcx + movq %rax, 72(%r15) + adcq 80(%r11), %rcx + movq 88(%r15), %r8 + movq %rcx, 80(%r15) + adcq 88(%r11), %r8 + movq 96(%r15), %rax + movq %r8, 88(%r15) + adcq 96(%r11), %rax + movq 104(%r15), %rcx + movq %rax, 96(%r15) + adcq 104(%r11), %rcx + movq 112(%r15), %r8 + movq %rcx, 104(%r15) + adcq 112(%r11), %r8 + movq 120(%r15), %rax + movq %r8, 112(%r15) + adcq 120(%r11), %rax + movq 128(%r15), %rcx + movq %rax, 120(%r15) + adcq 128(%r11), %rcx + movq %rcx, 128(%r15) + adcq $0, %r9 + # Add to zero + movq 136(%r11), %rax + adcq $0, %rax + movq 144(%r11), %rcx + movq %rax, 136(%r15) + adcq $0, %rcx + movq 152(%r11), %r8 + movq %rcx, 144(%r15) + adcq $0, %r8 + movq 160(%r11), %rax + movq %r8, 152(%r15) + adcq $0, %rax + movq 168(%r11), %rcx + movq %rax, 160(%r15) + adcq $0, %rcx + movq 176(%r11), %r8 + movq %rcx, 168(%r15) + adcq $0, %r8 + movq 184(%r11), %rax + movq %r8, 176(%r15) + adcq $0, %rax + movq 192(%r11), %rcx + movq %rax, 184(%r15) + adcq $0, %rcx + movq 200(%r11), %r8 + movq %rcx, 192(%r15) + adcq $0, %r8 + movq 208(%r11), %rax + movq %r8, 200(%r15) + adcq $0, %rax + movq 216(%r11), %rcx + movq %rax, 208(%r15) + adcq $0, %rcx + movq 224(%r11), %r8 + movq %rcx, 216(%r15) + adcq $0, %r8 + movq 232(%r11), %rax + movq %r8, 224(%r15) + adcq $0, %rax + movq 240(%r11), %rcx + movq %rax, 232(%r15) + adcq $0, %rcx + movq 248(%r11), %r8 + movq %rcx, 240(%r15) + adcq $0, %r8 + movq %r8, 248(%r15) + addq $808, %rsp + pop %r15 + pop %r14 + pop %r13 + pop %r12 + repz retq +#ifndef __APPLE__ +.size sp_2048_mul_32,.-sp_2048_mul_32 +#endif /* __APPLE__ */ /* Add a to a into r. (r = a + a) * * r A single precision integer. @@ -5982,6 +6720,1835 @@ _sp_2048_dbl_16: #ifndef __APPLE__ .size sp_2048_dbl_16,.-sp_2048_dbl_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__ +.globl sp_2048_sqr_32 +.type sp_2048_sqr_32,@function +.align 16 +sp_2048_sqr_32: +#else +.globl _sp_2048_sqr_32 +.p2align 4 +_sp_2048_sqr_32: +#endif /* __APPLE__ */ + subq $664, %rsp + movq %rdi, 640(%rsp) + movq %rsi, 648(%rsp) + leaq 512(%rsp), %r8 + leaq 128(%rsi), %r9 + # Add + movq (%rsi), %rdx + xorq %rcx, %rcx + addq (%r9), %rdx + movq 8(%rsi), %rax + movq %rdx, (%r8) + adcq 8(%r9), %rax + movq 16(%rsi), %rdx + movq %rax, 8(%r8) + adcq 16(%r9), %rdx + movq 24(%rsi), %rax + movq %rdx, 16(%r8) + adcq 24(%r9), %rax + movq 32(%rsi), %rdx + movq %rax, 24(%r8) + adcq 32(%r9), %rdx + movq 40(%rsi), %rax + movq %rdx, 32(%r8) + adcq 40(%r9), %rax + movq 48(%rsi), %rdx + movq %rax, 40(%r8) + adcq 48(%r9), %rdx + movq 56(%rsi), %rax + movq %rdx, 48(%r8) + adcq 56(%r9), %rax + movq 64(%rsi), %rdx + movq %rax, 56(%r8) + adcq 64(%r9), %rdx + movq 72(%rsi), %rax + movq %rdx, 64(%r8) + adcq 72(%r9), %rax + movq 80(%rsi), %rdx + movq %rax, 72(%r8) + adcq 80(%r9), %rdx + movq 88(%rsi), %rax + movq %rdx, 80(%r8) + adcq 88(%r9), %rax + movq 96(%rsi), %rdx + movq %rax, 88(%r8) + adcq 96(%r9), %rdx + movq 104(%rsi), %rax + movq %rdx, 96(%r8) + adcq 104(%r9), %rax + movq 112(%rsi), %rdx + movq %rax, 104(%r8) + adcq 112(%r9), %rdx + movq 120(%rsi), %rax + movq %rdx, 112(%r8) + adcq 120(%r9), %rax + movq %rax, 120(%r8) + adcq $0, %rcx + movq %rcx, 656(%rsp) + movq %r8, %rsi + movq %rsp, %rdi +#ifndef __APPLE__ + callq sp_2048_sqr_16@plt +#else + callq _sp_2048_sqr_16 +#endif /* __APPLE__ */ + movq 648(%rsp), %rsi + leaq 256(%rsp), %rdi + addq $128, %rsi +#ifndef __APPLE__ + callq sp_2048_sqr_16@plt +#else + callq _sp_2048_sqr_16 +#endif /* __APPLE__ */ + movq 648(%rsp), %rsi + movq 640(%rsp), %rdi +#ifndef __APPLE__ + callq sp_2048_sqr_16@plt +#else + callq _sp_2048_sqr_16 +#endif /* __APPLE__ */ + movq 656(%rsp), %r10 + leaq 512(%rsp), %r8 + movq %r10, %rcx + negq %r10 + movq (%r8), %rdx + movq 8(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 256(%rdi) + movq %rax, 264(%rdi) + movq 16(%r8), %rdx + movq 24(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 272(%rdi) + movq %rax, 280(%rdi) + movq 32(%r8), %rdx + movq 40(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 288(%rdi) + movq %rax, 296(%rdi) + movq 48(%r8), %rdx + movq 56(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 304(%rdi) + movq %rax, 312(%rdi) + movq 64(%r8), %rdx + movq 72(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 320(%rdi) + movq %rax, 328(%rdi) + movq 80(%r8), %rdx + movq 88(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 336(%rdi) + movq %rax, 344(%rdi) + movq 96(%r8), %rdx + movq 104(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 352(%rdi) + movq %rax, 360(%rdi) + movq 112(%r8), %rdx + movq 120(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 368(%rdi) + movq %rax, 376(%rdi) + movq 256(%rdi), %rdx + addq %rdx, %rdx + movq 264(%rdi), %rax + movq %rdx, 256(%rdi) + adcq %rax, %rax + movq 272(%rdi), %rdx + movq %rax, 264(%rdi) + adcq %rdx, %rdx + movq 280(%rdi), %rax + movq %rdx, 272(%rdi) + adcq %rax, %rax + movq 288(%rdi), %rdx + movq %rax, 280(%rdi) + adcq %rdx, %rdx + movq 296(%rdi), %rax + movq %rdx, 288(%rdi) + adcq %rax, %rax + movq 304(%rdi), %rdx + movq %rax, 296(%rdi) + adcq %rdx, %rdx + movq 312(%rdi), %rax + movq %rdx, 304(%rdi) + adcq %rax, %rax + movq 320(%rdi), %rdx + movq %rax, 312(%rdi) + adcq %rdx, %rdx + movq 328(%rdi), %rax + movq %rdx, 320(%rdi) + adcq %rax, %rax + movq 336(%rdi), %rdx + movq %rax, 328(%rdi) + adcq %rdx, %rdx + movq 344(%rdi), %rax + movq %rdx, 336(%rdi) + adcq %rax, %rax + movq 352(%rdi), %rdx + movq %rax, 344(%rdi) + adcq %rdx, %rdx + movq 360(%rdi), %rax + movq %rdx, 352(%rdi) + adcq %rax, %rax + movq 368(%rdi), %rdx + movq %rax, 360(%rdi) + adcq %rdx, %rdx + movq 376(%rdi), %rax + movq %rdx, 368(%rdi) + adcq %rax, %rax + movq %rax, 376(%rdi) + adcq $0, %rcx + leaq 256(%rsp), %rsi + movq %rsp, %r8 + movq (%r8), %rdx + subq (%rsi), %rdx + movq 8(%r8), %rax + movq %rdx, (%r8) + sbbq 8(%rsi), %rax + movq 16(%r8), %rdx + movq %rax, 8(%r8) + sbbq 16(%rsi), %rdx + movq 24(%r8), %rax + movq %rdx, 16(%r8) + sbbq 24(%rsi), %rax + movq 32(%r8), %rdx + movq %rax, 24(%r8) + sbbq 32(%rsi), %rdx + movq 40(%r8), %rax + movq %rdx, 32(%r8) + sbbq 40(%rsi), %rax + movq 48(%r8), %rdx + movq %rax, 40(%r8) + sbbq 48(%rsi), %rdx + movq 56(%r8), %rax + movq %rdx, 48(%r8) + sbbq 56(%rsi), %rax + movq 64(%r8), %rdx + movq %rax, 56(%r8) + sbbq 64(%rsi), %rdx + movq 72(%r8), %rax + movq %rdx, 64(%r8) + sbbq 72(%rsi), %rax + movq 80(%r8), %rdx + movq %rax, 72(%r8) + sbbq 80(%rsi), %rdx + movq 88(%r8), %rax + movq %rdx, 80(%r8) + sbbq 88(%rsi), %rax + movq 96(%r8), %rdx + movq %rax, 88(%r8) + sbbq 96(%rsi), %rdx + movq 104(%r8), %rax + movq %rdx, 96(%r8) + sbbq 104(%rsi), %rax + movq 112(%r8), %rdx + movq %rax, 104(%r8) + sbbq 112(%rsi), %rdx + movq 120(%r8), %rax + movq %rdx, 112(%r8) + sbbq 120(%rsi), %rax + movq 128(%r8), %rdx + movq %rax, 120(%r8) + sbbq 128(%rsi), %rdx + movq 136(%r8), %rax + movq %rdx, 128(%r8) + sbbq 136(%rsi), %rax + movq 144(%r8), %rdx + movq %rax, 136(%r8) + sbbq 144(%rsi), %rdx + movq 152(%r8), %rax + movq %rdx, 144(%r8) + sbbq 152(%rsi), %rax + movq 160(%r8), %rdx + movq %rax, 152(%r8) + sbbq 160(%rsi), %rdx + movq 168(%r8), %rax + movq %rdx, 160(%r8) + sbbq 168(%rsi), %rax + movq 176(%r8), %rdx + movq %rax, 168(%r8) + sbbq 176(%rsi), %rdx + movq 184(%r8), %rax + movq %rdx, 176(%r8) + sbbq 184(%rsi), %rax + movq 192(%r8), %rdx + movq %rax, 184(%r8) + sbbq 192(%rsi), %rdx + movq 200(%r8), %rax + movq %rdx, 192(%r8) + sbbq 200(%rsi), %rax + movq 208(%r8), %rdx + movq %rax, 200(%r8) + sbbq 208(%rsi), %rdx + movq 216(%r8), %rax + movq %rdx, 208(%r8) + sbbq 216(%rsi), %rax + movq 224(%r8), %rdx + movq %rax, 216(%r8) + sbbq 224(%rsi), %rdx + movq 232(%r8), %rax + movq %rdx, 224(%r8) + sbbq 232(%rsi), %rax + movq 240(%r8), %rdx + movq %rax, 232(%r8) + sbbq 240(%rsi), %rdx + movq 248(%r8), %rax + movq %rdx, 240(%r8) + sbbq 248(%rsi), %rax + movq %rax, 248(%r8) + sbbq $0, %rcx + movq (%r8), %rdx + subq (%rdi), %rdx + movq 8(%r8), %rax + movq %rdx, (%r8) + sbbq 8(%rdi), %rax + movq 16(%r8), %rdx + movq %rax, 8(%r8) + sbbq 16(%rdi), %rdx + movq 24(%r8), %rax + movq %rdx, 16(%r8) + sbbq 24(%rdi), %rax + movq 32(%r8), %rdx + movq %rax, 24(%r8) + sbbq 32(%rdi), %rdx + movq 40(%r8), %rax + movq %rdx, 32(%r8) + sbbq 40(%rdi), %rax + movq 48(%r8), %rdx + movq %rax, 40(%r8) + sbbq 48(%rdi), %rdx + movq 56(%r8), %rax + movq %rdx, 48(%r8) + sbbq 56(%rdi), %rax + movq 64(%r8), %rdx + movq %rax, 56(%r8) + sbbq 64(%rdi), %rdx + movq 72(%r8), %rax + movq %rdx, 64(%r8) + sbbq 72(%rdi), %rax + movq 80(%r8), %rdx + movq %rax, 72(%r8) + sbbq 80(%rdi), %rdx + movq 88(%r8), %rax + movq %rdx, 80(%r8) + sbbq 88(%rdi), %rax + movq 96(%r8), %rdx + movq %rax, 88(%r8) + sbbq 96(%rdi), %rdx + movq 104(%r8), %rax + movq %rdx, 96(%r8) + sbbq 104(%rdi), %rax + movq 112(%r8), %rdx + movq %rax, 104(%r8) + sbbq 112(%rdi), %rdx + movq 120(%r8), %rax + movq %rdx, 112(%r8) + sbbq 120(%rdi), %rax + movq 128(%r8), %rdx + movq %rax, 120(%r8) + sbbq 128(%rdi), %rdx + movq 136(%r8), %rax + movq %rdx, 128(%r8) + sbbq 136(%rdi), %rax + movq 144(%r8), %rdx + movq %rax, 136(%r8) + sbbq 144(%rdi), %rdx + movq 152(%r8), %rax + movq %rdx, 144(%r8) + sbbq 152(%rdi), %rax + movq 160(%r8), %rdx + movq %rax, 152(%r8) + sbbq 160(%rdi), %rdx + movq 168(%r8), %rax + movq %rdx, 160(%r8) + sbbq 168(%rdi), %rax + movq 176(%r8), %rdx + movq %rax, 168(%r8) + sbbq 176(%rdi), %rdx + movq 184(%r8), %rax + movq %rdx, 176(%r8) + sbbq 184(%rdi), %rax + movq 192(%r8), %rdx + movq %rax, 184(%r8) + sbbq 192(%rdi), %rdx + movq 200(%r8), %rax + movq %rdx, 192(%r8) + sbbq 200(%rdi), %rax + movq 208(%r8), %rdx + movq %rax, 200(%r8) + sbbq 208(%rdi), %rdx + movq 216(%r8), %rax + movq %rdx, 208(%r8) + sbbq 216(%rdi), %rax + movq 224(%r8), %rdx + movq %rax, 216(%r8) + sbbq 224(%rdi), %rdx + movq 232(%r8), %rax + movq %rdx, 224(%r8) + sbbq 232(%rdi), %rax + movq 240(%r8), %rdx + movq %rax, 232(%r8) + sbbq 240(%rdi), %rdx + movq 248(%r8), %rax + movq %rdx, 240(%r8) + sbbq 248(%rdi), %rax + movq %rax, 248(%r8) + sbbq $0, %rcx + # Add in place + movq 128(%rdi), %rdx + addq (%r8), %rdx + movq 136(%rdi), %rax + movq %rdx, 128(%rdi) + adcq 8(%r8), %rax + movq 144(%rdi), %rdx + movq %rax, 136(%rdi) + adcq 16(%r8), %rdx + movq 152(%rdi), %rax + movq %rdx, 144(%rdi) + adcq 24(%r8), %rax + movq 160(%rdi), %rdx + movq %rax, 152(%rdi) + adcq 32(%r8), %rdx + movq 168(%rdi), %rax + movq %rdx, 160(%rdi) + adcq 40(%r8), %rax + movq 176(%rdi), %rdx + movq %rax, 168(%rdi) + adcq 48(%r8), %rdx + movq 184(%rdi), %rax + movq %rdx, 176(%rdi) + adcq 56(%r8), %rax + movq 192(%rdi), %rdx + movq %rax, 184(%rdi) + adcq 64(%r8), %rdx + movq 200(%rdi), %rax + movq %rdx, 192(%rdi) + adcq 72(%r8), %rax + movq 208(%rdi), %rdx + movq %rax, 200(%rdi) + adcq 80(%r8), %rdx + movq 216(%rdi), %rax + movq %rdx, 208(%rdi) + adcq 88(%r8), %rax + movq 224(%rdi), %rdx + movq %rax, 216(%rdi) + adcq 96(%r8), %rdx + movq 232(%rdi), %rax + movq %rdx, 224(%rdi) + adcq 104(%r8), %rax + movq 240(%rdi), %rdx + movq %rax, 232(%rdi) + adcq 112(%r8), %rdx + movq 248(%rdi), %rax + movq %rdx, 240(%rdi) + adcq 120(%r8), %rax + movq 256(%rdi), %rdx + movq %rax, 248(%rdi) + adcq 128(%r8), %rdx + movq 264(%rdi), %rax + movq %rdx, 256(%rdi) + adcq 136(%r8), %rax + movq 272(%rdi), %rdx + movq %rax, 264(%rdi) + adcq 144(%r8), %rdx + movq 280(%rdi), %rax + movq %rdx, 272(%rdi) + adcq 152(%r8), %rax + movq 288(%rdi), %rdx + movq %rax, 280(%rdi) + adcq 160(%r8), %rdx + movq 296(%rdi), %rax + movq %rdx, 288(%rdi) + adcq 168(%r8), %rax + movq 304(%rdi), %rdx + movq %rax, 296(%rdi) + adcq 176(%r8), %rdx + movq 312(%rdi), %rax + movq %rdx, 304(%rdi) + adcq 184(%r8), %rax + movq 320(%rdi), %rdx + movq %rax, 312(%rdi) + adcq 192(%r8), %rdx + movq 328(%rdi), %rax + movq %rdx, 320(%rdi) + adcq 200(%r8), %rax + movq 336(%rdi), %rdx + movq %rax, 328(%rdi) + adcq 208(%r8), %rdx + movq 344(%rdi), %rax + movq %rdx, 336(%rdi) + adcq 216(%r8), %rax + movq 352(%rdi), %rdx + movq %rax, 344(%rdi) + adcq 224(%r8), %rdx + movq 360(%rdi), %rax + movq %rdx, 352(%rdi) + adcq 232(%r8), %rax + movq 368(%rdi), %rdx + movq %rax, 360(%rdi) + adcq 240(%r8), %rdx + movq 376(%rdi), %rax + movq %rdx, 368(%rdi) + adcq 248(%r8), %rax + movq %rax, 376(%rdi) + adcq $0, %rcx + movq %rcx, 384(%rdi) + # Add in place + movq 256(%rdi), %rdx + xorq %rcx, %rcx + addq (%rsi), %rdx + movq 264(%rdi), %rax + movq %rdx, 256(%rdi) + adcq 8(%rsi), %rax + movq 272(%rdi), %rdx + movq %rax, 264(%rdi) + adcq 16(%rsi), %rdx + movq 280(%rdi), %rax + movq %rdx, 272(%rdi) + adcq 24(%rsi), %rax + movq 288(%rdi), %rdx + movq %rax, 280(%rdi) + adcq 32(%rsi), %rdx + movq 296(%rdi), %rax + movq %rdx, 288(%rdi) + adcq 40(%rsi), %rax + movq 304(%rdi), %rdx + movq %rax, 296(%rdi) + adcq 48(%rsi), %rdx + movq 312(%rdi), %rax + movq %rdx, 304(%rdi) + adcq 56(%rsi), %rax + movq 320(%rdi), %rdx + movq %rax, 312(%rdi) + adcq 64(%rsi), %rdx + movq 328(%rdi), %rax + movq %rdx, 320(%rdi) + adcq 72(%rsi), %rax + movq 336(%rdi), %rdx + movq %rax, 328(%rdi) + adcq 80(%rsi), %rdx + movq 344(%rdi), %rax + movq %rdx, 336(%rdi) + adcq 88(%rsi), %rax + movq 352(%rdi), %rdx + movq %rax, 344(%rdi) + adcq 96(%rsi), %rdx + movq 360(%rdi), %rax + movq %rdx, 352(%rdi) + adcq 104(%rsi), %rax + movq 368(%rdi), %rdx + movq %rax, 360(%rdi) + adcq 112(%rsi), %rdx + movq 376(%rdi), %rax + movq %rdx, 368(%rdi) + adcq 120(%rsi), %rax + movq 384(%rdi), %rdx + movq %rax, 376(%rdi) + adcq 128(%rsi), %rdx + movq %rdx, 384(%rdi) + adcq $0, %rcx + # Add to zero + movq 136(%rsi), %rdx + adcq $0, %rdx + movq 144(%rsi), %rax + movq %rdx, 392(%rdi) + adcq $0, %rax + movq 152(%rsi), %rdx + movq %rax, 400(%rdi) + adcq $0, %rdx + movq 160(%rsi), %rax + movq %rdx, 408(%rdi) + adcq $0, %rax + movq 168(%rsi), %rdx + movq %rax, 416(%rdi) + adcq $0, %rdx + movq 176(%rsi), %rax + movq %rdx, 424(%rdi) + adcq $0, %rax + movq 184(%rsi), %rdx + movq %rax, 432(%rdi) + adcq $0, %rdx + movq 192(%rsi), %rax + movq %rdx, 440(%rdi) + adcq $0, %rax + movq 200(%rsi), %rdx + movq %rax, 448(%rdi) + adcq $0, %rdx + movq 208(%rsi), %rax + movq %rdx, 456(%rdi) + adcq $0, %rax + movq 216(%rsi), %rdx + movq %rax, 464(%rdi) + adcq $0, %rdx + movq 224(%rsi), %rax + movq %rdx, 472(%rdi) + adcq $0, %rax + movq 232(%rsi), %rdx + movq %rax, 480(%rdi) + adcq $0, %rdx + movq 240(%rsi), %rax + movq %rdx, 488(%rdi) + adcq $0, %rax + movq 248(%rsi), %rdx + movq %rax, 496(%rdi) + adcq $0, %rdx + movq %rdx, 504(%rdi) + addq $664, %rsp + repz retq +#ifndef __APPLE__ +.size sp_2048_sqr_32,.-sp_2048_sqr_32 +#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__ +.globl sp_2048_mul_avx2_32 +.type sp_2048_mul_avx2_32,@function +.align 16 +sp_2048_mul_avx2_32: +#else +.globl _sp_2048_mul_avx2_32 +.p2align 4 +_sp_2048_mul_avx2_32: +#endif /* __APPLE__ */ + push %r12 + push %r13 + push %r14 + push %r15 + subq $808, %rsp + movq %rdi, 768(%rsp) + movq %rsi, 776(%rsp) + movq %rdx, 784(%rsp) + leaq 512(%rsp), %r10 + leaq 128(%rsi), %r12 + # Add + movq (%rsi), %rax + xorq %r13, %r13 + addq (%r12), %rax + movq 8(%rsi), %rcx + movq %rax, (%r10) + adcq 8(%r12), %rcx + movq 16(%rsi), %r8 + movq %rcx, 8(%r10) + adcq 16(%r12), %r8 + movq 24(%rsi), %rax + movq %r8, 16(%r10) + adcq 24(%r12), %rax + movq 32(%rsi), %rcx + movq %rax, 24(%r10) + adcq 32(%r12), %rcx + movq 40(%rsi), %r8 + movq %rcx, 32(%r10) + adcq 40(%r12), %r8 + movq 48(%rsi), %rax + movq %r8, 40(%r10) + adcq 48(%r12), %rax + movq 56(%rsi), %rcx + movq %rax, 48(%r10) + adcq 56(%r12), %rcx + movq 64(%rsi), %r8 + movq %rcx, 56(%r10) + adcq 64(%r12), %r8 + movq 72(%rsi), %rax + movq %r8, 64(%r10) + adcq 72(%r12), %rax + movq 80(%rsi), %rcx + movq %rax, 72(%r10) + adcq 80(%r12), %rcx + movq 88(%rsi), %r8 + movq %rcx, 80(%r10) + adcq 88(%r12), %r8 + movq 96(%rsi), %rax + movq %r8, 88(%r10) + adcq 96(%r12), %rax + movq 104(%rsi), %rcx + movq %rax, 96(%r10) + adcq 104(%r12), %rcx + movq 112(%rsi), %r8 + movq %rcx, 104(%r10) + adcq 112(%r12), %r8 + movq 120(%rsi), %rax + movq %r8, 112(%r10) + adcq 120(%r12), %rax + movq %rax, 120(%r10) + adcq $0, %r13 + movq %r13, 792(%rsp) + leaq 640(%rsp), %r11 + leaq 128(%rdx), %r12 + # Add + movq (%rdx), %rax + xorq %r14, %r14 + addq (%r12), %rax + movq 8(%rdx), %rcx + movq %rax, (%r11) + adcq 8(%r12), %rcx + movq 16(%rdx), %r8 + movq %rcx, 8(%r11) + adcq 16(%r12), %r8 + movq 24(%rdx), %rax + movq %r8, 16(%r11) + adcq 24(%r12), %rax + movq 32(%rdx), %rcx + movq %rax, 24(%r11) + adcq 32(%r12), %rcx + movq 40(%rdx), %r8 + movq %rcx, 32(%r11) + adcq 40(%r12), %r8 + movq 48(%rdx), %rax + movq %r8, 40(%r11) + adcq 48(%r12), %rax + movq 56(%rdx), %rcx + movq %rax, 48(%r11) + adcq 56(%r12), %rcx + movq 64(%rdx), %r8 + movq %rcx, 56(%r11) + adcq 64(%r12), %r8 + movq 72(%rdx), %rax + movq %r8, 64(%r11) + adcq 72(%r12), %rax + movq 80(%rdx), %rcx + movq %rax, 72(%r11) + adcq 80(%r12), %rcx + movq 88(%rdx), %r8 + movq %rcx, 80(%r11) + adcq 88(%r12), %r8 + movq 96(%rdx), %rax + movq %r8, 88(%r11) + adcq 96(%r12), %rax + movq 104(%rdx), %rcx + movq %rax, 96(%r11) + adcq 104(%r12), %rcx + movq 112(%rdx), %r8 + movq %rcx, 104(%r11) + adcq 112(%r12), %r8 + movq 120(%rdx), %rax + movq %r8, 112(%r11) + adcq 120(%r12), %rax + movq %rax, 120(%r11) + adcq $0, %r14 + movq %r14, 800(%rsp) + movq %r11, %rdx + movq %r10, %rsi + movq %rsp, %rdi +#ifndef __APPLE__ + callq sp_2048_mul_avx2_16@plt +#else + callq _sp_2048_mul_avx2_16 +#endif /* __APPLE__ */ + movq 784(%rsp), %rdx + movq 776(%rsp), %rsi + leaq 256(%rsp), %rdi + addq $128, %rdx + addq $128, %rsi +#ifndef __APPLE__ + callq sp_2048_mul_avx2_16@plt +#else + callq _sp_2048_mul_avx2_16 +#endif /* __APPLE__ */ + movq 784(%rsp), %rdx + movq 776(%rsp), %rsi + movq 768(%rsp), %rdi +#ifndef __APPLE__ + callq sp_2048_mul_avx2_16@plt +#else + callq _sp_2048_mul_avx2_16 +#endif /* __APPLE__ */ + movq 792(%rsp), %r13 + movq 800(%rsp), %r14 + movq 768(%rsp), %r15 + movq %r13, %r9 + leaq 512(%rsp), %r10 + leaq 640(%rsp), %r11 + andq %r14, %r9 + negq %r13 + negq %r14 + addq $256, %r15 + movq (%r10), %rax + movq (%r11), %rcx + pextq %r14, %rax, %rax + pextq %r13, %rcx, %rcx + addq %rcx, %rax + movq 8(%r10), %rcx + movq 8(%r11), %r8 + pextq %r14, %rcx, %rcx + pextq %r13, %r8, %r8 + movq %rax, (%r15) + adcq %r8, %rcx + movq 16(%r10), %r8 + movq 16(%r11), %rax + pextq %r14, %r8, %r8 + pextq %r13, %rax, %rax + movq %rcx, 8(%r15) + adcq %rax, %r8 + movq 24(%r10), %rax + movq 24(%r11), %rcx + pextq %r14, %rax, %rax + pextq %r13, %rcx, %rcx + movq %r8, 16(%r15) + adcq %rcx, %rax + movq 32(%r10), %rcx + movq 32(%r11), %r8 + pextq %r14, %rcx, %rcx + pextq %r13, %r8, %r8 + movq %rax, 24(%r15) + adcq %r8, %rcx + movq 40(%r10), %r8 + movq 40(%r11), %rax + pextq %r14, %r8, %r8 + pextq %r13, %rax, %rax + movq %rcx, 32(%r15) + adcq %rax, %r8 + movq 48(%r10), %rax + movq 48(%r11), %rcx + pextq %r14, %rax, %rax + pextq %r13, %rcx, %rcx + movq %r8, 40(%r15) + adcq %rcx, %rax + movq 56(%r10), %rcx + movq 56(%r11), %r8 + pextq %r14, %rcx, %rcx + pextq %r13, %r8, %r8 + movq %rax, 48(%r15) + adcq %r8, %rcx + movq 64(%r10), %r8 + movq 64(%r11), %rax + pextq %r14, %r8, %r8 + pextq %r13, %rax, %rax + movq %rcx, 56(%r15) + adcq %rax, %r8 + movq 72(%r10), %rax + movq 72(%r11), %rcx + pextq %r14, %rax, %rax + pextq %r13, %rcx, %rcx + movq %r8, 64(%r15) + adcq %rcx, %rax + movq 80(%r10), %rcx + movq 80(%r11), %r8 + pextq %r14, %rcx, %rcx + pextq %r13, %r8, %r8 + movq %rax, 72(%r15) + adcq %r8, %rcx + movq 88(%r10), %r8 + movq 88(%r11), %rax + pextq %r14, %r8, %r8 + pextq %r13, %rax, %rax + movq %rcx, 80(%r15) + adcq %rax, %r8 + movq 96(%r10), %rax + movq 96(%r11), %rcx + pextq %r14, %rax, %rax + pextq %r13, %rcx, %rcx + movq %r8, 88(%r15) + adcq %rcx, %rax + movq 104(%r10), %rcx + movq 104(%r11), %r8 + pextq %r14, %rcx, %rcx + pextq %r13, %r8, %r8 + movq %rax, 96(%r15) + adcq %r8, %rcx + movq 112(%r10), %r8 + movq 112(%r11), %rax + pextq %r14, %r8, %r8 + pextq %r13, %rax, %rax + movq %rcx, 104(%r15) + adcq %rax, %r8 + movq 120(%r10), %rax + movq 120(%r11), %rcx + pextq %r14, %rax, %rax + pextq %r13, %rcx, %rcx + movq %r8, 112(%r15) + adcq %rcx, %rax + movq %rax, 120(%r15) + adcq $0, %r9 + leaq 256(%rsp), %r11 + movq %rsp, %r10 + movq (%r10), %rax + subq (%r11), %rax + movq 8(%r10), %rcx + movq %rax, (%r10) + sbbq 8(%r11), %rcx + movq 16(%r10), %r8 + movq %rcx, 8(%r10) + sbbq 16(%r11), %r8 + movq 24(%r10), %rax + movq %r8, 16(%r10) + sbbq 24(%r11), %rax + movq 32(%r10), %rcx + movq %rax, 24(%r10) + sbbq 32(%r11), %rcx + movq 40(%r10), %r8 + movq %rcx, 32(%r10) + sbbq 40(%r11), %r8 + movq 48(%r10), %rax + movq %r8, 40(%r10) + sbbq 48(%r11), %rax + movq 56(%r10), %rcx + movq %rax, 48(%r10) + sbbq 56(%r11), %rcx + movq 64(%r10), %r8 + movq %rcx, 56(%r10) + sbbq 64(%r11), %r8 + movq 72(%r10), %rax + movq %r8, 64(%r10) + sbbq 72(%r11), %rax + movq 80(%r10), %rcx + movq %rax, 72(%r10) + sbbq 80(%r11), %rcx + movq 88(%r10), %r8 + movq %rcx, 80(%r10) + sbbq 88(%r11), %r8 + movq 96(%r10), %rax + movq %r8, 88(%r10) + sbbq 96(%r11), %rax + movq 104(%r10), %rcx + movq %rax, 96(%r10) + sbbq 104(%r11), %rcx + movq 112(%r10), %r8 + movq %rcx, 104(%r10) + sbbq 112(%r11), %r8 + movq 120(%r10), %rax + movq %r8, 112(%r10) + sbbq 120(%r11), %rax + movq 128(%r10), %rcx + movq %rax, 120(%r10) + sbbq 128(%r11), %rcx + movq 136(%r10), %r8 + movq %rcx, 128(%r10) + sbbq 136(%r11), %r8 + movq 144(%r10), %rax + movq %r8, 136(%r10) + sbbq 144(%r11), %rax + movq 152(%r10), %rcx + movq %rax, 144(%r10) + sbbq 152(%r11), %rcx + movq 160(%r10), %r8 + movq %rcx, 152(%r10) + sbbq 160(%r11), %r8 + movq 168(%r10), %rax + movq %r8, 160(%r10) + sbbq 168(%r11), %rax + movq 176(%r10), %rcx + movq %rax, 168(%r10) + sbbq 176(%r11), %rcx + movq 184(%r10), %r8 + movq %rcx, 176(%r10) + sbbq 184(%r11), %r8 + movq 192(%r10), %rax + movq %r8, 184(%r10) + sbbq 192(%r11), %rax + movq 200(%r10), %rcx + movq %rax, 192(%r10) + sbbq 200(%r11), %rcx + movq 208(%r10), %r8 + movq %rcx, 200(%r10) + sbbq 208(%r11), %r8 + movq 216(%r10), %rax + movq %r8, 208(%r10) + sbbq 216(%r11), %rax + movq 224(%r10), %rcx + movq %rax, 216(%r10) + sbbq 224(%r11), %rcx + movq 232(%r10), %r8 + movq %rcx, 224(%r10) + sbbq 232(%r11), %r8 + movq 240(%r10), %rax + movq %r8, 232(%r10) + sbbq 240(%r11), %rax + movq 248(%r10), %rcx + movq %rax, 240(%r10) + sbbq 248(%r11), %rcx + movq %rcx, 248(%r10) + sbbq $0, %r9 + movq (%r10), %rax + subq (%rdi), %rax + movq 8(%r10), %rcx + movq %rax, (%r10) + sbbq 8(%rdi), %rcx + movq 16(%r10), %r8 + movq %rcx, 8(%r10) + sbbq 16(%rdi), %r8 + movq 24(%r10), %rax + movq %r8, 16(%r10) + sbbq 24(%rdi), %rax + movq 32(%r10), %rcx + movq %rax, 24(%r10) + sbbq 32(%rdi), %rcx + movq 40(%r10), %r8 + movq %rcx, 32(%r10) + sbbq 40(%rdi), %r8 + movq 48(%r10), %rax + movq %r8, 40(%r10) + sbbq 48(%rdi), %rax + movq 56(%r10), %rcx + movq %rax, 48(%r10) + sbbq 56(%rdi), %rcx + movq 64(%r10), %r8 + movq %rcx, 56(%r10) + sbbq 64(%rdi), %r8 + movq 72(%r10), %rax + movq %r8, 64(%r10) + sbbq 72(%rdi), %rax + movq 80(%r10), %rcx + movq %rax, 72(%r10) + sbbq 80(%rdi), %rcx + movq 88(%r10), %r8 + movq %rcx, 80(%r10) + sbbq 88(%rdi), %r8 + movq 96(%r10), %rax + movq %r8, 88(%r10) + sbbq 96(%rdi), %rax + movq 104(%r10), %rcx + movq %rax, 96(%r10) + sbbq 104(%rdi), %rcx + movq 112(%r10), %r8 + movq %rcx, 104(%r10) + sbbq 112(%rdi), %r8 + movq 120(%r10), %rax + movq %r8, 112(%r10) + sbbq 120(%rdi), %rax + movq 128(%r10), %rcx + movq %rax, 120(%r10) + sbbq 128(%rdi), %rcx + movq 136(%r10), %r8 + movq %rcx, 128(%r10) + sbbq 136(%rdi), %r8 + movq 144(%r10), %rax + movq %r8, 136(%r10) + sbbq 144(%rdi), %rax + movq 152(%r10), %rcx + movq %rax, 144(%r10) + sbbq 152(%rdi), %rcx + movq 160(%r10), %r8 + movq %rcx, 152(%r10) + sbbq 160(%rdi), %r8 + movq 168(%r10), %rax + movq %r8, 160(%r10) + sbbq 168(%rdi), %rax + movq 176(%r10), %rcx + movq %rax, 168(%r10) + sbbq 176(%rdi), %rcx + movq 184(%r10), %r8 + movq %rcx, 176(%r10) + sbbq 184(%rdi), %r8 + movq 192(%r10), %rax + movq %r8, 184(%r10) + sbbq 192(%rdi), %rax + movq 200(%r10), %rcx + movq %rax, 192(%r10) + sbbq 200(%rdi), %rcx + movq 208(%r10), %r8 + movq %rcx, 200(%r10) + sbbq 208(%rdi), %r8 + movq 216(%r10), %rax + movq %r8, 208(%r10) + sbbq 216(%rdi), %rax + movq 224(%r10), %rcx + movq %rax, 216(%r10) + sbbq 224(%rdi), %rcx + movq 232(%r10), %r8 + movq %rcx, 224(%r10) + sbbq 232(%rdi), %r8 + movq 240(%r10), %rax + movq %r8, 232(%r10) + sbbq 240(%rdi), %rax + movq 248(%r10), %rcx + movq %rax, 240(%r10) + sbbq 248(%rdi), %rcx + movq %rcx, 248(%r10) + sbbq $0, %r9 + subq $128, %r15 + # Add + movq (%r15), %rax + addq (%r10), %rax + movq 8(%r15), %rcx + movq %rax, (%r15) + adcq 8(%r10), %rcx + movq 16(%r15), %r8 + movq %rcx, 8(%r15) + adcq 16(%r10), %r8 + movq 24(%r15), %rax + movq %r8, 16(%r15) + adcq 24(%r10), %rax + movq 32(%r15), %rcx + movq %rax, 24(%r15) + adcq 32(%r10), %rcx + movq 40(%r15), %r8 + movq %rcx, 32(%r15) + adcq 40(%r10), %r8 + movq 48(%r15), %rax + movq %r8, 40(%r15) + adcq 48(%r10), %rax + movq 56(%r15), %rcx + movq %rax, 48(%r15) + adcq 56(%r10), %rcx + movq 64(%r15), %r8 + movq %rcx, 56(%r15) + adcq 64(%r10), %r8 + movq 72(%r15), %rax + movq %r8, 64(%r15) + adcq 72(%r10), %rax + movq 80(%r15), %rcx + movq %rax, 72(%r15) + adcq 80(%r10), %rcx + movq 88(%r15), %r8 + movq %rcx, 80(%r15) + adcq 88(%r10), %r8 + movq 96(%r15), %rax + movq %r8, 88(%r15) + adcq 96(%r10), %rax + movq 104(%r15), %rcx + movq %rax, 96(%r15) + adcq 104(%r10), %rcx + movq 112(%r15), %r8 + movq %rcx, 104(%r15) + adcq 112(%r10), %r8 + movq 120(%r15), %rax + movq %r8, 112(%r15) + adcq 120(%r10), %rax + movq 128(%r15), %rcx + movq %rax, 120(%r15) + adcq 128(%r10), %rcx + movq 136(%r15), %r8 + movq %rcx, 128(%r15) + adcq 136(%r10), %r8 + movq 144(%r15), %rax + movq %r8, 136(%r15) + adcq 144(%r10), %rax + movq 152(%r15), %rcx + movq %rax, 144(%r15) + adcq 152(%r10), %rcx + movq 160(%r15), %r8 + movq %rcx, 152(%r15) + adcq 160(%r10), %r8 + movq 168(%r15), %rax + movq %r8, 160(%r15) + adcq 168(%r10), %rax + movq 176(%r15), %rcx + movq %rax, 168(%r15) + adcq 176(%r10), %rcx + movq 184(%r15), %r8 + movq %rcx, 176(%r15) + adcq 184(%r10), %r8 + movq 192(%r15), %rax + movq %r8, 184(%r15) + adcq 192(%r10), %rax + movq 200(%r15), %rcx + movq %rax, 192(%r15) + adcq 200(%r10), %rcx + movq 208(%r15), %r8 + movq %rcx, 200(%r15) + adcq 208(%r10), %r8 + movq 216(%r15), %rax + movq %r8, 208(%r15) + adcq 216(%r10), %rax + movq 224(%r15), %rcx + movq %rax, 216(%r15) + adcq 224(%r10), %rcx + movq 232(%r15), %r8 + movq %rcx, 224(%r15) + adcq 232(%r10), %r8 + movq 240(%r15), %rax + movq %r8, 232(%r15) + adcq 240(%r10), %rax + movq 248(%r15), %rcx + movq %rax, 240(%r15) + adcq 248(%r10), %rcx + movq %rcx, 248(%r15) + adcq $0, %r9 + movq %r9, 384(%rdi) + addq $128, %r15 + # Add + movq (%r15), %rax + xorq %r9, %r9 + addq (%r11), %rax + movq 8(%r15), %rcx + movq %rax, (%r15) + adcq 8(%r11), %rcx + movq 16(%r15), %r8 + movq %rcx, 8(%r15) + adcq 16(%r11), %r8 + movq 24(%r15), %rax + movq %r8, 16(%r15) + adcq 24(%r11), %rax + movq 32(%r15), %rcx + movq %rax, 24(%r15) + adcq 32(%r11), %rcx + movq 40(%r15), %r8 + movq %rcx, 32(%r15) + adcq 40(%r11), %r8 + movq 48(%r15), %rax + movq %r8, 40(%r15) + adcq 48(%r11), %rax + movq 56(%r15), %rcx + movq %rax, 48(%r15) + adcq 56(%r11), %rcx + movq 64(%r15), %r8 + movq %rcx, 56(%r15) + adcq 64(%r11), %r8 + movq 72(%r15), %rax + movq %r8, 64(%r15) + adcq 72(%r11), %rax + movq 80(%r15), %rcx + movq %rax, 72(%r15) + adcq 80(%r11), %rcx + movq 88(%r15), %r8 + movq %rcx, 80(%r15) + adcq 88(%r11), %r8 + movq 96(%r15), %rax + movq %r8, 88(%r15) + adcq 96(%r11), %rax + movq 104(%r15), %rcx + movq %rax, 96(%r15) + adcq 104(%r11), %rcx + movq 112(%r15), %r8 + movq %rcx, 104(%r15) + adcq 112(%r11), %r8 + movq 120(%r15), %rax + movq %r8, 112(%r15) + adcq 120(%r11), %rax + movq 128(%r15), %rcx + movq %rax, 120(%r15) + adcq 128(%r11), %rcx + movq %rcx, 128(%r15) + adcq $0, %r9 + # Add to zero + movq 136(%r11), %rax + adcq $0, %rax + movq 144(%r11), %rcx + movq %rax, 136(%r15) + adcq $0, %rcx + movq 152(%r11), %r8 + movq %rcx, 144(%r15) + adcq $0, %r8 + movq 160(%r11), %rax + movq %r8, 152(%r15) + adcq $0, %rax + movq 168(%r11), %rcx + movq %rax, 160(%r15) + adcq $0, %rcx + movq 176(%r11), %r8 + movq %rcx, 168(%r15) + adcq $0, %r8 + movq 184(%r11), %rax + movq %r8, 176(%r15) + adcq $0, %rax + movq 192(%r11), %rcx + movq %rax, 184(%r15) + adcq $0, %rcx + movq 200(%r11), %r8 + movq %rcx, 192(%r15) + adcq $0, %r8 + movq 208(%r11), %rax + movq %r8, 200(%r15) + adcq $0, %rax + movq 216(%r11), %rcx + movq %rax, 208(%r15) + adcq $0, %rcx + movq 224(%r11), %r8 + movq %rcx, 216(%r15) + adcq $0, %r8 + movq 232(%r11), %rax + movq %r8, 224(%r15) + adcq $0, %rax + movq 240(%r11), %rcx + movq %rax, 232(%r15) + adcq $0, %rcx + movq 248(%r11), %r8 + movq %rcx, 240(%r15) + adcq $0, %r8 + movq %r8, 248(%r15) + addq $808, %rsp + pop %r15 + pop %r14 + pop %r13 + pop %r12 + repz retq +#ifndef __APPLE__ +.size sp_2048_mul_avx2_32,.-sp_2048_mul_avx2_32 +#endif /* __APPLE__ */ +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +#ifndef __APPLE__ +.globl sp_2048_sqr_avx2_32 +.type sp_2048_sqr_avx2_32,@function +.align 16 +sp_2048_sqr_avx2_32: +#else +.globl _sp_2048_sqr_avx2_32 +.p2align 4 +_sp_2048_sqr_avx2_32: +#endif /* __APPLE__ */ + subq $664, %rsp + movq %rdi, 640(%rsp) + movq %rsi, 648(%rsp) + leaq 512(%rsp), %r8 + leaq 128(%rsi), %r9 + # Add + movq (%rsi), %rdx + xorq %rcx, %rcx + addq (%r9), %rdx + movq 8(%rsi), %rax + movq %rdx, (%r8) + adcq 8(%r9), %rax + movq 16(%rsi), %rdx + movq %rax, 8(%r8) + adcq 16(%r9), %rdx + movq 24(%rsi), %rax + movq %rdx, 16(%r8) + adcq 24(%r9), %rax + movq 32(%rsi), %rdx + movq %rax, 24(%r8) + adcq 32(%r9), %rdx + movq 40(%rsi), %rax + movq %rdx, 32(%r8) + adcq 40(%r9), %rax + movq 48(%rsi), %rdx + movq %rax, 40(%r8) + adcq 48(%r9), %rdx + movq 56(%rsi), %rax + movq %rdx, 48(%r8) + adcq 56(%r9), %rax + movq 64(%rsi), %rdx + movq %rax, 56(%r8) + adcq 64(%r9), %rdx + movq 72(%rsi), %rax + movq %rdx, 64(%r8) + adcq 72(%r9), %rax + movq 80(%rsi), %rdx + movq %rax, 72(%r8) + adcq 80(%r9), %rdx + movq 88(%rsi), %rax + movq %rdx, 80(%r8) + adcq 88(%r9), %rax + movq 96(%rsi), %rdx + movq %rax, 88(%r8) + adcq 96(%r9), %rdx + movq 104(%rsi), %rax + movq %rdx, 96(%r8) + adcq 104(%r9), %rax + movq 112(%rsi), %rdx + movq %rax, 104(%r8) + adcq 112(%r9), %rdx + movq 120(%rsi), %rax + movq %rdx, 112(%r8) + adcq 120(%r9), %rax + movq %rax, 120(%r8) + adcq $0, %rcx + movq %rcx, 656(%rsp) + movq %r8, %rsi + movq %rsp, %rdi +#ifndef __APPLE__ + callq sp_2048_sqr_avx2_16@plt +#else + callq _sp_2048_sqr_avx2_16 +#endif /* __APPLE__ */ + movq 648(%rsp), %rsi + leaq 256(%rsp), %rdi + addq $128, %rsi +#ifndef __APPLE__ + callq sp_2048_sqr_avx2_16@plt +#else + callq _sp_2048_sqr_avx2_16 +#endif /* __APPLE__ */ + movq 648(%rsp), %rsi + movq 640(%rsp), %rdi +#ifndef __APPLE__ + callq sp_2048_sqr_avx2_16@plt +#else + callq _sp_2048_sqr_avx2_16 +#endif /* __APPLE__ */ + movq 656(%rsp), %r10 + leaq 512(%rsp), %r8 + movq %r10, %rcx + negq %r10 + movq (%r8), %rdx + pextq %r10, %rdx, %rdx + addq %rdx, %rdx + movq 8(%r8), %rax + movq %rdx, 256(%rdi) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 16(%r8), %rdx + movq %rax, 264(%rdi) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 24(%r8), %rax + movq %rdx, 272(%rdi) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 32(%r8), %rdx + movq %rax, 280(%rdi) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 40(%r8), %rax + movq %rdx, 288(%rdi) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 48(%r8), %rdx + movq %rax, 296(%rdi) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 56(%r8), %rax + movq %rdx, 304(%rdi) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 64(%r8), %rdx + movq %rax, 312(%rdi) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 72(%r8), %rax + movq %rdx, 320(%rdi) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 80(%r8), %rdx + movq %rax, 328(%rdi) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 88(%r8), %rax + movq %rdx, 336(%rdi) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 96(%r8), %rdx + movq %rax, 344(%rdi) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 104(%r8), %rax + movq %rdx, 352(%rdi) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 112(%r8), %rdx + movq %rax, 360(%rdi) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 120(%r8), %rax + movq %rdx, 368(%rdi) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq %rax, 376(%rdi) + adcq $0, %rcx + leaq 256(%rsp), %rsi + movq %rsp, %r8 + movq (%r8), %rdx + subq (%rsi), %rdx + movq 8(%r8), %rax + movq %rdx, (%r8) + sbbq 8(%rsi), %rax + movq 16(%r8), %rdx + movq %rax, 8(%r8) + sbbq 16(%rsi), %rdx + movq 24(%r8), %rax + movq %rdx, 16(%r8) + sbbq 24(%rsi), %rax + movq 32(%r8), %rdx + movq %rax, 24(%r8) + sbbq 32(%rsi), %rdx + movq 40(%r8), %rax + movq %rdx, 32(%r8) + sbbq 40(%rsi), %rax + movq 48(%r8), %rdx + movq %rax, 40(%r8) + sbbq 48(%rsi), %rdx + movq 56(%r8), %rax + movq %rdx, 48(%r8) + sbbq 56(%rsi), %rax + movq 64(%r8), %rdx + movq %rax, 56(%r8) + sbbq 64(%rsi), %rdx + movq 72(%r8), %rax + movq %rdx, 64(%r8) + sbbq 72(%rsi), %rax + movq 80(%r8), %rdx + movq %rax, 72(%r8) + sbbq 80(%rsi), %rdx + movq 88(%r8), %rax + movq %rdx, 80(%r8) + sbbq 88(%rsi), %rax + movq 96(%r8), %rdx + movq %rax, 88(%r8) + sbbq 96(%rsi), %rdx + movq 104(%r8), %rax + movq %rdx, 96(%r8) + sbbq 104(%rsi), %rax + movq 112(%r8), %rdx + movq %rax, 104(%r8) + sbbq 112(%rsi), %rdx + movq 120(%r8), %rax + movq %rdx, 112(%r8) + sbbq 120(%rsi), %rax + movq 128(%r8), %rdx + movq %rax, 120(%r8) + sbbq 128(%rsi), %rdx + movq 136(%r8), %rax + movq %rdx, 128(%r8) + sbbq 136(%rsi), %rax + movq 144(%r8), %rdx + movq %rax, 136(%r8) + sbbq 144(%rsi), %rdx + movq 152(%r8), %rax + movq %rdx, 144(%r8) + sbbq 152(%rsi), %rax + movq 160(%r8), %rdx + movq %rax, 152(%r8) + sbbq 160(%rsi), %rdx + movq 168(%r8), %rax + movq %rdx, 160(%r8) + sbbq 168(%rsi), %rax + movq 176(%r8), %rdx + movq %rax, 168(%r8) + sbbq 176(%rsi), %rdx + movq 184(%r8), %rax + movq %rdx, 176(%r8) + sbbq 184(%rsi), %rax + movq 192(%r8), %rdx + movq %rax, 184(%r8) + sbbq 192(%rsi), %rdx + movq 200(%r8), %rax + movq %rdx, 192(%r8) + sbbq 200(%rsi), %rax + movq 208(%r8), %rdx + movq %rax, 200(%r8) + sbbq 208(%rsi), %rdx + movq 216(%r8), %rax + movq %rdx, 208(%r8) + sbbq 216(%rsi), %rax + movq 224(%r8), %rdx + movq %rax, 216(%r8) + sbbq 224(%rsi), %rdx + movq 232(%r8), %rax + movq %rdx, 224(%r8) + sbbq 232(%rsi), %rax + movq 240(%r8), %rdx + movq %rax, 232(%r8) + sbbq 240(%rsi), %rdx + movq 248(%r8), %rax + movq %rdx, 240(%r8) + sbbq 248(%rsi), %rax + movq %rax, 248(%r8) + sbbq $0, %rcx + movq (%r8), %rdx + subq (%rdi), %rdx + movq 8(%r8), %rax + movq %rdx, (%r8) + sbbq 8(%rdi), %rax + movq 16(%r8), %rdx + movq %rax, 8(%r8) + sbbq 16(%rdi), %rdx + movq 24(%r8), %rax + movq %rdx, 16(%r8) + sbbq 24(%rdi), %rax + movq 32(%r8), %rdx + movq %rax, 24(%r8) + sbbq 32(%rdi), %rdx + movq 40(%r8), %rax + movq %rdx, 32(%r8) + sbbq 40(%rdi), %rax + movq 48(%r8), %rdx + movq %rax, 40(%r8) + sbbq 48(%rdi), %rdx + movq 56(%r8), %rax + movq %rdx, 48(%r8) + sbbq 56(%rdi), %rax + movq 64(%r8), %rdx + movq %rax, 56(%r8) + sbbq 64(%rdi), %rdx + movq 72(%r8), %rax + movq %rdx, 64(%r8) + sbbq 72(%rdi), %rax + movq 80(%r8), %rdx + movq %rax, 72(%r8) + sbbq 80(%rdi), %rdx + movq 88(%r8), %rax + movq %rdx, 80(%r8) + sbbq 88(%rdi), %rax + movq 96(%r8), %rdx + movq %rax, 88(%r8) + sbbq 96(%rdi), %rdx + movq 104(%r8), %rax + movq %rdx, 96(%r8) + sbbq 104(%rdi), %rax + movq 112(%r8), %rdx + movq %rax, 104(%r8) + sbbq 112(%rdi), %rdx + movq 120(%r8), %rax + movq %rdx, 112(%r8) + sbbq 120(%rdi), %rax + movq 128(%r8), %rdx + movq %rax, 120(%r8) + sbbq 128(%rdi), %rdx + movq 136(%r8), %rax + movq %rdx, 128(%r8) + sbbq 136(%rdi), %rax + movq 144(%r8), %rdx + movq %rax, 136(%r8) + sbbq 144(%rdi), %rdx + movq 152(%r8), %rax + movq %rdx, 144(%r8) + sbbq 152(%rdi), %rax + movq 160(%r8), %rdx + movq %rax, 152(%r8) + sbbq 160(%rdi), %rdx + movq 168(%r8), %rax + movq %rdx, 160(%r8) + sbbq 168(%rdi), %rax + movq 176(%r8), %rdx + movq %rax, 168(%r8) + sbbq 176(%rdi), %rdx + movq 184(%r8), %rax + movq %rdx, 176(%r8) + sbbq 184(%rdi), %rax + movq 192(%r8), %rdx + movq %rax, 184(%r8) + sbbq 192(%rdi), %rdx + movq 200(%r8), %rax + movq %rdx, 192(%r8) + sbbq 200(%rdi), %rax + movq 208(%r8), %rdx + movq %rax, 200(%r8) + sbbq 208(%rdi), %rdx + movq 216(%r8), %rax + movq %rdx, 208(%r8) + sbbq 216(%rdi), %rax + movq 224(%r8), %rdx + movq %rax, 216(%r8) + sbbq 224(%rdi), %rdx + movq 232(%r8), %rax + movq %rdx, 224(%r8) + sbbq 232(%rdi), %rax + movq 240(%r8), %rdx + movq %rax, 232(%r8) + sbbq 240(%rdi), %rdx + movq 248(%r8), %rax + movq %rdx, 240(%r8) + sbbq 248(%rdi), %rax + movq %rax, 248(%r8) + sbbq $0, %rcx + # Add in place + movq 128(%rdi), %rdx + addq (%r8), %rdx + movq 136(%rdi), %rax + movq %rdx, 128(%rdi) + adcq 8(%r8), %rax + movq 144(%rdi), %rdx + movq %rax, 136(%rdi) + adcq 16(%r8), %rdx + movq 152(%rdi), %rax + movq %rdx, 144(%rdi) + adcq 24(%r8), %rax + movq 160(%rdi), %rdx + movq %rax, 152(%rdi) + adcq 32(%r8), %rdx + movq 168(%rdi), %rax + movq %rdx, 160(%rdi) + adcq 40(%r8), %rax + movq 176(%rdi), %rdx + movq %rax, 168(%rdi) + adcq 48(%r8), %rdx + movq 184(%rdi), %rax + movq %rdx, 176(%rdi) + adcq 56(%r8), %rax + movq 192(%rdi), %rdx + movq %rax, 184(%rdi) + adcq 64(%r8), %rdx + movq 200(%rdi), %rax + movq %rdx, 192(%rdi) + adcq 72(%r8), %rax + movq 208(%rdi), %rdx + movq %rax, 200(%rdi) + adcq 80(%r8), %rdx + movq 216(%rdi), %rax + movq %rdx, 208(%rdi) + adcq 88(%r8), %rax + movq 224(%rdi), %rdx + movq %rax, 216(%rdi) + adcq 96(%r8), %rdx + movq 232(%rdi), %rax + movq %rdx, 224(%rdi) + adcq 104(%r8), %rax + movq 240(%rdi), %rdx + movq %rax, 232(%rdi) + adcq 112(%r8), %rdx + movq 248(%rdi), %rax + movq %rdx, 240(%rdi) + adcq 120(%r8), %rax + movq 256(%rdi), %rdx + movq %rax, 248(%rdi) + adcq 128(%r8), %rdx + movq 264(%rdi), %rax + movq %rdx, 256(%rdi) + adcq 136(%r8), %rax + movq 272(%rdi), %rdx + movq %rax, 264(%rdi) + adcq 144(%r8), %rdx + movq 280(%rdi), %rax + movq %rdx, 272(%rdi) + adcq 152(%r8), %rax + movq 288(%rdi), %rdx + movq %rax, 280(%rdi) + adcq 160(%r8), %rdx + movq 296(%rdi), %rax + movq %rdx, 288(%rdi) + adcq 168(%r8), %rax + movq 304(%rdi), %rdx + movq %rax, 296(%rdi) + adcq 176(%r8), %rdx + movq 312(%rdi), %rax + movq %rdx, 304(%rdi) + adcq 184(%r8), %rax + movq 320(%rdi), %rdx + movq %rax, 312(%rdi) + adcq 192(%r8), %rdx + movq 328(%rdi), %rax + movq %rdx, 320(%rdi) + adcq 200(%r8), %rax + movq 336(%rdi), %rdx + movq %rax, 328(%rdi) + adcq 208(%r8), %rdx + movq 344(%rdi), %rax + movq %rdx, 336(%rdi) + adcq 216(%r8), %rax + movq 352(%rdi), %rdx + movq %rax, 344(%rdi) + adcq 224(%r8), %rdx + movq 360(%rdi), %rax + movq %rdx, 352(%rdi) + adcq 232(%r8), %rax + movq 368(%rdi), %rdx + movq %rax, 360(%rdi) + adcq 240(%r8), %rdx + movq 376(%rdi), %rax + movq %rdx, 368(%rdi) + adcq 248(%r8), %rax + movq %rax, 376(%rdi) + adcq $0, %rcx + movq %rcx, 384(%rdi) + # Add in place + movq 256(%rdi), %rdx + xorq %rcx, %rcx + addq (%rsi), %rdx + movq 264(%rdi), %rax + movq %rdx, 256(%rdi) + adcq 8(%rsi), %rax + movq 272(%rdi), %rdx + movq %rax, 264(%rdi) + adcq 16(%rsi), %rdx + movq 280(%rdi), %rax + movq %rdx, 272(%rdi) + adcq 24(%rsi), %rax + movq 288(%rdi), %rdx + movq %rax, 280(%rdi) + adcq 32(%rsi), %rdx + movq 296(%rdi), %rax + movq %rdx, 288(%rdi) + adcq 40(%rsi), %rax + movq 304(%rdi), %rdx + movq %rax, 296(%rdi) + adcq 48(%rsi), %rdx + movq 312(%rdi), %rax + movq %rdx, 304(%rdi) + adcq 56(%rsi), %rax + movq 320(%rdi), %rdx + movq %rax, 312(%rdi) + adcq 64(%rsi), %rdx + movq 328(%rdi), %rax + movq %rdx, 320(%rdi) + adcq 72(%rsi), %rax + movq 336(%rdi), %rdx + movq %rax, 328(%rdi) + adcq 80(%rsi), %rdx + movq 344(%rdi), %rax + movq %rdx, 336(%rdi) + adcq 88(%rsi), %rax + movq 352(%rdi), %rdx + movq %rax, 344(%rdi) + adcq 96(%rsi), %rdx + movq 360(%rdi), %rax + movq %rdx, 352(%rdi) + adcq 104(%rsi), %rax + movq 368(%rdi), %rdx + movq %rax, 360(%rdi) + adcq 112(%rsi), %rdx + movq 376(%rdi), %rax + movq %rdx, 368(%rdi) + adcq 120(%rsi), %rax + movq 384(%rdi), %rdx + movq %rax, 376(%rdi) + adcq 128(%rsi), %rdx + movq %rdx, 384(%rdi) + adcq $0, %rcx + # Add to zero + movq 136(%rsi), %rdx + adcq $0, %rdx + movq 144(%rsi), %rax + movq %rdx, 392(%rdi) + adcq $0, %rax + movq 152(%rsi), %rdx + movq %rax, 400(%rdi) + adcq $0, %rdx + movq 160(%rsi), %rax + movq %rdx, 408(%rdi) + adcq $0, %rax + movq 168(%rsi), %rdx + movq %rax, 416(%rdi) + adcq $0, %rdx + movq 176(%rsi), %rax + movq %rdx, 424(%rdi) + adcq $0, %rax + movq 184(%rsi), %rdx + movq %rax, 432(%rdi) + adcq $0, %rdx + movq 192(%rsi), %rax + movq %rdx, 440(%rdi) + adcq $0, %rax + movq 200(%rsi), %rdx + movq %rax, 448(%rdi) + adcq $0, %rdx + movq 208(%rsi), %rax + movq %rdx, 456(%rdi) + adcq $0, %rax + movq 216(%rsi), %rdx + movq %rax, 464(%rdi) + adcq $0, %rdx + movq 224(%rsi), %rax + movq %rdx, 472(%rdi) + adcq $0, %rax + movq 232(%rsi), %rdx + movq %rax, 480(%rdi) + adcq $0, %rdx + movq 240(%rsi), %rax + movq %rdx, 488(%rdi) + adcq $0, %rax + movq 248(%rsi), %rdx + movq %rax, 496(%rdi) + adcq $0, %rdx + movq %rdx, 504(%rdi) + addq $664, %rsp + repz retq +#ifndef __APPLE__ +.size sp_2048_sqr_avx2_32,.-sp_2048_sqr_avx2_32 +#endif /* __APPLE__ */ /* Mul a by digit b into r. (r = a * b) * * r A single precision integer. @@ -6693,86 +9260,86 @@ sp_2048_cond_sub_avx2_16: _sp_2048_cond_sub_avx2_16: #endif /* __APPLE__ */ movq $0, %rax - movq (%rsi), %r8 movq (%rdx), %r10 + movq (%rsi), %r8 pextq %rcx, %r10, %r10 subq %r10, %r8 - movq 8(%rsi), %r9 movq 8(%rdx), %r10 + movq 8(%rsi), %r9 pextq %rcx, %r10, %r10 movq %r8, (%rdi) sbbq %r10, %r9 - movq 16(%rsi), %r8 - movq 16(%rdx), %r10 - pextq %rcx, %r10, %r10 + movq 16(%rdx), %r8 + movq 16(%rsi), %r10 + pextq %rcx, %r8, %r8 movq %r9, 8(%rdi) - sbbq %r10, %r8 - movq 24(%rsi), %r9 - movq 24(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 16(%rdi) - sbbq %r10, %r9 - movq 32(%rsi), %r8 + 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 %r9, 24(%rdi) - sbbq %r10, %r8 - movq 40(%rsi), %r9 - movq 40(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 32(%rdi) + 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 - movq 48(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r9, 40(%rdi) - sbbq %r10, %r8 - movq 56(%rsi), %r9 + 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(%rsi), %r8 - movq 64(%rdx), %r10 - pextq %rcx, %r10, %r10 + movq 64(%rdx), %r8 + movq 64(%rsi), %r10 + pextq %rcx, %r8, %r8 movq %r9, 56(%rdi) - sbbq %r10, %r8 - movq 72(%rsi), %r9 - movq 72(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 64(%rdi) - sbbq %r10, %r9 - movq 80(%rsi), %r8 + 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 %r9, 72(%rdi) - sbbq %r10, %r8 - movq 88(%rsi), %r9 - movq 88(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 80(%rdi) + 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 - movq 96(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r9, 88(%rdi) - sbbq %r10, %r8 - movq 104(%rsi), %r9 + 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(%rsi), %r8 - movq 112(%rdx), %r10 - pextq %rcx, %r10, %r10 + movq 112(%rdx), %r8 + movq 112(%rsi), %r10 + pextq %rcx, %r8, %r8 movq %r9, 104(%rdi) - sbbq %r10, %r8 - movq 120(%rsi), %r9 - movq 120(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 112(%rdi) - sbbq %r10, %r9 - movq %r9, 120(%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 $0, %rax repz retq #ifndef __APPLE__ @@ -6942,102 +9509,104 @@ sp_2048_mul_d_avx2_16: .p2align 4 _sp_2048_mul_d_avx2_16: #endif /* __APPLE__ */ + movq %rdx, %rax # A[0] * B - xorq %r10, %r10 - mulxq (%rsi), %r8, %r9 - movq %r8, (%rdi) + movq %rax, %rdx + xorq %r11, %r11 + mulxq (%rsi), %r9, %r10 + movq %r9, (%rdi) # A[1] * B - mulxq 8(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 8(%rdi) - adoxq %rcx, %r8 + mulxq 8(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 8(%rdi) + adoxq %r8, %r9 # A[2] * B - mulxq 16(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 16(%rdi) - adoxq %rcx, %r9 + mulxq 16(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 16(%rdi) + adoxq %r8, %r10 # A[3] * B - mulxq 24(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 24(%rdi) - adoxq %rcx, %r8 + mulxq 24(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 24(%rdi) + adoxq %r8, %r9 # A[4] * B - mulxq 32(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 32(%rdi) - adoxq %rcx, %r9 + mulxq 32(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 32(%rdi) + adoxq %r8, %r10 # A[5] * B - mulxq 40(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 40(%rdi) - adoxq %rcx, %r8 + mulxq 40(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 40(%rdi) + adoxq %r8, %r9 # A[6] * B - mulxq 48(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 48(%rdi) - adoxq %rcx, %r9 + mulxq 48(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 48(%rdi) + adoxq %r8, %r10 # A[7] * B - mulxq 56(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 56(%rdi) - adoxq %rcx, %r8 + mulxq 56(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 56(%rdi) + adoxq %r8, %r9 # A[8] * B - mulxq 64(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 64(%rdi) - adoxq %rcx, %r9 + mulxq 64(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 64(%rdi) + adoxq %r8, %r10 # A[9] * B - mulxq 72(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 72(%rdi) - adoxq %rcx, %r8 + mulxq 72(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 72(%rdi) + adoxq %r8, %r9 # A[10] * B - mulxq 80(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 80(%rdi) - adoxq %rcx, %r9 + mulxq 80(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 80(%rdi) + adoxq %r8, %r10 # A[11] * B - mulxq 88(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 88(%rdi) - adoxq %rcx, %r8 + mulxq 88(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 88(%rdi) + adoxq %r8, %r9 # A[12] * B - mulxq 96(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 96(%rdi) - adoxq %rcx, %r9 + mulxq 96(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 96(%rdi) + adoxq %r8, %r10 # A[13] * B - mulxq 104(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 104(%rdi) - adoxq %rcx, %r8 + mulxq 104(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 104(%rdi) + adoxq %r8, %r9 # A[14] * B - mulxq 112(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 112(%rdi) - adoxq %rcx, %r9 + mulxq 112(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 112(%rdi) + adoxq %r8, %r10 # A[15] * B - mulxq 120(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - adoxq %rcx, %r8 - adcxq %r10, %r8 - movq %r9, 120(%rdi) - movq %r8, 128(%rdi) + 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_2048_mul_d_avx2_16,.-sp_2048_mul_d_avx2_16 @@ -7217,131 +9786,311 @@ _sp_2048_mont_reduce_avx2_16: push %r12 push %r13 push %r14 - movq %rdx, %rax + movq %rdx, %r8 xorq %r14, %r14 # i = 16 movq $16, %r9 movq (%rdi), %r13 + addq $64, %rdi xorq %r12, %r12 L_mont_loop_avx2_16: # mu = a[i] * mp movq %r13, %rdx - mulxq %rax, %rdx, %r8 movq %r13, %r10 + imulq %r8, %rdx + xorq %r12, %r12 # a[i+0] += m[0] * mu - mulxq (%rsi), %rcx, %r8 - movq 8(%rdi), %r13 - adcxq %rcx, %r10 - adoxq %r8, %r13 + mulxq (%rsi), %rax, %rcx + movq -56(%rdi), %r13 + adcxq %rax, %r10 + adoxq %rcx, %r13 # a[i+1] += m[1] * mu - mulxq 8(%rsi), %rcx, %r8 - movq 16(%rdi), %r10 - adcxq %rcx, %r13 - adoxq %r8, %r10 + mulxq 8(%rsi), %rax, %rcx + movq -48(%rdi), %r10 + adcxq %rax, %r13 + adoxq %rcx, %r10 # a[i+2] += m[2] * mu - mulxq 16(%rsi), %rcx, %r8 - movq 24(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 16(%rdi) + mulxq 16(%rsi), %rax, %rcx + movq -40(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -48(%rdi) # a[i+3] += m[3] * mu - mulxq 24(%rsi), %rcx, %r8 - movq 32(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 24(%rdi) + mulxq 24(%rsi), %rax, %rcx + movq -32(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -40(%rdi) # a[i+4] += m[4] * mu - mulxq 32(%rsi), %rcx, %r8 - movq 40(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 32(%rdi) + mulxq 32(%rsi), %rax, %rcx + movq -24(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -32(%rdi) # a[i+5] += m[5] * mu - mulxq 40(%rsi), %rcx, %r8 - movq 48(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 40(%rdi) + 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), %rcx, %r8 - movq 56(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 48(%rdi) + 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), %rcx, %r8 - movq 64(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 56(%rdi) + 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), %rcx, %r8 - movq 72(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 64(%rdi) + 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), %rcx, %r8 - movq 80(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 72(%rdi) + 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), %rcx, %r8 - movq 88(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 80(%rdi) + 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), %rcx, %r8 - movq 96(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 88(%rdi) + 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), %rcx, %r8 - movq 104(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 96(%rdi) + 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), %rcx, %r8 - movq 112(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 104(%rdi) + 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), %rcx, %r8 - movq 120(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 112(%rdi) + 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), %rcx, %r8 - movq 128(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 120(%rdi) + mulxq 120(%rsi), %rax, %rcx + movq 64(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 56(%rdi) adcxq %r14, %r10 + movq %r10, 64(%rdi) movq %r12, %r14 - movq %r10, 128(%rdi) adoxq %r12, %r14 adcxq %r12, %r14 - # i -= 1 - addq $8, %rdi - decq %r9 + # 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 -48(%rdi), %r13 + adcxq %rax, %r10 + adoxq %rcx, %r13 + # a[i+1] += m[1] * mu + mulxq 8(%rsi), %rax, %rcx + movq -40(%rdi), %r10 + adcxq %rax, %r13 + adoxq %rcx, %r10 + # 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) + # 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) + # a[i+4] += m[4] * mu + mulxq 32(%rsi), %rax, %rcx + movq -16(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -24(%rdi) + # 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 %r14, %r10 + movq %r10, 72(%rdi) + movq %r12, %r14 + adoxq %r12, %r14 + adcxq %r12, %r14 + # a += 2 + addq $16, %rdi + # i -= 2 + subq $2, %r9 jnz L_mont_loop_avx2_16 - movq %r13, (%rdi) + subq $64, %rdi negq %r14 - movq %r14, %rcx - movq %rsi, %rdx - movq %rdi, %rsi + movq %rdi, %r8 subq $128, %rdi -#ifndef __APPLE__ - callq sp_2048_cond_sub_avx2_16@plt -#else - callq _sp_2048_cond_sub_avx2_16 -#endif /* __APPLE__ */ + movq (%rsi), %rcx + movq %r13, %rdx + pextq %r14, %rcx, %rcx + subq %rcx, %rdx + movq 8(%rsi), %rcx + movq 8(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, (%rdi) + sbbq %rcx, %rax + movq 16(%rsi), %rdx + movq 16(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 8(%rdi) + sbbq %rdx, %rcx + movq 24(%rsi), %rax + movq 24(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 16(%rdi) + sbbq %rax, %rdx + movq 32(%rsi), %rcx + movq 32(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 24(%rdi) + sbbq %rcx, %rax + movq 40(%rsi), %rdx + movq 40(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 32(%rdi) + sbbq %rdx, %rcx + movq 48(%rsi), %rax + movq 48(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 40(%rdi) + sbbq %rax, %rdx + movq 56(%rsi), %rcx + movq 56(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 48(%rdi) + sbbq %rcx, %rax + movq 64(%rsi), %rdx + movq 64(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 56(%rdi) + sbbq %rdx, %rcx + movq 72(%rsi), %rax + movq 72(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 64(%rdi) + sbbq %rax, %rdx + movq 80(%rsi), %rcx + movq 80(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 72(%rdi) + sbbq %rcx, %rax + movq 88(%rsi), %rdx + movq 88(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 80(%rdi) + sbbq %rdx, %rcx + movq 96(%rsi), %rax + movq 96(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 88(%rdi) + sbbq %rax, %rdx + movq 104(%rsi), %rcx + movq 104(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 96(%rdi) + sbbq %rcx, %rax + movq 112(%rsi), %rdx + movq 112(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 104(%rdi) + sbbq %rdx, %rcx + movq 120(%rsi), %rax + movq 120(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 112(%rdi) + sbbq %rax, %rdx + movq %rdx, 120(%rdi) pop %r14 pop %r13 pop %r12 @@ -7989,162 +10738,162 @@ sp_2048_cond_sub_avx2_32: _sp_2048_cond_sub_avx2_32: #endif /* __APPLE__ */ movq $0, %rax - movq (%rsi), %r8 movq (%rdx), %r10 + movq (%rsi), %r8 pextq %rcx, %r10, %r10 subq %r10, %r8 - movq 8(%rsi), %r9 movq 8(%rdx), %r10 + movq 8(%rsi), %r9 pextq %rcx, %r10, %r10 movq %r8, (%rdi) sbbq %r10, %r9 - movq 16(%rsi), %r8 - movq 16(%rdx), %r10 - pextq %rcx, %r10, %r10 + movq 16(%rdx), %r8 + movq 16(%rsi), %r10 + pextq %rcx, %r8, %r8 movq %r9, 8(%rdi) - sbbq %r10, %r8 - movq 24(%rsi), %r9 - movq 24(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 16(%rdi) - sbbq %r10, %r9 - movq 32(%rsi), %r8 + 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 %r9, 24(%rdi) - sbbq %r10, %r8 - movq 40(%rsi), %r9 - movq 40(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 32(%rdi) + 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 - movq 48(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r9, 40(%rdi) - sbbq %r10, %r8 - movq 56(%rsi), %r9 + 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(%rsi), %r8 - movq 64(%rdx), %r10 - pextq %rcx, %r10, %r10 + movq 64(%rdx), %r8 + movq 64(%rsi), %r10 + pextq %rcx, %r8, %r8 movq %r9, 56(%rdi) - sbbq %r10, %r8 - movq 72(%rsi), %r9 - movq 72(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 64(%rdi) - sbbq %r10, %r9 - movq 80(%rsi), %r8 + 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 %r9, 72(%rdi) - sbbq %r10, %r8 - movq 88(%rsi), %r9 - movq 88(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 80(%rdi) + 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 - movq 96(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r9, 88(%rdi) - sbbq %r10, %r8 - movq 104(%rsi), %r9 + 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(%rsi), %r8 - movq 112(%rdx), %r10 - pextq %rcx, %r10, %r10 + movq 112(%rdx), %r8 + movq 112(%rsi), %r10 + pextq %rcx, %r8, %r8 movq %r9, 104(%rdi) - sbbq %r10, %r8 - movq 120(%rsi), %r9 - movq 120(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 112(%rdi) - sbbq %r10, %r9 - movq 128(%rsi), %r8 + sbbq %r8, %r10 + movq 120(%rdx), %r9 + movq 120(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 112(%rdi) + sbbq %r9, %r8 movq 128(%rdx), %r10 + movq 128(%rsi), %r9 pextq %rcx, %r10, %r10 - movq %r9, 120(%rdi) - sbbq %r10, %r8 - movq 136(%rsi), %r9 - movq 136(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 128(%rdi) + movq %r8, 120(%rdi) sbbq %r10, %r9 + movq 136(%rdx), %r8 + movq 136(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 128(%rdi) + sbbq %r8, %r10 + movq 144(%rdx), %r9 movq 144(%rsi), %r8 - movq 144(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r9, 136(%rdi) - sbbq %r10, %r8 - movq 152(%rsi), %r9 + pextq %rcx, %r9, %r9 + movq %r10, 136(%rdi) + sbbq %r9, %r8 movq 152(%rdx), %r10 + movq 152(%rsi), %r9 pextq %rcx, %r10, %r10 movq %r8, 144(%rdi) sbbq %r10, %r9 - movq 160(%rsi), %r8 - movq 160(%rdx), %r10 - pextq %rcx, %r10, %r10 + movq 160(%rdx), %r8 + movq 160(%rsi), %r10 + pextq %rcx, %r8, %r8 movq %r9, 152(%rdi) - sbbq %r10, %r8 - movq 168(%rsi), %r9 - movq 168(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 160(%rdi) - sbbq %r10, %r9 - movq 176(%rsi), %r8 + sbbq %r8, %r10 + movq 168(%rdx), %r9 + movq 168(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 160(%rdi) + sbbq %r9, %r8 movq 176(%rdx), %r10 + movq 176(%rsi), %r9 pextq %rcx, %r10, %r10 - movq %r9, 168(%rdi) - sbbq %r10, %r8 - movq 184(%rsi), %r9 - movq 184(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 176(%rdi) + movq %r8, 168(%rdi) sbbq %r10, %r9 + movq 184(%rdx), %r8 + movq 184(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 176(%rdi) + sbbq %r8, %r10 + movq 192(%rdx), %r9 movq 192(%rsi), %r8 - movq 192(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r9, 184(%rdi) - sbbq %r10, %r8 - movq 200(%rsi), %r9 + pextq %rcx, %r9, %r9 + movq %r10, 184(%rdi) + sbbq %r9, %r8 movq 200(%rdx), %r10 + movq 200(%rsi), %r9 pextq %rcx, %r10, %r10 movq %r8, 192(%rdi) sbbq %r10, %r9 - movq 208(%rsi), %r8 - movq 208(%rdx), %r10 - pextq %rcx, %r10, %r10 + movq 208(%rdx), %r8 + movq 208(%rsi), %r10 + pextq %rcx, %r8, %r8 movq %r9, 200(%rdi) - sbbq %r10, %r8 - movq 216(%rsi), %r9 - movq 216(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 208(%rdi) - sbbq %r10, %r9 - movq 224(%rsi), %r8 + sbbq %r8, %r10 + movq 216(%rdx), %r9 + movq 216(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 208(%rdi) + sbbq %r9, %r8 movq 224(%rdx), %r10 + movq 224(%rsi), %r9 pextq %rcx, %r10, %r10 - movq %r9, 216(%rdi) - sbbq %r10, %r8 - movq 232(%rsi), %r9 - movq 232(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 224(%rdi) + movq %r8, 216(%rdi) sbbq %r10, %r9 + movq 232(%rdx), %r8 + movq 232(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 224(%rdi) + sbbq %r8, %r10 + movq 240(%rdx), %r9 movq 240(%rsi), %r8 - movq 240(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r9, 232(%rdi) - sbbq %r10, %r8 - movq 248(%rsi), %r9 + pextq %rcx, %r9, %r9 + movq %r10, 232(%rdi) + sbbq %r9, %r8 movq 248(%rdx), %r10 + movq 248(%rsi), %r9 pextq %rcx, %r10, %r10 movq %r8, 240(%rdi) sbbq %r10, %r9 @@ -8171,198 +10920,200 @@ sp_2048_mul_d_avx2_32: .p2align 4 _sp_2048_mul_d_avx2_32: #endif /* __APPLE__ */ + movq %rdx, %rax # A[0] * B - xorq %r10, %r10 - mulxq (%rsi), %r8, %r9 - movq %r8, (%rdi) + movq %rax, %rdx + xorq %r11, %r11 + mulxq (%rsi), %r9, %r10 + movq %r9, (%rdi) # A[1] * B - mulxq 8(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 8(%rdi) - adoxq %rcx, %r8 + mulxq 8(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 8(%rdi) + adoxq %r8, %r9 # A[2] * B - mulxq 16(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 16(%rdi) - adoxq %rcx, %r9 + mulxq 16(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 16(%rdi) + adoxq %r8, %r10 # A[3] * B - mulxq 24(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 24(%rdi) - adoxq %rcx, %r8 + mulxq 24(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 24(%rdi) + adoxq %r8, %r9 # A[4] * B - mulxq 32(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 32(%rdi) - adoxq %rcx, %r9 + mulxq 32(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 32(%rdi) + adoxq %r8, %r10 # A[5] * B - mulxq 40(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 40(%rdi) - adoxq %rcx, %r8 + mulxq 40(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 40(%rdi) + adoxq %r8, %r9 # A[6] * B - mulxq 48(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 48(%rdi) - adoxq %rcx, %r9 + mulxq 48(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 48(%rdi) + adoxq %r8, %r10 # A[7] * B - mulxq 56(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 56(%rdi) - adoxq %rcx, %r8 + mulxq 56(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 56(%rdi) + adoxq %r8, %r9 # A[8] * B - mulxq 64(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 64(%rdi) - adoxq %rcx, %r9 + mulxq 64(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 64(%rdi) + adoxq %r8, %r10 # A[9] * B - mulxq 72(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 72(%rdi) - adoxq %rcx, %r8 + mulxq 72(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 72(%rdi) + adoxq %r8, %r9 # A[10] * B - mulxq 80(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 80(%rdi) - adoxq %rcx, %r9 + mulxq 80(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 80(%rdi) + adoxq %r8, %r10 # A[11] * B - mulxq 88(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 88(%rdi) - adoxq %rcx, %r8 + mulxq 88(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 88(%rdi) + adoxq %r8, %r9 # A[12] * B - mulxq 96(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 96(%rdi) - adoxq %rcx, %r9 + mulxq 96(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 96(%rdi) + adoxq %r8, %r10 # A[13] * B - mulxq 104(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 104(%rdi) - adoxq %rcx, %r8 + mulxq 104(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 104(%rdi) + adoxq %r8, %r9 # A[14] * B - mulxq 112(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 112(%rdi) - adoxq %rcx, %r9 + mulxq 112(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 112(%rdi) + adoxq %r8, %r10 # A[15] * B - mulxq 120(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 120(%rdi) - adoxq %rcx, %r8 + mulxq 120(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 120(%rdi) + adoxq %r8, %r9 # A[16] * B - mulxq 128(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 128(%rdi) - adoxq %rcx, %r9 + mulxq 128(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 128(%rdi) + adoxq %r8, %r10 # A[17] * B - mulxq 136(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 136(%rdi) - adoxq %rcx, %r8 + mulxq 136(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 136(%rdi) + adoxq %r8, %r9 # A[18] * B - mulxq 144(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 144(%rdi) - adoxq %rcx, %r9 + mulxq 144(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 144(%rdi) + adoxq %r8, %r10 # A[19] * B - mulxq 152(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 152(%rdi) - adoxq %rcx, %r8 + mulxq 152(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 152(%rdi) + adoxq %r8, %r9 # A[20] * B - mulxq 160(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 160(%rdi) - adoxq %rcx, %r9 + mulxq 160(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 160(%rdi) + adoxq %r8, %r10 # A[21] * B - mulxq 168(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 168(%rdi) - adoxq %rcx, %r8 + mulxq 168(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 168(%rdi) + adoxq %r8, %r9 # A[22] * B - mulxq 176(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 176(%rdi) - adoxq %rcx, %r9 + mulxq 176(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 176(%rdi) + adoxq %r8, %r10 # A[23] * B - mulxq 184(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 184(%rdi) - adoxq %rcx, %r8 + mulxq 184(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 184(%rdi) + adoxq %r8, %r9 # A[24] * B - mulxq 192(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 192(%rdi) - adoxq %rcx, %r9 + mulxq 192(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 192(%rdi) + adoxq %r8, %r10 # A[25] * B - mulxq 200(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 200(%rdi) - adoxq %rcx, %r8 + mulxq 200(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 200(%rdi) + adoxq %r8, %r9 # A[26] * B - mulxq 208(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 208(%rdi) - adoxq %rcx, %r9 + mulxq 208(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 208(%rdi) + adoxq %r8, %r10 # A[27] * B - mulxq 216(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 216(%rdi) - adoxq %rcx, %r8 + mulxq 216(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 216(%rdi) + adoxq %r8, %r9 # A[28] * B - mulxq 224(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 224(%rdi) - adoxq %rcx, %r9 + mulxq 224(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 224(%rdi) + adoxq %r8, %r10 # A[29] * B - mulxq 232(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 232(%rdi) - adoxq %rcx, %r8 + mulxq 232(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 232(%rdi) + adoxq %r8, %r9 # A[30] * B - mulxq 240(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 240(%rdi) - adoxq %rcx, %r9 + mulxq 240(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 240(%rdi) + adoxq %r8, %r10 # A[31] * B - mulxq 248(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - adoxq %rcx, %r8 - adcxq %r10, %r8 - movq %r9, 248(%rdi) - movq %r8, 256(%rdi) + mulxq 248(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + adoxq %r8, %r9 + adcxq %r11, %r9 + movq %r10, 248(%rdi) + movq %r9, 256(%rdi) repz retq #ifndef __APPLE__ .size sp_2048_mul_d_avx2_32,.-sp_2048_mul_d_avx2_32 @@ -8788,227 +11539,383 @@ _sp_2048_mont_reduce_avx2_32: push %r12 push %r13 push %r14 - movq %rdx, %rax + movq %rdx, %r8 xorq %r14, %r14 # i = 32 movq $32, %r9 movq (%rdi), %r13 + addq $128, %rdi xorq %r12, %r12 L_mont_loop_avx2_32: # mu = a[i] * mp movq %r13, %rdx - mulxq %rax, %rdx, %r8 movq %r13, %r10 + imulq %r8, %rdx + xorq %r12, %r12 # a[i+0] += m[0] * mu - mulxq (%rsi), %rcx, %r8 - movq 8(%rdi), %r13 - adcxq %rcx, %r10 - adoxq %r8, %r13 + mulxq (%rsi), %rax, %rcx + movq -120(%rdi), %r13 + adcxq %rax, %r10 + adoxq %rcx, %r13 # a[i+1] += m[1] * mu - mulxq 8(%rsi), %rcx, %r8 - movq 16(%rdi), %r10 - adcxq %rcx, %r13 - adoxq %r8, %r10 + mulxq 8(%rsi), %rax, %rcx + movq -112(%rdi), %r10 + adcxq %rax, %r13 + adoxq %rcx, %r10 # a[i+2] += m[2] * mu - mulxq 16(%rsi), %rcx, %r8 - movq 24(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 16(%rdi) + mulxq 16(%rsi), %rax, %rcx + movq -104(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -112(%rdi) # a[i+3] += m[3] * mu - mulxq 24(%rsi), %rcx, %r8 - movq 32(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 24(%rdi) + mulxq 24(%rsi), %rax, %rcx + movq -96(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -104(%rdi) # a[i+4] += m[4] * mu - mulxq 32(%rsi), %rcx, %r8 - movq 40(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 32(%rdi) + mulxq 32(%rsi), %rax, %rcx + movq -88(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -96(%rdi) # a[i+5] += m[5] * mu - mulxq 40(%rsi), %rcx, %r8 - movq 48(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 40(%rdi) + mulxq 40(%rsi), %rax, %rcx + movq -80(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -88(%rdi) # a[i+6] += m[6] * mu - mulxq 48(%rsi), %rcx, %r8 - movq 56(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 48(%rdi) + mulxq 48(%rsi), %rax, %rcx + movq -72(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -80(%rdi) # a[i+7] += m[7] * mu - mulxq 56(%rsi), %rcx, %r8 - movq 64(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 56(%rdi) + mulxq 56(%rsi), %rax, %rcx + movq -64(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -72(%rdi) # a[i+8] += m[8] * mu - mulxq 64(%rsi), %rcx, %r8 - movq 72(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 64(%rdi) + mulxq 64(%rsi), %rax, %rcx + movq -56(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -64(%rdi) # a[i+9] += m[9] * mu - mulxq 72(%rsi), %rcx, %r8 - movq 80(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 72(%rdi) + mulxq 72(%rsi), %rax, %rcx + movq -48(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -56(%rdi) # a[i+10] += m[10] * mu - mulxq 80(%rsi), %rcx, %r8 - movq 88(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 80(%rdi) + mulxq 80(%rsi), %rax, %rcx + movq -40(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -48(%rdi) # a[i+11] += m[11] * mu - mulxq 88(%rsi), %rcx, %r8 - movq 96(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 88(%rdi) + mulxq 88(%rsi), %rax, %rcx + movq -32(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -40(%rdi) # a[i+12] += m[12] * mu - mulxq 96(%rsi), %rcx, %r8 - movq 104(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 96(%rdi) + mulxq 96(%rsi), %rax, %rcx + movq -24(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -32(%rdi) # a[i+13] += m[13] * mu - mulxq 104(%rsi), %rcx, %r8 - movq 112(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 104(%rdi) + mulxq 104(%rsi), %rax, %rcx + movq -16(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -24(%rdi) # a[i+14] += m[14] * mu - mulxq 112(%rsi), %rcx, %r8 - movq 120(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 112(%rdi) + mulxq 112(%rsi), %rax, %rcx + movq -8(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -16(%rdi) # a[i+15] += m[15] * mu - mulxq 120(%rsi), %rcx, %r8 - movq 128(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 120(%rdi) + mulxq 120(%rsi), %rax, %rcx + movq (%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -8(%rdi) # a[i+16] += m[16] * mu - mulxq 128(%rsi), %rcx, %r8 - movq 136(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 128(%rdi) + mulxq 128(%rsi), %rax, %rcx + movq 8(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, (%rdi) # a[i+17] += m[17] * mu - mulxq 136(%rsi), %rcx, %r8 - movq 144(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 136(%rdi) + mulxq 136(%rsi), %rax, %rcx + movq 16(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 8(%rdi) # a[i+18] += m[18] * mu - mulxq 144(%rsi), %rcx, %r8 - movq 152(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 144(%rdi) + mulxq 144(%rsi), %rax, %rcx + movq 24(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 16(%rdi) # a[i+19] += m[19] * mu - mulxq 152(%rsi), %rcx, %r8 - movq 160(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 152(%rdi) + mulxq 152(%rsi), %rax, %rcx + movq 32(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 24(%rdi) # a[i+20] += m[20] * mu - mulxq 160(%rsi), %rcx, %r8 - movq 168(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 160(%rdi) + mulxq 160(%rsi), %rax, %rcx + movq 40(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 32(%rdi) # a[i+21] += m[21] * mu - mulxq 168(%rsi), %rcx, %r8 - movq 176(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 168(%rdi) + mulxq 168(%rsi), %rax, %rcx + movq 48(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 40(%rdi) # a[i+22] += m[22] * mu - mulxq 176(%rsi), %rcx, %r8 - movq 184(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 176(%rdi) + mulxq 176(%rsi), %rax, %rcx + movq 56(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 48(%rdi) # a[i+23] += m[23] * mu - mulxq 184(%rsi), %rcx, %r8 - movq 192(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 184(%rdi) + mulxq 184(%rsi), %rax, %rcx + movq 64(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 56(%rdi) # a[i+24] += m[24] * mu - mulxq 192(%rsi), %rcx, %r8 - movq 200(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 192(%rdi) + mulxq 192(%rsi), %rax, %rcx + movq 72(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 64(%rdi) # a[i+25] += m[25] * mu - mulxq 200(%rsi), %rcx, %r8 - movq 208(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 200(%rdi) + mulxq 200(%rsi), %rax, %rcx + movq 80(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 72(%rdi) # a[i+26] += m[26] * mu - mulxq 208(%rsi), %rcx, %r8 - movq 216(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 208(%rdi) + mulxq 208(%rsi), %rax, %rcx + movq 88(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 80(%rdi) # a[i+27] += m[27] * mu - mulxq 216(%rsi), %rcx, %r8 - movq 224(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 216(%rdi) + mulxq 216(%rsi), %rax, %rcx + movq 96(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 88(%rdi) # a[i+28] += m[28] * mu - mulxq 224(%rsi), %rcx, %r8 - movq 232(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 224(%rdi) + mulxq 224(%rsi), %rax, %rcx + movq 104(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 96(%rdi) # a[i+29] += m[29] * mu - mulxq 232(%rsi), %rcx, %r8 - movq 240(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 232(%rdi) + mulxq 232(%rsi), %rax, %rcx + movq 112(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 104(%rdi) # a[i+30] += m[30] * mu - mulxq 240(%rsi), %rcx, %r8 - movq 248(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 240(%rdi) + mulxq 240(%rsi), %rax, %rcx + movq 120(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 112(%rdi) # a[i+31] += m[31] * mu - mulxq 248(%rsi), %rcx, %r8 - movq 256(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 248(%rdi) + mulxq 248(%rsi), %rax, %rcx + movq 128(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 120(%rdi) adcxq %r14, %r10 + movq %r10, 128(%rdi) movq %r12, %r14 - movq %r10, 256(%rdi) adoxq %r12, %r14 adcxq %r12, %r14 - # i -= 1 + # a += 1 addq $8, %rdi - decq %r9 + # i -= 1 + subq $1, %r9 jnz L_mont_loop_avx2_32 - movq %r13, (%rdi) + subq $128, %rdi negq %r14 - movq %r14, %rcx - movq %rsi, %rdx - movq %rdi, %rsi + movq %rdi, %r8 subq $256, %rdi -#ifndef __APPLE__ - callq sp_2048_cond_sub_avx2_32@plt -#else - callq _sp_2048_cond_sub_avx2_32 -#endif /* __APPLE__ */ + movq (%rsi), %rcx + movq %r13, %rdx + pextq %r14, %rcx, %rcx + subq %rcx, %rdx + movq 8(%rsi), %rcx + movq 8(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, (%rdi) + sbbq %rcx, %rax + movq 16(%rsi), %rdx + movq 16(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 8(%rdi) + sbbq %rdx, %rcx + movq 24(%rsi), %rax + movq 24(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 16(%rdi) + sbbq %rax, %rdx + movq 32(%rsi), %rcx + movq 32(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 24(%rdi) + sbbq %rcx, %rax + movq 40(%rsi), %rdx + movq 40(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 32(%rdi) + sbbq %rdx, %rcx + movq 48(%rsi), %rax + movq 48(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 40(%rdi) + sbbq %rax, %rdx + movq 56(%rsi), %rcx + movq 56(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 48(%rdi) + sbbq %rcx, %rax + movq 64(%rsi), %rdx + movq 64(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 56(%rdi) + sbbq %rdx, %rcx + movq 72(%rsi), %rax + movq 72(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 64(%rdi) + sbbq %rax, %rdx + movq 80(%rsi), %rcx + movq 80(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 72(%rdi) + sbbq %rcx, %rax + movq 88(%rsi), %rdx + movq 88(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 80(%rdi) + sbbq %rdx, %rcx + movq 96(%rsi), %rax + movq 96(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 88(%rdi) + sbbq %rax, %rdx + movq 104(%rsi), %rcx + movq 104(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 96(%rdi) + sbbq %rcx, %rax + movq 112(%rsi), %rdx + movq 112(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 104(%rdi) + sbbq %rdx, %rcx + movq 120(%rsi), %rax + movq 120(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 112(%rdi) + sbbq %rax, %rdx + movq 128(%rsi), %rcx + movq 128(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 120(%rdi) + sbbq %rcx, %rax + movq 136(%rsi), %rdx + movq 136(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 128(%rdi) + sbbq %rdx, %rcx + movq 144(%rsi), %rax + movq 144(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 136(%rdi) + sbbq %rax, %rdx + movq 152(%rsi), %rcx + movq 152(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 144(%rdi) + sbbq %rcx, %rax + movq 160(%rsi), %rdx + movq 160(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 152(%rdi) + sbbq %rdx, %rcx + movq 168(%rsi), %rax + movq 168(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 160(%rdi) + sbbq %rax, %rdx + movq 176(%rsi), %rcx + movq 176(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 168(%rdi) + sbbq %rcx, %rax + movq 184(%rsi), %rdx + movq 184(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 176(%rdi) + sbbq %rdx, %rcx + movq 192(%rsi), %rax + movq 192(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 184(%rdi) + sbbq %rax, %rdx + movq 200(%rsi), %rcx + movq 200(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 192(%rdi) + sbbq %rcx, %rax + movq 208(%rsi), %rdx + movq 208(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 200(%rdi) + sbbq %rdx, %rcx + movq 216(%rsi), %rax + movq 216(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 208(%rdi) + sbbq %rax, %rdx + movq 224(%rsi), %rcx + movq 224(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 216(%rdi) + sbbq %rcx, %rax + movq 232(%rsi), %rdx + movq 232(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 224(%rdi) + sbbq %rdx, %rcx + movq 240(%rsi), %rax + movq 240(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 232(%rdi) + sbbq %rax, %rdx + movq 248(%rsi), %rcx + movq 248(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 240(%rdi) + sbbq %rcx, %rax + movq %rax, 248(%rdi) pop %r14 pop %r13 pop %r12 @@ -9343,17 +12250,17 @@ _sp_3072_to_bin: * b A single precision integer. */ #ifndef __APPLE__ -.globl sp_3072_mul_24 -.type sp_3072_mul_24,@function +.globl sp_3072_mul_12 +.type sp_3072_mul_12,@function .align 16 -sp_3072_mul_24: +sp_3072_mul_12: #else -.globl _sp_3072_mul_24 +.globl _sp_3072_mul_12 .p2align 4 -_sp_3072_mul_24: +_sp_3072_mul_12: #endif /* __APPLE__ */ movq %rdx, %rcx - subq $192, %rsp + subq $96, %rsp # A[0] * B[0] movq (%rcx), %rax mulq (%rsi) @@ -9844,16 +12751,10 @@ _sp_3072_mul_24: adcq %rdx, %r8 adcq $0, %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 $0, %r10 # A[1] * B[11] movq 88(%rcx), %rax mulq 8(%rsi) + xorq %r10, %r10 addq %rax, %r8 adcq %rdx, %r9 adcq $0, %r10 @@ -9917,29 +12818,11 @@ _sp_3072_mul_24: addq %rax, %r8 adcq %rdx, %r9 adcq $0, %r10 - # A[12] * B[0] - movq (%rcx), %rax - mulq 96(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %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 $0, %r8 - # A[1] * B[12] - movq 96(%rcx), %rax - mulq 8(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 + movq %r8, 96(%rdi) # A[2] * B[11] movq 88(%rcx), %rax mulq 16(%rsi) + xorq %r8, %r8 addq %rax, %r9 adcq %rdx, %r10 adcq $0, %r8 @@ -9997,41 +12880,11 @@ _sp_3072_mul_24: addq %rax, %r9 adcq %rdx, %r10 adcq $0, %r8 - # A[12] * B[1] - movq 8(%rcx), %rax - mulq 96(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[13] * B[0] - movq (%rcx), %rax - mulq 104(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %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 $0, %r9 - # A[1] * B[13] - movq 104(%rcx), %rax - mulq 8(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[2] * B[12] - movq 96(%rcx), %rax - mulq 16(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 + movq %r9, 104(%rdi) # A[3] * B[11] movq 88(%rcx), %rax mulq 24(%rsi) + xorq %r9, %r9 addq %rax, %r10 adcq %rdx, %r8 adcq $0, %r9 @@ -10083,53 +12936,11 @@ _sp_3072_mul_24: addq %rax, %r10 adcq %rdx, %r8 adcq $0, %r9 - # A[12] * B[2] - movq 16(%rcx), %rax - mulq 96(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[13] * B[1] - movq 8(%rcx), %rax - mulq 104(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[14] * B[0] - movq (%rcx), %rax - mulq 112(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %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 $0, %r10 - # A[1] * B[14] - movq 112(%rcx), %rax - mulq 8(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[2] * B[13] - movq 104(%rcx), %rax - mulq 16(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[3] * B[12] - movq 96(%rcx), %rax - mulq 24(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 + movq %r10, 112(%rdi) # A[4] * B[11] movq 88(%rcx), %rax mulq 32(%rsi) + xorq %r10, %r10 addq %rax, %r8 adcq %rdx, %r9 adcq $0, %r10 @@ -10175,65 +12986,11 @@ _sp_3072_mul_24: addq %rax, %r8 adcq %rdx, %r9 adcq $0, %r10 - # A[12] * B[3] - movq 24(%rcx), %rax - mulq 96(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[13] * B[2] - movq 16(%rcx), %rax - mulq 104(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[14] * B[1] - movq 8(%rcx), %rax - mulq 112(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[15] * B[0] - movq (%rcx), %rax - mulq 120(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - movq %r8, 120(%rsp) - # A[0] * B[16] - movq 128(%rcx), %rax - mulq (%rsi) - xorq %r8, %r8 - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[1] * B[15] - movq 120(%rcx), %rax - mulq 8(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[2] * B[14] - movq 112(%rcx), %rax - mulq 16(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[3] * B[13] - movq 104(%rcx), %rax - mulq 24(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[4] * B[12] - movq 96(%rcx), %rax - mulq 32(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 + movq %r8, 120(%rdi) # A[5] * B[11] movq 88(%rcx), %rax mulq 40(%rsi) + xorq %r8, %r8 addq %rax, %r9 adcq %rdx, %r10 adcq $0, %r8 @@ -10273,77 +13030,11 @@ _sp_3072_mul_24: addq %rax, %r9 adcq %rdx, %r10 adcq $0, %r8 - # A[12] * B[4] - movq 32(%rcx), %rax - mulq 96(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[13] * B[3] - movq 24(%rcx), %rax - mulq 104(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[14] * B[2] - movq 16(%rcx), %rax - mulq 112(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[15] * B[1] - movq 8(%rcx), %rax - mulq 120(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[16] * B[0] - movq (%rcx), %rax - mulq 128(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - movq %r9, 128(%rsp) - # A[0] * B[17] - movq 136(%rcx), %rax - mulq (%rsi) - xorq %r9, %r9 - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[1] * B[16] - movq 128(%rcx), %rax - mulq 8(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[2] * B[15] - movq 120(%rcx), %rax - mulq 16(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[3] * B[14] - movq 112(%rcx), %rax - mulq 24(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[4] * B[13] - movq 104(%rcx), %rax - mulq 32(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[5] * B[12] - movq 96(%rcx), %rax - mulq 40(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 + movq %r9, 128(%rdi) # A[6] * B[11] movq 88(%rcx), %rax mulq 48(%rsi) + xorq %r9, %r9 addq %rax, %r10 adcq %rdx, %r8 adcq $0, %r9 @@ -10377,89 +13068,11 @@ _sp_3072_mul_24: addq %rax, %r10 adcq %rdx, %r8 adcq $0, %r9 - # A[12] * B[5] - movq 40(%rcx), %rax - mulq 96(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[13] * B[4] - movq 32(%rcx), %rax - mulq 104(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[14] * B[3] - movq 24(%rcx), %rax - mulq 112(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[15] * B[2] - movq 16(%rcx), %rax - mulq 120(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[16] * B[1] - movq 8(%rcx), %rax - mulq 128(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[17] * B[0] - movq (%rcx), %rax - mulq 136(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - movq %r10, 136(%rsp) - # A[0] * B[18] - movq 144(%rcx), %rax - mulq (%rsi) - xorq %r10, %r10 - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[1] * B[17] - movq 136(%rcx), %rax - mulq 8(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[2] * B[16] - movq 128(%rcx), %rax - mulq 16(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[3] * B[15] - movq 120(%rcx), %rax - mulq 24(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[4] * B[14] - movq 112(%rcx), %rax - mulq 32(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[5] * B[13] - movq 104(%rcx), %rax - mulq 40(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[6] * B[12] - movq 96(%rcx), %rax - mulq 48(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 + movq %r10, 136(%rdi) # A[7] * B[11] movq 88(%rcx), %rax mulq 56(%rsi) + xorq %r10, %r10 addq %rax, %r8 adcq %rdx, %r9 adcq $0, %r10 @@ -10487,101 +13100,11 @@ _sp_3072_mul_24: addq %rax, %r8 adcq %rdx, %r9 adcq $0, %r10 - # A[12] * B[6] - movq 48(%rcx), %rax - mulq 96(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[13] * B[5] - movq 40(%rcx), %rax - mulq 104(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[14] * B[4] - movq 32(%rcx), %rax - mulq 112(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[15] * B[3] - movq 24(%rcx), %rax - mulq 120(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[16] * B[2] - movq 16(%rcx), %rax - mulq 128(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[17] * B[1] - movq 8(%rcx), %rax - mulq 136(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[18] * B[0] - movq (%rcx), %rax - mulq 144(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - movq %r8, 144(%rsp) - # A[0] * B[19] - movq 152(%rcx), %rax - mulq (%rsi) - xorq %r8, %r8 - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[1] * B[18] - movq 144(%rcx), %rax - mulq 8(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[2] * B[17] - movq 136(%rcx), %rax - mulq 16(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[3] * B[16] - movq 128(%rcx), %rax - mulq 24(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[4] * B[15] - movq 120(%rcx), %rax - mulq 32(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[5] * B[14] - movq 112(%rcx), %rax - mulq 40(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[6] * B[13] - movq 104(%rcx), %rax - mulq 48(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[7] * B[12] - movq 96(%rcx), %rax - mulq 56(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 + movq %r8, 144(%rdi) # A[8] * B[11] movq 88(%rcx), %rax mulq 64(%rsi) + xorq %r8, %r8 addq %rax, %r9 adcq %rdx, %r10 adcq $0, %r8 @@ -10603,113 +13126,11 @@ _sp_3072_mul_24: addq %rax, %r9 adcq %rdx, %r10 adcq $0, %r8 - # A[12] * B[7] - movq 56(%rcx), %rax - mulq 96(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[13] * B[6] - movq 48(%rcx), %rax - mulq 104(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[14] * B[5] - movq 40(%rcx), %rax - mulq 112(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[15] * B[4] - movq 32(%rcx), %rax - mulq 120(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[16] * B[3] - movq 24(%rcx), %rax - mulq 128(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[17] * B[2] - movq 16(%rcx), %rax - mulq 136(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[18] * B[1] - movq 8(%rcx), %rax - mulq 144(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[19] * B[0] - movq (%rcx), %rax - mulq 152(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - movq %r9, 152(%rsp) - # A[0] * B[20] - movq 160(%rcx), %rax - mulq (%rsi) - xorq %r9, %r9 - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[1] * B[19] - movq 152(%rcx), %rax - mulq 8(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[2] * B[18] - movq 144(%rcx), %rax - mulq 16(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[3] * B[17] - movq 136(%rcx), %rax - mulq 24(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[4] * B[16] - movq 128(%rcx), %rax - mulq 32(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[5] * B[15] - movq 120(%rcx), %rax - mulq 40(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[6] * B[14] - movq 112(%rcx), %rax - mulq 48(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[7] * B[13] - movq 104(%rcx), %rax - mulq 56(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[8] * B[12] - movq 96(%rcx), %rax - mulq 64(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 + movq %r9, 152(%rdi) # A[9] * B[11] movq 88(%rcx), %rax mulq 72(%rsi) + xorq %r9, %r9 addq %rax, %r10 adcq %rdx, %r8 adcq $0, %r9 @@ -10725,125 +13146,11 @@ _sp_3072_mul_24: addq %rax, %r10 adcq %rdx, %r8 adcq $0, %r9 - # A[12] * B[8] - movq 64(%rcx), %rax - mulq 96(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[13] * B[7] - movq 56(%rcx), %rax - mulq 104(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[14] * B[6] - movq 48(%rcx), %rax - mulq 112(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[15] * B[5] - movq 40(%rcx), %rax - mulq 120(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[16] * B[4] - movq 32(%rcx), %rax - mulq 128(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[17] * B[3] - movq 24(%rcx), %rax - mulq 136(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[18] * B[2] - movq 16(%rcx), %rax - mulq 144(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[19] * B[1] - movq 8(%rcx), %rax - mulq 152(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[20] * B[0] - movq (%rcx), %rax - mulq 160(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - movq %r10, 160(%rsp) - # A[0] * B[21] - movq 168(%rcx), %rax - mulq (%rsi) - xorq %r10, %r10 - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[1] * B[20] - movq 160(%rcx), %rax - mulq 8(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[2] * B[19] - movq 152(%rcx), %rax - mulq 16(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[3] * B[18] - movq 144(%rcx), %rax - mulq 24(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[4] * B[17] - movq 136(%rcx), %rax - mulq 32(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[5] * B[16] - movq 128(%rcx), %rax - mulq 40(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[6] * B[15] - movq 120(%rcx), %rax - mulq 48(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[7] * B[14] - movq 112(%rcx), %rax - mulq 56(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[8] * B[13] - movq 104(%rcx), %rax - mulq 64(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[9] * B[12] - movq 96(%rcx), %rax - mulq 72(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 + movq %r10, 160(%rdi) # A[10] * B[11] movq 88(%rcx), %rax mulq 80(%rsi) + xorq %r10, %r10 addq %rax, %r8 adcq %rdx, %r9 adcq $0, %r10 @@ -10853,2054 +13160,14 @@ _sp_3072_mul_24: addq %rax, %r8 adcq %rdx, %r9 adcq $0, %r10 - # A[12] * B[9] - movq 72(%rcx), %rax - mulq 96(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[13] * B[8] - movq 64(%rcx), %rax - mulq 104(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[14] * B[7] - movq 56(%rcx), %rax - mulq 112(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[15] * B[6] - movq 48(%rcx), %rax - mulq 120(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[16] * B[5] - movq 40(%rcx), %rax - mulq 128(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[17] * B[4] - movq 32(%rcx), %rax - mulq 136(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[18] * B[3] - movq 24(%rcx), %rax - mulq 144(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[19] * B[2] - movq 16(%rcx), %rax - mulq 152(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[20] * B[1] - movq 8(%rcx), %rax - mulq 160(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[21] * B[0] - movq (%rcx), %rax - mulq 168(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - movq %r8, 168(%rsp) - # A[0] * B[22] - movq 176(%rcx), %rax - mulq (%rsi) - xorq %r8, %r8 - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[1] * B[21] - movq 168(%rcx), %rax - mulq 8(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[2] * B[20] - movq 160(%rcx), %rax - mulq 16(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[3] * B[19] - movq 152(%rcx), %rax - mulq 24(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[4] * B[18] - movq 144(%rcx), %rax - mulq 32(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[5] * B[17] - movq 136(%rcx), %rax - mulq 40(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[6] * B[16] - movq 128(%rcx), %rax - mulq 48(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[7] * B[15] - movq 120(%rcx), %rax - mulq 56(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[8] * B[14] - movq 112(%rcx), %rax - mulq 64(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[9] * B[13] - movq 104(%rcx), %rax - mulq 72(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[10] * B[12] - movq 96(%rcx), %rax - mulq 80(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 + movq %r8, 168(%rdi) # A[11] * B[11] movq 88(%rcx), %rax mulq 88(%rsi) addq %rax, %r9 adcq %rdx, %r10 - adcq $0, %r8 - # A[12] * B[10] - movq 80(%rcx), %rax - mulq 96(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[13] * B[9] - movq 72(%rcx), %rax - mulq 104(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[14] * B[8] - movq 64(%rcx), %rax - mulq 112(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[15] * B[7] - movq 56(%rcx), %rax - mulq 120(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[16] * B[6] - movq 48(%rcx), %rax - mulq 128(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[17] * B[5] - movq 40(%rcx), %rax - mulq 136(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[18] * B[4] - movq 32(%rcx), %rax - mulq 144(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[19] * B[3] - movq 24(%rcx), %rax - mulq 152(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[20] * B[2] - movq 16(%rcx), %rax - mulq 160(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[21] * B[1] - movq 8(%rcx), %rax - mulq 168(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[22] * B[0] - movq (%rcx), %rax - mulq 176(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - movq %r9, 176(%rsp) - # A[0] * B[23] - movq 184(%rcx), %rax - mulq (%rsi) - xorq %r9, %r9 - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[1] * B[22] - movq 176(%rcx), %rax - mulq 8(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[2] * B[21] - movq 168(%rcx), %rax - mulq 16(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[3] * B[20] - movq 160(%rcx), %rax - mulq 24(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[4] * B[19] - movq 152(%rcx), %rax - mulq 32(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[5] * B[18] - movq 144(%rcx), %rax - mulq 40(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[6] * B[17] - movq 136(%rcx), %rax - mulq 48(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[7] * B[16] - movq 128(%rcx), %rax - mulq 56(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[8] * B[15] - movq 120(%rcx), %rax - mulq 64(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[9] * B[14] - movq 112(%rcx), %rax - mulq 72(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[10] * B[13] - movq 104(%rcx), %rax - mulq 80(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[11] * B[12] - movq 96(%rcx), %rax - mulq 88(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[12] * B[11] - movq 88(%rcx), %rax - mulq 96(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[13] * B[10] - movq 80(%rcx), %rax - mulq 104(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[14] * B[9] - movq 72(%rcx), %rax - mulq 112(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[15] * B[8] - movq 64(%rcx), %rax - mulq 120(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[16] * B[7] - movq 56(%rcx), %rax - mulq 128(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[17] * B[6] - movq 48(%rcx), %rax - mulq 136(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[18] * B[5] - movq 40(%rcx), %rax - mulq 144(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[19] * B[4] - movq 32(%rcx), %rax - mulq 152(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[20] * B[3] - movq 24(%rcx), %rax - mulq 160(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[21] * B[2] - movq 16(%rcx), %rax - mulq 168(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[22] * B[1] - movq 8(%rcx), %rax - mulq 176(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[23] * B[0] - movq (%rcx), %rax - mulq 184(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - movq %r10, 184(%rsp) - # A[1] * B[23] - movq 184(%rcx), %rax - mulq 8(%rsi) - xorq %r10, %r10 - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[2] * B[22] - movq 176(%rcx), %rax - mulq 16(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[3] * B[21] - movq 168(%rcx), %rax - mulq 24(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[4] * B[20] - movq 160(%rcx), %rax - mulq 32(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[5] * B[19] - movq 152(%rcx), %rax - mulq 40(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[6] * B[18] - movq 144(%rcx), %rax - mulq 48(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[7] * B[17] - movq 136(%rcx), %rax - mulq 56(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[8] * B[16] - movq 128(%rcx), %rax - mulq 64(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[9] * B[15] - movq 120(%rcx), %rax - mulq 72(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[10] * B[14] - movq 112(%rcx), %rax - mulq 80(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[11] * B[13] - movq 104(%rcx), %rax - mulq 88(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[12] * B[12] - movq 96(%rcx), %rax - mulq 96(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[13] * B[11] - movq 88(%rcx), %rax - mulq 104(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[14] * B[10] - movq 80(%rcx), %rax - mulq 112(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[15] * B[9] - movq 72(%rcx), %rax - mulq 120(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[16] * B[8] - movq 64(%rcx), %rax - mulq 128(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[17] * B[7] - movq 56(%rcx), %rax - mulq 136(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[18] * B[6] - movq 48(%rcx), %rax - mulq 144(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[19] * B[5] - movq 40(%rcx), %rax - mulq 152(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[20] * B[4] - movq 32(%rcx), %rax - mulq 160(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[21] * B[3] - movq 24(%rcx), %rax - mulq 168(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[22] * B[2] - movq 16(%rcx), %rax - mulq 176(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[23] * B[1] - movq 8(%rcx), %rax - mulq 184(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - movq %r8, 192(%rdi) - # A[2] * B[23] - movq 184(%rcx), %rax - mulq 16(%rsi) - xorq %r8, %r8 - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[3] * B[22] - movq 176(%rcx), %rax - mulq 24(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[4] * B[21] - movq 168(%rcx), %rax - mulq 32(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[5] * B[20] - movq 160(%rcx), %rax - mulq 40(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[6] * B[19] - movq 152(%rcx), %rax - mulq 48(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[7] * B[18] - movq 144(%rcx), %rax - mulq 56(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[8] * B[17] - movq 136(%rcx), %rax - mulq 64(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[9] * B[16] - movq 128(%rcx), %rax - mulq 72(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[10] * B[15] - movq 120(%rcx), %rax - mulq 80(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[11] * B[14] - movq 112(%rcx), %rax - mulq 88(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[12] * B[13] - movq 104(%rcx), %rax - mulq 96(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[13] * B[12] - movq 96(%rcx), %rax - mulq 104(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[14] * B[11] - movq 88(%rcx), %rax - mulq 112(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[15] * B[10] - movq 80(%rcx), %rax - mulq 120(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[16] * B[9] - movq 72(%rcx), %rax - mulq 128(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[17] * B[8] - movq 64(%rcx), %rax - mulq 136(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[18] * B[7] - movq 56(%rcx), %rax - mulq 144(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[19] * B[6] - movq 48(%rcx), %rax - mulq 152(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[20] * B[5] - movq 40(%rcx), %rax - mulq 160(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[21] * B[4] - movq 32(%rcx), %rax - mulq 168(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[22] * B[3] - movq 24(%rcx), %rax - mulq 176(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[23] * B[2] - movq 16(%rcx), %rax - mulq 184(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - movq %r9, 200(%rdi) - # A[3] * B[23] - movq 184(%rcx), %rax - mulq 24(%rsi) - xorq %r9, %r9 - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[4] * B[22] - movq 176(%rcx), %rax - mulq 32(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[5] * B[21] - movq 168(%rcx), %rax - mulq 40(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[6] * B[20] - movq 160(%rcx), %rax - mulq 48(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[7] * B[19] - movq 152(%rcx), %rax - mulq 56(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[8] * B[18] - movq 144(%rcx), %rax - mulq 64(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[9] * B[17] - movq 136(%rcx), %rax - mulq 72(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[10] * B[16] - movq 128(%rcx), %rax - mulq 80(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[11] * B[15] - movq 120(%rcx), %rax - mulq 88(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[12] * B[14] - movq 112(%rcx), %rax - mulq 96(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[13] * B[13] - movq 104(%rcx), %rax - mulq 104(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[14] * B[12] - movq 96(%rcx), %rax - mulq 112(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[15] * B[11] - movq 88(%rcx), %rax - mulq 120(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[16] * B[10] - movq 80(%rcx), %rax - mulq 128(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[17] * B[9] - movq 72(%rcx), %rax - mulq 136(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[18] * B[8] - movq 64(%rcx), %rax - mulq 144(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[19] * B[7] - movq 56(%rcx), %rax - mulq 152(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[20] * B[6] - movq 48(%rcx), %rax - mulq 160(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[21] * B[5] - movq 40(%rcx), %rax - mulq 168(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[22] * B[4] - movq 32(%rcx), %rax - mulq 176(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[23] * B[3] - movq 24(%rcx), %rax - mulq 184(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - movq %r10, 208(%rdi) - # A[4] * B[23] - movq 184(%rcx), %rax - mulq 32(%rsi) - xorq %r10, %r10 - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[5] * B[22] - movq 176(%rcx), %rax - mulq 40(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[6] * B[21] - movq 168(%rcx), %rax - mulq 48(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[7] * B[20] - movq 160(%rcx), %rax - mulq 56(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[8] * B[19] - movq 152(%rcx), %rax - mulq 64(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[9] * B[18] - movq 144(%rcx), %rax - mulq 72(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[10] * B[17] - movq 136(%rcx), %rax - mulq 80(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[11] * B[16] - movq 128(%rcx), %rax - mulq 88(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[12] * B[15] - movq 120(%rcx), %rax - mulq 96(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[13] * B[14] - movq 112(%rcx), %rax - mulq 104(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[14] * B[13] - movq 104(%rcx), %rax - mulq 112(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[15] * B[12] - movq 96(%rcx), %rax - mulq 120(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[16] * B[11] - movq 88(%rcx), %rax - mulq 128(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[17] * B[10] - movq 80(%rcx), %rax - mulq 136(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[18] * B[9] - movq 72(%rcx), %rax - mulq 144(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[19] * B[8] - movq 64(%rcx), %rax - mulq 152(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[20] * B[7] - movq 56(%rcx), %rax - mulq 160(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[21] * B[6] - movq 48(%rcx), %rax - mulq 168(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[22] * B[5] - movq 40(%rcx), %rax - mulq 176(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[23] * B[4] - movq 32(%rcx), %rax - mulq 184(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - movq %r8, 216(%rdi) - # A[5] * B[23] - movq 184(%rcx), %rax - mulq 40(%rsi) - xorq %r8, %r8 - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[6] * B[22] - movq 176(%rcx), %rax - mulq 48(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[7] * B[21] - movq 168(%rcx), %rax - mulq 56(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[8] * B[20] - movq 160(%rcx), %rax - mulq 64(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[9] * B[19] - movq 152(%rcx), %rax - mulq 72(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[10] * B[18] - movq 144(%rcx), %rax - mulq 80(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[11] * B[17] - movq 136(%rcx), %rax - mulq 88(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[12] * B[16] - movq 128(%rcx), %rax - mulq 96(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[13] * B[15] - movq 120(%rcx), %rax - mulq 104(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[14] * B[14] - movq 112(%rcx), %rax - mulq 112(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[15] * B[13] - movq 104(%rcx), %rax - mulq 120(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[16] * B[12] - movq 96(%rcx), %rax - mulq 128(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[17] * B[11] - movq 88(%rcx), %rax - mulq 136(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[18] * B[10] - movq 80(%rcx), %rax - mulq 144(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[19] * B[9] - movq 72(%rcx), %rax - mulq 152(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[20] * B[8] - movq 64(%rcx), %rax - mulq 160(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[21] * B[7] - movq 56(%rcx), %rax - mulq 168(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[22] * B[6] - movq 48(%rcx), %rax - mulq 176(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[23] * B[5] - movq 40(%rcx), %rax - mulq 184(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - movq %r9, 224(%rdi) - # A[6] * B[23] - movq 184(%rcx), %rax - mulq 48(%rsi) - xorq %r9, %r9 - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[7] * B[22] - movq 176(%rcx), %rax - mulq 56(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[8] * B[21] - movq 168(%rcx), %rax - mulq 64(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[9] * B[20] - movq 160(%rcx), %rax - mulq 72(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[10] * B[19] - movq 152(%rcx), %rax - mulq 80(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[11] * B[18] - movq 144(%rcx), %rax - mulq 88(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[12] * B[17] - movq 136(%rcx), %rax - mulq 96(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[13] * B[16] - movq 128(%rcx), %rax - mulq 104(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[14] * B[15] - movq 120(%rcx), %rax - mulq 112(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[15] * B[14] - movq 112(%rcx), %rax - mulq 120(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[16] * B[13] - movq 104(%rcx), %rax - mulq 128(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[17] * B[12] - movq 96(%rcx), %rax - mulq 136(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[18] * B[11] - movq 88(%rcx), %rax - mulq 144(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[19] * B[10] - movq 80(%rcx), %rax - mulq 152(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[20] * B[9] - movq 72(%rcx), %rax - mulq 160(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[21] * B[8] - movq 64(%rcx), %rax - mulq 168(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[22] * B[7] - movq 56(%rcx), %rax - mulq 176(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[23] * B[6] - movq 48(%rcx), %rax - mulq 184(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - movq %r10, 232(%rdi) - # A[7] * B[23] - movq 184(%rcx), %rax - mulq 56(%rsi) - xorq %r10, %r10 - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[8] * B[22] - movq 176(%rcx), %rax - mulq 64(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[9] * B[21] - movq 168(%rcx), %rax - mulq 72(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[10] * B[20] - movq 160(%rcx), %rax - mulq 80(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[11] * B[19] - movq 152(%rcx), %rax - mulq 88(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[12] * B[18] - movq 144(%rcx), %rax - mulq 96(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[13] * B[17] - movq 136(%rcx), %rax - mulq 104(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[14] * B[16] - movq 128(%rcx), %rax - mulq 112(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[15] * B[15] - movq 120(%rcx), %rax - mulq 120(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[16] * B[14] - movq 112(%rcx), %rax - mulq 128(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[17] * B[13] - movq 104(%rcx), %rax - mulq 136(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[18] * B[12] - movq 96(%rcx), %rax - mulq 144(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[19] * B[11] - movq 88(%rcx), %rax - mulq 152(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[20] * B[10] - movq 80(%rcx), %rax - mulq 160(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[21] * B[9] - movq 72(%rcx), %rax - mulq 168(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[22] * B[8] - movq 64(%rcx), %rax - mulq 176(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[23] * B[7] - movq 56(%rcx), %rax - mulq 184(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - movq %r8, 240(%rdi) - # A[8] * B[23] - movq 184(%rcx), %rax - mulq 64(%rsi) - xorq %r8, %r8 - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[9] * B[22] - movq 176(%rcx), %rax - mulq 72(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[10] * B[21] - movq 168(%rcx), %rax - mulq 80(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[11] * B[20] - movq 160(%rcx), %rax - mulq 88(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[12] * B[19] - movq 152(%rcx), %rax - mulq 96(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[13] * B[18] - movq 144(%rcx), %rax - mulq 104(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[14] * B[17] - movq 136(%rcx), %rax - mulq 112(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[15] * B[16] - movq 128(%rcx), %rax - mulq 120(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[16] * B[15] - movq 120(%rcx), %rax - mulq 128(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[17] * B[14] - movq 112(%rcx), %rax - mulq 136(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[18] * B[13] - movq 104(%rcx), %rax - mulq 144(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[19] * B[12] - movq 96(%rcx), %rax - mulq 152(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[20] * B[11] - movq 88(%rcx), %rax - mulq 160(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[21] * B[10] - movq 80(%rcx), %rax - mulq 168(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[22] * B[9] - movq 72(%rcx), %rax - mulq 176(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[23] * B[8] - movq 64(%rcx), %rax - mulq 184(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - movq %r9, 248(%rdi) - # A[9] * B[23] - movq 184(%rcx), %rax - mulq 72(%rsi) - xorq %r9, %r9 - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[10] * B[22] - movq 176(%rcx), %rax - mulq 80(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[11] * B[21] - movq 168(%rcx), %rax - mulq 88(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[12] * B[20] - movq 160(%rcx), %rax - mulq 96(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[13] * B[19] - movq 152(%rcx), %rax - mulq 104(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[14] * B[18] - movq 144(%rcx), %rax - mulq 112(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[15] * B[17] - movq 136(%rcx), %rax - mulq 120(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[16] * B[16] - movq 128(%rcx), %rax - mulq 128(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[17] * B[15] - movq 120(%rcx), %rax - mulq 136(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[18] * B[14] - movq 112(%rcx), %rax - mulq 144(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[19] * B[13] - movq 104(%rcx), %rax - mulq 152(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[20] * B[12] - movq 96(%rcx), %rax - mulq 160(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[21] * B[11] - movq 88(%rcx), %rax - mulq 168(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[22] * B[10] - movq 80(%rcx), %rax - mulq 176(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[23] * B[9] - movq 72(%rcx), %rax - mulq 184(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - movq %r10, 256(%rdi) - # A[10] * B[23] - movq 184(%rcx), %rax - mulq 80(%rsi) - xorq %r10, %r10 - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[11] * B[22] - movq 176(%rcx), %rax - mulq 88(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[12] * B[21] - movq 168(%rcx), %rax - mulq 96(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[13] * B[20] - movq 160(%rcx), %rax - mulq 104(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[14] * B[19] - movq 152(%rcx), %rax - mulq 112(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[15] * B[18] - movq 144(%rcx), %rax - mulq 120(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[16] * B[17] - movq 136(%rcx), %rax - mulq 128(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[17] * B[16] - movq 128(%rcx), %rax - mulq 136(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[18] * B[15] - movq 120(%rcx), %rax - mulq 144(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[19] * B[14] - movq 112(%rcx), %rax - mulq 152(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[20] * B[13] - movq 104(%rcx), %rax - mulq 160(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[21] * B[12] - movq 96(%rcx), %rax - mulq 168(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[22] * B[11] - movq 88(%rcx), %rax - mulq 176(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[23] * B[10] - movq 80(%rcx), %rax - mulq 184(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - movq %r8, 264(%rdi) - # A[11] * B[23] - movq 184(%rcx), %rax - mulq 88(%rsi) - xorq %r8, %r8 - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[12] * B[22] - movq 176(%rcx), %rax - mulq 96(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[13] * B[21] - movq 168(%rcx), %rax - mulq 104(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[14] * B[20] - movq 160(%rcx), %rax - mulq 112(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[15] * B[19] - movq 152(%rcx), %rax - mulq 120(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[16] * B[18] - movq 144(%rcx), %rax - mulq 128(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[17] * B[17] - movq 136(%rcx), %rax - mulq 136(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[18] * B[16] - movq 128(%rcx), %rax - mulq 144(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[19] * B[15] - movq 120(%rcx), %rax - mulq 152(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[20] * B[14] - movq 112(%rcx), %rax - mulq 160(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[21] * B[13] - movq 104(%rcx), %rax - mulq 168(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[22] * B[12] - movq 96(%rcx), %rax - mulq 176(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[23] * B[11] - movq 88(%rcx), %rax - mulq 184(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - movq %r9, 272(%rdi) - # A[12] * B[23] - movq 184(%rcx), %rax - mulq 96(%rsi) - xorq %r9, %r9 - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[13] * B[22] - movq 176(%rcx), %rax - mulq 104(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[14] * B[21] - movq 168(%rcx), %rax - mulq 112(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[15] * B[20] - movq 160(%rcx), %rax - mulq 120(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[16] * B[19] - movq 152(%rcx), %rax - mulq 128(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[17] * B[18] - movq 144(%rcx), %rax - mulq 136(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[18] * B[17] - movq 136(%rcx), %rax - mulq 144(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[19] * B[16] - movq 128(%rcx), %rax - mulq 152(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[20] * B[15] - movq 120(%rcx), %rax - mulq 160(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[21] * B[14] - movq 112(%rcx), %rax - mulq 168(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[22] * B[13] - movq 104(%rcx), %rax - mulq 176(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[23] * B[12] - movq 96(%rcx), %rax - mulq 184(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - movq %r10, 280(%rdi) - # A[13] * B[23] - movq 184(%rcx), %rax - mulq 104(%rsi) - xorq %r10, %r10 - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[14] * B[22] - movq 176(%rcx), %rax - mulq 112(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[15] * B[21] - movq 168(%rcx), %rax - mulq 120(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[16] * B[20] - movq 160(%rcx), %rax - mulq 128(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[17] * B[19] - movq 152(%rcx), %rax - mulq 136(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[18] * B[18] - movq 144(%rcx), %rax - mulq 144(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[19] * B[17] - movq 136(%rcx), %rax - mulq 152(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[20] * B[16] - movq 128(%rcx), %rax - mulq 160(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[21] * B[15] - movq 120(%rcx), %rax - mulq 168(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[22] * B[14] - movq 112(%rcx), %rax - mulq 176(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[23] * B[13] - movq 104(%rcx), %rax - mulq 184(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - movq %r8, 288(%rdi) - # A[14] * B[23] - movq 184(%rcx), %rax - mulq 112(%rsi) - xorq %r8, %r8 - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[15] * B[22] - movq 176(%rcx), %rax - mulq 120(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[16] * B[21] - movq 168(%rcx), %rax - mulq 128(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[17] * B[20] - movq 160(%rcx), %rax - mulq 136(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[18] * B[19] - movq 152(%rcx), %rax - mulq 144(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[19] * B[18] - movq 144(%rcx), %rax - mulq 152(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[20] * B[17] - movq 136(%rcx), %rax - mulq 160(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[21] * B[16] - movq 128(%rcx), %rax - mulq 168(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[22] * B[15] - movq 120(%rcx), %rax - mulq 176(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[23] * B[14] - movq 112(%rcx), %rax - mulq 184(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - movq %r9, 296(%rdi) - # A[15] * B[23] - movq 184(%rcx), %rax - mulq 120(%rsi) - xorq %r9, %r9 - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[16] * B[22] - movq 176(%rcx), %rax - mulq 128(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[17] * B[21] - movq 168(%rcx), %rax - mulq 136(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[18] * B[20] - movq 160(%rcx), %rax - mulq 144(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[19] * B[19] - movq 152(%rcx), %rax - mulq 152(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[20] * B[18] - movq 144(%rcx), %rax - mulq 160(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[21] * B[17] - movq 136(%rcx), %rax - mulq 168(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[22] * B[16] - movq 128(%rcx), %rax - mulq 176(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[23] * B[15] - movq 120(%rcx), %rax - mulq 184(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - movq %r10, 304(%rdi) - # A[16] * B[23] - movq 184(%rcx), %rax - mulq 128(%rsi) - xorq %r10, %r10 - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[17] * B[22] - movq 176(%rcx), %rax - mulq 136(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[18] * B[21] - movq 168(%rcx), %rax - mulq 144(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[19] * B[20] - movq 160(%rcx), %rax - mulq 152(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[20] * B[19] - movq 152(%rcx), %rax - mulq 160(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[21] * B[18] - movq 144(%rcx), %rax - mulq 168(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[22] * B[17] - movq 136(%rcx), %rax - mulq 176(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[23] * B[16] - movq 128(%rcx), %rax - mulq 184(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - movq %r8, 312(%rdi) - # A[17] * B[23] - movq 184(%rcx), %rax - mulq 136(%rsi) - xorq %r8, %r8 - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[18] * B[22] - movq 176(%rcx), %rax - mulq 144(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[19] * B[21] - movq 168(%rcx), %rax - mulq 152(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[20] * B[20] - movq 160(%rcx), %rax - mulq 160(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[21] * B[19] - movq 152(%rcx), %rax - mulq 168(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[22] * B[18] - movq 144(%rcx), %rax - mulq 176(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[23] * B[17] - movq 136(%rcx), %rax - mulq 184(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - movq %r9, 320(%rdi) - # A[18] * B[23] - movq 184(%rcx), %rax - mulq 144(%rsi) - xorq %r9, %r9 - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[19] * B[22] - movq 176(%rcx), %rax - mulq 152(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[20] * B[21] - movq 168(%rcx), %rax - mulq 160(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[21] * B[20] - movq 160(%rcx), %rax - mulq 168(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[22] * B[19] - movq 152(%rcx), %rax - mulq 176(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[23] * B[18] - movq 144(%rcx), %rax - mulq 184(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - movq %r10, 328(%rdi) - # A[19] * B[23] - movq 184(%rcx), %rax - mulq 152(%rsi) - xorq %r10, %r10 - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[20] * B[22] - movq 176(%rcx), %rax - mulq 160(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[21] * B[21] - movq 168(%rcx), %rax - mulq 168(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[22] * B[20] - movq 160(%rcx), %rax - mulq 176(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[23] * B[19] - movq 152(%rcx), %rax - mulq 184(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - movq %r8, 336(%rdi) - # A[20] * B[23] - movq 184(%rcx), %rax - mulq 160(%rsi) - xorq %r8, %r8 - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[21] * B[22] - movq 176(%rcx), %rax - mulq 168(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[22] * B[21] - movq 168(%rcx), %rax - mulq 176(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - # A[23] * B[20] - movq 160(%rcx), %rax - mulq 184(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - adcq $0, %r8 - movq %r9, 344(%rdi) - # A[21] * B[23] - movq 184(%rcx), %rax - mulq 168(%rsi) - xorq %r9, %r9 - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[22] * B[22] - movq 176(%rcx), %rax - mulq 176(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - # A[23] * B[21] - movq 168(%rcx), %rax - mulq 184(%rsi) - addq %rax, %r10 - adcq %rdx, %r8 - adcq $0, %r9 - movq %r10, 352(%rdi) - # A[22] * B[23] - movq 184(%rcx), %rax - mulq 176(%rsi) - xorq %r10, %r10 - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - # A[23] * B[22] - movq 176(%rcx), %rax - mulq 184(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %r10 - movq %r8, 360(%rdi) - # A[23] * B[23] - movq 184(%rcx), %rax - mulq 184(%rsi) - addq %rax, %r9 - adcq %rdx, %r10 - movq %r9, 368(%rdi) - movq %r10, 376(%rdi) + movq %r9, 176(%rdi) + movq %r10, 184(%rdi) movq (%rsp), %rax movq 8(%rsp), %rdx movq 16(%rsp), %r8 @@ -12925,34 +13192,10 @@ _sp_3072_mul_24: 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) - movq 128(%rsp), %rax - movq 136(%rsp), %rdx - movq 144(%rsp), %r8 - movq 152(%rsp), %r9 - movq %rax, 128(%rdi) - movq %rdx, 136(%rdi) - movq %r8, 144(%rdi) - movq %r9, 152(%rdi) - movq 160(%rsp), %rax - movq 168(%rsp), %rdx - movq 176(%rsp), %r8 - movq 184(%rsp), %r9 - movq %rax, 160(%rdi) - movq %rdx, 168(%rdi) - movq %r8, 176(%rdi) - movq %r9, 184(%rdi) - addq $192, %rsp + addq $96, %rsp repz retq #ifndef __APPLE__ -.size sp_3072_mul_24,.-sp_3072_mul_24 +.size sp_3072_mul_12,.-sp_3072_mul_12 #endif /* __APPLE__ */ /* Square a and put result in r. (r = a * a) * @@ -12960,17 +13203,17 @@ _sp_3072_mul_24: * a A single precision integer. */ #ifndef __APPLE__ -.globl sp_3072_sqr_24 -.type sp_3072_sqr_24,@function +.globl sp_3072_sqr_12 +.type sp_3072_sqr_12,@function .align 16 -sp_3072_sqr_24: +sp_3072_sqr_12: #else -.globl _sp_3072_sqr_24 +.globl _sp_3072_sqr_12 .p2align 4 -_sp_3072_sqr_24: +_sp_3072_sqr_12: #endif /* __APPLE__ */ push %r12 - subq $192, %rsp + subq $96, %rsp # A[0] * A[0] movq (%rsi), %rax mulq %rax @@ -13305,19 +13548,13 @@ _sp_3072_sqr_24: adcq %r11, %rcx adcq %r12, %r8 movq %r9, 88(%rsp) - # A[0] * A[12] - movq 96(%rsi), %rax - mulq (%rsi) + # A[1] * A[11] + movq 88(%rsi), %rax + mulq 8(%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 $0, %r12 # A[2] * A[10] movq 80(%rsi), %rax mulq 16(%rsi) @@ -13354,26 +13591,14 @@ _sp_3072_sqr_24: addq %r10, %rcx adcq %r11, %r8 adcq %r12, %r9 - movq %rcx, 96(%rsp) - # A[0] * A[13] - movq 104(%rsi), %rax - mulq (%rsi) + movq %rcx, 96(%rdi) + # A[2] * A[11] + movq 88(%rsi), %rax + mulq 16(%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 $0, %r12 - # A[2] * A[11] - movq 88(%rsi), %rax - mulq 16(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 # A[3] * A[10] movq 80(%rsi), %rax mulq 24(%rsi) @@ -13404,32 +13629,14 @@ _sp_3072_sqr_24: addq %r10, %r8 adcq %r11, %r9 adcq %r12, %rcx - movq %r8, 104(%rsp) - # A[0] * A[14] - movq 112(%rsi), %rax - mulq (%rsi) + movq %r8, 104(%rdi) + # A[3] * A[11] + movq 88(%rsi), %rax + mulq 24(%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 $0, %r12 - # A[2] * A[12] - movq 96(%rsi), %rax - mulq 16(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[3] * A[11] - movq 88(%rsi), %rax - mulq 24(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 # A[4] * A[10] movq 80(%rsi), %rax mulq 32(%rsi) @@ -13460,38 +13667,14 @@ _sp_3072_sqr_24: addq %r10, %r9 adcq %r11, %rcx adcq %r12, %r8 - movq %r9, 112(%rsp) - # A[0] * A[15] - movq 120(%rsi), %rax - mulq (%rsi) + movq %r9, 112(%rdi) + # A[4] * A[11] + movq 88(%rsi), %rax + mulq 32(%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 $0, %r12 - # A[2] * A[13] - movq 104(%rsi), %rax - mulq 16(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[3] * A[12] - movq 96(%rsi), %rax - mulq 24(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[4] * A[11] - movq 88(%rsi), %rax - mulq 32(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 # A[5] * A[10] movq 80(%rsi), %rax mulq 40(%rsi) @@ -13516,44 +13699,14 @@ _sp_3072_sqr_24: addq %r10, %rcx adcq %r11, %r8 adcq %r12, %r9 - movq %rcx, 120(%rsp) - # A[0] * A[16] - movq 128(%rsi), %rax - mulq (%rsi) + movq %rcx, 120(%rdi) + # A[5] * A[11] + movq 88(%rsi), %rax + mulq 40(%rsi) xorq %rcx, %rcx xorq %r12, %r12 movq %rax, %r10 movq %rdx, %r11 - # A[1] * A[15] - movq 120(%rsi), %rax - mulq 8(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[2] * A[14] - movq 112(%rsi), %rax - mulq 16(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[3] * A[13] - movq 104(%rsi), %rax - mulq 24(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[4] * A[12] - movq 96(%rsi), %rax - mulq 32(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[5] * A[11] - movq 88(%rsi), %rax - mulq 40(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 # A[6] * A[10] movq 80(%rsi), %rax mulq 48(%rsi) @@ -13578,50 +13731,14 @@ _sp_3072_sqr_24: addq %r10, %r8 adcq %r11, %r9 adcq %r12, %rcx - movq %r8, 128(%rsp) - # A[0] * A[17] - movq 136(%rsi), %rax - mulq (%rsi) + movq %r8, 128(%rdi) + # A[6] * A[11] + movq 88(%rsi), %rax + mulq 48(%rsi) xorq %r8, %r8 xorq %r12, %r12 movq %rax, %r10 movq %rdx, %r11 - # A[1] * A[16] - movq 128(%rsi), %rax - mulq 8(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[2] * A[15] - movq 120(%rsi), %rax - mulq 16(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[3] * A[14] - movq 112(%rsi), %rax - mulq 24(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[4] * A[13] - movq 104(%rsi), %rax - mulq 32(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[5] * A[12] - movq 96(%rsi), %rax - mulq 40(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[6] * A[11] - movq 88(%rsi), %rax - mulq 48(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 # A[7] * A[10] movq 80(%rsi), %rax mulq 56(%rsi) @@ -13640,1486 +13757,88 @@ _sp_3072_sqr_24: addq %r10, %r9 adcq %r11, %rcx adcq %r12, %r8 - movq %r9, 136(%rsp) - # A[0] * A[18] - movq 144(%rsi), %rax - mulq (%rsi) - xorq %r9, %r9 - xorq %r12, %r12 - movq %rax, %r10 - movq %rdx, %r11 - # A[1] * A[17] - movq 136(%rsi), %rax - mulq 8(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[2] * A[16] - movq 128(%rsi), %rax - mulq 16(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[3] * A[15] - movq 120(%rsi), %rax - mulq 24(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[4] * A[14] - movq 112(%rsi), %rax - mulq 32(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[5] * A[13] - movq 104(%rsi), %rax - mulq 40(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[6] * A[12] - movq 96(%rsi), %rax - mulq 48(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 + movq %r9, 136(%rdi) # A[7] * A[11] movq 88(%rsi), %rax mulq 56(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 + xorq %r9, %r9 + addq %rax, %rcx + adcq %rdx, %r8 + adcq $0, %r9 + addq %rax, %rcx + adcq %rdx, %r8 + adcq $0, %r9 # A[8] * A[10] movq 80(%rsi), %rax mulq 64(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 + addq %rax, %rcx + adcq %rdx, %r8 + adcq $0, %r9 + addq %rax, %rcx + adcq %rdx, %r8 + adcq $0, %r9 # 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 $0, %r12 - addq %r10, %rcx - adcq %r11, %r8 - adcq %r12, %r9 - movq %rcx, 144(%rsp) - # A[0] * A[19] - movq 152(%rsi), %rax - mulq (%rsi) - xorq %rcx, %rcx - xorq %r12, %r12 - movq %rax, %r10 - movq %rdx, %r11 - # A[1] * A[18] - movq 144(%rsi), %rax - mulq 8(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[2] * A[17] - movq 136(%rsi), %rax - mulq 16(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[3] * A[16] - movq 128(%rsi), %rax - mulq 24(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[4] * A[15] - movq 120(%rsi), %rax - mulq 32(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[5] * A[14] - movq 112(%rsi), %rax - mulq 40(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[6] * A[13] - movq 104(%rsi), %rax - mulq 48(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[7] * A[12] - movq 96(%rsi), %rax - mulq 56(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 + addq %rax, %rcx + adcq %rdx, %r8 + adcq $0, %r9 + movq %rcx, 144(%rdi) # A[8] * A[11] movq 88(%rsi), %rax mulq 64(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 + xorq %rcx, %rcx + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0, %rcx + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0, %rcx # A[9] * A[10] movq 80(%rsi), %rax mulq 72(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - addq %r10, %r10 - adcq %r11, %r11 - adcq %r12, %r12 - addq %r10, %r8 - adcq %r11, %r9 - adcq %r12, %rcx - movq %r8, 152(%rsp) - # A[0] * A[20] - movq 160(%rsi), %rax - mulq (%rsi) - xorq %r8, %r8 - xorq %r12, %r12 - movq %rax, %r10 - movq %rdx, %r11 - # A[1] * A[19] - movq 152(%rsi), %rax - mulq 8(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[2] * A[18] - movq 144(%rsi), %rax - mulq 16(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[3] * A[17] - movq 136(%rsi), %rax - mulq 24(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[4] * A[16] - movq 128(%rsi), %rax - mulq 32(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[5] * A[15] - movq 120(%rsi), %rax - mulq 40(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[6] * A[14] - movq 112(%rsi), %rax - mulq 48(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[7] * A[13] - movq 104(%rsi), %rax - mulq 56(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[8] * A[12] - movq 96(%rsi), %rax - mulq 64(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0, %rcx + addq %rax, %r8 + adcq %rdx, %r9 + adcq $0, %rcx + movq %r8, 152(%rdi) # A[9] * A[11] movq 88(%rsi), %rax mulq 72(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 + xorq %r8, %r8 + addq %rax, %r9 + adcq %rdx, %rcx + adcq $0, %r8 + addq %rax, %r9 + adcq %rdx, %rcx + adcq $0, %r8 # 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 $0, %r12 - addq %r10, %r9 - adcq %r11, %rcx - adcq %r12, %r8 - movq %r9, 160(%rsp) - # A[0] * A[21] - movq 168(%rsi), %rax - mulq (%rsi) - xorq %r9, %r9 - xorq %r12, %r12 - movq %rax, %r10 - movq %rdx, %r11 - # A[1] * A[20] - movq 160(%rsi), %rax - mulq 8(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[2] * A[19] - movq 152(%rsi), %rax - mulq 16(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[3] * A[18] - movq 144(%rsi), %rax - mulq 24(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[4] * A[17] - movq 136(%rsi), %rax - mulq 32(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[5] * A[16] - movq 128(%rsi), %rax - mulq 40(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[6] * A[15] - movq 120(%rsi), %rax - mulq 48(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[7] * A[14] - movq 112(%rsi), %rax - mulq 56(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[8] * A[13] - movq 104(%rsi), %rax - mulq 64(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[9] * A[12] - movq 96(%rsi), %rax - mulq 72(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 + addq %rax, %r9 + adcq %rdx, %rcx + adcq $0, %r8 + movq %r9, 160(%rdi) # A[10] * A[11] movq 88(%rsi), %rax mulq 80(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - addq %r10, %r10 - adcq %r11, %r11 - adcq %r12, %r12 - addq %r10, %rcx - adcq %r11, %r8 - adcq %r12, %r9 - movq %rcx, 168(%rsp) - # A[0] * A[22] - movq 176(%rsi), %rax - mulq (%rsi) - xorq %rcx, %rcx - xorq %r12, %r12 - movq %rax, %r10 - movq %rdx, %r11 - # A[1] * A[21] - movq 168(%rsi), %rax - mulq 8(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[2] * A[20] - movq 160(%rsi), %rax - mulq 16(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[3] * A[19] - movq 152(%rsi), %rax - mulq 24(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[4] * A[18] - movq 144(%rsi), %rax - mulq 32(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[5] * A[17] - movq 136(%rsi), %rax - mulq 40(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[6] * A[16] - movq 128(%rsi), %rax - mulq 48(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[7] * A[15] - movq 120(%rsi), %rax - mulq 56(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[8] * A[14] - movq 112(%rsi), %rax - mulq 64(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[9] * A[13] - movq 104(%rsi), %rax - mulq 72(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[10] * A[12] - movq 96(%rsi), %rax - mulq 80(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 + xorq %r9, %r9 + addq %rax, %rcx + adcq %rdx, %r8 + adcq $0, %r9 + addq %rax, %rcx + adcq %rdx, %r8 + adcq $0, %r9 + movq %rcx, 168(%rdi) # 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 $0, %r12 - addq %r10, %r8 - adcq %r11, %r9 - adcq %r12, %rcx - movq %r8, 176(%rsp) - # A[0] * A[23] - movq 184(%rsi), %rax - mulq (%rsi) - xorq %r8, %r8 - xorq %r12, %r12 - movq %rax, %r10 - movq %rdx, %r11 - # A[1] * A[22] - movq 176(%rsi), %rax - mulq 8(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[2] * A[21] - movq 168(%rsi), %rax - mulq 16(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[3] * A[20] - movq 160(%rsi), %rax - mulq 24(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[4] * A[19] - movq 152(%rsi), %rax - mulq 32(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[5] * A[18] - movq 144(%rsi), %rax - mulq 40(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[6] * A[17] - movq 136(%rsi), %rax - mulq 48(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[7] * A[16] - movq 128(%rsi), %rax - mulq 56(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[8] * A[15] - movq 120(%rsi), %rax - mulq 64(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[9] * A[14] - movq 112(%rsi), %rax - mulq 72(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[10] * A[13] - movq 104(%rsi), %rax - mulq 80(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[11] * A[12] - movq 96(%rsi), %rax - mulq 88(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - addq %r10, %r10 - adcq %r11, %r11 - adcq %r12, %r12 - addq %r10, %r9 - adcq %r11, %rcx - adcq %r12, %r8 - movq %r9, 184(%rsp) - # A[1] * A[23] - movq 184(%rsi), %rax - mulq 8(%rsi) - xorq %r9, %r9 - xorq %r12, %r12 - movq %rax, %r10 - movq %rdx, %r11 - # A[2] * A[22] - movq 176(%rsi), %rax - mulq 16(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[3] * A[21] - movq 168(%rsi), %rax - mulq 24(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[4] * A[20] - movq 160(%rsi), %rax - mulq 32(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[5] * A[19] - movq 152(%rsi), %rax - mulq 40(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[6] * A[18] - movq 144(%rsi), %rax - mulq 48(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[7] * A[17] - movq 136(%rsi), %rax - mulq 56(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[8] * A[16] - movq 128(%rsi), %rax - mulq 64(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[9] * A[15] - movq 120(%rsi), %rax - mulq 72(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[10] * A[14] - movq 112(%rsi), %rax - mulq 80(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[11] * A[13] - movq 104(%rsi), %rax - mulq 88(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %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 $0, %r12 - addq %r10, %rcx - adcq %r11, %r8 - adcq %r12, %r9 - movq %rcx, 192(%rdi) - # A[2] * A[23] - movq 184(%rsi), %rax - mulq 16(%rsi) - xorq %rcx, %rcx - xorq %r12, %r12 - movq %rax, %r10 - movq %rdx, %r11 - # A[3] * A[22] - movq 176(%rsi), %rax - mulq 24(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[4] * A[21] - movq 168(%rsi), %rax - mulq 32(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[5] * A[20] - movq 160(%rsi), %rax - mulq 40(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[6] * A[19] - movq 152(%rsi), %rax - mulq 48(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[7] * A[18] - movq 144(%rsi), %rax - mulq 56(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[8] * A[17] - movq 136(%rsi), %rax - mulq 64(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[9] * A[16] - movq 128(%rsi), %rax - mulq 72(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[10] * A[15] - movq 120(%rsi), %rax - mulq 80(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[11] * A[14] - movq 112(%rsi), %rax - mulq 88(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[12] * A[13] - movq 104(%rsi), %rax - mulq 96(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - addq %r10, %r10 - adcq %r11, %r11 - adcq %r12, %r12 - addq %r10, %r8 - adcq %r11, %r9 - adcq %r12, %rcx - movq %r8, 200(%rdi) - # A[3] * A[23] - movq 184(%rsi), %rax - mulq 24(%rsi) - xorq %r8, %r8 - xorq %r12, %r12 - movq %rax, %r10 - movq %rdx, %r11 - # A[4] * A[22] - movq 176(%rsi), %rax - mulq 32(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[5] * A[21] - movq 168(%rsi), %rax - mulq 40(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[6] * A[20] - movq 160(%rsi), %rax - mulq 48(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[7] * A[19] - movq 152(%rsi), %rax - mulq 56(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[8] * A[18] - movq 144(%rsi), %rax - mulq 64(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[9] * A[17] - movq 136(%rsi), %rax - mulq 72(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[10] * A[16] - movq 128(%rsi), %rax - mulq 80(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[11] * A[15] - movq 120(%rsi), %rax - mulq 88(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[12] * A[14] - movq 112(%rsi), %rax - mulq 96(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[13] * A[13] - movq 104(%rsi), %rax - mulq %rax - addq %r10, %r10 - adcq %r11, %r11 - adcq %r12, %r12 - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - addq %r10, %r9 - adcq %r11, %rcx - adcq %r12, %r8 - movq %r9, 208(%rdi) - # A[4] * A[23] - movq 184(%rsi), %rax - mulq 32(%rsi) - xorq %r9, %r9 - xorq %r12, %r12 - movq %rax, %r10 - movq %rdx, %r11 - # A[5] * A[22] - movq 176(%rsi), %rax - mulq 40(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[6] * A[21] - movq 168(%rsi), %rax - mulq 48(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[7] * A[20] - movq 160(%rsi), %rax - mulq 56(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[8] * A[19] - movq 152(%rsi), %rax - mulq 64(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[9] * A[18] - movq 144(%rsi), %rax - mulq 72(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[10] * A[17] - movq 136(%rsi), %rax - mulq 80(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[11] * A[16] - movq 128(%rsi), %rax - mulq 88(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[12] * A[15] - movq 120(%rsi), %rax - mulq 96(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[13] * A[14] - movq 112(%rsi), %rax - mulq 104(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - addq %r10, %r10 - adcq %r11, %r11 - adcq %r12, %r12 - addq %r10, %rcx - adcq %r11, %r8 - adcq %r12, %r9 - movq %rcx, 216(%rdi) - # A[5] * A[23] - movq 184(%rsi), %rax - mulq 40(%rsi) - xorq %rcx, %rcx - xorq %r12, %r12 - movq %rax, %r10 - movq %rdx, %r11 - # A[6] * A[22] - movq 176(%rsi), %rax - mulq 48(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[7] * A[21] - movq 168(%rsi), %rax - mulq 56(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[8] * A[20] - movq 160(%rsi), %rax - mulq 64(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[9] * A[19] - movq 152(%rsi), %rax - mulq 72(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[10] * A[18] - movq 144(%rsi), %rax - mulq 80(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[11] * A[17] - movq 136(%rsi), %rax - mulq 88(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[12] * A[16] - movq 128(%rsi), %rax - mulq 96(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[13] * A[15] - movq 120(%rsi), %rax - mulq 104(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[14] * A[14] - movq 112(%rsi), %rax - mulq %rax - addq %r10, %r10 - adcq %r11, %r11 - adcq %r12, %r12 - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - addq %r10, %r8 - adcq %r11, %r9 - adcq %r12, %rcx - movq %r8, 224(%rdi) - # A[6] * A[23] - movq 184(%rsi), %rax - mulq 48(%rsi) - xorq %r8, %r8 - xorq %r12, %r12 - movq %rax, %r10 - movq %rdx, %r11 - # A[7] * A[22] - movq 176(%rsi), %rax - mulq 56(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[8] * A[21] - movq 168(%rsi), %rax - mulq 64(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[9] * A[20] - movq 160(%rsi), %rax - mulq 72(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[10] * A[19] - movq 152(%rsi), %rax - mulq 80(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[11] * A[18] - movq 144(%rsi), %rax - mulq 88(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[12] * A[17] - movq 136(%rsi), %rax - mulq 96(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[13] * A[16] - movq 128(%rsi), %rax - mulq 104(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[14] * A[15] - movq 120(%rsi), %rax - mulq 112(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - addq %r10, %r10 - adcq %r11, %r11 - adcq %r12, %r12 - addq %r10, %r9 - adcq %r11, %rcx - adcq %r12, %r8 - movq %r9, 232(%rdi) - # A[7] * A[23] - movq 184(%rsi), %rax - mulq 56(%rsi) - xorq %r9, %r9 - xorq %r12, %r12 - movq %rax, %r10 - movq %rdx, %r11 - # A[8] * A[22] - movq 176(%rsi), %rax - mulq 64(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[9] * A[21] - movq 168(%rsi), %rax - mulq 72(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[10] * A[20] - movq 160(%rsi), %rax - mulq 80(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[11] * A[19] - movq 152(%rsi), %rax - mulq 88(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[12] * A[18] - movq 144(%rsi), %rax - mulq 96(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[13] * A[17] - movq 136(%rsi), %rax - mulq 104(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[14] * A[16] - movq 128(%rsi), %rax - mulq 112(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[15] * A[15] - movq 120(%rsi), %rax - mulq %rax - addq %r10, %r10 - adcq %r11, %r11 - adcq %r12, %r12 - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - addq %r10, %rcx - adcq %r11, %r8 - adcq %r12, %r9 - movq %rcx, 240(%rdi) - # A[8] * A[23] - movq 184(%rsi), %rax - mulq 64(%rsi) - xorq %rcx, %rcx - xorq %r12, %r12 - movq %rax, %r10 - movq %rdx, %r11 - # A[9] * A[22] - movq 176(%rsi), %rax - mulq 72(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[10] * A[21] - movq 168(%rsi), %rax - mulq 80(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[11] * A[20] - movq 160(%rsi), %rax - mulq 88(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[12] * A[19] - movq 152(%rsi), %rax - mulq 96(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[13] * A[18] - movq 144(%rsi), %rax - mulq 104(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[14] * A[17] - movq 136(%rsi), %rax - mulq 112(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[15] * A[16] - movq 128(%rsi), %rax - mulq 120(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - addq %r10, %r10 - adcq %r11, %r11 - adcq %r12, %r12 - addq %r10, %r8 - adcq %r11, %r9 - adcq %r12, %rcx - movq %r8, 248(%rdi) - # A[9] * A[23] - movq 184(%rsi), %rax - mulq 72(%rsi) - xorq %r8, %r8 - xorq %r12, %r12 - movq %rax, %r10 - movq %rdx, %r11 - # A[10] * A[22] - movq 176(%rsi), %rax - mulq 80(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[11] * A[21] - movq 168(%rsi), %rax - mulq 88(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[12] * A[20] - movq 160(%rsi), %rax - mulq 96(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[13] * A[19] - movq 152(%rsi), %rax - mulq 104(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[14] * A[18] - movq 144(%rsi), %rax - mulq 112(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[15] * A[17] - movq 136(%rsi), %rax - mulq 120(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[16] * A[16] - movq 128(%rsi), %rax - mulq %rax - addq %r10, %r10 - adcq %r11, %r11 - adcq %r12, %r12 - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - addq %r10, %r9 - adcq %r11, %rcx - adcq %r12, %r8 - movq %r9, 256(%rdi) - # A[10] * A[23] - movq 184(%rsi), %rax - mulq 80(%rsi) - xorq %r9, %r9 - xorq %r12, %r12 - movq %rax, %r10 - movq %rdx, %r11 - # A[11] * A[22] - movq 176(%rsi), %rax - mulq 88(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[12] * A[21] - movq 168(%rsi), %rax - mulq 96(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[13] * A[20] - movq 160(%rsi), %rax - mulq 104(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[14] * A[19] - movq 152(%rsi), %rax - mulq 112(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[15] * A[18] - movq 144(%rsi), %rax - mulq 120(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[16] * A[17] - movq 136(%rsi), %rax - mulq 128(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - addq %r10, %r10 - adcq %r11, %r11 - adcq %r12, %r12 - addq %r10, %rcx - adcq %r11, %r8 - adcq %r12, %r9 - movq %rcx, 264(%rdi) - # A[11] * A[23] - movq 184(%rsi), %rax - mulq 88(%rsi) - xorq %rcx, %rcx - xorq %r12, %r12 - movq %rax, %r10 - movq %rdx, %r11 - # A[12] * A[22] - movq 176(%rsi), %rax - mulq 96(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[13] * A[21] - movq 168(%rsi), %rax - mulq 104(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[14] * A[20] - movq 160(%rsi), %rax - mulq 112(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[15] * A[19] - movq 152(%rsi), %rax - mulq 120(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[16] * A[18] - movq 144(%rsi), %rax - mulq 128(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[17] * A[17] - movq 136(%rsi), %rax - mulq %rax - addq %r10, %r10 - adcq %r11, %r11 - adcq %r12, %r12 - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - addq %r10, %r8 - adcq %r11, %r9 - adcq %r12, %rcx - movq %r8, 272(%rdi) - # A[12] * A[23] - movq 184(%rsi), %rax - mulq 96(%rsi) - xorq %r8, %r8 - xorq %r12, %r12 - movq %rax, %r10 - movq %rdx, %r11 - # A[13] * A[22] - movq 176(%rsi), %rax - mulq 104(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[14] * A[21] - movq 168(%rsi), %rax - mulq 112(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[15] * A[20] - movq 160(%rsi), %rax - mulq 120(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[16] * A[19] - movq 152(%rsi), %rax - mulq 128(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[17] * A[18] - movq 144(%rsi), %rax - mulq 136(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - addq %r10, %r10 - adcq %r11, %r11 - adcq %r12, %r12 - addq %r10, %r9 - adcq %r11, %rcx - adcq %r12, %r8 - movq %r9, 280(%rdi) - # A[13] * A[23] - movq 184(%rsi), %rax - mulq 104(%rsi) - xorq %r9, %r9 - xorq %r12, %r12 - movq %rax, %r10 - movq %rdx, %r11 - # A[14] * A[22] - movq 176(%rsi), %rax - mulq 112(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[15] * A[21] - movq 168(%rsi), %rax - mulq 120(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[16] * A[20] - movq 160(%rsi), %rax - mulq 128(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[17] * A[19] - movq 152(%rsi), %rax - mulq 136(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[18] * A[18] - movq 144(%rsi), %rax - mulq %rax - addq %r10, %r10 - adcq %r11, %r11 - adcq %r12, %r12 - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - addq %r10, %rcx - adcq %r11, %r8 - adcq %r12, %r9 - movq %rcx, 288(%rdi) - # A[14] * A[23] - movq 184(%rsi), %rax - mulq 112(%rsi) - xorq %rcx, %rcx - xorq %r12, %r12 - movq %rax, %r10 - movq %rdx, %r11 - # A[15] * A[22] - movq 176(%rsi), %rax - mulq 120(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[16] * A[21] - movq 168(%rsi), %rax - mulq 128(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[17] * A[20] - movq 160(%rsi), %rax - mulq 136(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[18] * A[19] - movq 152(%rsi), %rax - mulq 144(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - addq %r10, %r10 - adcq %r11, %r11 - adcq %r12, %r12 - addq %r10, %r8 - adcq %r11, %r9 - adcq %r12, %rcx - movq %r8, 296(%rdi) - # A[15] * A[23] - movq 184(%rsi), %rax - mulq 120(%rsi) - xorq %r8, %r8 - xorq %r12, %r12 - movq %rax, %r10 - movq %rdx, %r11 - # A[16] * A[22] - movq 176(%rsi), %rax - mulq 128(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[17] * A[21] - movq 168(%rsi), %rax - mulq 136(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[18] * A[20] - movq 160(%rsi), %rax - mulq 144(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[19] * A[19] - movq 152(%rsi), %rax - mulq %rax - addq %r10, %r10 - adcq %r11, %r11 - adcq %r12, %r12 - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - addq %r10, %r9 - adcq %r11, %rcx - adcq %r12, %r8 - movq %r9, 304(%rdi) - # A[16] * A[23] - movq 184(%rsi), %rax - mulq 128(%rsi) - xorq %r9, %r9 - xorq %r12, %r12 - movq %rax, %r10 - movq %rdx, %r11 - # A[17] * A[22] - movq 176(%rsi), %rax - mulq 136(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[18] * A[21] - movq 168(%rsi), %rax - mulq 144(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[19] * A[20] - movq 160(%rsi), %rax - mulq 152(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - addq %r10, %r10 - adcq %r11, %r11 - adcq %r12, %r12 - addq %r10, %rcx - adcq %r11, %r8 - adcq %r12, %r9 - movq %rcx, 312(%rdi) - # A[17] * A[23] - movq 184(%rsi), %rax - mulq 136(%rsi) - xorq %rcx, %rcx - xorq %r12, %r12 - movq %rax, %r10 - movq %rdx, %r11 - # A[18] * A[22] - movq 176(%rsi), %rax - mulq 144(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[19] * A[21] - movq 168(%rsi), %rax - mulq 152(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[20] * A[20] - movq 160(%rsi), %rax - mulq %rax - addq %r10, %r10 - adcq %r11, %r11 - adcq %r12, %r12 - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - addq %r10, %r8 - adcq %r11, %r9 - adcq %r12, %rcx - movq %r8, 320(%rdi) - # A[18] * A[23] - movq 184(%rsi), %rax - mulq 144(%rsi) - xorq %r8, %r8 - xorq %r12, %r12 - movq %rax, %r10 - movq %rdx, %r11 - # A[19] * A[22] - movq 176(%rsi), %rax - mulq 152(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - # A[20] * A[21] - movq 168(%rsi), %rax - mulq 160(%rsi) - addq %rax, %r10 - adcq %rdx, %r11 - adcq $0, %r12 - addq %r10, %r10 - adcq %r11, %r11 - adcq %r12, %r12 - addq %r10, %r9 - adcq %r11, %rcx - adcq %r12, %r8 - movq %r9, 328(%rdi) - # A[19] * A[23] - movq 184(%rsi), %rax - mulq 152(%rsi) - xorq %r9, %r9 - addq %rax, %rcx - adcq %rdx, %r8 - adcq $0, %r9 - addq %rax, %rcx - adcq %rdx, %r8 - adcq $0, %r9 - # A[20] * A[22] - movq 176(%rsi), %rax - mulq 160(%rsi) - addq %rax, %rcx - adcq %rdx, %r8 - adcq $0, %r9 - addq %rax, %rcx - adcq %rdx, %r8 - adcq $0, %r9 - # A[21] * A[21] - movq 168(%rsi), %rax - mulq %rax - addq %rax, %rcx - adcq %rdx, %r8 - adcq $0, %r9 - movq %rcx, 336(%rdi) - # A[20] * A[23] - movq 184(%rsi), %rax - mulq 160(%rsi) - xorq %rcx, %rcx addq %rax, %r8 adcq %rdx, %r9 - adcq $0, %rcx - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %rcx - # A[21] * A[22] - movq 176(%rsi), %rax - mulq 168(%rsi) - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %rcx - addq %rax, %r8 - adcq %rdx, %r9 - adcq $0, %rcx - movq %r8, 344(%rdi) - # A[21] * A[23] - movq 184(%rsi), %rax - mulq 168(%rsi) - xorq %r8, %r8 - addq %rax, %r9 - adcq %rdx, %rcx - adcq $0, %r8 - addq %rax, %r9 - adcq %rdx, %rcx - adcq $0, %r8 - # A[22] * A[22] - movq 176(%rsi), %rax - mulq %rax - addq %rax, %r9 - adcq %rdx, %rcx - adcq $0, %r8 - movq %r9, 352(%rdi) - # A[22] * A[23] - movq 184(%rsi), %rax - mulq 176(%rsi) - xorq %r9, %r9 - addq %rax, %rcx - adcq %rdx, %r8 - adcq $0, %r9 - addq %rax, %rcx - adcq %rdx, %r8 - adcq $0, %r9 - movq %rcx, 360(%rdi) - # A[23] * A[23] - movq 184(%rsi), %rax - mulq %rax - addq %rax, %r8 - adcq %rdx, %r9 - movq %r8, 368(%rdi) - movq %r9, 376(%rdi) + movq %r8, 176(%rdi) + movq %r9, 184(%rdi) movq (%rsp), %rax movq 8(%rsp), %rdx movq 16(%rsp), %r10 @@ -15144,35 +13863,11 @@ _sp_3072_sqr_24: 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) - movq 128(%rsp), %rax - movq 136(%rsp), %rdx - movq 144(%rsp), %r10 - movq 152(%rsp), %r11 - movq %rax, 128(%rdi) - movq %rdx, 136(%rdi) - movq %r10, 144(%rdi) - movq %r11, 152(%rdi) - movq 160(%rsp), %rax - movq 168(%rsp), %rdx - movq 176(%rsp), %r10 - movq 184(%rsp), %r11 - movq %rax, 160(%rdi) - movq %rdx, 168(%rdi) - movq %r10, 176(%rdi) - movq %r11, 184(%rdi) - addq $192, %rsp + addq $96, %rsp pop %r12 repz retq #ifndef __APPLE__ -.size sp_3072_sqr_24,.-sp_3072_sqr_24 +.size sp_3072_sqr_12,.-sp_3072_sqr_12 #endif /* __APPLE__ */ #ifdef HAVE_INTEL_AVX2 /* Multiply a and b into r. (r = a * b) @@ -15182,3618 +13877,969 @@ _sp_3072_sqr_24: * b Second number to multiply. */ #ifndef __APPLE__ -.globl sp_3072_mul_avx2_24 -.type sp_3072_mul_avx2_24,@function +.globl sp_3072_mul_avx2_12 +.type sp_3072_mul_avx2_12,@function .align 16 -sp_3072_mul_avx2_24: +sp_3072_mul_avx2_12: #else -.globl _sp_3072_mul_avx2_24 +.globl _sp_3072_mul_avx2_12 .p2align 4 -_sp_3072_mul_avx2_24: +_sp_3072_mul_avx2_12: #endif /* __APPLE__ */ + push %rbx push %rbp push %r12 - push %r13 - push %r14 - push %r15 - push %rbx movq %rdx, %rbp - subq $192, %rsp - movq $0, %r14 + subq $96, %rsp + cmpq %rdi, %rsi + movq %rsp, %rbx + cmovne %rdi, %rbx + cmpq %rdi, %rbp + cmove %rsp, %rbx + xorq %r12, %r12 movq (%rsi), %rdx # A[0] * B[0] mulx (%rbp), %r8, %r9 # A[0] * B[1] mulx 8(%rbp), %rax, %r10 - movq %r8, (%rsp) + movq %r8, (%rbx) adcxq %rax, %r9 + movq %r9, 8(%rbx) # A[0] * B[2] - mulx 16(%rbp), %rax, %r11 - movq %r9, 8(%rsp) + mulx 16(%rbp), %rax, %r8 adcxq %rax, %r10 # A[0] * B[3] - mulx 24(%rbp), %rax, %r12 - movq %r10, 16(%rsp) - adcxq %rax, %r11 - movq %r11, 24(%rsp) + mulx 24(%rbp), %rax, %r9 + movq %r10, 16(%rbx) + adcxq %rax, %r8 + movq %r8, 24(%rbx) # A[0] * B[4] - mulx 32(%rbp), %rax, %r8 - adcxq %rax, %r12 + mulx 32(%rbp), %rax, %r10 + adcxq %rax, %r9 # A[0] * B[5] - mulx 40(%rbp), %rax, %r9 - movq %r12, 32(%rsp) - adcxq %rax, %r8 + mulx 40(%rbp), %rax, %r8 + movq %r9, 32(%rbx) + adcxq %rax, %r10 + movq %r10, 40(%rbx) # A[0] * B[6] - mulx 48(%rbp), %rax, %r10 - movq %r8, 40(%rsp) - adcxq %rax, %r9 + mulx 48(%rbp), %rax, %r9 + adcxq %rax, %r8 # A[0] * B[7] - mulx 56(%rbp), %rax, %r11 - movq %r9, 48(%rsp) - adcxq %rax, %r10 - movq %r10, 56(%rsp) + mulx 56(%rbp), %rax, %r10 + movq %r8, 48(%rbx) + adcxq %rax, %r9 + movq %r9, 56(%rbx) # A[0] * B[8] - mulx 64(%rbp), %rax, %r12 - adcxq %rax, %r11 + mulx 64(%rbp), %rax, %r8 + adcxq %rax, %r10 # A[0] * B[9] - mulx 72(%rbp), %rax, %r8 - movq %r11, 64(%rsp) - adcxq %rax, %r12 + mulx 72(%rbp), %rax, %r9 + movq %r10, 64(%rbx) + adcxq %rax, %r8 + movq %r8, 72(%rbx) # A[0] * B[10] - mulx 80(%rbp), %rax, %r9 - movq %r12, 72(%rsp) - adcxq %rax, %r8 + mulx 80(%rbp), %rax, %r10 + adcxq %rax, %r9 # A[0] * B[11] - mulx 88(%rbp), %rax, %r10 - movq %r8, 80(%rsp) - adcxq %rax, %r9 - movq %r9, 88(%rsp) - # A[0] * B[12] - mulx 96(%rbp), %rax, %r11 + mulx 88(%rbp), %rax, %r8 + movq %r9, 80(%rbx) adcxq %rax, %r10 - # A[0] * B[13] - mulx 104(%rbp), %rax, %r12 - movq %r10, 96(%rsp) - adcxq %rax, %r11 - # A[0] * B[14] - mulx 112(%rbp), %rax, %r8 - movq %r11, 104(%rsp) - adcxq %rax, %r12 - # A[0] * B[15] - mulx 120(%rbp), %rax, %r9 - movq %r12, 112(%rsp) - adcxq %rax, %r8 - movq %r8, 120(%rsp) - # A[0] * B[16] - mulx 128(%rbp), %rax, %r10 - adcxq %rax, %r9 - # A[0] * B[17] - mulx 136(%rbp), %rax, %r11 - movq %r9, 128(%rsp) - adcxq %rax, %r10 - # A[0] * B[18] - mulx 144(%rbp), %rax, %r12 - movq %r10, 136(%rsp) - adcxq %rax, %r11 - # A[0] * B[19] - mulx 152(%rbp), %rax, %r8 - movq %r11, 144(%rsp) - adcxq %rax, %r12 - movq %r12, 152(%rsp) - # A[0] * B[20] - mulx 160(%rbp), %rax, %r9 - adcxq %rax, %r8 - # A[0] * B[21] - mulx 168(%rbp), %rax, %r10 - movq %r8, 160(%rsp) - adcxq %rax, %r9 - # A[0] * B[22] - mulx 176(%rbp), %rax, %r11 - movq %r9, 168(%rsp) - adcxq %rax, %r10 - # A[0] * B[23] - mulx 184(%rbp), %rax, %r12 - movq %r10, %r15 - adcxq %rax, %r11 - adcxq %r14, %r12 - movq %r14, %r13 - adcxq %r14, %r13 - movq %r11, %rbx - movq %r12, 192(%rdi) + adcxq %r12, %r8 + movq %r12, %r11 + adcxq %r12, %r11 + movq %r10, 88(%rbx) + movq %r8, 96(%rdi) movq 8(%rsi), %rdx - movq 8(%rsp), %r9 - movq 16(%rsp), %r10 - movq 24(%rsp), %r11 - movq 32(%rsp), %r12 - movq 40(%rsp), %r8 + movq 8(%rbx), %r9 + movq 16(%rbx), %r10 + movq 24(%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(%rsp) + movq %r9, 8(%rbx) adcxq %rax, %r10 - adoxq %rcx, %r11 + adoxq %rcx, %r8 + movq %r10, 16(%rbx) + movq 32(%rbx), %r9 + movq 40(%rbx), %r10 # A[1] * B[2] mulx 16(%rbp), %rax, %rcx - movq %r10, 16(%rsp) - adcxq %rax, %r11 - adoxq %rcx, %r12 + adcxq %rax, %r8 + adoxq %rcx, %r9 # A[1] * B[3] mulx 24(%rbp), %rax, %rcx - movq %r11, 24(%rsp) - adcxq %rax, %r12 - adoxq %rcx, %r8 - movq %r12, 32(%rsp) - movq 48(%rsp), %r9 - movq 56(%rsp), %r10 - movq 64(%rsp), %r11 - movq 72(%rsp), %r12 + movq %r8, 24(%rbx) + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r9, 32(%rbx) + movq 48(%rbx), %r8 + movq 56(%rbx), %r9 # A[1] * B[4] mulx 32(%rbp), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 + adcxq %rax, %r10 + adoxq %rcx, %r8 # A[1] * B[5] mulx 40(%rbp), %rax, %rcx - movq %r8, 40(%rsp) - adcxq %rax, %r9 - adoxq %rcx, %r10 + movq %r10, 40(%rbx) + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r8, 48(%rbx) + movq 64(%rbx), %r10 + movq 72(%rbx), %r8 # A[1] * B[6] mulx 48(%rbp), %rax, %rcx - movq %r9, 48(%rsp) - adcxq %rax, %r10 - adoxq %rcx, %r11 + adcxq %rax, %r9 + adoxq %rcx, %r10 # A[1] * B[7] mulx 56(%rbp), %rax, %rcx - movq %r10, 56(%rsp) - adcxq %rax, %r11 - adoxq %rcx, %r12 - movq %r11, 64(%rsp) - movq 80(%rsp), %r8 - movq 88(%rsp), %r9 - movq 96(%rsp), %r10 - movq 104(%rsp), %r11 + movq %r9, 56(%rbx) + adcxq %rax, %r10 + adoxq %rcx, %r8 + movq %r10, 64(%rbx) + movq 80(%rbx), %r9 + movq 88(%rbx), %r10 # A[1] * B[8] mulx 64(%rbp), %rax, %rcx - adcxq %rax, %r12 - adoxq %rcx, %r8 + adcxq %rax, %r8 + adoxq %rcx, %r9 # A[1] * B[9] mulx 72(%rbp), %rax, %rcx - movq %r12, 72(%rsp) - adcxq %rax, %r8 - adoxq %rcx, %r9 + movq %r8, 72(%rbx) + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r9, 80(%rbx) + movq 96(%rdi), %r8 # A[1] * B[10] mulx 80(%rbp), %rax, %rcx - movq %r8, 80(%rsp) - adcxq %rax, %r9 - adoxq %rcx, %r10 + adcxq %rax, %r10 + adoxq %rcx, %r8 # A[1] * B[11] mulx 88(%rbp), %rax, %rcx - movq %r9, 88(%rsp) - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r10, 96(%rsp) - movq 112(%rsp), %r12 - movq 120(%rsp), %r8 - movq 128(%rsp), %r9 - movq 136(%rsp), %r10 - # 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(%rsp) - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[1] * B[14] - mulx 112(%rbp), %rax, %rcx - movq %r12, 112(%rsp) + movq %r10, 88(%rbx) + movq %r12, %r9 adcxq %rax, %r8 adoxq %rcx, %r9 - # A[1] * B[15] - mulx 120(%rbp), %rax, %rcx - movq %r8, 120(%rsp) - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r9, 128(%rsp) - movq 144(%rsp), %r11 - movq 152(%rsp), %r12 - movq 160(%rsp), %r8 - movq 168(%rsp), %r9 - # A[1] * B[16] - mulx 128(%rbp), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[1] * B[17] - mulx 136(%rbp), %rax, %rcx - movq %r10, 136(%rsp) - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[1] * B[18] - mulx 144(%rbp), %rax, %rcx - movq %r11, 144(%rsp) - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[1] * B[19] - mulx 152(%rbp), %rax, %rcx - movq %r12, 152(%rsp) - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r8, 160(%rsp) - movq %r15, %r10 - movq %rbx, %r11 - movq 192(%rdi), %r12 - # A[1] * B[20] - mulx 160(%rbp), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[1] * B[21] - mulx 168(%rbp), %rax, %rcx - movq %r9, 168(%rsp) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[1] * B[22] - mulx 176(%rbp), %rax, %rcx - movq %r10, %r15 - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[1] * B[23] - mulx 184(%rbp), %rax, %rcx - movq %r11, %rbx - movq %r14, %r8 - adcxq %rax, %r12 - adoxq %rcx, %r8 - adcxq %r13, %r8 - movq %r14, %r13 - adoxq %r14, %r13 - adcxq %r14, %r13 - movq %r12, 192(%rdi) - movq %r8, 200(%rdi) + adcxq %r11, %r9 + movq %r12, %r11 + adoxq %r12, %r11 + adcxq %r12, %r11 + movq %r8, 96(%rdi) + movq %r9, 104(%rdi) movq 16(%rsi), %rdx - movq 16(%rsp), %r10 - movq 24(%rsp), %r11 - movq 32(%rsp), %r12 - movq 40(%rsp), %r8 - movq 48(%rsp), %r9 + movq 16(%rbx), %r10 + movq 24(%rbx), %r8 + movq 32(%rbx), %r9 # A[2] * B[0] mulx (%rbp), %rax, %rcx adcxq %rax, %r10 - adoxq %rcx, %r11 + adoxq %rcx, %r8 # A[2] * B[1] mulx 8(%rbp), %rax, %rcx - movq %r10, 16(%rsp) - adcxq %rax, %r11 - adoxq %rcx, %r12 + movq %r10, 16(%rbx) + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r8, 24(%rbx) + movq 40(%rbx), %r10 + movq 48(%rbx), %r8 # A[2] * B[2] mulx 16(%rbp), %rax, %rcx - movq %r11, 24(%rsp) - adcxq %rax, %r12 - adoxq %rcx, %r8 + adcxq %rax, %r9 + adoxq %rcx, %r10 # A[2] * B[3] mulx 24(%rbp), %rax, %rcx - movq %r12, 32(%rsp) - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r8, 40(%rsp) - movq 56(%rsp), %r10 - movq 64(%rsp), %r11 - movq 72(%rsp), %r12 - movq 80(%rsp), %r8 + movq %r9, 32(%rbx) + adcxq %rax, %r10 + adoxq %rcx, %r8 + movq %r10, 40(%rbx) + movq 56(%rbx), %r9 + movq 64(%rbx), %r10 # A[2] * B[4] mulx 32(%rbp), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 + adcxq %rax, %r8 + adoxq %rcx, %r9 # A[2] * B[5] mulx 40(%rbp), %rax, %rcx - movq %r9, 48(%rsp) - adcxq %rax, %r10 - adoxq %rcx, %r11 + movq %r8, 48(%rbx) + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r9, 56(%rbx) + movq 72(%rbx), %r8 + movq 80(%rbx), %r9 # A[2] * B[6] mulx 48(%rbp), %rax, %rcx - movq %r10, 56(%rsp) - adcxq %rax, %r11 - adoxq %rcx, %r12 + adcxq %rax, %r10 + adoxq %rcx, %r8 # A[2] * B[7] mulx 56(%rbp), %rax, %rcx - movq %r11, 64(%rsp) - adcxq %rax, %r12 - adoxq %rcx, %r8 - movq %r12, 72(%rsp) - movq 88(%rsp), %r9 - movq 96(%rsp), %r10 - movq 104(%rsp), %r11 - movq 112(%rsp), %r12 + movq %r10, 64(%rbx) + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r8, 72(%rbx) + movq 88(%rbx), %r10 + movq 96(%rdi), %r8 # A[2] * B[8] mulx 64(%rbp), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 + adcxq %rax, %r9 + adoxq %rcx, %r10 # A[2] * B[9] mulx 72(%rbp), %rax, %rcx - movq %r8, 80(%rsp) - adcxq %rax, %r9 - adoxq %rcx, %r10 + movq %r9, 80(%rbx) + adcxq %rax, %r10 + adoxq %rcx, %r8 + movq %r10, 88(%rbx) + movq 104(%rdi), %r9 # A[2] * B[10] mulx 80(%rbp), %rax, %rcx - movq %r9, 88(%rsp) - adcxq %rax, %r10 - adoxq %rcx, %r11 + adcxq %rax, %r8 + adoxq %rcx, %r9 # A[2] * B[11] mulx 88(%rbp), %rax, %rcx - movq %r10, 96(%rsp) - adcxq %rax, %r11 - adoxq %rcx, %r12 - movq %r11, 104(%rsp) - movq 120(%rsp), %r8 - movq 128(%rsp), %r9 - movq 136(%rsp), %r10 - movq 144(%rsp), %r11 - # 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(%rsp) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[2] * B[14] - mulx 112(%rbp), %rax, %rcx - movq %r8, 120(%rsp) + movq %r8, 96(%rdi) + movq %r12, %r10 adcxq %rax, %r9 adoxq %rcx, %r10 - # A[2] * B[15] - mulx 120(%rbp), %rax, %rcx - movq %r9, 128(%rsp) - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r10, 136(%rsp) - movq 152(%rsp), %r12 - movq 160(%rsp), %r8 - movq 168(%rsp), %r9 - movq %r15, %r10 - # A[2] * B[16] - mulx 128(%rbp), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[2] * B[17] - mulx 136(%rbp), %rax, %rcx - movq %r11, 144(%rsp) - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[2] * B[18] - mulx 144(%rbp), %rax, %rcx - movq %r12, 152(%rsp) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[2] * B[19] - mulx 152(%rbp), %rax, %rcx - movq %r8, 160(%rsp) - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r9, 168(%rsp) - movq %rbx, %r11 - movq 192(%rdi), %r12 - movq 200(%rdi), %r8 - # A[2] * B[20] - mulx 160(%rbp), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[2] * B[21] - mulx 168(%rbp), %rax, %rcx - movq %r10, %r15 - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[2] * B[22] - mulx 176(%rbp), %rax, %rcx - movq %r11, %rbx - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[2] * B[23] - mulx 184(%rbp), %rax, %rcx - movq %r12, 192(%rdi) - movq %r14, %r9 - adcxq %rax, %r8 - adoxq %rcx, %r9 - adcxq %r13, %r9 - movq %r14, %r13 - adoxq %r14, %r13 - adcxq %r14, %r13 - movq %r8, 200(%rdi) - movq %r9, 208(%rdi) + adcxq %r11, %r10 + movq %r12, %r11 + adoxq %r12, %r11 + adcxq %r12, %r11 + movq %r9, 104(%rdi) + movq %r10, 112(%rdi) movq 24(%rsi), %rdx - movq 24(%rsp), %r11 - movq 32(%rsp), %r12 - movq 40(%rsp), %r8 - movq 48(%rsp), %r9 - movq 56(%rsp), %r10 + movq 24(%rbx), %r8 + movq 32(%rbx), %r9 + movq 40(%rbx), %r10 # A[3] * B[0] mulx (%rbp), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r12 + adcxq %rax, %r8 + adoxq %rcx, %r9 # A[3] * B[1] mulx 8(%rbp), %rax, %rcx - movq %r11, 24(%rsp) - adcxq %rax, %r12 - adoxq %rcx, %r8 + movq %r8, 24(%rbx) + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r9, 32(%rbx) + movq 48(%rbx), %r8 + movq 56(%rbx), %r9 # A[3] * B[2] mulx 16(%rbp), %rax, %rcx - movq %r12, 32(%rsp) - adcxq %rax, %r8 - adoxq %rcx, %r9 + adcxq %rax, %r10 + adoxq %rcx, %r8 # A[3] * B[3] mulx 24(%rbp), %rax, %rcx - movq %r8, 40(%rsp) - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r9, 48(%rsp) - movq 64(%rsp), %r11 - movq 72(%rsp), %r12 - movq 80(%rsp), %r8 - movq 88(%rsp), %r9 + movq %r10, 40(%rbx) + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r8, 48(%rbx) + movq 64(%rbx), %r10 + movq 72(%rbx), %r8 # A[3] * B[4] mulx 32(%rbp), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 + adcxq %rax, %r9 + adoxq %rcx, %r10 # A[3] * B[5] mulx 40(%rbp), %rax, %rcx - movq %r10, 56(%rsp) - adcxq %rax, %r11 - adoxq %rcx, %r12 + movq %r9, 56(%rbx) + adcxq %rax, %r10 + adoxq %rcx, %r8 + movq %r10, 64(%rbx) + movq 80(%rbx), %r9 + movq 88(%rbx), %r10 # A[3] * B[6] mulx 48(%rbp), %rax, %rcx - movq %r11, 64(%rsp) - adcxq %rax, %r12 - adoxq %rcx, %r8 + adcxq %rax, %r8 + adoxq %rcx, %r9 # A[3] * B[7] mulx 56(%rbp), %rax, %rcx - movq %r12, 72(%rsp) - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r8, 80(%rsp) - movq 96(%rsp), %r10 - movq 104(%rsp), %r11 - movq 112(%rsp), %r12 - movq 120(%rsp), %r8 + movq %r8, 72(%rbx) + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r9, 80(%rbx) + movq 96(%rdi), %r8 + movq 104(%rdi), %r9 # A[3] * B[8] mulx 64(%rbp), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 + adcxq %rax, %r10 + adoxq %rcx, %r8 # A[3] * B[9] mulx 72(%rbp), %rax, %rcx - movq %r9, 88(%rsp) - adcxq %rax, %r10 - adoxq %rcx, %r11 + movq %r10, 88(%rbx) + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r8, 96(%rdi) + movq 112(%rdi), %r10 # A[3] * B[10] mulx 80(%rbp), %rax, %rcx - movq %r10, 96(%rsp) - adcxq %rax, %r11 - adoxq %rcx, %r12 + adcxq %rax, %r9 + adoxq %rcx, %r10 # A[3] * B[11] mulx 88(%rbp), %rax, %rcx - movq %r11, 104(%rsp) - adcxq %rax, %r12 - adoxq %rcx, %r8 - movq %r12, 112(%rsp) - movq 128(%rsp), %r9 - movq 136(%rsp), %r10 - movq 144(%rsp), %r11 - movq 152(%rsp), %r12 - # 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(%rsp) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[3] * B[14] - mulx 112(%rbp), %rax, %rcx - movq %r9, 128(%rsp) + movq %r9, 104(%rdi) + movq %r12, %r8 adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[3] * B[15] - mulx 120(%rbp), %rax, %rcx - movq %r10, 136(%rsp) - adcxq %rax, %r11 - adoxq %rcx, %r12 - movq %r11, 144(%rsp) - movq 160(%rsp), %r8 - movq 168(%rsp), %r9 - movq %r15, %r10 - movq %rbx, %r11 - # A[3] * B[16] - mulx 128(%rbp), %rax, %rcx - adcxq %rax, %r12 adoxq %rcx, %r8 - # A[3] * B[17] - mulx 136(%rbp), %rax, %rcx - movq %r12, 152(%rsp) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[3] * B[18] - mulx 144(%rbp), %rax, %rcx - movq %r8, 160(%rsp) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[3] * B[19] - mulx 152(%rbp), %rax, %rcx - movq %r9, 168(%rsp) - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r10, %r15 - movq 192(%rdi), %r12 - movq 200(%rdi), %r8 - movq 208(%rdi), %r9 - # A[3] * B[20] - mulx 160(%rbp), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[3] * B[21] - mulx 168(%rbp), %rax, %rcx - movq %r11, %rbx - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[3] * B[22] - mulx 176(%rbp), %rax, %rcx - movq %r12, 192(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[3] * B[23] - mulx 184(%rbp), %rax, %rcx - movq %r8, 200(%rdi) - movq %r14, %r10 - adcxq %rax, %r9 - adoxq %rcx, %r10 - adcxq %r13, %r10 - movq %r14, %r13 - adoxq %r14, %r13 - adcxq %r14, %r13 - movq %r9, 208(%rdi) - movq %r10, 216(%rdi) + adcxq %r11, %r8 + movq %r12, %r11 + adoxq %r12, %r11 + adcxq %r12, %r11 + movq %r10, 112(%rdi) + movq %r8, 120(%rdi) movq 32(%rsi), %rdx - movq 32(%rsp), %r12 - movq 40(%rsp), %r8 - movq 48(%rsp), %r9 - movq 56(%rsp), %r10 - movq 64(%rsp), %r11 + movq 32(%rbx), %r9 + movq 40(%rbx), %r10 + movq 48(%rbx), %r8 # A[4] * B[0] mulx (%rbp), %rax, %rcx - adcxq %rax, %r12 - adoxq %rcx, %r8 + adcxq %rax, %r9 + adoxq %rcx, %r10 # A[4] * B[1] mulx 8(%rbp), %rax, %rcx - movq %r12, 32(%rsp) - adcxq %rax, %r8 - adoxq %rcx, %r9 + movq %r9, 32(%rbx) + adcxq %rax, %r10 + adoxq %rcx, %r8 + movq %r10, 40(%rbx) + movq 56(%rbx), %r9 + movq 64(%rbx), %r10 # A[4] * B[2] mulx 16(%rbp), %rax, %rcx - movq %r8, 40(%rsp) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[4] * B[3] - mulx 24(%rbp), %rax, %rcx - movq %r9, 48(%rsp) - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r10, 56(%rsp) - movq 72(%rsp), %r12 - movq 80(%rsp), %r8 - movq 88(%rsp), %r9 - movq 96(%rsp), %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(%rsp) - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[4] * B[6] - mulx 48(%rbp), %rax, %rcx - movq %r12, 72(%rsp) adcxq %rax, %r8 adoxq %rcx, %r9 - # A[4] * B[7] - mulx 56(%rbp), %rax, %rcx - movq %r8, 80(%rsp) + # A[4] * B[3] + mulx 24(%rbp), %rax, %rcx + movq %r8, 48(%rbx) adcxq %rax, %r9 adoxq %rcx, %r10 - movq %r9, 88(%rsp) - movq 104(%rsp), %r11 - movq 112(%rsp), %r12 - movq 120(%rsp), %r8 - movq 128(%rsp), %r9 + movq %r9, 56(%rbx) + movq 72(%rbx), %r8 + movq 80(%rbx), %r9 + # A[4] * B[4] + mulx 32(%rbp), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 + # A[4] * B[5] + mulx 40(%rbp), %rax, %rcx + movq %r10, 64(%rbx) + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r8, 72(%rbx) + movq 88(%rbx), %r10 + movq 96(%rdi), %r8 + # A[4] * B[6] + mulx 48(%rbp), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[4] * B[7] + mulx 56(%rbp), %rax, %rcx + movq %r9, 80(%rbx) + adcxq %rax, %r10 + adoxq %rcx, %r8 + movq %r10, 88(%rbx) + movq 104(%rdi), %r9 + movq 112(%rdi), %r10 # A[4] * B[8] mulx 64(%rbp), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 + adcxq %rax, %r8 + adoxq %rcx, %r9 # A[4] * B[9] mulx 72(%rbp), %rax, %rcx - movq %r10, 96(%rsp) - adcxq %rax, %r11 - adoxq %rcx, %r12 + movq %r8, 96(%rdi) + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r9, 104(%rdi) + movq 120(%rdi), %r8 # A[4] * B[10] mulx 80(%rbp), %rax, %rcx - movq %r11, 104(%rsp) - adcxq %rax, %r12 + adcxq %rax, %r10 adoxq %rcx, %r8 # A[4] * B[11] mulx 88(%rbp), %rax, %rcx - movq %r12, 112(%rsp) + movq %r10, 112(%rdi) + movq %r12, %r9 adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r8, 120(%rsp) - movq 136(%rsp), %r10 - movq 144(%rsp), %r11 - movq 152(%rsp), %r12 - movq 160(%rsp), %r8 - # 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(%rsp) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[4] * B[14] - mulx 112(%rbp), %rax, %rcx - movq %r10, 136(%rsp) - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[4] * B[15] - mulx 120(%rbp), %rax, %rcx - movq %r11, 144(%rsp) - adcxq %rax, %r12 - adoxq %rcx, %r8 - movq %r12, 152(%rsp) - movq 168(%rsp), %r9 - movq %r15, %r10 - movq %rbx, %r11 - movq 192(%rdi), %r12 - # A[4] * B[16] - mulx 128(%rbp), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[4] * B[17] - mulx 136(%rbp), %rax, %rcx - movq %r8, 160(%rsp) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[4] * B[18] - mulx 144(%rbp), %rax, %rcx - movq %r9, 168(%rsp) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[4] * B[19] - mulx 152(%rbp), %rax, %rcx - movq %r10, %r15 - adcxq %rax, %r11 - adoxq %rcx, %r12 - movq %r11, %rbx - movq 200(%rdi), %r8 - movq 208(%rdi), %r9 - movq 216(%rdi), %r10 - # A[4] * B[20] - mulx 160(%rbp), %rax, %rcx - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[4] * B[21] - mulx 168(%rbp), %rax, %rcx - movq %r12, 192(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[4] * B[22] - mulx 176(%rbp), %rax, %rcx - movq %r8, 200(%rdi) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[4] * B[23] - mulx 184(%rbp), %rax, %rcx - movq %r9, 208(%rdi) - movq %r14, %r11 - adcxq %rax, %r10 - adoxq %rcx, %r11 - adcxq %r13, %r11 - movq %r14, %r13 - adoxq %r14, %r13 - adcxq %r14, %r13 - movq %r10, 216(%rdi) - movq %r11, 224(%rdi) + adcxq %r11, %r9 + movq %r12, %r11 + adoxq %r12, %r11 + adcxq %r12, %r11 + movq %r8, 120(%rdi) + movq %r9, 128(%rdi) movq 40(%rsi), %rdx - movq 40(%rsp), %r8 - movq 48(%rsp), %r9 - movq 56(%rsp), %r10 - movq 64(%rsp), %r11 - movq 72(%rsp), %r12 + movq 40(%rbx), %r10 + movq 48(%rbx), %r8 + movq 56(%rbx), %r9 # A[5] * B[0] mulx (%rbp), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 + adcxq %rax, %r10 + adoxq %rcx, %r8 # A[5] * B[1] mulx 8(%rbp), %rax, %rcx - movq %r8, 40(%rsp) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[5] * B[2] - mulx 16(%rbp), %rax, %rcx - movq %r9, 48(%rsp) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[5] * B[3] - mulx 24(%rbp), %rax, %rcx - movq %r10, 56(%rsp) - adcxq %rax, %r11 - adoxq %rcx, %r12 - movq %r11, 64(%rsp) - movq 80(%rsp), %r8 - movq 88(%rsp), %r9 - movq 96(%rsp), %r10 - movq 104(%rsp), %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(%rsp) + movq %r10, 40(%rbx) adcxq %rax, %r8 adoxq %rcx, %r9 - # A[5] * B[6] - mulx 48(%rbp), %rax, %rcx - movq %r8, 80(%rsp) + movq %r8, 48(%rbx) + movq 64(%rbx), %r10 + movq 72(%rbx), %r8 + # A[5] * B[2] + mulx 16(%rbp), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r10 + # A[5] * B[3] + mulx 24(%rbp), %rax, %rcx + movq %r9, 56(%rbx) + adcxq %rax, %r10 + adoxq %rcx, %r8 + movq %r10, 64(%rbx) + movq 80(%rbx), %r9 + movq 88(%rbx), %r10 + # A[5] * B[4] + mulx 32(%rbp), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[5] * B[5] + mulx 40(%rbp), %rax, %rcx + movq %r8, 72(%rbx) + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r9, 80(%rbx) + movq 96(%rdi), %r8 + movq 104(%rdi), %r9 + # A[5] * B[6] + mulx 48(%rbp), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 # A[5] * B[7] mulx 56(%rbp), %rax, %rcx - movq %r9, 88(%rsp) - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r10, 96(%rsp) - movq 112(%rsp), %r12 - movq 120(%rsp), %r8 - movq 128(%rsp), %r9 - movq 136(%rsp), %r10 + movq %r10, 88(%rbx) + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r8, 96(%rdi) + movq 112(%rdi), %r10 + movq 120(%rdi), %r8 # A[5] * B[8] mulx 64(%rbp), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r12 + adcxq %rax, %r9 + adoxq %rcx, %r10 # A[5] * B[9] mulx 72(%rbp), %rax, %rcx - movq %r11, 104(%rsp) - adcxq %rax, %r12 + movq %r9, 104(%rdi) + adcxq %rax, %r10 adoxq %rcx, %r8 + movq %r10, 112(%rdi) + movq 128(%rdi), %r9 # A[5] * B[10] mulx 80(%rbp), %rax, %rcx - movq %r12, 112(%rsp) adcxq %rax, %r8 adoxq %rcx, %r9 # A[5] * B[11] mulx 88(%rbp), %rax, %rcx - movq %r8, 120(%rsp) + movq %r8, 120(%rdi) + movq %r12, %r10 adcxq %rax, %r9 adoxq %rcx, %r10 - movq %r9, 128(%rsp) - movq 144(%rsp), %r11 - movq 152(%rsp), %r12 - movq 160(%rsp), %r8 - movq 168(%rsp), %r9 - # 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(%rsp) - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[5] * B[14] - mulx 112(%rbp), %rax, %rcx - movq %r11, 144(%rsp) - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[5] * B[15] - mulx 120(%rbp), %rax, %rcx - movq %r12, 152(%rsp) - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r8, 160(%rsp) - movq %r15, %r10 - movq %rbx, %r11 - movq 192(%rdi), %r12 - movq 200(%rdi), %r8 - # A[5] * B[16] - mulx 128(%rbp), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[5] * B[17] - mulx 136(%rbp), %rax, %rcx - movq %r9, 168(%rsp) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[5] * B[18] - mulx 144(%rbp), %rax, %rcx - movq %r10, %r15 - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[5] * B[19] - mulx 152(%rbp), %rax, %rcx - movq %r11, %rbx - adcxq %rax, %r12 - adoxq %rcx, %r8 - movq %r12, 192(%rdi) - movq 208(%rdi), %r9 - movq 216(%rdi), %r10 - movq 224(%rdi), %r11 - # A[5] * B[20] - mulx 160(%rbp), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[5] * B[21] - mulx 168(%rbp), %rax, %rcx - movq %r8, 200(%rdi) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[5] * B[22] - mulx 176(%rbp), %rax, %rcx - movq %r9, 208(%rdi) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[5] * B[23] - mulx 184(%rbp), %rax, %rcx - movq %r10, 216(%rdi) - movq %r14, %r12 - adcxq %rax, %r11 - adoxq %rcx, %r12 - adcxq %r13, %r12 - movq %r14, %r13 - adoxq %r14, %r13 - adcxq %r14, %r13 - movq %r11, 224(%rdi) - movq %r12, 232(%rdi) + adcxq %r11, %r10 + movq %r12, %r11 + adoxq %r12, %r11 + adcxq %r12, %r11 + movq %r9, 128(%rdi) + movq %r10, 136(%rdi) movq 48(%rsi), %rdx - movq 48(%rsp), %r9 - movq 56(%rsp), %r10 - movq 64(%rsp), %r11 - movq 72(%rsp), %r12 - movq 80(%rsp), %r8 + movq 48(%rbx), %r8 + movq 56(%rbx), %r9 + movq 64(%rbx), %r10 # 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(%rsp) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[6] * B[2] - mulx 16(%rbp), %rax, %rcx - movq %r10, 56(%rsp) - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[6] * B[3] - mulx 24(%rbp), %rax, %rcx - movq %r11, 64(%rsp) - adcxq %rax, %r12 - adoxq %rcx, %r8 - movq %r12, 72(%rsp) - movq 88(%rsp), %r9 - movq 96(%rsp), %r10 - movq 104(%rsp), %r11 - movq 112(%rsp), %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(%rsp) + # A[6] * B[1] + mulx 8(%rbp), %rax, %rcx + movq %r8, 48(%rbx) adcxq %rax, %r9 adoxq %rcx, %r10 + movq %r9, 56(%rbx) + movq 72(%rbx), %r8 + movq 80(%rbx), %r9 + # A[6] * B[2] + mulx 16(%rbp), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 + # A[6] * B[3] + mulx 24(%rbp), %rax, %rcx + movq %r10, 64(%rbx) + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r8, 72(%rbx) + movq 88(%rbx), %r10 + movq 96(%rdi), %r8 + # A[6] * B[4] + mulx 32(%rbp), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r10 + # A[6] * B[5] + mulx 40(%rbp), %rax, %rcx + movq %r9, 80(%rbx) + adcxq %rax, %r10 + adoxq %rcx, %r8 + movq %r10, 88(%rbx) + movq 104(%rdi), %r9 + movq 112(%rdi), %r10 # A[6] * B[6] mulx 48(%rbp), %rax, %rcx - movq %r9, 88(%rsp) - adcxq %rax, %r10 - adoxq %rcx, %r11 + adcxq %rax, %r8 + adoxq %rcx, %r9 # A[6] * B[7] mulx 56(%rbp), %rax, %rcx - movq %r10, 96(%rsp) - adcxq %rax, %r11 - adoxq %rcx, %r12 - movq %r11, 104(%rsp) - movq 120(%rsp), %r8 - movq 128(%rsp), %r9 - movq 136(%rsp), %r10 - movq 144(%rsp), %r11 + movq %r8, 96(%rdi) + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r9, 104(%rdi) + movq 120(%rdi), %r8 + movq 128(%rdi), %r9 # A[6] * B[8] mulx 64(%rbp), %rax, %rcx - adcxq %rax, %r12 + adcxq %rax, %r10 adoxq %rcx, %r8 # A[6] * B[9] mulx 72(%rbp), %rax, %rcx - movq %r12, 112(%rsp) + movq %r10, 112(%rdi) adcxq %rax, %r8 adoxq %rcx, %r9 + movq %r8, 120(%rdi) + movq 136(%rdi), %r10 # A[6] * B[10] mulx 80(%rbp), %rax, %rcx - movq %r8, 120(%rsp) adcxq %rax, %r9 adoxq %rcx, %r10 # A[6] * B[11] mulx 88(%rbp), %rax, %rcx - movq %r9, 128(%rsp) + movq %r9, 128(%rdi) + movq %r12, %r8 adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r10, 136(%rsp) - movq 152(%rsp), %r12 - movq 160(%rsp), %r8 - movq 168(%rsp), %r9 - movq %r15, %r10 - # 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(%rsp) - adcxq %rax, %r12 adoxq %rcx, %r8 - # A[6] * B[14] - mulx 112(%rbp), %rax, %rcx - movq %r12, 152(%rsp) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[6] * B[15] - mulx 120(%rbp), %rax, %rcx - movq %r8, 160(%rsp) - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r9, 168(%rsp) - movq %rbx, %r11 - movq 192(%rdi), %r12 - movq 200(%rdi), %r8 - movq 208(%rdi), %r9 - # A[6] * B[16] - mulx 128(%rbp), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[6] * B[17] - mulx 136(%rbp), %rax, %rcx - movq %r10, %r15 - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[6] * B[18] - mulx 144(%rbp), %rax, %rcx - movq %r11, %rbx - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[6] * B[19] - mulx 152(%rbp), %rax, %rcx - movq %r12, 192(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r8, 200(%rdi) - movq 216(%rdi), %r10 - movq 224(%rdi), %r11 - movq 232(%rdi), %r12 - # A[6] * B[20] - mulx 160(%rbp), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[6] * B[21] - mulx 168(%rbp), %rax, %rcx - movq %r9, 208(%rdi) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[6] * B[22] - mulx 176(%rbp), %rax, %rcx - movq %r10, 216(%rdi) - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[6] * B[23] - mulx 184(%rbp), %rax, %rcx - movq %r11, 224(%rdi) - movq %r14, %r8 - adcxq %rax, %r12 - adoxq %rcx, %r8 - adcxq %r13, %r8 - movq %r14, %r13 - adoxq %r14, %r13 - adcxq %r14, %r13 - movq %r12, 232(%rdi) - movq %r8, 240(%rdi) + adcxq %r11, %r8 + movq %r12, %r11 + adoxq %r12, %r11 + adcxq %r12, %r11 + movq %r10, 136(%rdi) + movq %r8, 144(%rdi) movq 56(%rsi), %rdx - movq 56(%rsp), %r10 - movq 64(%rsp), %r11 - movq 72(%rsp), %r12 - movq 80(%rsp), %r8 - movq 88(%rsp), %r9 + movq 56(%rbx), %r9 + movq 64(%rbx), %r10 + movq 72(%rbx), %r8 # 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(%rsp) - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[7] * B[2] - mulx 16(%rbp), %rax, %rcx - movq %r11, 64(%rsp) - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[7] * B[3] - mulx 24(%rbp), %rax, %rcx - movq %r12, 72(%rsp) - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r8, 80(%rsp) - movq 96(%rsp), %r10 - movq 104(%rsp), %r11 - movq 112(%rsp), %r12 - movq 120(%rsp), %r8 - # A[7] * B[4] - mulx 32(%rbp), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r10 + # A[7] * B[1] + mulx 8(%rbp), %rax, %rcx + movq %r9, 56(%rbx) + adcxq %rax, %r10 + adoxq %rcx, %r8 + movq %r10, 64(%rbx) + movq 80(%rbx), %r9 + movq 88(%rbx), %r10 + # A[7] * B[2] + mulx 16(%rbp), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + # A[7] * B[3] + mulx 24(%rbp), %rax, %rcx + movq %r8, 72(%rbx) + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r9, 80(%rbx) + movq 96(%rdi), %r8 + movq 104(%rdi), %r9 + # A[7] * B[4] + mulx 32(%rbp), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 # A[7] * B[5] mulx 40(%rbp), %rax, %rcx - movq %r9, 88(%rsp) - adcxq %rax, %r10 - adoxq %rcx, %r11 + movq %r10, 88(%rbx) + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r8, 96(%rdi) + movq 112(%rdi), %r10 + movq 120(%rdi), %r8 # A[7] * B[6] mulx 48(%rbp), %rax, %rcx - movq %r10, 96(%rsp) - adcxq %rax, %r11 - adoxq %rcx, %r12 + adcxq %rax, %r9 + adoxq %rcx, %r10 # A[7] * B[7] mulx 56(%rbp), %rax, %rcx - movq %r11, 104(%rsp) - adcxq %rax, %r12 + movq %r9, 104(%rdi) + adcxq %rax, %r10 adoxq %rcx, %r8 - movq %r12, 112(%rsp) - movq 128(%rsp), %r9 - movq 136(%rsp), %r10 - movq 144(%rsp), %r11 - movq 152(%rsp), %r12 + movq %r10, 112(%rdi) + movq 128(%rdi), %r9 + movq 136(%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(%rsp) + movq %r8, 120(%rdi) adcxq %rax, %r9 adoxq %rcx, %r10 + movq %r9, 128(%rdi) + movq 144(%rdi), %r8 # A[7] * B[10] mulx 80(%rbp), %rax, %rcx - movq %r9, 128(%rsp) adcxq %rax, %r10 - adoxq %rcx, %r11 + adoxq %rcx, %r8 # A[7] * B[11] mulx 88(%rbp), %rax, %rcx - movq %r10, 136(%rsp) - adcxq %rax, %r11 - adoxq %rcx, %r12 - movq %r11, 144(%rsp) - movq 160(%rsp), %r8 - movq 168(%rsp), %r9 - movq %r15, %r10 - movq %rbx, %r11 - # 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(%rsp) + movq %r10, 136(%rdi) + movq %r12, %r9 adcxq %rax, %r8 adoxq %rcx, %r9 - # A[7] * B[14] - mulx 112(%rbp), %rax, %rcx - movq %r8, 160(%rsp) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[7] * B[15] - mulx 120(%rbp), %rax, %rcx - movq %r9, 168(%rsp) - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r10, %r15 - movq 192(%rdi), %r12 - movq 200(%rdi), %r8 - movq 208(%rdi), %r9 - movq 216(%rdi), %r10 - # A[7] * B[16] - mulx 128(%rbp), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[7] * B[17] - mulx 136(%rbp), %rax, %rcx - movq %r11, %rbx - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[7] * B[18] - mulx 144(%rbp), %rax, %rcx - movq %r12, 192(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[7] * B[19] - mulx 152(%rbp), %rax, %rcx - movq %r8, 200(%rdi) - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r9, 208(%rdi) - movq 224(%rdi), %r11 - movq 232(%rdi), %r12 - movq 240(%rdi), %r8 - # A[7] * B[20] - mulx 160(%rbp), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[7] * B[21] - mulx 168(%rbp), %rax, %rcx - movq %r10, 216(%rdi) - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[7] * B[22] - mulx 176(%rbp), %rax, %rcx - movq %r11, 224(%rdi) - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[7] * B[23] - mulx 184(%rbp), %rax, %rcx - movq %r12, 232(%rdi) - movq %r14, %r9 - adcxq %rax, %r8 - adoxq %rcx, %r9 - adcxq %r13, %r9 - movq %r14, %r13 - adoxq %r14, %r13 - adcxq %r14, %r13 - movq %r8, 240(%rdi) - movq %r9, 248(%rdi) + adcxq %r11, %r9 + movq %r12, %r11 + adoxq %r12, %r11 + adcxq %r12, %r11 + movq %r8, 144(%rdi) + movq %r9, 152(%rdi) movq 64(%rsi), %rdx - movq 64(%rsp), %r11 - movq 72(%rsp), %r12 - movq 80(%rsp), %r8 - movq 88(%rsp), %r9 - movq 96(%rsp), %r10 + movq 64(%rbx), %r10 + movq 72(%rbx), %r8 + movq 80(%rbx), %r9 # A[8] * B[0] mulx (%rbp), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r12 + adcxq %rax, %r10 + adoxq %rcx, %r8 # A[8] * B[1] mulx 8(%rbp), %rax, %rcx - movq %r11, 64(%rsp) - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[8] * B[2] - mulx 16(%rbp), %rax, %rcx - movq %r12, 72(%rsp) + movq %r10, 64(%rbx) adcxq %rax, %r8 adoxq %rcx, %r9 - # A[8] * B[3] - mulx 24(%rbp), %rax, %rcx - movq %r8, 80(%rsp) + movq %r8, 72(%rbx) + movq 88(%rbx), %r10 + movq 96(%rdi), %r8 + # A[8] * B[2] + mulx 16(%rbp), %rax, %rcx adcxq %rax, %r9 adoxq %rcx, %r10 - movq %r9, 88(%rsp) - movq 104(%rsp), %r11 - movq 112(%rsp), %r12 - movq 120(%rsp), %r8 - movq 128(%rsp), %r9 + # A[8] * B[3] + mulx 24(%rbp), %rax, %rcx + movq %r9, 80(%rbx) + adcxq %rax, %r10 + adoxq %rcx, %r8 + movq %r10, 88(%rbx) + movq 104(%rdi), %r9 + movq 112(%rdi), %r10 # A[8] * B[4] mulx 32(%rbp), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 + adcxq %rax, %r8 + adoxq %rcx, %r9 # A[8] * B[5] mulx 40(%rbp), %rax, %rcx - movq %r10, 96(%rsp) - adcxq %rax, %r11 - adoxq %rcx, %r12 + movq %r8, 96(%rdi) + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r9, 104(%rdi) + movq 120(%rdi), %r8 + movq 128(%rdi), %r9 # A[8] * B[6] mulx 48(%rbp), %rax, %rcx - movq %r11, 104(%rsp) - adcxq %rax, %r12 + adcxq %rax, %r10 adoxq %rcx, %r8 # A[8] * B[7] mulx 56(%rbp), %rax, %rcx - movq %r12, 112(%rsp) + movq %r10, 112(%rdi) adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r8, 120(%rsp) - movq 136(%rsp), %r10 - movq 144(%rsp), %r11 - movq 152(%rsp), %r12 - movq 160(%rsp), %r8 + movq %r8, 120(%rdi) + movq 136(%rdi), %r10 + movq 144(%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(%rsp) + movq %r9, 128(%rdi) adcxq %rax, %r10 - adoxq %rcx, %r11 + adoxq %rcx, %r8 + movq %r10, 136(%rdi) + movq 152(%rdi), %r9 # A[8] * B[10] mulx 80(%rbp), %rax, %rcx - movq %r10, 136(%rsp) - adcxq %rax, %r11 - adoxq %rcx, %r12 + adcxq %rax, %r8 + adoxq %rcx, %r9 # A[8] * B[11] mulx 88(%rbp), %rax, %rcx - movq %r11, 144(%rsp) - adcxq %rax, %r12 - adoxq %rcx, %r8 - movq %r12, 152(%rsp) - movq 168(%rsp), %r9 - movq %r15, %r10 - movq %rbx, %r11 - movq 192(%rdi), %r12 - # 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(%rsp) + movq %r8, 144(%rdi) + movq %r12, %r10 adcxq %rax, %r9 adoxq %rcx, %r10 - # A[8] * B[14] - mulx 112(%rbp), %rax, %rcx - movq %r9, 168(%rsp) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[8] * B[15] - mulx 120(%rbp), %rax, %rcx - movq %r10, %r15 - adcxq %rax, %r11 - adoxq %rcx, %r12 - movq %r11, %rbx - movq 200(%rdi), %r8 - movq 208(%rdi), %r9 - movq 216(%rdi), %r10 - movq 224(%rdi), %r11 - # A[8] * B[16] - mulx 128(%rbp), %rax, %rcx - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[8] * B[17] - mulx 136(%rbp), %rax, %rcx - movq %r12, 192(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[8] * B[18] - mulx 144(%rbp), %rax, %rcx - movq %r8, 200(%rdi) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[8] * B[19] - mulx 152(%rbp), %rax, %rcx - movq %r9, 208(%rdi) - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r10, 216(%rdi) - movq 232(%rdi), %r12 - movq 240(%rdi), %r8 - movq 248(%rdi), %r9 - # A[8] * B[20] - mulx 160(%rbp), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[8] * B[21] - mulx 168(%rbp), %rax, %rcx - movq %r11, 224(%rdi) - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[8] * B[22] - mulx 176(%rbp), %rax, %rcx - movq %r12, 232(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[8] * B[23] - mulx 184(%rbp), %rax, %rcx - movq %r8, 240(%rdi) - movq %r14, %r10 - adcxq %rax, %r9 - adoxq %rcx, %r10 - adcxq %r13, %r10 - movq %r14, %r13 - adoxq %r14, %r13 - adcxq %r14, %r13 - movq %r9, 248(%rdi) - movq %r10, 256(%rdi) + adcxq %r11, %r10 + movq %r12, %r11 + adoxq %r12, %r11 + adcxq %r12, %r11 + movq %r9, 152(%rdi) + movq %r10, 160(%rdi) movq 72(%rsi), %rdx - movq 72(%rsp), %r12 - movq 80(%rsp), %r8 - movq 88(%rsp), %r9 - movq 96(%rsp), %r10 - movq 104(%rsp), %r11 + movq 72(%rbx), %r8 + movq 80(%rbx), %r9 + movq 88(%rbx), %r10 # 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(%rsp) adcxq %rax, %r8 adoxq %rcx, %r9 - # A[9] * B[2] - mulx 16(%rbp), %rax, %rcx - movq %r8, 80(%rsp) + # A[9] * B[1] + mulx 8(%rbp), %rax, %rcx + movq %r8, 72(%rbx) adcxq %rax, %r9 adoxq %rcx, %r10 + movq %r9, 80(%rbx) + movq 96(%rdi), %r8 + movq 104(%rdi), %r9 + # A[9] * B[2] + mulx 16(%rbp), %rax, %rcx + adcxq %rax, %r10 + adoxq %rcx, %r8 # A[9] * B[3] mulx 24(%rbp), %rax, %rcx - movq %r9, 88(%rsp) - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r10, 96(%rsp) - movq 112(%rsp), %r12 - movq 120(%rsp), %r8 - movq 128(%rsp), %r9 - movq 136(%rsp), %r10 + movq %r10, 88(%rbx) + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r8, 96(%rdi) + movq 112(%rdi), %r10 + movq 120(%rdi), %r8 # A[9] * B[4] mulx 32(%rbp), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r12 + adcxq %rax, %r9 + adoxq %rcx, %r10 # A[9] * B[5] mulx 40(%rbp), %rax, %rcx - movq %r11, 104(%rsp) - adcxq %rax, %r12 + movq %r9, 104(%rdi) + adcxq %rax, %r10 adoxq %rcx, %r8 + movq %r10, 112(%rdi) + movq 128(%rdi), %r9 + movq 136(%rdi), %r10 # A[9] * B[6] mulx 48(%rbp), %rax, %rcx - movq %r12, 112(%rsp) adcxq %rax, %r8 adoxq %rcx, %r9 # A[9] * B[7] mulx 56(%rbp), %rax, %rcx - movq %r8, 120(%rsp) + movq %r8, 120(%rdi) adcxq %rax, %r9 adoxq %rcx, %r10 - movq %r9, 128(%rsp) - movq 144(%rsp), %r11 - movq 152(%rsp), %r12 - movq 160(%rsp), %r8 - movq 168(%rsp), %r9 + movq %r9, 128(%rdi) + movq 144(%rdi), %r8 + movq 152(%rdi), %r9 # A[9] * B[8] mulx 64(%rbp), %rax, %rcx adcxq %rax, %r10 - adoxq %rcx, %r11 + adoxq %rcx, %r8 # A[9] * B[9] mulx 72(%rbp), %rax, %rcx - movq %r10, 136(%rsp) - adcxq %rax, %r11 - adoxq %rcx, %r12 + movq %r10, 136(%rdi) + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r8, 144(%rdi) + movq 160(%rdi), %r10 # A[9] * B[10] mulx 80(%rbp), %rax, %rcx - movq %r11, 144(%rsp) - adcxq %rax, %r12 - adoxq %rcx, %r8 + adcxq %rax, %r9 + adoxq %rcx, %r10 # A[9] * B[11] mulx 88(%rbp), %rax, %rcx - movq %r12, 152(%rsp) - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r8, 160(%rsp) - movq %r15, %r10 - movq %rbx, %r11 - movq 192(%rdi), %r12 - movq 200(%rdi), %r8 - # 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(%rsp) + movq %r9, 152(%rdi) + movq %r12, %r8 adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[9] * B[14] - mulx 112(%rbp), %rax, %rcx - movq %r10, %r15 - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[9] * B[15] - mulx 120(%rbp), %rax, %rcx - movq %r11, %rbx - adcxq %rax, %r12 adoxq %rcx, %r8 - movq %r12, 192(%rdi) - movq 208(%rdi), %r9 - movq 216(%rdi), %r10 - movq 224(%rdi), %r11 - movq 232(%rdi), %r12 - # A[9] * B[16] - mulx 128(%rbp), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[9] * B[17] - mulx 136(%rbp), %rax, %rcx - movq %r8, 200(%rdi) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[9] * B[18] - mulx 144(%rbp), %rax, %rcx - movq %r9, 208(%rdi) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[9] * B[19] - mulx 152(%rbp), %rax, %rcx - movq %r10, 216(%rdi) - adcxq %rax, %r11 - adoxq %rcx, %r12 - movq %r11, 224(%rdi) - movq 240(%rdi), %r8 - movq 248(%rdi), %r9 - movq 256(%rdi), %r10 - # A[9] * B[20] - mulx 160(%rbp), %rax, %rcx - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[9] * B[21] - mulx 168(%rbp), %rax, %rcx - movq %r12, 232(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[9] * B[22] - mulx 176(%rbp), %rax, %rcx - movq %r8, 240(%rdi) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[9] * B[23] - mulx 184(%rbp), %rax, %rcx - movq %r9, 248(%rdi) - movq %r14, %r11 - adcxq %rax, %r10 - adoxq %rcx, %r11 - adcxq %r13, %r11 - movq %r14, %r13 - adoxq %r14, %r13 - adcxq %r14, %r13 - movq %r10, 256(%rdi) - movq %r11, 264(%rdi) + adcxq %r11, %r8 + movq %r12, %r11 + adoxq %r12, %r11 + adcxq %r12, %r11 + movq %r10, 160(%rdi) + movq %r8, 168(%rdi) movq 80(%rsi), %rdx - movq 80(%rsp), %r8 - movq 88(%rsp), %r9 - movq 96(%rsp), %r10 - movq 104(%rsp), %r11 - movq 112(%rsp), %r12 + movq 80(%rbx), %r9 + movq 88(%rbx), %r10 + movq 96(%rdi), %r8 # 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(%rsp) adcxq %rax, %r9 adoxq %rcx, %r10 + # A[10] * B[1] + mulx 8(%rbp), %rax, %rcx + movq %r9, 80(%rbx) + adcxq %rax, %r10 + adoxq %rcx, %r8 + movq %r10, 88(%rbx) + movq 104(%rdi), %r9 + movq 112(%rdi), %r10 # A[10] * B[2] mulx 16(%rbp), %rax, %rcx - movq %r9, 88(%rsp) - adcxq %rax, %r10 - adoxq %rcx, %r11 + adcxq %rax, %r8 + adoxq %rcx, %r9 # A[10] * B[3] mulx 24(%rbp), %rax, %rcx - movq %r10, 96(%rsp) - adcxq %rax, %r11 - adoxq %rcx, %r12 - movq %r11, 104(%rsp) - movq 120(%rsp), %r8 - movq 128(%rsp), %r9 - movq 136(%rsp), %r10 - movq 144(%rsp), %r11 + movq %r8, 96(%rdi) + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r9, 104(%rdi) + movq 120(%rdi), %r8 + movq 128(%rdi), %r9 # A[10] * B[4] mulx 32(%rbp), %rax, %rcx - adcxq %rax, %r12 + adcxq %rax, %r10 adoxq %rcx, %r8 # A[10] * B[5] mulx 40(%rbp), %rax, %rcx - movq %r12, 112(%rsp) + movq %r10, 112(%rdi) adcxq %rax, %r8 adoxq %rcx, %r9 + movq %r8, 120(%rdi) + movq 136(%rdi), %r10 + movq 144(%rdi), %r8 # A[10] * B[6] mulx 48(%rbp), %rax, %rcx - movq %r8, 120(%rsp) adcxq %rax, %r9 adoxq %rcx, %r10 # A[10] * B[7] mulx 56(%rbp), %rax, %rcx - movq %r9, 128(%rsp) + movq %r9, 128(%rdi) adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r10, 136(%rsp) - movq 152(%rsp), %r12 - movq 160(%rsp), %r8 - movq 168(%rsp), %r9 - movq %r15, %r10 + adoxq %rcx, %r8 + movq %r10, 136(%rdi) + movq 152(%rdi), %r9 + movq 160(%rdi), %r10 # A[10] * B[8] mulx 64(%rbp), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r12 + adcxq %rax, %r8 + adoxq %rcx, %r9 # A[10] * B[9] mulx 72(%rbp), %rax, %rcx - movq %r11, 144(%rsp) - adcxq %rax, %r12 - adoxq %rcx, %r8 + movq %r8, 144(%rdi) + adcxq %rax, %r9 + adoxq %rcx, %r10 + movq %r9, 152(%rdi) + movq 168(%rdi), %r8 # A[10] * B[10] mulx 80(%rbp), %rax, %rcx - movq %r12, 152(%rsp) - adcxq %rax, %r8 - adoxq %rcx, %r9 + adcxq %rax, %r10 + adoxq %rcx, %r8 # A[10] * B[11] mulx 88(%rbp), %rax, %rcx - movq %r8, 160(%rsp) - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r9, 168(%rsp) - movq %rbx, %r11 - movq 192(%rdi), %r12 - movq 200(%rdi), %r8 - movq 208(%rdi), %r9 - # 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, %r15 - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[10] * B[14] - mulx 112(%rbp), %rax, %rcx - movq %r11, %rbx - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[10] * B[15] - mulx 120(%rbp), %rax, %rcx - movq %r12, 192(%rdi) + movq %r10, 160(%rdi) + movq %r12, %r9 adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r8, 200(%rdi) - movq 216(%rdi), %r10 - movq 224(%rdi), %r11 - movq 232(%rdi), %r12 - movq 240(%rdi), %r8 - # A[10] * B[16] - mulx 128(%rbp), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[10] * B[17] - mulx 136(%rbp), %rax, %rcx - movq %r9, 208(%rdi) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[10] * B[18] - mulx 144(%rbp), %rax, %rcx - movq %r10, 216(%rdi) - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[10] * B[19] - mulx 152(%rbp), %rax, %rcx - movq %r11, 224(%rdi) - adcxq %rax, %r12 - adoxq %rcx, %r8 - movq %r12, 232(%rdi) - movq 248(%rdi), %r9 - movq 256(%rdi), %r10 - movq 264(%rdi), %r11 - # A[10] * B[20] - mulx 160(%rbp), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[10] * B[21] - mulx 168(%rbp), %rax, %rcx - movq %r8, 240(%rdi) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[10] * B[22] - mulx 176(%rbp), %rax, %rcx - movq %r9, 248(%rdi) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[10] * B[23] - mulx 184(%rbp), %rax, %rcx - movq %r10, 256(%rdi) - movq %r14, %r12 - adcxq %rax, %r11 - adoxq %rcx, %r12 - adcxq %r13, %r12 - movq %r14, %r13 - adoxq %r14, %r13 - adcxq %r14, %r13 - movq %r11, 264(%rdi) - movq %r12, 272(%rdi) + adcxq %r11, %r9 + movq %r12, %r11 + adoxq %r12, %r11 + adcxq %r12, %r11 + movq %r8, 168(%rdi) + movq %r9, 176(%rdi) movq 88(%rsi), %rdx - movq 88(%rsp), %r9 - movq 96(%rsp), %r10 - movq 104(%rsp), %r11 - movq 112(%rsp), %r12 - movq 120(%rsp), %r8 + movq 88(%rbx), %r10 + movq 96(%rdi), %r8 + movq 104(%rdi), %r9 # A[11] * B[0] mulx (%rbp), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 + adcxq %rax, %r10 + adoxq %rcx, %r8 # A[11] * B[1] mulx 8(%rbp), %rax, %rcx - movq %r9, 88(%rsp) - adcxq %rax, %r10 - adoxq %rcx, %r11 + movq %r10, 88(%rbx) + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r8, 96(%rdi) + movq 112(%rdi), %r10 + movq 120(%rdi), %r8 # A[11] * B[2] mulx 16(%rbp), %rax, %rcx - movq %r10, 96(%rsp) - adcxq %rax, %r11 - adoxq %rcx, %r12 + adcxq %rax, %r9 + adoxq %rcx, %r10 # A[11] * B[3] mulx 24(%rbp), %rax, %rcx - movq %r11, 104(%rsp) - adcxq %rax, %r12 + movq %r9, 104(%rdi) + adcxq %rax, %r10 adoxq %rcx, %r8 - movq %r12, 112(%rsp) - movq 128(%rsp), %r9 - movq 136(%rsp), %r10 - movq 144(%rsp), %r11 - movq 152(%rsp), %r12 + movq %r10, 112(%rdi) + movq 128(%rdi), %r9 + movq 136(%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(%rsp) + movq %r8, 120(%rdi) adcxq %rax, %r9 adoxq %rcx, %r10 + movq %r9, 128(%rdi) + movq 144(%rdi), %r8 + movq 152(%rdi), %r9 # A[11] * B[6] mulx 48(%rbp), %rax, %rcx - movq %r9, 128(%rsp) adcxq %rax, %r10 - adoxq %rcx, %r11 + adoxq %rcx, %r8 # A[11] * B[7] mulx 56(%rbp), %rax, %rcx - movq %r10, 136(%rsp) - adcxq %rax, %r11 - adoxq %rcx, %r12 - movq %r11, 144(%rsp) - movq 160(%rsp), %r8 - movq 168(%rsp), %r9 - movq %r15, %r10 - movq %rbx, %r11 + movq %r10, 136(%rdi) + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r8, 144(%rdi) + movq 160(%rdi), %r10 + movq 168(%rdi), %r8 # A[11] * B[8] mulx 64(%rbp), %rax, %rcx - adcxq %rax, %r12 - adoxq %rcx, %r8 + adcxq %rax, %r9 + adoxq %rcx, %r10 # A[11] * B[9] mulx 72(%rbp), %rax, %rcx - movq %r12, 152(%rsp) - adcxq %rax, %r8 - adoxq %rcx, %r9 + movq %r9, 152(%rdi) + adcxq %rax, %r10 + adoxq %rcx, %r8 + movq %r10, 160(%rdi) + movq 176(%rdi), %r9 # A[11] * B[10] mulx 80(%rbp), %rax, %rcx - movq %r8, 160(%rsp) - adcxq %rax, %r9 - adoxq %rcx, %r10 + adcxq %rax, %r8 + adoxq %rcx, %r9 # A[11] * B[11] mulx 88(%rbp), %rax, %rcx - movq %r9, 168(%rsp) - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r10, %r15 - movq 192(%rdi), %r12 - movq 200(%rdi), %r8 - movq 208(%rdi), %r9 - movq 216(%rdi), %r10 - # 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, %rbx - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[11] * B[14] - mulx 112(%rbp), %rax, %rcx - movq %r12, 192(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[11] * B[15] - mulx 120(%rbp), %rax, %rcx - movq %r8, 200(%rdi) + movq %r8, 168(%rdi) + movq %r12, %r10 adcxq %rax, %r9 adoxq %rcx, %r10 - movq %r9, 208(%rdi) - movq 224(%rdi), %r11 - movq 232(%rdi), %r12 - movq 240(%rdi), %r8 - movq 248(%rdi), %r9 - # A[11] * B[16] - mulx 128(%rbp), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[11] * B[17] - mulx 136(%rbp), %rax, %rcx - movq %r10, 216(%rdi) - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[11] * B[18] - mulx 144(%rbp), %rax, %rcx - movq %r11, 224(%rdi) - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[11] * B[19] - mulx 152(%rbp), %rax, %rcx - movq %r12, 232(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r8, 240(%rdi) - movq 256(%rdi), %r10 - movq 264(%rdi), %r11 - movq 272(%rdi), %r12 - # A[11] * B[20] - mulx 160(%rbp), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[11] * B[21] - mulx 168(%rbp), %rax, %rcx - movq %r9, 248(%rdi) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[11] * B[22] - mulx 176(%rbp), %rax, %rcx - movq %r10, 256(%rdi) - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[11] * B[23] - mulx 184(%rbp), %rax, %rcx - movq %r11, 264(%rdi) - movq %r14, %r8 - adcxq %rax, %r12 - adoxq %rcx, %r8 - adcxq %r13, %r8 - movq %r14, %r13 - adoxq %r14, %r13 - adcxq %r14, %r13 - movq %r12, 272(%rdi) - movq %r8, 280(%rdi) - movq 96(%rsi), %rdx - movq 96(%rsp), %r10 - movq 104(%rsp), %r11 - movq 112(%rsp), %r12 - movq 120(%rsp), %r8 - movq 128(%rsp), %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(%rsp) - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[12] * B[2] - mulx 16(%rbp), %rax, %rcx - movq %r11, 104(%rsp) - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[12] * B[3] - mulx 24(%rbp), %rax, %rcx - movq %r12, 112(%rsp) - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r8, 120(%rsp) - movq 136(%rsp), %r10 - movq 144(%rsp), %r11 - movq 152(%rsp), %r12 - movq 160(%rsp), %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(%rsp) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[12] * B[6] - mulx 48(%rbp), %rax, %rcx - movq %r10, 136(%rsp) - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[12] * B[7] - mulx 56(%rbp), %rax, %rcx - movq %r11, 144(%rsp) - adcxq %rax, %r12 - adoxq %rcx, %r8 - movq %r12, 152(%rsp) - movq 168(%rsp), %r9 - movq %r15, %r10 - movq %rbx, %r11 - movq 192(%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(%rsp) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[12] * B[10] - mulx 80(%rbp), %rax, %rcx - movq %r9, 168(%rsp) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[12] * B[11] - mulx 88(%rbp), %rax, %rcx - movq %r10, %r15 - adcxq %rax, %r11 - adoxq %rcx, %r12 - movq %r11, %rbx - movq 200(%rdi), %r8 - movq 208(%rdi), %r9 - movq 216(%rdi), %r10 - movq 224(%rdi), %r11 - # 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) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[12] * B[14] - mulx 112(%rbp), %rax, %rcx - movq %r8, 200(%rdi) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[12] * B[15] - mulx 120(%rbp), %rax, %rcx - movq %r9, 208(%rdi) - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r10, 216(%rdi) - movq 232(%rdi), %r12 - movq 240(%rdi), %r8 - movq 248(%rdi), %r9 - movq 256(%rdi), %r10 - # A[12] * B[16] - mulx 128(%rbp), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[12] * B[17] - mulx 136(%rbp), %rax, %rcx - movq %r11, 224(%rdi) - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[12] * B[18] - mulx 144(%rbp), %rax, %rcx - movq %r12, 232(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[12] * B[19] - mulx 152(%rbp), %rax, %rcx - movq %r8, 240(%rdi) - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r9, 248(%rdi) - movq 264(%rdi), %r11 - movq 272(%rdi), %r12 - movq 280(%rdi), %r8 - # A[12] * B[20] - mulx 160(%rbp), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[12] * B[21] - mulx 168(%rbp), %rax, %rcx - movq %r10, 256(%rdi) - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[12] * B[22] - mulx 176(%rbp), %rax, %rcx - movq %r11, 264(%rdi) - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[12] * B[23] - mulx 184(%rbp), %rax, %rcx - movq %r12, 272(%rdi) - movq %r14, %r9 - adcxq %rax, %r8 - adoxq %rcx, %r9 - adcxq %r13, %r9 - movq %r14, %r13 - adoxq %r14, %r13 - adcxq %r14, %r13 - movq %r8, 280(%rdi) - movq %r9, 288(%rdi) - movq 104(%rsi), %rdx - movq 104(%rsp), %r11 - movq 112(%rsp), %r12 - movq 120(%rsp), %r8 - movq 128(%rsp), %r9 - movq 136(%rsp), %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(%rsp) - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[13] * B[2] - mulx 16(%rbp), %rax, %rcx - movq %r12, 112(%rsp) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[13] * B[3] - mulx 24(%rbp), %rax, %rcx - movq %r8, 120(%rsp) - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r9, 128(%rsp) - movq 144(%rsp), %r11 - movq 152(%rsp), %r12 - movq 160(%rsp), %r8 - movq 168(%rsp), %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(%rsp) - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[13] * B[6] - mulx 48(%rbp), %rax, %rcx - movq %r11, 144(%rsp) - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[13] * B[7] - mulx 56(%rbp), %rax, %rcx - movq %r12, 152(%rsp) - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r8, 160(%rsp) - movq %r15, %r10 - movq %rbx, %r11 - movq 192(%rdi), %r12 - movq 200(%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(%rsp) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[13] * B[10] - mulx 80(%rbp), %rax, %rcx - movq %r10, %r15 - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[13] * B[11] - mulx 88(%rbp), %rax, %rcx - movq %r11, %rbx - adcxq %rax, %r12 - adoxq %rcx, %r8 - movq %r12, 192(%rdi) - movq 208(%rdi), %r9 - movq 216(%rdi), %r10 - movq 224(%rdi), %r11 - movq 232(%rdi), %r12 - # 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) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[13] * B[14] - mulx 112(%rbp), %rax, %rcx - movq %r9, 208(%rdi) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[13] * B[15] - mulx 120(%rbp), %rax, %rcx - movq %r10, 216(%rdi) - adcxq %rax, %r11 - adoxq %rcx, %r12 - movq %r11, 224(%rdi) - movq 240(%rdi), %r8 - movq 248(%rdi), %r9 - movq 256(%rdi), %r10 - movq 264(%rdi), %r11 - # A[13] * B[16] - mulx 128(%rbp), %rax, %rcx - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[13] * B[17] - mulx 136(%rbp), %rax, %rcx - movq %r12, 232(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[13] * B[18] - mulx 144(%rbp), %rax, %rcx - movq %r8, 240(%rdi) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[13] * B[19] - mulx 152(%rbp), %rax, %rcx - movq %r9, 248(%rdi) - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r10, 256(%rdi) - movq 272(%rdi), %r12 - movq 280(%rdi), %r8 - movq 288(%rdi), %r9 - # A[13] * B[20] - mulx 160(%rbp), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[13] * B[21] - mulx 168(%rbp), %rax, %rcx - movq %r11, 264(%rdi) - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[13] * B[22] - mulx 176(%rbp), %rax, %rcx - movq %r12, 272(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[13] * B[23] - mulx 184(%rbp), %rax, %rcx - movq %r8, 280(%rdi) - movq %r14, %r10 - adcxq %rax, %r9 - adoxq %rcx, %r10 - adcxq %r13, %r10 - movq %r14, %r13 - adoxq %r14, %r13 - adcxq %r14, %r13 - movq %r9, 288(%rdi) - movq %r10, 296(%rdi) - movq 112(%rsi), %rdx - movq 112(%rsp), %r12 - movq 120(%rsp), %r8 - movq 128(%rsp), %r9 - movq 136(%rsp), %r10 - movq 144(%rsp), %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(%rsp) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[14] * B[2] - mulx 16(%rbp), %rax, %rcx - movq %r8, 120(%rsp) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[14] * B[3] - mulx 24(%rbp), %rax, %rcx - movq %r9, 128(%rsp) - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r10, 136(%rsp) - movq 152(%rsp), %r12 - movq 160(%rsp), %r8 - movq 168(%rsp), %r9 - movq %r15, %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(%rsp) - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[14] * B[6] - mulx 48(%rbp), %rax, %rcx - movq %r12, 152(%rsp) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[14] * B[7] - mulx 56(%rbp), %rax, %rcx - movq %r8, 160(%rsp) - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r9, 168(%rsp) - movq %rbx, %r11 - movq 192(%rdi), %r12 - movq 200(%rdi), %r8 - movq 208(%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, %r15 - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[14] * B[10] - mulx 80(%rbp), %rax, %rcx - movq %r11, %rbx - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[14] * B[11] - mulx 88(%rbp), %rax, %rcx - movq %r12, 192(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r8, 200(%rdi) - movq 216(%rdi), %r10 - movq 224(%rdi), %r11 - movq 232(%rdi), %r12 - movq 240(%rdi), %r8 - # 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) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[14] * B[14] - mulx 112(%rbp), %rax, %rcx - movq %r10, 216(%rdi) - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[14] * B[15] - mulx 120(%rbp), %rax, %rcx - movq %r11, 224(%rdi) - adcxq %rax, %r12 - adoxq %rcx, %r8 - movq %r12, 232(%rdi) - movq 248(%rdi), %r9 - movq 256(%rdi), %r10 - movq 264(%rdi), %r11 - movq 272(%rdi), %r12 - # A[14] * B[16] - mulx 128(%rbp), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[14] * B[17] - mulx 136(%rbp), %rax, %rcx - movq %r8, 240(%rdi) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[14] * B[18] - mulx 144(%rbp), %rax, %rcx - movq %r9, 248(%rdi) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[14] * B[19] - mulx 152(%rbp), %rax, %rcx - movq %r10, 256(%rdi) - adcxq %rax, %r11 - adoxq %rcx, %r12 - movq %r11, 264(%rdi) - movq 280(%rdi), %r8 - movq 288(%rdi), %r9 - movq 296(%rdi), %r10 - # A[14] * B[20] - mulx 160(%rbp), %rax, %rcx - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[14] * B[21] - mulx 168(%rbp), %rax, %rcx - movq %r12, 272(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[14] * B[22] - mulx 176(%rbp), %rax, %rcx - movq %r8, 280(%rdi) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[14] * B[23] - mulx 184(%rbp), %rax, %rcx - movq %r9, 288(%rdi) - movq %r14, %r11 - adcxq %rax, %r10 - adoxq %rcx, %r11 - adcxq %r13, %r11 - movq %r14, %r13 - adoxq %r14, %r13 - adcxq %r14, %r13 - movq %r10, 296(%rdi) - movq %r11, 304(%rdi) - movq 120(%rsi), %rdx - movq 120(%rsp), %r8 - movq 128(%rsp), %r9 - movq 136(%rsp), %r10 - movq 144(%rsp), %r11 - movq 152(%rsp), %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(%rsp) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[15] * B[2] - mulx 16(%rbp), %rax, %rcx - movq %r9, 128(%rsp) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[15] * B[3] - mulx 24(%rbp), %rax, %rcx - movq %r10, 136(%rsp) - adcxq %rax, %r11 - adoxq %rcx, %r12 - movq %r11, 144(%rsp) - movq 160(%rsp), %r8 - movq 168(%rsp), %r9 - movq %r15, %r10 - movq %rbx, %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(%rsp) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[15] * B[6] - mulx 48(%rbp), %rax, %rcx - movq %r8, 160(%rsp) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[15] * B[7] - mulx 56(%rbp), %rax, %rcx - movq %r9, 168(%rsp) - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r10, %r15 - movq 192(%rdi), %r12 - movq 200(%rdi), %r8 - movq 208(%rdi), %r9 - movq 216(%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, %rbx - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[15] * B[10] - mulx 80(%rbp), %rax, %rcx - movq %r12, 192(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[15] * B[11] - mulx 88(%rbp), %rax, %rcx - movq %r8, 200(%rdi) - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r9, 208(%rdi) - movq 224(%rdi), %r11 - movq 232(%rdi), %r12 - movq 240(%rdi), %r8 - movq 248(%rdi), %r9 - # 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) - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[15] * B[14] - mulx 112(%rbp), %rax, %rcx - movq %r11, 224(%rdi) - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[15] * B[15] - mulx 120(%rbp), %rax, %rcx - movq %r12, 232(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r8, 240(%rdi) - movq 256(%rdi), %r10 - movq 264(%rdi), %r11 - movq 272(%rdi), %r12 - movq 280(%rdi), %r8 - # A[15] * B[16] - mulx 128(%rbp), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[15] * B[17] - mulx 136(%rbp), %rax, %rcx - movq %r9, 248(%rdi) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[15] * B[18] - mulx 144(%rbp), %rax, %rcx - movq %r10, 256(%rdi) - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[15] * B[19] - mulx 152(%rbp), %rax, %rcx - movq %r11, 264(%rdi) - adcxq %rax, %r12 - adoxq %rcx, %r8 - movq %r12, 272(%rdi) - movq 288(%rdi), %r9 - movq 296(%rdi), %r10 - movq 304(%rdi), %r11 - # A[15] * B[20] - mulx 160(%rbp), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[15] * B[21] - mulx 168(%rbp), %rax, %rcx - movq %r8, 280(%rdi) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[15] * B[22] - mulx 176(%rbp), %rax, %rcx - movq %r9, 288(%rdi) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[15] * B[23] - mulx 184(%rbp), %rax, %rcx - movq %r10, 296(%rdi) - movq %r14, %r12 - adcxq %rax, %r11 - adoxq %rcx, %r12 - adcxq %r13, %r12 - movq %r14, %r13 - adoxq %r14, %r13 - adcxq %r14, %r13 - movq %r11, 304(%rdi) - movq %r12, 312(%rdi) - movq 128(%rsi), %rdx - movq 128(%rsp), %r9 - movq 136(%rsp), %r10 - movq 144(%rsp), %r11 - movq 152(%rsp), %r12 - movq 160(%rsp), %r8 - # A[16] * B[0] - mulx (%rbp), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[16] * B[1] - mulx 8(%rbp), %rax, %rcx - movq %r9, 128(%rsp) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[16] * B[2] - mulx 16(%rbp), %rax, %rcx - movq %r10, 136(%rsp) - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[16] * B[3] - mulx 24(%rbp), %rax, %rcx - movq %r11, 144(%rsp) - adcxq %rax, %r12 - adoxq %rcx, %r8 - movq %r12, 152(%rsp) - movq 168(%rsp), %r9 - movq %r15, %r10 - movq %rbx, %r11 - movq 192(%rdi), %r12 - # A[16] * B[4] - mulx 32(%rbp), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[16] * B[5] - mulx 40(%rbp), %rax, %rcx - movq %r8, 160(%rsp) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[16] * B[6] - mulx 48(%rbp), %rax, %rcx - movq %r9, 168(%rsp) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[16] * B[7] - mulx 56(%rbp), %rax, %rcx - movq %r10, %r15 - adcxq %rax, %r11 - adoxq %rcx, %r12 - movq %r11, %rbx - movq 200(%rdi), %r8 - movq 208(%rdi), %r9 - movq 216(%rdi), %r10 - movq 224(%rdi), %r11 - # A[16] * B[8] - mulx 64(%rbp), %rax, %rcx - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[16] * B[9] - mulx 72(%rbp), %rax, %rcx - movq %r12, 192(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[16] * B[10] - mulx 80(%rbp), %rax, %rcx - movq %r8, 200(%rdi) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[16] * B[11] - mulx 88(%rbp), %rax, %rcx - movq %r9, 208(%rdi) - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r10, 216(%rdi) - movq 232(%rdi), %r12 - movq 240(%rdi), %r8 - movq 248(%rdi), %r9 - movq 256(%rdi), %r10 - # A[16] * B[12] - mulx 96(%rbp), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[16] * B[13] - mulx 104(%rbp), %rax, %rcx - movq %r11, 224(%rdi) - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[16] * B[14] - mulx 112(%rbp), %rax, %rcx - movq %r12, 232(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[16] * B[15] - mulx 120(%rbp), %rax, %rcx - movq %r8, 240(%rdi) - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r9, 248(%rdi) - movq 264(%rdi), %r11 - movq 272(%rdi), %r12 - movq 280(%rdi), %r8 - movq 288(%rdi), %r9 - # A[16] * B[16] - mulx 128(%rbp), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[16] * B[17] - mulx 136(%rbp), %rax, %rcx - movq %r10, 256(%rdi) - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[16] * B[18] - mulx 144(%rbp), %rax, %rcx - movq %r11, 264(%rdi) - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[16] * B[19] - mulx 152(%rbp), %rax, %rcx - movq %r12, 272(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r8, 280(%rdi) - movq 296(%rdi), %r10 - movq 304(%rdi), %r11 - movq 312(%rdi), %r12 - # A[16] * B[20] - mulx 160(%rbp), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[16] * B[21] - mulx 168(%rbp), %rax, %rcx - movq %r9, 288(%rdi) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[16] * B[22] - mulx 176(%rbp), %rax, %rcx - movq %r10, 296(%rdi) - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[16] * B[23] - mulx 184(%rbp), %rax, %rcx - movq %r11, 304(%rdi) - movq %r14, %r8 - adcxq %rax, %r12 - adoxq %rcx, %r8 - adcxq %r13, %r8 - movq %r14, %r13 - adoxq %r14, %r13 - adcxq %r14, %r13 - movq %r12, 312(%rdi) - movq %r8, 320(%rdi) - movq 136(%rsi), %rdx - movq 136(%rsp), %r10 - movq 144(%rsp), %r11 - movq 152(%rsp), %r12 - movq 160(%rsp), %r8 - movq 168(%rsp), %r9 - # A[17] * B[0] - mulx (%rbp), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[17] * B[1] - mulx 8(%rbp), %rax, %rcx - movq %r10, 136(%rsp) - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[17] * B[2] - mulx 16(%rbp), %rax, %rcx - movq %r11, 144(%rsp) - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[17] * B[3] - mulx 24(%rbp), %rax, %rcx - movq %r12, 152(%rsp) - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r8, 160(%rsp) - movq %r15, %r10 - movq %rbx, %r11 - movq 192(%rdi), %r12 - movq 200(%rdi), %r8 - # A[17] * B[4] - mulx 32(%rbp), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[17] * B[5] - mulx 40(%rbp), %rax, %rcx - movq %r9, 168(%rsp) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[17] * B[6] - mulx 48(%rbp), %rax, %rcx - movq %r10, %r15 - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[17] * B[7] - mulx 56(%rbp), %rax, %rcx - movq %r11, %rbx - adcxq %rax, %r12 - adoxq %rcx, %r8 - movq %r12, 192(%rdi) - movq 208(%rdi), %r9 - movq 216(%rdi), %r10 - movq 224(%rdi), %r11 - movq 232(%rdi), %r12 - # A[17] * B[8] - mulx 64(%rbp), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[17] * B[9] - mulx 72(%rbp), %rax, %rcx - movq %r8, 200(%rdi) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[17] * B[10] - mulx 80(%rbp), %rax, %rcx - movq %r9, 208(%rdi) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[17] * B[11] - mulx 88(%rbp), %rax, %rcx - movq %r10, 216(%rdi) - adcxq %rax, %r11 - adoxq %rcx, %r12 - movq %r11, 224(%rdi) - movq 240(%rdi), %r8 - movq 248(%rdi), %r9 - movq 256(%rdi), %r10 - movq 264(%rdi), %r11 - # A[17] * B[12] - mulx 96(%rbp), %rax, %rcx - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[17] * B[13] - mulx 104(%rbp), %rax, %rcx - movq %r12, 232(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[17] * B[14] - mulx 112(%rbp), %rax, %rcx - movq %r8, 240(%rdi) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[17] * B[15] - mulx 120(%rbp), %rax, %rcx - movq %r9, 248(%rdi) - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r10, 256(%rdi) - movq 272(%rdi), %r12 - movq 280(%rdi), %r8 - movq 288(%rdi), %r9 - movq 296(%rdi), %r10 - # A[17] * B[16] - mulx 128(%rbp), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[17] * B[17] - mulx 136(%rbp), %rax, %rcx - movq %r11, 264(%rdi) - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[17] * B[18] - mulx 144(%rbp), %rax, %rcx - movq %r12, 272(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[17] * B[19] - mulx 152(%rbp), %rax, %rcx - movq %r8, 280(%rdi) - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r9, 288(%rdi) - movq 304(%rdi), %r11 - movq 312(%rdi), %r12 - movq 320(%rdi), %r8 - # A[17] * B[20] - mulx 160(%rbp), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[17] * B[21] - mulx 168(%rbp), %rax, %rcx - movq %r10, 296(%rdi) - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[17] * B[22] - mulx 176(%rbp), %rax, %rcx - movq %r11, 304(%rdi) - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[17] * B[23] - mulx 184(%rbp), %rax, %rcx - movq %r12, 312(%rdi) - movq %r14, %r9 - adcxq %rax, %r8 - adoxq %rcx, %r9 - adcxq %r13, %r9 - movq %r14, %r13 - adoxq %r14, %r13 - adcxq %r14, %r13 - movq %r8, 320(%rdi) - movq %r9, 328(%rdi) - movq 144(%rsi), %rdx - movq 144(%rsp), %r11 - movq 152(%rsp), %r12 - movq 160(%rsp), %r8 - movq 168(%rsp), %r9 - movq %r15, %r10 - # A[18] * B[0] - mulx (%rbp), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[18] * B[1] - mulx 8(%rbp), %rax, %rcx - movq %r11, 144(%rsp) - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[18] * B[2] - mulx 16(%rbp), %rax, %rcx - movq %r12, 152(%rsp) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[18] * B[3] - mulx 24(%rbp), %rax, %rcx - movq %r8, 160(%rsp) - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r9, 168(%rsp) - movq %rbx, %r11 - movq 192(%rdi), %r12 - movq 200(%rdi), %r8 - movq 208(%rdi), %r9 - # A[18] * B[4] - mulx 32(%rbp), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[18] * B[5] - mulx 40(%rbp), %rax, %rcx - movq %r10, %r15 - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[18] * B[6] - mulx 48(%rbp), %rax, %rcx - movq %r11, %rbx - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[18] * B[7] - mulx 56(%rbp), %rax, %rcx - movq %r12, 192(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r8, 200(%rdi) - movq 216(%rdi), %r10 - movq 224(%rdi), %r11 - movq 232(%rdi), %r12 - movq 240(%rdi), %r8 - # A[18] * B[8] - mulx 64(%rbp), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[18] * B[9] - mulx 72(%rbp), %rax, %rcx - movq %r9, 208(%rdi) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[18] * B[10] - mulx 80(%rbp), %rax, %rcx - movq %r10, 216(%rdi) - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[18] * B[11] - mulx 88(%rbp), %rax, %rcx - movq %r11, 224(%rdi) - adcxq %rax, %r12 - adoxq %rcx, %r8 - movq %r12, 232(%rdi) - movq 248(%rdi), %r9 - movq 256(%rdi), %r10 - movq 264(%rdi), %r11 - movq 272(%rdi), %r12 - # A[18] * B[12] - mulx 96(%rbp), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[18] * B[13] - mulx 104(%rbp), %rax, %rcx - movq %r8, 240(%rdi) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[18] * B[14] - mulx 112(%rbp), %rax, %rcx - movq %r9, 248(%rdi) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[18] * B[15] - mulx 120(%rbp), %rax, %rcx - movq %r10, 256(%rdi) - adcxq %rax, %r11 - adoxq %rcx, %r12 - movq %r11, 264(%rdi) - movq 280(%rdi), %r8 - movq 288(%rdi), %r9 - movq 296(%rdi), %r10 - movq 304(%rdi), %r11 - # A[18] * B[16] - mulx 128(%rbp), %rax, %rcx - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[18] * B[17] - mulx 136(%rbp), %rax, %rcx - movq %r12, 272(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[18] * B[18] - mulx 144(%rbp), %rax, %rcx - movq %r8, 280(%rdi) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[18] * B[19] - mulx 152(%rbp), %rax, %rcx - movq %r9, 288(%rdi) - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r10, 296(%rdi) - movq 312(%rdi), %r12 - movq 320(%rdi), %r8 - movq 328(%rdi), %r9 - # A[18] * B[20] - mulx 160(%rbp), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[18] * B[21] - mulx 168(%rbp), %rax, %rcx - movq %r11, 304(%rdi) - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[18] * B[22] - mulx 176(%rbp), %rax, %rcx - movq %r12, 312(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[18] * B[23] - mulx 184(%rbp), %rax, %rcx - movq %r8, 320(%rdi) - movq %r14, %r10 - adcxq %rax, %r9 - adoxq %rcx, %r10 - adcxq %r13, %r10 - movq %r14, %r13 - adoxq %r14, %r13 - adcxq %r14, %r13 - movq %r9, 328(%rdi) - movq %r10, 336(%rdi) - movq 152(%rsi), %rdx - movq 152(%rsp), %r12 - movq 160(%rsp), %r8 - movq 168(%rsp), %r9 - movq %r15, %r10 - movq %rbx, %r11 - # A[19] * B[0] - mulx (%rbp), %rax, %rcx - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[19] * B[1] - mulx 8(%rbp), %rax, %rcx - movq %r12, 152(%rsp) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[19] * B[2] - mulx 16(%rbp), %rax, %rcx - movq %r8, 160(%rsp) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[19] * B[3] - mulx 24(%rbp), %rax, %rcx - movq %r9, 168(%rsp) - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r10, %r15 - movq 192(%rdi), %r12 - movq 200(%rdi), %r8 - movq 208(%rdi), %r9 - movq 216(%rdi), %r10 - # A[19] * B[4] - mulx 32(%rbp), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[19] * B[5] - mulx 40(%rbp), %rax, %rcx - movq %r11, %rbx - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[19] * B[6] - mulx 48(%rbp), %rax, %rcx - movq %r12, 192(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[19] * B[7] - mulx 56(%rbp), %rax, %rcx - movq %r8, 200(%rdi) - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r9, 208(%rdi) - movq 224(%rdi), %r11 - movq 232(%rdi), %r12 - movq 240(%rdi), %r8 - movq 248(%rdi), %r9 - # A[19] * B[8] - mulx 64(%rbp), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[19] * B[9] - mulx 72(%rbp), %rax, %rcx - movq %r10, 216(%rdi) - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[19] * B[10] - mulx 80(%rbp), %rax, %rcx - movq %r11, 224(%rdi) - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[19] * B[11] - mulx 88(%rbp), %rax, %rcx - movq %r12, 232(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r8, 240(%rdi) - movq 256(%rdi), %r10 - movq 264(%rdi), %r11 - movq 272(%rdi), %r12 - movq 280(%rdi), %r8 - # A[19] * B[12] - mulx 96(%rbp), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[19] * B[13] - mulx 104(%rbp), %rax, %rcx - movq %r9, 248(%rdi) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[19] * B[14] - mulx 112(%rbp), %rax, %rcx - movq %r10, 256(%rdi) - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[19] * B[15] - mulx 120(%rbp), %rax, %rcx - movq %r11, 264(%rdi) - adcxq %rax, %r12 - adoxq %rcx, %r8 - movq %r12, 272(%rdi) - movq 288(%rdi), %r9 - movq 296(%rdi), %r10 - movq 304(%rdi), %r11 - movq 312(%rdi), %r12 - # A[19] * B[16] - mulx 128(%rbp), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[19] * B[17] - mulx 136(%rbp), %rax, %rcx - movq %r8, 280(%rdi) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[19] * B[18] - mulx 144(%rbp), %rax, %rcx - movq %r9, 288(%rdi) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[19] * B[19] - mulx 152(%rbp), %rax, %rcx - movq %r10, 296(%rdi) - adcxq %rax, %r11 - adoxq %rcx, %r12 - movq %r11, 304(%rdi) - movq 320(%rdi), %r8 - movq 328(%rdi), %r9 - movq 336(%rdi), %r10 - # A[19] * B[20] - mulx 160(%rbp), %rax, %rcx - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[19] * B[21] - mulx 168(%rbp), %rax, %rcx - movq %r12, 312(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[19] * B[22] - mulx 176(%rbp), %rax, %rcx - movq %r8, 320(%rdi) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[19] * B[23] - mulx 184(%rbp), %rax, %rcx - movq %r9, 328(%rdi) - movq %r14, %r11 - adcxq %rax, %r10 - adoxq %rcx, %r11 - adcxq %r13, %r11 - movq %r14, %r13 - adoxq %r14, %r13 - adcxq %r14, %r13 - movq %r10, 336(%rdi) - movq %r11, 344(%rdi) - movq 160(%rsi), %rdx - movq 160(%rsp), %r8 - movq 168(%rsp), %r9 - movq %r15, %r10 - movq %rbx, %r11 - movq 192(%rdi), %r12 - # A[20] * B[0] - mulx (%rbp), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[20] * B[1] - mulx 8(%rbp), %rax, %rcx - movq %r8, 160(%rsp) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[20] * B[2] - mulx 16(%rbp), %rax, %rcx - movq %r9, 168(%rsp) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[20] * B[3] - mulx 24(%rbp), %rax, %rcx - movq %r10, %r15 - adcxq %rax, %r11 - adoxq %rcx, %r12 - movq %r11, %rbx - movq 200(%rdi), %r8 - movq 208(%rdi), %r9 - movq 216(%rdi), %r10 - movq 224(%rdi), %r11 - # A[20] * B[4] - mulx 32(%rbp), %rax, %rcx - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[20] * B[5] - mulx 40(%rbp), %rax, %rcx - movq %r12, 192(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[20] * B[6] - mulx 48(%rbp), %rax, %rcx - movq %r8, 200(%rdi) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[20] * B[7] - mulx 56(%rbp), %rax, %rcx - movq %r9, 208(%rdi) - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r10, 216(%rdi) - movq 232(%rdi), %r12 - movq 240(%rdi), %r8 - movq 248(%rdi), %r9 - movq 256(%rdi), %r10 - # A[20] * B[8] - mulx 64(%rbp), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[20] * B[9] - mulx 72(%rbp), %rax, %rcx - movq %r11, 224(%rdi) - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[20] * B[10] - mulx 80(%rbp), %rax, %rcx - movq %r12, 232(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[20] * B[11] - mulx 88(%rbp), %rax, %rcx - movq %r8, 240(%rdi) - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r9, 248(%rdi) - movq 264(%rdi), %r11 - movq 272(%rdi), %r12 - movq 280(%rdi), %r8 - movq 288(%rdi), %r9 - # A[20] * B[12] - mulx 96(%rbp), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[20] * B[13] - mulx 104(%rbp), %rax, %rcx - movq %r10, 256(%rdi) - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[20] * B[14] - mulx 112(%rbp), %rax, %rcx - movq %r11, 264(%rdi) - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[20] * B[15] - mulx 120(%rbp), %rax, %rcx - movq %r12, 272(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r8, 280(%rdi) - movq 296(%rdi), %r10 - movq 304(%rdi), %r11 - movq 312(%rdi), %r12 - movq 320(%rdi), %r8 - # A[20] * B[16] - mulx 128(%rbp), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[20] * B[17] - mulx 136(%rbp), %rax, %rcx - movq %r9, 288(%rdi) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[20] * B[18] - mulx 144(%rbp), %rax, %rcx - movq %r10, 296(%rdi) - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[20] * B[19] - mulx 152(%rbp), %rax, %rcx - movq %r11, 304(%rdi) - adcxq %rax, %r12 - adoxq %rcx, %r8 - movq %r12, 312(%rdi) - movq 328(%rdi), %r9 - movq 336(%rdi), %r10 - movq 344(%rdi), %r11 - # A[20] * B[20] - mulx 160(%rbp), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[20] * B[21] - mulx 168(%rbp), %rax, %rcx - movq %r8, 320(%rdi) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[20] * B[22] - mulx 176(%rbp), %rax, %rcx - movq %r9, 328(%rdi) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[20] * B[23] - mulx 184(%rbp), %rax, %rcx - movq %r10, 336(%rdi) - movq %r14, %r12 - adcxq %rax, %r11 - adoxq %rcx, %r12 - adcxq %r13, %r12 - movq %r14, %r13 - adoxq %r14, %r13 - adcxq %r14, %r13 - movq %r11, 344(%rdi) - movq %r12, 352(%rdi) - movq 168(%rsi), %rdx - movq 168(%rsp), %r9 - movq %r15, %r10 - movq %rbx, %r11 - movq 192(%rdi), %r12 - movq 200(%rdi), %r8 - # A[21] * B[0] - mulx (%rbp), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[21] * B[1] - mulx 8(%rbp), %rax, %rcx - movq %r9, 168(%rsp) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[21] * B[2] - mulx 16(%rbp), %rax, %rcx - movq %r10, %r15 - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[21] * B[3] - mulx 24(%rbp), %rax, %rcx - movq %r11, %rbx - adcxq %rax, %r12 - adoxq %rcx, %r8 - movq %r12, 192(%rdi) - movq 208(%rdi), %r9 - movq 216(%rdi), %r10 - movq 224(%rdi), %r11 - movq 232(%rdi), %r12 - # A[21] * B[4] - mulx 32(%rbp), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[21] * B[5] - mulx 40(%rbp), %rax, %rcx - movq %r8, 200(%rdi) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[21] * B[6] - mulx 48(%rbp), %rax, %rcx - movq %r9, 208(%rdi) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[21] * B[7] - mulx 56(%rbp), %rax, %rcx - movq %r10, 216(%rdi) - adcxq %rax, %r11 - adoxq %rcx, %r12 - movq %r11, 224(%rdi) - movq 240(%rdi), %r8 - movq 248(%rdi), %r9 - movq 256(%rdi), %r10 - movq 264(%rdi), %r11 - # A[21] * B[8] - mulx 64(%rbp), %rax, %rcx - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[21] * B[9] - mulx 72(%rbp), %rax, %rcx - movq %r12, 232(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[21] * B[10] - mulx 80(%rbp), %rax, %rcx - movq %r8, 240(%rdi) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[21] * B[11] - mulx 88(%rbp), %rax, %rcx - movq %r9, 248(%rdi) - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r10, 256(%rdi) - movq 272(%rdi), %r12 - movq 280(%rdi), %r8 - movq 288(%rdi), %r9 - movq 296(%rdi), %r10 - # A[21] * B[12] - mulx 96(%rbp), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[21] * B[13] - mulx 104(%rbp), %rax, %rcx - movq %r11, 264(%rdi) - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[21] * B[14] - mulx 112(%rbp), %rax, %rcx - movq %r12, 272(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[21] * B[15] - mulx 120(%rbp), %rax, %rcx - movq %r8, 280(%rdi) - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r9, 288(%rdi) - movq 304(%rdi), %r11 - movq 312(%rdi), %r12 - movq 320(%rdi), %r8 - movq 328(%rdi), %r9 - # A[21] * B[16] - mulx 128(%rbp), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[21] * B[17] - mulx 136(%rbp), %rax, %rcx - movq %r10, 296(%rdi) - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[21] * B[18] - mulx 144(%rbp), %rax, %rcx - movq %r11, 304(%rdi) - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[21] * B[19] - mulx 152(%rbp), %rax, %rcx - movq %r12, 312(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r8, 320(%rdi) - movq 336(%rdi), %r10 - movq 344(%rdi), %r11 - movq 352(%rdi), %r12 - # A[21] * B[20] - mulx 160(%rbp), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[21] * B[21] - mulx 168(%rbp), %rax, %rcx - movq %r9, 328(%rdi) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[21] * B[22] - mulx 176(%rbp), %rax, %rcx - movq %r10, 336(%rdi) - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[21] * B[23] - mulx 184(%rbp), %rax, %rcx - movq %r11, 344(%rdi) - movq %r14, %r8 - adcxq %rax, %r12 - adoxq %rcx, %r8 - adcxq %r13, %r8 - movq %r14, %r13 - adoxq %r14, %r13 - adcxq %r14, %r13 - movq %r12, 352(%rdi) - movq %r8, 360(%rdi) - movq 176(%rsi), %rdx - movq %r15, %r10 - movq %rbx, %r11 - movq 192(%rdi), %r12 - movq 200(%rdi), %r8 - movq 208(%rdi), %r9 - # A[22] * B[0] - mulx (%rbp), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[22] * B[1] - mulx 8(%rbp), %rax, %rcx - movq %r10, %r15 - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[22] * B[2] - mulx 16(%rbp), %rax, %rcx - movq %r11, %rbx - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[22] * B[3] - mulx 24(%rbp), %rax, %rcx - movq %r12, 192(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r8, 200(%rdi) - movq 216(%rdi), %r10 - movq 224(%rdi), %r11 - movq 232(%rdi), %r12 - movq 240(%rdi), %r8 - # A[22] * B[4] - mulx 32(%rbp), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[22] * B[5] - mulx 40(%rbp), %rax, %rcx - movq %r9, 208(%rdi) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[22] * B[6] - mulx 48(%rbp), %rax, %rcx - movq %r10, 216(%rdi) - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[22] * B[7] - mulx 56(%rbp), %rax, %rcx - movq %r11, 224(%rdi) - adcxq %rax, %r12 - adoxq %rcx, %r8 - movq %r12, 232(%rdi) - movq 248(%rdi), %r9 - movq 256(%rdi), %r10 - movq 264(%rdi), %r11 - movq 272(%rdi), %r12 - # A[22] * B[8] - mulx 64(%rbp), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[22] * B[9] - mulx 72(%rbp), %rax, %rcx - movq %r8, 240(%rdi) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[22] * B[10] - mulx 80(%rbp), %rax, %rcx - movq %r9, 248(%rdi) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[22] * B[11] - mulx 88(%rbp), %rax, %rcx - movq %r10, 256(%rdi) - adcxq %rax, %r11 - adoxq %rcx, %r12 - movq %r11, 264(%rdi) - movq 280(%rdi), %r8 - movq 288(%rdi), %r9 - movq 296(%rdi), %r10 - movq 304(%rdi), %r11 - # A[22] * B[12] - mulx 96(%rbp), %rax, %rcx - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[22] * B[13] - mulx 104(%rbp), %rax, %rcx - movq %r12, 272(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[22] * B[14] - mulx 112(%rbp), %rax, %rcx - movq %r8, 280(%rdi) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[22] * B[15] - mulx 120(%rbp), %rax, %rcx - movq %r9, 288(%rdi) - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r10, 296(%rdi) - movq 312(%rdi), %r12 - movq 320(%rdi), %r8 - movq 328(%rdi), %r9 - movq 336(%rdi), %r10 - # A[22] * B[16] - mulx 128(%rbp), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[22] * B[17] - mulx 136(%rbp), %rax, %rcx - movq %r11, 304(%rdi) - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[22] * B[18] - mulx 144(%rbp), %rax, %rcx - movq %r12, 312(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[22] * B[19] - mulx 152(%rbp), %rax, %rcx - movq %r8, 320(%rdi) - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r9, 328(%rdi) - movq 344(%rdi), %r11 - movq 352(%rdi), %r12 - movq 360(%rdi), %r8 - # A[22] * B[20] - mulx 160(%rbp), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[22] * B[21] - mulx 168(%rbp), %rax, %rcx - movq %r10, 336(%rdi) - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[22] * B[22] - mulx 176(%rbp), %rax, %rcx - movq %r11, 344(%rdi) - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[22] * B[23] - mulx 184(%rbp), %rax, %rcx - movq %r12, 352(%rdi) - movq %r14, %r9 - adcxq %rax, %r8 - adoxq %rcx, %r9 - adcxq %r13, %r9 - movq %r14, %r13 - adoxq %r14, %r13 - adcxq %r14, %r13 - movq %r8, 360(%rdi) - movq %r9, 368(%rdi) - movq 184(%rsi), %rdx - movq %rbx, %r11 - movq 192(%rdi), %r12 - movq 200(%rdi), %r8 - movq 208(%rdi), %r9 - movq 216(%rdi), %r10 - # A[23] * B[0] - mulx (%rbp), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[23] * B[1] - mulx 8(%rbp), %rax, %rcx - movq %r11, %rbx - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[23] * B[2] - mulx 16(%rbp), %rax, %rcx - movq %r12, 192(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[23] * B[3] - mulx 24(%rbp), %rax, %rcx - movq %r8, 200(%rdi) - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r9, 208(%rdi) - movq 224(%rdi), %r11 - movq 232(%rdi), %r12 - movq 240(%rdi), %r8 - movq 248(%rdi), %r9 - # A[23] * B[4] - mulx 32(%rbp), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[23] * B[5] - mulx 40(%rbp), %rax, %rcx - movq %r10, 216(%rdi) - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[23] * B[6] - mulx 48(%rbp), %rax, %rcx - movq %r11, 224(%rdi) - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[23] * B[7] - mulx 56(%rbp), %rax, %rcx - movq %r12, 232(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r8, 240(%rdi) - movq 256(%rdi), %r10 - movq 264(%rdi), %r11 - movq 272(%rdi), %r12 - movq 280(%rdi), %r8 - # A[23] * B[8] - mulx 64(%rbp), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[23] * B[9] - mulx 72(%rbp), %rax, %rcx - movq %r9, 248(%rdi) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[23] * B[10] - mulx 80(%rbp), %rax, %rcx - movq %r10, 256(%rdi) - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[23] * B[11] - mulx 88(%rbp), %rax, %rcx - movq %r11, 264(%rdi) - adcxq %rax, %r12 - adoxq %rcx, %r8 - movq %r12, 272(%rdi) - movq 288(%rdi), %r9 - movq 296(%rdi), %r10 - movq 304(%rdi), %r11 - movq 312(%rdi), %r12 - # A[23] * B[12] - mulx 96(%rbp), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[23] * B[13] - mulx 104(%rbp), %rax, %rcx - movq %r8, 280(%rdi) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[23] * B[14] - mulx 112(%rbp), %rax, %rcx - movq %r9, 288(%rdi) - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[23] * B[15] - mulx 120(%rbp), %rax, %rcx - movq %r10, 296(%rdi) - adcxq %rax, %r11 - adoxq %rcx, %r12 - movq %r11, 304(%rdi) - movq 320(%rdi), %r8 - movq 328(%rdi), %r9 - movq 336(%rdi), %r10 - movq 344(%rdi), %r11 - # A[23] * B[16] - mulx 128(%rbp), %rax, %rcx - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[23] * B[17] - mulx 136(%rbp), %rax, %rcx - movq %r12, 312(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[23] * B[18] - mulx 144(%rbp), %rax, %rcx - movq %r8, 320(%rdi) - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[23] * B[19] - mulx 152(%rbp), %rax, %rcx - movq %r9, 328(%rdi) - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r10, 336(%rdi) - movq 352(%rdi), %r12 - movq 360(%rdi), %r8 - movq 368(%rdi), %r9 - # A[23] * B[20] - mulx 160(%rbp), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r12 - # A[23] * B[21] - mulx 168(%rbp), %rax, %rcx - movq %r11, 344(%rdi) - adcxq %rax, %r12 - adoxq %rcx, %r8 - # A[23] * B[22] - mulx 176(%rbp), %rax, %rcx - movq %r12, 352(%rdi) - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[23] * B[23] - mulx 184(%rbp), %rax, %rcx - movq %r8, 360(%rdi) - movq %r14, %r10 - adcxq %rax, %r9 - adoxq %rcx, %r10 - adcxq %r13, %r10 - movq %r9, 368(%rdi) - movq %r10, 376(%rdi) - vmovdqu (%rsp), %ymm0 - vmovdqu 32(%rsp), %ymm1 - vmovdqu 64(%rsp), %ymm2 - vmovdqu 96(%rsp), %ymm3 - vmovdqu 128(%rsp), %ymm4 - vmovdqu 160(%rsp), %xmm5 - vmovdqu %ymm0, (%rdi) - vmovdqu %ymm1, 32(%rdi) - vmovdqu %ymm2, 64(%rdi) - vmovdqu %ymm3, 96(%rdi) - vmovdqu %ymm4, 128(%rdi) - vmovdqu %xmm5, 160(%rdi) - movq %r15, 176(%rdi) - movq %rbx, 184(%rdi) - addq $192, %rsp - pop %rbx - pop %r15 - pop %r14 - pop %r13 + adcxq %r11, %r10 + movq %r9, 176(%rdi) + movq %r10, 184(%rdi) + cmpq %rdi, %rsi + je L_start_3072_mul_avx2_12 + cmpq %rdi, %rbp + jne L_end_3072_mul_avx2_12 +L_start_3072_mul_avx2_12: + 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) +L_end_3072_mul_avx2_12: + addq $96, %rsp pop %r12 pop %rbp + pop %rbx repz retq #ifndef __APPLE__ -.size sp_3072_mul_avx2_24,.-sp_3072_mul_avx2_24 +.size sp_3072_mul_avx2_12,.-sp_3072_mul_avx2_12 #endif /* __APPLE__ */ #endif /* HAVE_INTEL_AVX2 */ #ifdef HAVE_INTEL_AVX2 @@ -18803,1801 +14849,479 @@ _sp_3072_mul_avx2_24: * a A single precision integer. */ #ifndef __APPLE__ -.globl sp_3072_sqr_avx2_24 -.type sp_3072_sqr_avx2_24,@function +.globl sp_3072_sqr_avx2_12 +.type sp_3072_sqr_avx2_12,@function .align 16 -sp_3072_sqr_avx2_24: +sp_3072_sqr_avx2_12: #else -.globl _sp_3072_sqr_avx2_24 +.globl _sp_3072_sqr_avx2_12 .p2align 4 -_sp_3072_sqr_avx2_24: +_sp_3072_sqr_avx2_12: #endif /* __APPLE__ */ push %rbp push %r12 push %r13 - subq $192, %rsp + push %r14 + push %r15 + push %rbx + subq $96, %rsp cmpq %rdi, %rsi movq %rsp, %rbp cmovne %rdi, %rbp - xorq %r12, %r12 - # Diagonal 1 - xorq %r8, %r8 - xorq %r9, %r9 xorq %r10, %r10 - xorq %r11, %r11 + # Diagonal 1 # A[1] x A[0] movq (%rsi), %rdx mulxq 8(%rsi), %r8, %r9 + movq %r8, 8(%rbp) + movq %r10, %r8 # A[2] x A[0] mulxq 16(%rsi), %rax, %rcx adcxq %rax, %r9 - adoxq %rcx, %r10 + adoxq %rcx, %r8 + movq %r9, 16(%rbp) + movq %r10, %r9 # A[3] x A[0] mulxq 24(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r8, 8(%rbp) - movq %r9, 16(%rbp) - movq %r10, 24(%rbp) - movq %r12, %r8 - movq %r12, %r9 - movq %r12, %r10 + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r8, 24(%rbp) + movq %r10, %r8 # A[4] x A[0] mulxq 32(%rsi), %rax, %rcx - adcxq %rax, %r11 + adcxq %rax, %r9 adoxq %rcx, %r8 + movq %r9, 32(%rbp) + movq %r10, %r9 # A[5] x A[0] mulxq 40(%rsi), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 + movq %r8, 40(%rbp) + movq %r10, %r8 # A[6] x A[0] mulxq 48(%rsi), %rax, %rcx adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r11, 32(%rbp) - movq %r8, 40(%rbp) + adoxq %rcx, %r8 movq %r9, 48(%rbp) - movq %r12, %r11 - movq %r12, %r8 - movq %r12, %r9 + movq %r10, %r9 # A[7] x A[0] mulxq 56(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r8, %r12 + movq %r10, %r8 # A[8] x A[0] mulxq 64(%rsi), %rax, %rcx - adcxq %rax, %r11 + adcxq %rax, %r9 adoxq %rcx, %r8 + movq %r9, %r13 + movq %r10, %r9 # A[9] x A[0] mulxq 72(%rsi), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r10, 56(%rbp) - movq %r11, 64(%rbp) - movq %r8, 72(%rbp) - movq %r12, %r10 - movq %r12, %r11 - movq %r12, %r8 + movq %r8, %r14 + movq %r10, %r8 # A[10] x A[0] mulxq 80(%rsi), %rax, %rcx adcxq %rax, %r9 - adoxq %rcx, %r10 + adoxq %rcx, %r8 + movq %r9, %r15 + movq %r10, %r9 # A[11] x A[0] mulxq 88(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[12] x A[0] - mulxq 96(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - movq %r9, 80(%rbp) - movq %r10, 88(%rbp) - movq %r11, 96(%rbp) - movq %r12, %r9 - movq %r12, %r10 - movq %r12, %r11 - # 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 - # A[15] x A[0] - mulxq 120(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r8, 104(%rbp) - movq %r9, 112(%rbp) - movq %r10, 120(%rbp) - movq %r12, %r8 - movq %r12, %r9 - movq %r12, %r10 - # A[16] x A[0] - mulxq 128(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[17] x A[0] - mulxq 136(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[18] x A[0] - mulxq 144(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r11, 128(%rbp) - movq %r8, 136(%rbp) - movq %r9, 144(%rbp) - movq %r12, %r11 - movq %r12, %r8 - movq %r12, %r9 - # A[19] x A[0] - mulxq 152(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[20] x A[0] - mulxq 160(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[21] x A[0] - mulxq 168(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r10, 152(%rbp) - movq %r11, 160(%rbp) - movq %r8, 168(%rbp) - movq %r12, %r10 - movq %r12, %r11 - # A[22] x A[0] - mulxq 176(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[23] x A[0] - mulxq 184(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r9, 176(%rbp) - movq %r10, 184(%rbp) + movq %r8, %rbx # Carry - adcxq %r12, %r11 - movq %r12, %r13 - adcxq %r12, %r13 - adoxq %r12, %r13 - movq %r11, 192(%rdi) + adcxq %r10, %r9 + movq %r10, %r11 + adcxq %r10, %r11 + adoxq %r10, %r11 + movq %r9, 96(%rdi) # Diagonal 2 - movq 24(%rbp), %r11 + movq 24(%rbp), %r9 movq 32(%rbp), %r8 - movq 40(%rbp), %r9 - movq 48(%rbp), %r10 # A[2] x A[1] movq 8(%rsi), %rdx mulxq 16(%rsi), %rax, %rcx - adcxq %rax, %r11 + adcxq %rax, %r9 adoxq %rcx, %r8 + movq %r9, 24(%rbp) + movq 40(%rbp), %r9 # A[3] x A[1] mulxq 24(%rsi), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 + movq %r8, 32(%rbp) + movq 48(%rbp), %r8 # A[4] x A[1] mulxq 32(%rsi), %rax, %rcx adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r11, 24(%rbp) - movq %r8, 32(%rbp) + adoxq %rcx, %r8 movq %r9, 40(%rbp) - movq 56(%rbp), %r11 - movq 64(%rbp), %r8 - movq 72(%rbp), %r9 + # No load %r12 - %r9 # A[5] x A[1] mulxq 40(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 + adcxq %rax, %r8 + adoxq %rcx, %r12 + movq %r8, 48(%rbp) + # No load %r13 - %r8 # A[6] x A[1] mulxq 48(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 + adcxq %rax, %r12 + adoxq %rcx, %r13 + # No store %r12 + # No load %r14 - %r9 # A[7] x A[1] mulxq 56(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r10, 48(%rbp) - movq %r11, 56(%rbp) - movq %r8, 64(%rbp) - movq 80(%rbp), %r10 - movq 88(%rbp), %r11 - movq 96(%rbp), %r8 + adcxq %rax, %r13 + adoxq %rcx, %r14 + # No store %r13 + # No load %r15 - %r8 # A[8] x A[1] mulxq 64(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 + adcxq %rax, %r14 + adoxq %rcx, %r15 + # No store %r14 + # No load %rbx - %r9 # A[9] x A[1] mulxq 72(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 + adcxq %rax, %r15 + adoxq %rcx, %rbx + # No store %r15 + movq 96(%rdi), %r8 # A[10] x A[1] mulxq 80(%rsi), %rax, %rcx - adcxq %rax, %r11 + adcxq %rax, %rbx adoxq %rcx, %r8 - movq %r9, 72(%rbp) - movq %r10, 80(%rbp) - movq %r11, 88(%rbp) - movq 104(%rbp), %r9 - movq 112(%rbp), %r10 - movq 120(%rbp), %r11 + # No store %rbx + movq %r10, %r9 # A[11] x A[1] mulxq 88(%rsi), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 - # A[12] x A[1] - mulxq 96(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[13] x A[1] - mulxq 104(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r8, 96(%rbp) - movq %r9, 104(%rbp) - movq %r10, 112(%rbp) - movq 128(%rbp), %r8 - movq 136(%rbp), %r9 - movq 144(%rbp), %r10 - # A[14] x A[1] - mulxq 112(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[15] x A[1] - mulxq 120(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[16] x A[1] - mulxq 128(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r11, 120(%rbp) - movq %r8, 128(%rbp) - movq %r9, 136(%rbp) - movq 152(%rbp), %r11 - movq 160(%rbp), %r8 - movq 168(%rbp), %r9 - # A[17] x A[1] - mulxq 136(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[18] x A[1] - mulxq 144(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[19] x A[1] - mulxq 152(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r10, 144(%rbp) - movq %r11, 152(%rbp) - movq %r8, 160(%rbp) - movq 176(%rbp), %r10 - movq 184(%rbp), %r11 - movq 192(%rdi), %r8 - # A[20] x A[1] - mulxq 160(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[21] x A[1] - mulxq 168(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[22] x A[1] - mulxq 176(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - movq %r9, 168(%rbp) - movq %r10, 176(%rbp) - movq %r11, 184(%rbp) - movq %r12, %r9 - movq %r12, %r10 - # A[23] x A[1] - mulxq 184(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[23] x A[2] + movq %r8, 96(%rdi) + movq %r10, %r8 + # A[11] x A[2] movq 16(%rsi), %rdx - mulxq 184(%rsi), %rax, %rcx + mulxq 88(%rsi), %rax, %rcx adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r8, 192(%rdi) - movq %r9, 200(%rdi) + adoxq %rcx, %r8 + movq %r9, 104(%rdi) # Carry - adcxq %r13, %r10 - movq %r12, %r13 - adcxq %r12, %r13 - adoxq %r12, %r13 - movq %r10, 208(%rdi) + adcxq %r11, %r8 + movq %r10, %r11 + adcxq %r10, %r11 + adoxq %r10, %r11 + movq %r8, 112(%rdi) # Diagonal 3 - movq 40(%rbp), %r10 - movq 48(%rbp), %r11 - movq 56(%rbp), %r8 - movq 64(%rbp), %r9 + movq 40(%rbp), %r8 + movq 48(%rbp), %r9 # A[3] x A[2] mulxq 24(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r8, 40(%rbp) + # No load %r12 - %r8 # A[4] x A[2] mulxq 32(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 + adcxq %rax, %r9 + adoxq %rcx, %r12 + movq %r9, 48(%rbp) + # No load %r13 - %r9 # A[5] x A[2] mulxq 40(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r10, 40(%rbp) - movq %r11, 48(%rbp) - movq %r8, 56(%rbp) - movq 72(%rbp), %r10 - movq 80(%rbp), %r11 - movq 88(%rbp), %r8 + adcxq %rax, %r12 + adoxq %rcx, %r13 + # No store %r12 + # No load %r14 - %r8 # A[6] x A[2] mulxq 48(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 + adcxq %rax, %r13 + adoxq %rcx, %r14 + # No store %r13 + # No load %r15 - %r9 # A[7] x A[2] mulxq 56(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 + adcxq %rax, %r14 + adoxq %rcx, %r15 + # No store %r14 + # No load %rbx - %r8 # A[8] x A[2] mulxq 64(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - movq %r9, 64(%rbp) - movq %r10, 72(%rbp) - movq %r11, 80(%rbp) - movq 96(%rbp), %r9 - movq 104(%rbp), %r10 - movq 112(%rbp), %r11 + adcxq %rax, %r15 + adoxq %rcx, %rbx + # No store %r15 + movq 96(%rdi), %r9 # A[9] x A[2] mulxq 72(%rsi), %rax, %rcx - adcxq %rax, %r8 + adcxq %rax, %rbx adoxq %rcx, %r9 + # No store %rbx + movq 104(%rdi), %r8 # A[10] x A[2] mulxq 80(%rsi), %rax, %rcx adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[11] x A[2] - mulxq 88(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r8, 88(%rbp) - movq %r9, 96(%rbp) - movq %r10, 104(%rbp) - movq 120(%rbp), %r8 - movq 128(%rbp), %r9 - movq 136(%rbp), %r10 - # A[12] x A[2] - mulxq 96(%rsi), %rax, %rcx - adcxq %rax, %r11 adoxq %rcx, %r8 - # A[13] x A[2] - mulxq 104(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[14] x A[2] - mulxq 112(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r11, 112(%rbp) - movq %r8, 120(%rbp) - movq %r9, 128(%rbp) - movq 144(%rbp), %r11 - movq 152(%rbp), %r8 - movq 160(%rbp), %r9 - # A[15] x A[2] - mulxq 120(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[16] x A[2] - mulxq 128(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[17] x A[2] - mulxq 136(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r10, 136(%rbp) - movq %r11, 144(%rbp) - movq %r8, 152(%rbp) - movq 168(%rbp), %r10 - movq 176(%rbp), %r11 - movq 184(%rbp), %r8 - # A[18] x A[2] - mulxq 144(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[19] x A[2] - mulxq 152(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[20] x A[2] - mulxq 160(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - movq %r9, 160(%rbp) - movq %r10, 168(%rbp) - movq %r11, 176(%rbp) - movq 192(%rdi), %r9 - movq 200(%rdi), %r10 - movq 208(%rdi), %r11 - # A[21] x A[2] - mulxq 168(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[22] x A[2] - mulxq 176(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[22] x A[3] - movq 176(%rsi), %rdx + movq %r9, 96(%rdi) + movq 112(%rdi), %r9 + # A[10] x A[3] + movq 80(%rsi), %rdx mulxq 24(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r8, 184(%rbp) - movq %r9, 192(%rdi) - movq %r10, 200(%rdi) - movq %r12, %r8 - movq %r12, %r9 - # A[22] x A[4] + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r8, 104(%rdi) + movq %r10, %r8 + # A[10] x A[4] mulxq 32(%rsi), %rax, %rcx - adcxq %rax, %r11 + adcxq %rax, %r9 adoxq %rcx, %r8 - # A[22] x A[5] + movq %r9, 112(%rdi) + movq %r10, %r9 + # A[10] x A[5] mulxq 40(%rsi), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r11, 208(%rdi) - movq %r8, 216(%rdi) + movq %r8, 120(%rdi) # Carry - adcxq %r13, %r9 - movq %r12, %r13 - adcxq %r12, %r13 - adoxq %r12, %r13 - movq %r9, 224(%rdi) + adcxq %r11, %r9 + movq %r10, %r11 + adcxq %r10, %r11 + adoxq %r10, %r11 + movq %r9, 128(%rdi) # Diagonal 4 - movq 56(%rbp), %r9 - movq 64(%rbp), %r10 - movq 72(%rbp), %r11 - movq 80(%rbp), %r8 + # No load %r12 - %r9 + # No load %r13 - %r8 # A[4] x A[3] movq 24(%rsi), %rdx mulxq 32(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 + adcxq %rax, %r12 + adoxq %rcx, %r13 + # No store %r12 + # No load %r14 - %r9 # A[5] x A[3] mulxq 40(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 + adcxq %rax, %r13 + adoxq %rcx, %r14 + # No store %r13 + # No load %r15 - %r8 # A[6] x A[3] mulxq 48(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - movq %r9, 56(%rbp) - movq %r10, 64(%rbp) - movq %r11, 72(%rbp) - movq 88(%rbp), %r9 - movq 96(%rbp), %r10 - movq 104(%rbp), %r11 + adcxq %rax, %r14 + adoxq %rcx, %r15 + # No store %r14 + # No load %rbx - %r9 # A[7] x A[3] mulxq 56(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 + adcxq %rax, %r15 + adoxq %rcx, %rbx + # No store %r15 + movq 96(%rdi), %r8 # A[8] x A[3] mulxq 64(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 + adcxq %rax, %rbx + adoxq %rcx, %r8 + # No store %rbx + movq 104(%rdi), %r9 # A[9] x A[3] mulxq 72(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r8, 80(%rbp) - movq %r9, 88(%rbp) - movq %r10, 96(%rbp) - movq 112(%rbp), %r8 - movq 120(%rbp), %r9 - movq 128(%rbp), %r10 - # A[10] x A[3] - mulxq 80(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[11] x A[3] - mulxq 88(%rsi), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 - # A[12] x A[3] - mulxq 96(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r11, 104(%rbp) - movq %r8, 112(%rbp) - movq %r9, 120(%rbp) - movq 136(%rbp), %r11 - movq 144(%rbp), %r8 - movq 152(%rbp), %r9 - # A[13] x A[3] - mulxq 104(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[14] x A[3] - mulxq 112(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[15] x A[3] - mulxq 120(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r10, 128(%rbp) - movq %r11, 136(%rbp) - movq %r8, 144(%rbp) - movq 160(%rbp), %r10 - movq 168(%rbp), %r11 - movq 176(%rbp), %r8 - # A[16] x A[3] - mulxq 128(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[17] x A[3] - mulxq 136(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[18] x A[3] - mulxq 144(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - movq %r9, 152(%rbp) - movq %r10, 160(%rbp) - movq %r11, 168(%rbp) - movq 184(%rbp), %r9 - movq 192(%rdi), %r10 - movq 200(%rdi), %r11 - # A[19] x A[3] - mulxq 152(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[20] x A[3] - mulxq 160(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[21] x A[3] - mulxq 168(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r8, 176(%rbp) - movq %r9, 184(%rbp) - movq %r10, 192(%rdi) - movq 208(%rdi), %r8 - movq 216(%rdi), %r9 - movq 224(%rdi), %r10 - # A[21] x A[4] - movq 168(%rsi), %rdx + movq %r8, 96(%rdi) + movq 112(%rdi), %r8 + # A[9] x A[4] + movq 72(%rsi), %rdx mulxq 32(%rsi), %rax, %rcx - adcxq %rax, %r11 + adcxq %rax, %r9 adoxq %rcx, %r8 - # A[21] x A[5] + movq %r9, 104(%rdi) + movq 120(%rdi), %r9 + # A[9] x A[5] mulxq 40(%rsi), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 - # A[21] x A[6] + movq %r8, 112(%rdi) + movq 128(%rdi), %r8 + # A[9] x A[6] mulxq 48(%rsi), %rax, %rcx adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r11, 200(%rdi) - movq %r8, 208(%rdi) - movq %r9, 216(%rdi) - movq %r12, %r11 - movq %r12, %r8 - # A[21] x A[7] - mulxq 56(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[21] x A[8] - mulxq 64(%rsi), %rax, %rcx - adcxq %rax, %r11 adoxq %rcx, %r8 - movq %r10, 224(%rdi) - movq %r11, 232(%rdi) + movq %r9, 120(%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 %r10, %r8 + # A[9] x A[8] + mulxq 64(%rsi), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r8 + movq %r9, 136(%rdi) # Carry - adcxq %r13, %r8 - movq %r12, %r13 - adcxq %r12, %r13 - adoxq %r12, %r13 - movq %r8, 240(%rdi) + adcxq %r11, %r8 + movq %r10, %r11 + adcxq %r10, %r11 + adoxq %r10, %r11 + movq %r8, 144(%rdi) # Diagonal 5 - movq 72(%rbp), %r8 - movq 80(%rbp), %r9 - movq 88(%rbp), %r10 - movq 96(%rbp), %r11 + # No load %r14 - %r8 + # No load %r15 - %r9 # A[5] x A[4] movq 32(%rsi), %rdx mulxq 40(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 + adcxq %rax, %r14 + adoxq %rcx, %r15 + # No store %r14 + # No load %rbx - %r8 # A[6] x A[4] mulxq 48(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 + adcxq %rax, %r15 + adoxq %rcx, %rbx + # No store %r15 + movq 96(%rdi), %r9 # A[7] x A[4] mulxq 56(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r8, 72(%rbp) - movq %r9, 80(%rbp) - movq %r10, 88(%rbp) - movq 104(%rbp), %r8 - movq 112(%rbp), %r9 - movq 120(%rbp), %r10 + adcxq %rax, %rbx + adoxq %rcx, %r9 + # No store %rbx + movq 104(%rdi), %r8 # A[8] x A[4] mulxq 64(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[9] x A[4] - mulxq 72(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[10] x A[4] - mulxq 80(%rsi), %rax, %rcx adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r11, 96(%rbp) - movq %r8, 104(%rbp) - movq %r9, 112(%rbp) - movq 128(%rbp), %r11 - movq 136(%rbp), %r8 - movq 144(%rbp), %r9 - # A[11] x A[4] - mulxq 88(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[12] x A[4] - mulxq 96(%rsi), %rax, %rcx - adcxq %rax, %r11 adoxq %rcx, %r8 - # A[13] x A[4] - mulxq 104(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r10, 120(%rbp) - movq %r11, 128(%rbp) - movq %r8, 136(%rbp) - movq 152(%rbp), %r10 - movq 160(%rbp), %r11 - movq 168(%rbp), %r8 - # A[14] x A[4] - mulxq 112(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[15] x A[4] - mulxq 120(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[16] x A[4] - mulxq 128(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - movq %r9, 144(%rbp) - movq %r10, 152(%rbp) - movq %r11, 160(%rbp) - movq 176(%rbp), %r9 - movq 184(%rbp), %r10 - movq 192(%rdi), %r11 - # A[17] x A[4] - mulxq 136(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[18] x A[4] - mulxq 144(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[19] x A[4] - mulxq 152(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r8, 168(%rbp) - movq %r9, 176(%rbp) - movq %r10, 184(%rbp) - movq 200(%rdi), %r8 - movq 208(%rdi), %r9 - movq 216(%rdi), %r10 - # A[20] x A[4] - mulxq 160(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[20] x A[5] - movq 160(%rsi), %rdx + movq %r9, 96(%rdi) + movq 112(%rdi), %r9 + # A[8] x A[5] + movq 64(%rsi), %rdx mulxq 40(%rsi), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 - # A[20] x A[6] + movq %r8, 104(%rdi) + movq 120(%rdi), %r8 + # A[8] x A[6] mulxq 48(%rsi), %rax, %rcx adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r11, 192(%rdi) - movq %r8, 200(%rdi) - movq %r9, 208(%rdi) - movq 224(%rdi), %r11 - movq 232(%rdi), %r8 - movq 240(%rdi), %r9 - # A[20] x A[7] - mulxq 56(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[20] x A[8] - mulxq 64(%rsi), %rax, %rcx - adcxq %rax, %r11 adoxq %rcx, %r8 - # A[20] x A[9] + movq %r9, 112(%rdi) + movq 128(%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 + # 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 + # A[10] x A[7] + mulxq 56(%rsi), %rax, %rcx + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r8, 136(%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 %r10, %r9 + # A[10] x A[9] mulxq 72(%rsi), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 - movq %r10, 216(%rdi) - movq %r11, 224(%rdi) - movq %r8, 232(%rdi) - movq %r12, %r10 - movq %r12, %r11 - # A[20] x A[10] - mulxq 80(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[20] x A[11] - mulxq 88(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r9, 240(%rdi) - movq %r10, 248(%rdi) + movq %r8, 152(%rdi) # Carry - adcxq %r13, %r11 - movq %r12, %r13 - adcxq %r12, %r13 - adoxq %r12, %r13 - movq %r11, 256(%rdi) + adcxq %r11, %r9 + movq %r10, %r11 + adcxq %r10, %r11 + adoxq %r10, %r11 + movq %r9, 160(%rdi) # Diagonal 6 - movq 88(%rbp), %r11 - movq 96(%rbp), %r8 - movq 104(%rbp), %r9 - movq 112(%rbp), %r10 + # No load %rbx - %r9 + movq 96(%rdi), %r8 # A[6] x A[5] movq 40(%rsi), %rdx mulxq 48(%rsi), %rax, %rcx - adcxq %rax, %r11 + adcxq %rax, %rbx adoxq %rcx, %r8 + # No store %rbx + movq 104(%rdi), %r9 # A[7] x A[5] mulxq 56(%rsi), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 - # A[8] x A[5] - mulxq 64(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r11, 88(%rbp) - movq %r8, 96(%rbp) - movq %r9, 104(%rbp) - movq 120(%rbp), %r11 - movq 128(%rbp), %r8 - movq 136(%rbp), %r9 - # A[9] x A[5] - mulxq 72(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[10] x A[5] - mulxq 80(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[11] x A[5] - mulxq 88(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r10, 112(%rbp) - movq %r11, 120(%rbp) - movq %r8, 128(%rbp) - movq 144(%rbp), %r10 - movq 152(%rbp), %r11 - movq 160(%rbp), %r8 - # A[12] x A[5] - mulxq 96(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[13] x A[5] - mulxq 104(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[14] x A[5] - mulxq 112(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - movq %r9, 136(%rbp) - movq %r10, 144(%rbp) - movq %r11, 152(%rbp) - movq 168(%rbp), %r9 - movq 176(%rbp), %r10 - movq 184(%rbp), %r11 - # A[15] x A[5] - mulxq 120(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[16] x A[5] - mulxq 128(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[17] x A[5] - mulxq 136(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r8, 160(%rbp) - movq %r9, 168(%rbp) - movq %r10, 176(%rbp) - movq 192(%rdi), %r8 - movq 200(%rdi), %r9 - movq 208(%rdi), %r10 - # A[18] x A[5] - mulxq 144(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[19] x A[5] - mulxq 152(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[19] x A[6] - movq 152(%rsi), %rdx - mulxq 48(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r11, 184(%rbp) - movq %r8, 192(%rdi) - movq %r9, 200(%rdi) - movq 216(%rdi), %r11 - movq 224(%rdi), %r8 - movq 232(%rdi), %r9 - # A[19] x A[7] - mulxq 56(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[19] x A[8] - mulxq 64(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[19] x A[9] - mulxq 72(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r10, 208(%rdi) - movq %r11, 216(%rdi) - movq %r8, 224(%rdi) - movq 240(%rdi), %r10 - movq 248(%rdi), %r11 - movq 256(%rdi), %r8 - # A[19] x A[10] - mulxq 80(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[19] x A[11] - mulxq 88(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[19] x A[12] - mulxq 96(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - movq %r9, 232(%rdi) - movq %r10, 240(%rdi) - movq %r11, 248(%rdi) - movq %r12, %r9 - movq %r12, %r10 - # A[19] x A[13] - mulxq 104(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[19] x A[14] - mulxq 112(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r8, 256(%rdi) - movq %r9, 264(%rdi) - # Carry - adcxq %r13, %r10 - movq %r12, %r13 - adcxq %r12, %r13 - adoxq %r12, %r13 - movq %r10, 272(%rdi) - # Diagonal 7 - movq 104(%rbp), %r10 - movq 112(%rbp), %r11 - movq 120(%rbp), %r8 - movq 128(%rbp), %r9 + movq %r8, 96(%rdi) + movq 112(%rdi), %r8 # A[7] x A[6] movq 48(%rsi), %rdx mulxq 56(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[8] x A[6] - mulxq 64(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[9] x A[6] - mulxq 72(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r10, 104(%rbp) - movq %r11, 112(%rbp) - movq %r8, 120(%rbp) - movq 136(%rbp), %r10 - movq 144(%rbp), %r11 - movq 152(%rbp), %r8 - # A[10] x A[6] - mulxq 80(%rsi), %rax, %rcx adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[11] x A[6] - mulxq 88(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[12] x A[6] - mulxq 96(%rsi), %rax, %rcx - adcxq %rax, %r11 adoxq %rcx, %r8 - movq %r9, 128(%rbp) - movq %r10, 136(%rbp) - movq %r11, 144(%rbp) - movq 160(%rbp), %r9 - movq 168(%rbp), %r10 - movq 176(%rbp), %r11 - # A[13] x A[6] - mulxq 104(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[14] x A[6] - mulxq 112(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[15] x A[6] - mulxq 120(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r8, 152(%rbp) - movq %r9, 160(%rbp) - movq %r10, 168(%rbp) - movq 184(%rbp), %r8 - movq 192(%rdi), %r9 - movq 200(%rdi), %r10 - # A[16] x A[6] - mulxq 128(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[17] x A[6] - mulxq 136(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[18] x A[6] - mulxq 144(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r11, 176(%rbp) - movq %r8, 184(%rbp) - movq %r9, 192(%rdi) - movq 208(%rdi), %r11 - movq 216(%rdi), %r8 - movq 224(%rdi), %r9 - # A[18] x A[7] - movq 144(%rsi), %rdx - mulxq 56(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[18] x A[8] - mulxq 64(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[18] x A[9] - mulxq 72(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r10, 200(%rdi) - movq %r11, 208(%rdi) - movq %r8, 216(%rdi) - movq 232(%rdi), %r10 - movq 240(%rdi), %r11 - movq 248(%rdi), %r8 - # A[18] x A[10] - mulxq 80(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[18] x A[11] - mulxq 88(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[18] x A[12] - mulxq 96(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - movq %r9, 224(%rdi) - movq %r10, 232(%rdi) - movq %r11, 240(%rdi) - movq 256(%rdi), %r9 - movq 264(%rdi), %r10 - movq 272(%rdi), %r11 - # A[18] x A[13] - mulxq 104(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[18] x A[14] - mulxq 112(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[18] x A[15] - mulxq 120(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r8, 248(%rdi) - movq %r9, 256(%rdi) - movq %r10, 264(%rdi) - movq %r12, %r8 - movq %r12, %r9 - # A[18] x A[16] - mulxq 128(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[18] x A[17] - mulxq 136(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r11, 272(%rdi) - movq %r8, 280(%rdi) - # Carry - adcxq %r13, %r9 - movq %r12, %r13 - adcxq %r12, %r13 - adoxq %r12, %r13 - movq %r9, 288(%rdi) - # Diagonal 8 - movq 120(%rbp), %r9 - movq 128(%rbp), %r10 - movq 136(%rbp), %r11 - movq 144(%rbp), %r8 - # A[8] x A[7] - movq 56(%rsi), %rdx - mulxq 64(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[9] x A[7] - mulxq 72(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[10] x A[7] - mulxq 80(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - movq %r9, 120(%rbp) - movq %r10, 128(%rbp) - movq %r11, 136(%rbp) - movq 152(%rbp), %r9 - movq 160(%rbp), %r10 - movq 168(%rbp), %r11 - # A[11] x A[7] - mulxq 88(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[12] x A[7] - mulxq 96(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[13] x A[7] - mulxq 104(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r8, 144(%rbp) - movq %r9, 152(%rbp) - movq %r10, 160(%rbp) - movq 176(%rbp), %r8 - movq 184(%rbp), %r9 - movq 192(%rdi), %r10 - # A[14] x A[7] - mulxq 112(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[15] x A[7] - mulxq 120(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[16] x A[7] - mulxq 128(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r11, 168(%rbp) - movq %r8, 176(%rbp) - movq %r9, 184(%rbp) - movq 200(%rdi), %r11 - movq 208(%rdi), %r8 - movq 216(%rdi), %r9 - # A[17] x A[7] - mulxq 136(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[17] x A[8] - movq 136(%rsi), %rdx - mulxq 64(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[17] x A[9] - mulxq 72(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r10, 192(%rdi) - movq %r11, 200(%rdi) - movq %r8, 208(%rdi) - movq 224(%rdi), %r10 - movq 232(%rdi), %r11 - movq 240(%rdi), %r8 - # A[17] x A[10] - mulxq 80(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[17] x A[11] - mulxq 88(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[17] x A[12] - mulxq 96(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - movq %r9, 216(%rdi) - movq %r10, 224(%rdi) - movq %r11, 232(%rdi) - movq 248(%rdi), %r9 - movq 256(%rdi), %r10 - movq 264(%rdi), %r11 - # A[17] x A[13] - mulxq 104(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[17] x A[14] - mulxq 112(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[17] x A[15] - mulxq 120(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r8, 240(%rdi) - movq %r9, 248(%rdi) - movq %r10, 256(%rdi) - movq 272(%rdi), %r8 - movq 280(%rdi), %r9 - movq 288(%rdi), %r10 - # A[17] x A[16] - mulxq 128(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[19] x A[15] - movq 152(%rsi), %rdx - mulxq 120(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[19] x A[16] - mulxq 128(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r11, 264(%rdi) - movq %r8, 272(%rdi) - movq %r9, 280(%rdi) - movq %r12, %r11 - movq %r12, %r8 - # A[19] x A[17] - mulxq 136(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[19] x A[18] - mulxq 144(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - movq %r10, 288(%rdi) - movq %r11, 296(%rdi) - # Carry - adcxq %r13, %r8 - movq %r12, %r13 - adcxq %r12, %r13 - adoxq %r12, %r13 - movq %r8, 304(%rdi) - # Diagonal 9 - movq 136(%rbp), %r8 - movq 144(%rbp), %r9 - movq 152(%rbp), %r10 - movq 160(%rbp), %r11 - # A[9] x A[8] - movq 64(%rsi), %rdx - mulxq 72(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[10] x A[8] - mulxq 80(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[11] x A[8] - mulxq 88(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r8, 136(%rbp) - movq %r9, 144(%rbp) - movq %r10, 152(%rbp) - movq 168(%rbp), %r8 - movq 176(%rbp), %r9 - movq 184(%rbp), %r10 - # A[12] x A[8] - mulxq 96(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[13] x A[8] - mulxq 104(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[14] x A[8] - mulxq 112(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r11, 160(%rbp) - movq %r8, 168(%rbp) - movq %r9, 176(%rbp) - movq 192(%rdi), %r11 - movq 200(%rdi), %r8 - movq 208(%rdi), %r9 - # A[15] x A[8] - mulxq 120(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[16] x A[8] - mulxq 128(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[16] x A[9] - movq 128(%rsi), %rdx - mulxq 72(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r10, 184(%rbp) - movq %r11, 192(%rdi) - movq %r8, 200(%rdi) - movq 216(%rdi), %r10 - movq 224(%rdi), %r11 - movq 232(%rdi), %r8 - # A[16] x A[10] - mulxq 80(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[16] x A[11] - mulxq 88(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[16] x A[12] - mulxq 96(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - movq %r9, 208(%rdi) - movq %r10, 216(%rdi) - movq %r11, 224(%rdi) - movq 240(%rdi), %r9 - movq 248(%rdi), %r10 - movq 256(%rdi), %r11 - # A[16] x A[13] - mulxq 104(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[16] x A[14] - mulxq 112(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[16] x A[15] - mulxq 120(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r8, 232(%rdi) - movq %r9, 240(%rdi) - movq %r10, 248(%rdi) - movq 264(%rdi), %r8 - movq 272(%rdi), %r9 - movq 280(%rdi), %r10 - # A[20] x A[12] - movq 160(%rsi), %rdx - mulxq 96(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[20] x A[13] - mulxq 104(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[20] x A[14] - mulxq 112(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r11, 256(%rdi) - movq %r8, 264(%rdi) - movq %r9, 272(%rdi) - movq 288(%rdi), %r11 - movq 296(%rdi), %r8 - movq 304(%rdi), %r9 - # A[20] x A[15] - mulxq 120(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[20] x A[16] - mulxq 128(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[20] x A[17] - mulxq 136(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r10, 280(%rdi) - movq %r11, 288(%rdi) - movq %r8, 296(%rdi) - movq %r12, %r10 - movq %r12, %r11 - # A[20] x A[18] - mulxq 144(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[20] x A[19] - mulxq 152(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r9, 304(%rdi) - movq %r10, 312(%rdi) - # Carry - adcxq %r13, %r11 - movq %r12, %r13 - adcxq %r12, %r13 - adoxq %r12, %r13 - movq %r11, 320(%rdi) - # Diagonal 10 - movq 152(%rbp), %r11 - movq 160(%rbp), %r8 - movq 168(%rbp), %r9 - movq 176(%rbp), %r10 - # A[10] x A[9] - movq 72(%rsi), %rdx - mulxq 80(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[11] x A[9] - mulxq 88(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[12] x A[9] - mulxq 96(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r11, 152(%rbp) - movq %r8, 160(%rbp) - movq %r9, 168(%rbp) - movq 184(%rbp), %r11 - movq 192(%rdi), %r8 - movq 200(%rdi), %r9 - # A[13] x A[9] - mulxq 104(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[14] x A[9] - mulxq 112(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[15] x A[9] - mulxq 120(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r10, 176(%rbp) - movq %r11, 184(%rbp) - movq %r8, 192(%rdi) - movq 208(%rdi), %r10 - movq 216(%rdi), %r11 - movq 224(%rdi), %r8 - # A[15] x A[10] - movq 120(%rsi), %rdx - 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, %r11 - # A[15] x A[12] - mulxq 96(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - movq %r9, 200(%rdi) - movq %r10, 208(%rdi) - movq %r11, 216(%rdi) - movq 232(%rdi), %r9 - movq 240(%rdi), %r10 - movq 248(%rdi), %r11 - # A[15] x A[13] - mulxq 104(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[15] x A[14] - mulxq 112(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[21] x A[9] - movq 168(%rsi), %rdx - mulxq 72(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r8, 224(%rdi) - movq %r9, 232(%rdi) - movq %r10, 240(%rdi) - movq 256(%rdi), %r8 - movq 264(%rdi), %r9 - movq 272(%rdi), %r10 - # A[21] x A[10] - mulxq 80(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[21] x A[11] - mulxq 88(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[21] x A[12] - mulxq 96(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r11, 248(%rdi) - movq %r8, 256(%rdi) - movq %r9, 264(%rdi) - movq 280(%rdi), %r11 - movq 288(%rdi), %r8 - movq 296(%rdi), %r9 - # A[21] x A[13] - mulxq 104(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[21] x A[14] - mulxq 112(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[21] x A[15] - mulxq 120(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r10, 272(%rdi) - movq %r11, 280(%rdi) - movq %r8, 288(%rdi) - movq 304(%rdi), %r10 - movq 312(%rdi), %r11 - movq 320(%rdi), %r8 - # A[21] x A[16] - mulxq 128(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[21] x A[17] - mulxq 136(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[21] x A[18] - mulxq 144(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - movq %r9, 296(%rdi) - movq %r10, 304(%rdi) - movq %r11, 312(%rdi) - movq %r12, %r9 - movq %r12, %r10 - # A[21] x A[19] - mulxq 152(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[21] x A[20] - mulxq 160(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r8, 320(%rdi) - movq %r9, 328(%rdi) - # Carry - adcxq %r13, %r10 - movq %r12, %r13 - adcxq %r12, %r13 - adoxq %r12, %r13 - movq %r10, 336(%rdi) - # Diagonal 11 - movq 168(%rbp), %r10 - movq 176(%rbp), %r11 - movq 184(%rbp), %r8 - movq 192(%rdi), %r9 - # A[11] x A[10] - movq 80(%rsi), %rdx - mulxq 88(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[12] x A[10] - mulxq 96(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[13] x A[10] - mulxq 104(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r10, 168(%rbp) - movq %r11, 176(%rbp) - movq %r8, 184(%rbp) - movq 200(%rdi), %r10 - movq 208(%rdi), %r11 - movq 216(%rdi), %r8 - # A[14] x A[10] - mulxq 112(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[14] x A[11] - movq 112(%rsi), %rdx - mulxq 88(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[14] x A[12] - mulxq 96(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - movq %r9, 192(%rdi) - movq %r10, 200(%rdi) - movq %r11, 208(%rdi) - movq 224(%rdi), %r9 - movq 232(%rdi), %r10 - movq 240(%rdi), %r11 - # A[14] x A[13] - mulxq 104(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[22] x A[6] - movq 176(%rsi), %rdx - mulxq 48(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[22] x A[7] - mulxq 56(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r8, 216(%rdi) - movq %r9, 224(%rdi) - movq %r10, 232(%rdi) - movq 248(%rdi), %r8 - movq 256(%rdi), %r9 - movq 264(%rdi), %r10 - # A[22] x A[8] - mulxq 64(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[22] x A[9] - mulxq 72(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[22] x A[10] - mulxq 80(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r11, 240(%rdi) - movq %r8, 248(%rdi) - movq %r9, 256(%rdi) - movq 272(%rdi), %r11 - movq 280(%rdi), %r8 - movq 288(%rdi), %r9 - # A[22] x A[11] - mulxq 88(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[22] x A[12] - mulxq 96(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[22] x A[13] - mulxq 104(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r10, 264(%rdi) - movq %r11, 272(%rdi) - movq %r8, 280(%rdi) - movq 296(%rdi), %r10 - movq 304(%rdi), %r11 - movq 312(%rdi), %r8 - # A[22] x A[14] - mulxq 112(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[22] x A[15] - mulxq 120(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[22] x A[16] - mulxq 128(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - movq %r9, 288(%rdi) - movq %r10, 296(%rdi) - movq %r11, 304(%rdi) - movq 320(%rdi), %r9 - movq 328(%rdi), %r10 - movq 336(%rdi), %r11 - # A[22] x A[17] - mulxq 136(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[22] x A[18] - mulxq 144(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[22] x A[19] - mulxq 152(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r8, 312(%rdi) - movq %r9, 320(%rdi) - movq %r10, 328(%rdi) - movq %r12, %r8 - movq %r12, %r9 - # A[22] x A[20] - mulxq 160(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[22] x A[21] - mulxq 168(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r11, 336(%rdi) - movq %r8, 344(%rdi) - # Carry - adcxq %r13, %r9 - movq %r12, %r13 - adcxq %r12, %r13 - adoxq %r12, %r13 - movq %r9, 352(%rdi) - # Diagonal 12 - movq 184(%rbp), %r9 - movq 192(%rdi), %r10 - movq 200(%rdi), %r11 - movq 208(%rdi), %r8 - # A[12] x A[11] + movq %r9, 104(%rdi) + movq 120(%rdi), %r9 + # A[11] x A[3] movq 88(%rsi), %rdx - mulxq 96(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[13] x A[11] - mulxq 104(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[13] x A[12] - movq 96(%rsi), %rdx - mulxq 104(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - movq %r9, 184(%rbp) - movq %r10, 192(%rdi) - movq %r11, 200(%rdi) - movq 216(%rdi), %r9 - movq 224(%rdi), %r10 - movq 232(%rdi), %r11 - # A[23] x A[3] - movq 184(%rsi), %rdx mulxq 24(%rsi), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 - # A[23] x A[4] + movq %r8, 112(%rdi) + movq 128(%rdi), %r8 + # A[11] x A[4] mulxq 32(%rsi), %rax, %rcx adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[23] x A[5] - mulxq 40(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r8, 208(%rdi) - movq %r9, 216(%rdi) - movq %r10, 224(%rdi) - movq 240(%rdi), %r8 - movq 248(%rdi), %r9 - movq 256(%rdi), %r10 - # A[23] x A[6] - mulxq 48(%rsi), %rax, %rcx - adcxq %rax, %r11 adoxq %rcx, %r8 - # A[23] x A[7] + movq %r9, 120(%rdi) + movq 136(%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 + # A[11] x A[6] + mulxq 48(%rsi), %rax, %rcx + adcxq %rax, %r9 + adoxq %rcx, %r8 + movq %r9, 136(%rdi) + movq 152(%rdi), %r9 + # A[11] x A[7] mulxq 56(%rsi), %rax, %rcx adcxq %rax, %r8 adoxq %rcx, %r9 - # A[23] x A[8] + movq %r8, 144(%rdi) + movq 160(%rdi), %r8 + # A[11] x A[8] mulxq 64(%rsi), %rax, %rcx adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r11, 232(%rdi) - movq %r8, 240(%rdi) - movq %r9, 248(%rdi) - movq 264(%rdi), %r11 - movq 272(%rdi), %r8 - movq 280(%rdi), %r9 - # A[23] x A[9] + adoxq %rcx, %r8 + movq %r9, 152(%rdi) + movq %r10, %r9 + # A[11] x A[9] mulxq 72(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[23] x A[10] + adcxq %rax, %r8 + adoxq %rcx, %r9 + movq %r8, 160(%rdi) + movq %r10, %r8 + # A[11] x A[10] mulxq 80(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[23] x A[11] - mulxq 88(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - movq %r10, 256(%rdi) - movq %r11, 264(%rdi) - movq %r8, 272(%rdi) - movq 288(%rdi), %r10 - movq 296(%rdi), %r11 - movq 304(%rdi), %r8 - # A[23] x A[12] - mulxq 96(%rsi), %rax, %rcx adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[23] x A[13] - mulxq 104(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[23] x A[14] - mulxq 112(%rsi), %rax, %rcx - adcxq %rax, %r11 adoxq %rcx, %r8 - movq %r9, 280(%rdi) - movq %r10, 288(%rdi) - movq %r11, 296(%rdi) - movq 312(%rdi), %r9 - movq 320(%rdi), %r10 - movq 328(%rdi), %r11 - # A[23] x A[15] - mulxq 120(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[23] x A[16] - mulxq 128(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - # A[23] x A[17] - mulxq 136(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - movq %r8, 304(%rdi) - movq %r9, 312(%rdi) - movq %r10, 320(%rdi) - movq 336(%rdi), %r8 - movq 344(%rdi), %r9 - movq 352(%rdi), %r10 - # A[23] x A[18] - mulxq 144(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - # A[23] x A[19] - mulxq 152(%rsi), %rax, %rcx - adcxq %rax, %r8 - adoxq %rcx, %r9 - # A[23] x A[20] - mulxq 160(%rsi), %rax, %rcx - adcxq %rax, %r9 - adoxq %rcx, %r10 - movq %r11, 328(%rdi) - movq %r8, 336(%rdi) - movq %r9, 344(%rdi) - movq %r12, %r11 - movq %r12, %r8 - # A[23] x A[21] - mulxq 168(%rsi), %rax, %rcx - adcxq %rax, %r10 - adoxq %rcx, %r11 - # A[23] x A[22] - mulxq 176(%rsi), %rax, %rcx - adcxq %rax, %r11 - adoxq %rcx, %r8 - movq %r10, 352(%rdi) - movq %r11, 360(%rdi) + movq %r9, 168(%rdi) # Carry - adcxq %r13, %r8 - movq %r12, %r13 - adcxq %r12, %r13 - adoxq %r12, %r13 - movq %r8, 368(%rdi) - movq %r13, 376(%rdi) + adcxq %r11, %r8 + movq %r10, %r11 + adcxq %r10, %r11 + adoxq %r10, %r11 + movq %r8, 176(%rdi) + movq %r11, 184(%rdi) # Double and Add in A[i] x A[i] movq 8(%rbp), %r9 # A[0] x A[0] @@ -20613,8 +15337,8 @@ _sp_3072_sqr_avx2_24: movq 8(%rsi), %rdx mulxq %rdx, %rax, %rcx adoxq %r8, %r8 - adcxq %rax, %r8 adoxq %r9, %r9 + adcxq %rax, %r8 adcxq %rcx, %r9 movq %r8, 16(%rbp) movq %r9, 24(%rbp) @@ -20624,266 +15348,126 @@ _sp_3072_sqr_avx2_24: movq 16(%rsi), %rdx mulxq %rdx, %rax, %rcx adoxq %r8, %r8 - adcxq %rax, %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 %r12, %r12 adcxq %rax, %r8 - adoxq %r9, %r9 - adcxq %rcx, %r9 + adcxq %rcx, %r12 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 - adcxq %rax, %r8 - adoxq %r9, %r9 - adcxq %rcx, %r9 - movq %r8, 64(%rbp) - movq %r9, 72(%rbp) - movq 80(%rbp), %r8 - movq 88(%rbp), %r9 + adoxq %r13, %r13 + adoxq %r14, %r14 + adcxq %rax, %r13 + adcxq %rcx, %r14 # A[5] x A[5] movq 40(%rsi), %rdx mulxq %rdx, %rax, %rcx - adoxq %r8, %r8 - adcxq %rax, %r8 - adoxq %r9, %r9 - adcxq %rcx, %r9 - movq %r8, 80(%rbp) - movq %r9, 88(%rbp) - movq 96(%rbp), %r8 - movq 104(%rbp), %r9 + adoxq %r15, %r15 + adoxq %rbx, %rbx + adcxq %rax, %r15 + adcxq %rcx, %rbx + movq 96(%rdi), %r8 + movq 104(%rdi), %r9 # A[6] x A[6] movq 48(%rsi), %rdx mulxq %rdx, %rax, %rcx adoxq %r8, %r8 - adcxq %rax, %r8 adoxq %r9, %r9 + adcxq %rax, %r8 adcxq %rcx, %r9 - movq %r8, 96(%rbp) - movq %r9, 104(%rbp) - movq 112(%rbp), %r8 - movq 120(%rbp), %r9 + movq %r8, 96(%rdi) + movq %r9, 104(%rdi) + movq 112(%rdi), %r8 + movq 120(%rdi), %r9 # A[7] x A[7] movq 56(%rsi), %rdx mulxq %rdx, %rax, %rcx adoxq %r8, %r8 - adcxq %rax, %r8 adoxq %r9, %r9 + adcxq %rax, %r8 adcxq %rcx, %r9 - movq %r8, 112(%rbp) - movq %r9, 120(%rbp) - movq 128(%rbp), %r8 - movq 136(%rbp), %r9 + movq %r8, 112(%rdi) + movq %r9, 120(%rdi) + movq 128(%rdi), %r8 + movq 136(%rdi), %r9 # A[8] x A[8] movq 64(%rsi), %rdx mulxq %rdx, %rax, %rcx adoxq %r8, %r8 - adcxq %rax, %r8 adoxq %r9, %r9 + adcxq %rax, %r8 adcxq %rcx, %r9 - movq %r8, 128(%rbp) - movq %r9, 136(%rbp) - movq 144(%rbp), %r8 - movq 152(%rbp), %r9 + movq %r8, 128(%rdi) + movq %r9, 136(%rdi) + movq 144(%rdi), %r8 + movq 152(%rdi), %r9 # A[9] x A[9] movq 72(%rsi), %rdx mulxq %rdx, %rax, %rcx adoxq %r8, %r8 - adcxq %rax, %r8 adoxq %r9, %r9 + adcxq %rax, %r8 adcxq %rcx, %r9 - movq %r8, 144(%rbp) - movq %r9, 152(%rbp) - movq 160(%rbp), %r8 - movq 168(%rbp), %r9 + movq %r8, 144(%rdi) + movq %r9, 152(%rdi) + movq 160(%rdi), %r8 + movq 168(%rdi), %r9 # A[10] x A[10] movq 80(%rsi), %rdx mulxq %rdx, %rax, %rcx adoxq %r8, %r8 - adcxq %rax, %r8 adoxq %r9, %r9 + adcxq %rax, %r8 adcxq %rcx, %r9 - movq %r8, 160(%rbp) - movq %r9, 168(%rbp) - movq 176(%rbp), %r8 - movq 184(%rbp), %r9 + movq %r8, 160(%rdi) + movq %r9, 168(%rdi) + movq 176(%rdi), %r8 + movq 184(%rdi), %r9 # A[11] x A[11] movq 88(%rsi), %rdx mulxq %rdx, %rax, %rcx adoxq %r8, %r8 - adcxq %rax, %r8 adoxq %r9, %r9 - adcxq %rcx, %r9 - movq %r8, 176(%rbp) - movq %r9, 184(%rbp) - movq 192(%rdi), %r8 - movq 200(%rdi), %r9 - # A[12] x A[12] - movq 96(%rsi), %rdx - mulxq %rdx, %rax, %rcx - adoxq %r8, %r8 adcxq %rax, %r8 - adoxq %r9, %r9 adcxq %rcx, %r9 - movq %r8, 192(%rdi) - movq %r9, 200(%rdi) - movq 208(%rdi), %r8 - movq 216(%rdi), %r9 - # A[13] x A[13] - movq 104(%rsi), %rdx - mulxq %rdx, %rax, %rcx - adoxq %r8, %r8 - adcxq %rax, %r8 - adoxq %r9, %r9 - adcxq %rcx, %r9 - movq %r8, 208(%rdi) - movq %r9, 216(%rdi) - movq 224(%rdi), %r8 - movq 232(%rdi), %r9 - # A[14] x A[14] - movq 112(%rsi), %rdx - mulxq %rdx, %rax, %rcx - adoxq %r8, %r8 - adcxq %rax, %r8 - adoxq %r9, %r9 - adcxq %rcx, %r9 - movq %r8, 224(%rdi) - movq %r9, 232(%rdi) - movq 240(%rdi), %r8 - movq 248(%rdi), %r9 - # A[15] x A[15] - movq 120(%rsi), %rdx - mulxq %rdx, %rax, %rcx - adoxq %r8, %r8 - adcxq %rax, %r8 - adoxq %r9, %r9 - adcxq %rcx, %r9 - movq %r8, 240(%rdi) - movq %r9, 248(%rdi) - movq 256(%rdi), %r8 - movq 264(%rdi), %r9 - # A[16] x A[16] - movq 128(%rsi), %rdx - mulxq %rdx, %rax, %rcx - adoxq %r8, %r8 - adcxq %rax, %r8 - adoxq %r9, %r9 - adcxq %rcx, %r9 - movq %r8, 256(%rdi) - movq %r9, 264(%rdi) - movq 272(%rdi), %r8 - movq 280(%rdi), %r9 - # A[17] x A[17] - movq 136(%rsi), %rdx - mulxq %rdx, %rax, %rcx - adoxq %r8, %r8 - adcxq %rax, %r8 - adoxq %r9, %r9 - adcxq %rcx, %r9 - movq %r8, 272(%rdi) - movq %r9, 280(%rdi) - movq 288(%rdi), %r8 - movq 296(%rdi), %r9 - # A[18] x A[18] - movq 144(%rsi), %rdx - mulxq %rdx, %rax, %rcx - adoxq %r8, %r8 - adcxq %rax, %r8 - adoxq %r9, %r9 - adcxq %rcx, %r9 - movq %r8, 288(%rdi) - movq %r9, 296(%rdi) - movq 304(%rdi), %r8 - movq 312(%rdi), %r9 - # A[19] x A[19] - movq 152(%rsi), %rdx - mulxq %rdx, %rax, %rcx - adoxq %r8, %r8 - adcxq %rax, %r8 - adoxq %r9, %r9 - adcxq %rcx, %r9 - movq %r8, 304(%rdi) - movq %r9, 312(%rdi) - movq 320(%rdi), %r8 - movq 328(%rdi), %r9 - # A[20] x A[20] - movq 160(%rsi), %rdx - mulxq %rdx, %rax, %rcx - adoxq %r8, %r8 - adcxq %rax, %r8 - adoxq %r9, %r9 - adcxq %rcx, %r9 - movq %r8, 320(%rdi) - movq %r9, 328(%rdi) - movq 336(%rdi), %r8 - movq 344(%rdi), %r9 - # A[21] x A[21] - movq 168(%rsi), %rdx - mulxq %rdx, %rax, %rcx - adoxq %r8, %r8 - adcxq %rax, %r8 - adoxq %r9, %r9 - adcxq %rcx, %r9 - movq %r8, 336(%rdi) - movq %r9, 344(%rdi) - movq 352(%rdi), %r8 - movq 360(%rdi), %r9 - # A[22] x A[22] - movq 176(%rsi), %rdx - mulxq %rdx, %rax, %rcx - adoxq %r8, %r8 - adcxq %rax, %r8 - adoxq %r9, %r9 - adcxq %rcx, %r9 - movq %r8, 352(%rdi) - movq %r9, 360(%rdi) - movq 368(%rdi), %r8 - movq 376(%rdi), %r9 - # A[23] x A[23] - movq 184(%rsi), %rdx - mulxq %rdx, %rax, %rcx - adoxq %r8, %r8 - adcxq %rax, %r8 - adoxq %r9, %r9 - adcxq %rcx, %r9 - movq %r8, 368(%rdi) - movq %r9, 376(%rdi) + 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) cmpq %rdi, %rsi - jne L_end_3072_sqr_avx2_24 - vmovdqu (%rbp), %ymm0 - vmovdqu 32(%rbp), %ymm1 - vmovdqu 64(%rbp), %ymm2 - vmovdqu 96(%rbp), %ymm3 - vmovdqu 128(%rbp), %ymm4 - vmovdqu 160(%rbp), %ymm5 - vmovdqu 192(%rdi), %ymm6 - vmovdqu %ymm0, (%rdi) - vmovdqu %ymm1, 32(%rdi) - vmovdqu %ymm2, 64(%rdi) - vmovdqu %ymm3, 96(%rdi) - vmovdqu %ymm4, 128(%rdi) - vmovdqu %ymm5, 160(%rdi) - vmovdqu %ymm6, 192(%rdi) -L_end_3072_sqr_avx2_24: - addq $192, %rsp + jne L_end_3072_sqr_avx2_12 + vmovdqu (%rbp), %xmm0 + vmovups %xmm0, (%rdi) + vmovdqu 16(%rbp), %xmm0 + vmovups %xmm0, 16(%rdi) + vmovdqu 32(%rbp), %xmm0 + vmovups %xmm0, 32(%rdi) + movq 48(%rbp), %rax + movq %rax, 48(%rdi) +L_end_3072_sqr_avx2_12: + addq $96, %rsp + pop %rbx + pop %r15 + pop %r14 pop %r13 pop %r12 pop %rbp repz retq #ifndef __APPLE__ -.size sp_3072_sqr_avx2_24,.-sp_3072_sqr_avx2_24 +.size sp_3072_sqr_avx2_12,.-sp_3072_sqr_avx2_12 #endif /* __APPLE__ */ #endif /* HAVE_INTEL_AVX2 */ /* Add b to a into r. (r = a + b) @@ -20893,6 +15477,158 @@ L_end_3072_sqr_avx2_24: * b A single precision integer. */ #ifndef __APPLE__ +.globl sp_3072_add_12 +.type sp_3072_add_12,@function +.align 16 +sp_3072_add_12: +#else +.globl _sp_3072_add_12 +.p2align 4 +_sp_3072_add_12: +#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 %r8, 88(%rdi) + adcq $0, %rax + repz retq +#ifndef __APPLE__ +.size sp_3072_add_12,.-sp_3072_add_12 +#endif /* __APPLE__ */ +/* Sub b from a into a. (a -= b) + * + * a A single precision integer and result. + * b A single precision integer. + */ +#ifndef __APPLE__ +.globl sp_3072_sub_in_place_24 +.type sp_3072_sub_in_place_24,@function +.align 16 +sp_3072_sub_in_place_24: +#else +.globl _sp_3072_sub_in_place_24 +.p2align 4 +_sp_3072_sub_in_place_24: +#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 128(%rdi), %rdx + movq %rcx, 120(%rdi) + sbbq 128(%rsi), %rdx + movq 136(%rdi), %rcx + movq %rdx, 128(%rdi) + sbbq 136(%rsi), %rcx + movq 144(%rdi), %rdx + movq %rcx, 136(%rdi) + sbbq 144(%rsi), %rdx + movq 152(%rdi), %rcx + movq %rdx, 144(%rdi) + sbbq 152(%rsi), %rcx + movq 160(%rdi), %rdx + movq %rcx, 152(%rdi) + sbbq 160(%rsi), %rdx + movq 168(%rdi), %rcx + movq %rdx, 160(%rdi) + sbbq 168(%rsi), %rcx + movq 176(%rdi), %rdx + movq %rcx, 168(%rdi) + sbbq 176(%rsi), %rdx + movq 184(%rdi), %rcx + movq %rdx, 176(%rdi) + sbbq 184(%rsi), %rcx + movq %rcx, 184(%rdi) + sbbq $0, %rax + repz retq +#ifndef __APPLE__ +.size sp_3072_sub_in_place_24,.-sp_3072_sub_in_place_24 +#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__ .globl sp_3072_add_24 .type sp_3072_add_24,@function .align 16 @@ -20902,6 +15638,7 @@ sp_3072_add_24: .p2align 4 _sp_3072_add_24: #endif /* __APPLE__ */ + # Add movq (%rsi), %rcx xorq %rax, %rax addq (%rdx), %rcx @@ -20980,6 +15717,2053 @@ _sp_3072_add_24: #ifndef __APPLE__ .size sp_3072_add_24,.-sp_3072_add_24 #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__ +.globl sp_3072_mul_24 +.type sp_3072_mul_24,@function +.align 16 +sp_3072_mul_24: +#else +.globl _sp_3072_mul_24 +.p2align 4 +_sp_3072_mul_24: +#endif /* __APPLE__ */ + push %r12 + push %r13 + push %r14 + push %r15 + subq $616, %rsp + movq %rdi, 576(%rsp) + movq %rsi, 584(%rsp) + movq %rdx, 592(%rsp) + leaq 384(%rsp), %r10 + leaq 96(%rsi), %r12 + # Add + movq (%rsi), %rax + xorq %r13, %r13 + addq (%r12), %rax + movq 8(%rsi), %rcx + movq %rax, (%r10) + adcq 8(%r12), %rcx + movq 16(%rsi), %r8 + movq %rcx, 8(%r10) + adcq 16(%r12), %r8 + movq 24(%rsi), %rax + movq %r8, 16(%r10) + adcq 24(%r12), %rax + movq 32(%rsi), %rcx + movq %rax, 24(%r10) + adcq 32(%r12), %rcx + movq 40(%rsi), %r8 + movq %rcx, 32(%r10) + adcq 40(%r12), %r8 + movq 48(%rsi), %rax + movq %r8, 40(%r10) + adcq 48(%r12), %rax + movq 56(%rsi), %rcx + movq %rax, 48(%r10) + adcq 56(%r12), %rcx + movq 64(%rsi), %r8 + movq %rcx, 56(%r10) + adcq 64(%r12), %r8 + movq 72(%rsi), %rax + movq %r8, 64(%r10) + adcq 72(%r12), %rax + movq 80(%rsi), %rcx + movq %rax, 72(%r10) + adcq 80(%r12), %rcx + movq 88(%rsi), %r8 + movq %rcx, 80(%r10) + adcq 88(%r12), %r8 + movq %r8, 88(%r10) + adcq $0, %r13 + movq %r13, 600(%rsp) + leaq 480(%rsp), %r11 + leaq 96(%rdx), %r12 + # Add + movq (%rdx), %rax + xorq %r14, %r14 + addq (%r12), %rax + movq 8(%rdx), %rcx + movq %rax, (%r11) + adcq 8(%r12), %rcx + movq 16(%rdx), %r8 + movq %rcx, 8(%r11) + adcq 16(%r12), %r8 + movq 24(%rdx), %rax + movq %r8, 16(%r11) + adcq 24(%r12), %rax + movq 32(%rdx), %rcx + movq %rax, 24(%r11) + adcq 32(%r12), %rcx + movq 40(%rdx), %r8 + movq %rcx, 32(%r11) + adcq 40(%r12), %r8 + movq 48(%rdx), %rax + movq %r8, 40(%r11) + adcq 48(%r12), %rax + movq 56(%rdx), %rcx + movq %rax, 48(%r11) + adcq 56(%r12), %rcx + movq 64(%rdx), %r8 + movq %rcx, 56(%r11) + adcq 64(%r12), %r8 + movq 72(%rdx), %rax + movq %r8, 64(%r11) + adcq 72(%r12), %rax + movq 80(%rdx), %rcx + movq %rax, 72(%r11) + adcq 80(%r12), %rcx + movq 88(%rdx), %r8 + movq %rcx, 80(%r11) + adcq 88(%r12), %r8 + movq %r8, 88(%r11) + adcq $0, %r14 + movq %r14, 608(%rsp) + movq %r11, %rdx + movq %r10, %rsi + movq %rsp, %rdi +#ifndef __APPLE__ + callq sp_3072_mul_12@plt +#else + callq _sp_3072_mul_12 +#endif /* __APPLE__ */ + movq 592(%rsp), %rdx + movq 584(%rsp), %rsi + leaq 192(%rsp), %rdi + addq $96, %rdx + addq $96, %rsi +#ifndef __APPLE__ + callq sp_3072_mul_12@plt +#else + callq _sp_3072_mul_12 +#endif /* __APPLE__ */ + movq 592(%rsp), %rdx + movq 584(%rsp), %rsi + movq 576(%rsp), %rdi +#ifndef __APPLE__ + callq sp_3072_mul_12@plt +#else + callq _sp_3072_mul_12 +#endif /* __APPLE__ */ + movq 600(%rsp), %r13 + movq 608(%rsp), %r14 + movq 576(%rsp), %r15 + movq %r13, %r9 + leaq 384(%rsp), %r10 + leaq 480(%rsp), %r11 + andq %r14, %r9 + negq %r13 + negq %r14 + addq $192, %r15 + movq (%r10), %rax + movq (%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, (%r10) + movq %rcx, (%r11) + movq 8(%r10), %rax + movq 8(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 8(%r10) + movq %rcx, 8(%r11) + movq 16(%r10), %rax + movq 16(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 16(%r10) + movq %rcx, 16(%r11) + movq 24(%r10), %rax + movq 24(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 24(%r10) + movq %rcx, 24(%r11) + movq 32(%r10), %rax + movq 32(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 32(%r10) + movq %rcx, 32(%r11) + movq 40(%r10), %rax + movq 40(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 40(%r10) + movq %rcx, 40(%r11) + movq 48(%r10), %rax + movq 48(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 48(%r10) + movq %rcx, 48(%r11) + movq 56(%r10), %rax + movq 56(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 56(%r10) + movq %rcx, 56(%r11) + movq 64(%r10), %rax + movq 64(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 64(%r10) + movq %rcx, 64(%r11) + movq 72(%r10), %rax + movq 72(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 72(%r10) + movq %rcx, 72(%r11) + movq 80(%r10), %rax + movq 80(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 80(%r10) + movq %rcx, 80(%r11) + movq 88(%r10), %rax + movq 88(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 88(%r10) + movq %rcx, 88(%r11) + movq (%r10), %rax + addq (%r11), %rax + movq 8(%r10), %rcx + movq %rax, (%r15) + adcq 8(%r11), %rcx + movq 16(%r10), %r8 + movq %rcx, 8(%r15) + adcq 16(%r11), %r8 + movq 24(%r10), %rax + movq %r8, 16(%r15) + adcq 24(%r11), %rax + movq 32(%r10), %rcx + movq %rax, 24(%r15) + adcq 32(%r11), %rcx + movq 40(%r10), %r8 + movq %rcx, 32(%r15) + adcq 40(%r11), %r8 + movq 48(%r10), %rax + movq %r8, 40(%r15) + adcq 48(%r11), %rax + movq 56(%r10), %rcx + movq %rax, 48(%r15) + adcq 56(%r11), %rcx + movq 64(%r10), %r8 + movq %rcx, 56(%r15) + adcq 64(%r11), %r8 + movq 72(%r10), %rax + movq %r8, 64(%r15) + adcq 72(%r11), %rax + movq 80(%r10), %rcx + movq %rax, 72(%r15) + adcq 80(%r11), %rcx + movq 88(%r10), %r8 + movq %rcx, 80(%r15) + adcq 88(%r11), %r8 + movq %r8, 88(%r15) + adcq $0, %r9 + leaq 192(%rsp), %r11 + movq %rsp, %r10 + movq (%r10), %rax + subq (%r11), %rax + movq 8(%r10), %rcx + movq %rax, (%r10) + sbbq 8(%r11), %rcx + movq 16(%r10), %r8 + movq %rcx, 8(%r10) + sbbq 16(%r11), %r8 + movq 24(%r10), %rax + movq %r8, 16(%r10) + sbbq 24(%r11), %rax + movq 32(%r10), %rcx + movq %rax, 24(%r10) + sbbq 32(%r11), %rcx + movq 40(%r10), %r8 + movq %rcx, 32(%r10) + sbbq 40(%r11), %r8 + movq 48(%r10), %rax + movq %r8, 40(%r10) + sbbq 48(%r11), %rax + movq 56(%r10), %rcx + movq %rax, 48(%r10) + sbbq 56(%r11), %rcx + movq 64(%r10), %r8 + movq %rcx, 56(%r10) + sbbq 64(%r11), %r8 + movq 72(%r10), %rax + movq %r8, 64(%r10) + sbbq 72(%r11), %rax + movq 80(%r10), %rcx + movq %rax, 72(%r10) + sbbq 80(%r11), %rcx + movq 88(%r10), %r8 + movq %rcx, 80(%r10) + sbbq 88(%r11), %r8 + movq 96(%r10), %rax + movq %r8, 88(%r10) + sbbq 96(%r11), %rax + movq 104(%r10), %rcx + movq %rax, 96(%r10) + sbbq 104(%r11), %rcx + movq 112(%r10), %r8 + movq %rcx, 104(%r10) + sbbq 112(%r11), %r8 + movq 120(%r10), %rax + movq %r8, 112(%r10) + sbbq 120(%r11), %rax + movq 128(%r10), %rcx + movq %rax, 120(%r10) + sbbq 128(%r11), %rcx + movq 136(%r10), %r8 + movq %rcx, 128(%r10) + sbbq 136(%r11), %r8 + movq 144(%r10), %rax + movq %r8, 136(%r10) + sbbq 144(%r11), %rax + movq 152(%r10), %rcx + movq %rax, 144(%r10) + sbbq 152(%r11), %rcx + movq 160(%r10), %r8 + movq %rcx, 152(%r10) + sbbq 160(%r11), %r8 + movq 168(%r10), %rax + movq %r8, 160(%r10) + sbbq 168(%r11), %rax + movq 176(%r10), %rcx + movq %rax, 168(%r10) + sbbq 176(%r11), %rcx + movq 184(%r10), %r8 + movq %rcx, 176(%r10) + sbbq 184(%r11), %r8 + movq %r8, 184(%r10) + sbbq $0, %r9 + movq (%r10), %rax + subq (%rdi), %rax + movq 8(%r10), %rcx + movq %rax, (%r10) + sbbq 8(%rdi), %rcx + movq 16(%r10), %r8 + movq %rcx, 8(%r10) + sbbq 16(%rdi), %r8 + movq 24(%r10), %rax + movq %r8, 16(%r10) + sbbq 24(%rdi), %rax + movq 32(%r10), %rcx + movq %rax, 24(%r10) + sbbq 32(%rdi), %rcx + movq 40(%r10), %r8 + movq %rcx, 32(%r10) + sbbq 40(%rdi), %r8 + movq 48(%r10), %rax + movq %r8, 40(%r10) + sbbq 48(%rdi), %rax + movq 56(%r10), %rcx + movq %rax, 48(%r10) + sbbq 56(%rdi), %rcx + movq 64(%r10), %r8 + movq %rcx, 56(%r10) + sbbq 64(%rdi), %r8 + movq 72(%r10), %rax + movq %r8, 64(%r10) + sbbq 72(%rdi), %rax + movq 80(%r10), %rcx + movq %rax, 72(%r10) + sbbq 80(%rdi), %rcx + movq 88(%r10), %r8 + movq %rcx, 80(%r10) + sbbq 88(%rdi), %r8 + movq 96(%r10), %rax + movq %r8, 88(%r10) + sbbq 96(%rdi), %rax + movq 104(%r10), %rcx + movq %rax, 96(%r10) + sbbq 104(%rdi), %rcx + movq 112(%r10), %r8 + movq %rcx, 104(%r10) + sbbq 112(%rdi), %r8 + movq 120(%r10), %rax + movq %r8, 112(%r10) + sbbq 120(%rdi), %rax + movq 128(%r10), %rcx + movq %rax, 120(%r10) + sbbq 128(%rdi), %rcx + movq 136(%r10), %r8 + movq %rcx, 128(%r10) + sbbq 136(%rdi), %r8 + movq 144(%r10), %rax + movq %r8, 136(%r10) + sbbq 144(%rdi), %rax + movq 152(%r10), %rcx + movq %rax, 144(%r10) + sbbq 152(%rdi), %rcx + movq 160(%r10), %r8 + movq %rcx, 152(%r10) + sbbq 160(%rdi), %r8 + movq 168(%r10), %rax + movq %r8, 160(%r10) + sbbq 168(%rdi), %rax + movq 176(%r10), %rcx + movq %rax, 168(%r10) + sbbq 176(%rdi), %rcx + movq 184(%r10), %r8 + movq %rcx, 176(%r10) + sbbq 184(%rdi), %r8 + movq %r8, 184(%r10) + sbbq $0, %r9 + subq $96, %r15 + # Add + movq (%r15), %rax + addq (%r10), %rax + movq 8(%r15), %rcx + movq %rax, (%r15) + adcq 8(%r10), %rcx + movq 16(%r15), %r8 + movq %rcx, 8(%r15) + adcq 16(%r10), %r8 + movq 24(%r15), %rax + movq %r8, 16(%r15) + adcq 24(%r10), %rax + movq 32(%r15), %rcx + movq %rax, 24(%r15) + adcq 32(%r10), %rcx + movq 40(%r15), %r8 + movq %rcx, 32(%r15) + adcq 40(%r10), %r8 + movq 48(%r15), %rax + movq %r8, 40(%r15) + adcq 48(%r10), %rax + movq 56(%r15), %rcx + movq %rax, 48(%r15) + adcq 56(%r10), %rcx + movq 64(%r15), %r8 + movq %rcx, 56(%r15) + adcq 64(%r10), %r8 + movq 72(%r15), %rax + movq %r8, 64(%r15) + adcq 72(%r10), %rax + movq 80(%r15), %rcx + movq %rax, 72(%r15) + adcq 80(%r10), %rcx + movq 88(%r15), %r8 + movq %rcx, 80(%r15) + adcq 88(%r10), %r8 + movq 96(%r15), %rax + movq %r8, 88(%r15) + adcq 96(%r10), %rax + movq 104(%r15), %rcx + movq %rax, 96(%r15) + adcq 104(%r10), %rcx + movq 112(%r15), %r8 + movq %rcx, 104(%r15) + adcq 112(%r10), %r8 + movq 120(%r15), %rax + movq %r8, 112(%r15) + adcq 120(%r10), %rax + movq 128(%r15), %rcx + movq %rax, 120(%r15) + adcq 128(%r10), %rcx + movq 136(%r15), %r8 + movq %rcx, 128(%r15) + adcq 136(%r10), %r8 + movq 144(%r15), %rax + movq %r8, 136(%r15) + adcq 144(%r10), %rax + movq 152(%r15), %rcx + movq %rax, 144(%r15) + adcq 152(%r10), %rcx + movq 160(%r15), %r8 + movq %rcx, 152(%r15) + adcq 160(%r10), %r8 + movq 168(%r15), %rax + movq %r8, 160(%r15) + adcq 168(%r10), %rax + movq 176(%r15), %rcx + movq %rax, 168(%r15) + adcq 176(%r10), %rcx + movq 184(%r15), %r8 + movq %rcx, 176(%r15) + adcq 184(%r10), %r8 + movq %r8, 184(%r15) + adcq $0, %r9 + movq %r9, 288(%rdi) + addq $96, %r15 + # Add + movq (%r15), %rax + addq (%r11), %rax + movq 8(%r15), %rcx + movq %rax, (%r15) + adcq 8(%r11), %rcx + movq 16(%r15), %r8 + movq %rcx, 8(%r15) + adcq 16(%r11), %r8 + movq 24(%r15), %rax + movq %r8, 16(%r15) + adcq 24(%r11), %rax + movq 32(%r15), %rcx + movq %rax, 24(%r15) + adcq 32(%r11), %rcx + movq 40(%r15), %r8 + movq %rcx, 32(%r15) + adcq 40(%r11), %r8 + movq 48(%r15), %rax + movq %r8, 40(%r15) + adcq 48(%r11), %rax + movq 56(%r15), %rcx + movq %rax, 48(%r15) + adcq 56(%r11), %rcx + movq 64(%r15), %r8 + movq %rcx, 56(%r15) + adcq 64(%r11), %r8 + movq 72(%r15), %rax + movq %r8, 64(%r15) + adcq 72(%r11), %rax + movq 80(%r15), %rcx + movq %rax, 72(%r15) + adcq 80(%r11), %rcx + movq 88(%r15), %r8 + movq %rcx, 80(%r15) + adcq 88(%r11), %r8 + movq 96(%r15), %rax + movq %r8, 88(%r15) + adcq 96(%r11), %rax + movq %rax, 96(%r15) + # Add to zero + movq 104(%r11), %rax + adcq $0, %rax + movq 112(%r11), %rcx + movq %rax, 104(%r15) + adcq $0, %rcx + movq 120(%r11), %r8 + movq %rcx, 112(%r15) + adcq $0, %r8 + movq 128(%r11), %rax + movq %r8, 120(%r15) + adcq $0, %rax + movq 136(%r11), %rcx + movq %rax, 128(%r15) + adcq $0, %rcx + movq 144(%r11), %r8 + movq %rcx, 136(%r15) + adcq $0, %r8 + movq 152(%r11), %rax + movq %r8, 144(%r15) + adcq $0, %rax + movq 160(%r11), %rcx + movq %rax, 152(%r15) + adcq $0, %rcx + movq 168(%r11), %r8 + movq %rcx, 160(%r15) + adcq $0, %r8 + movq 176(%r11), %rax + movq %r8, 168(%r15) + adcq $0, %rax + movq 184(%r11), %rcx + movq %rax, 176(%r15) + adcq $0, %rcx + movq %rcx, 184(%r15) + addq $616, %rsp + pop %r15 + pop %r14 + pop %r13 + pop %r12 + repz retq +#ifndef __APPLE__ +.size sp_3072_mul_24,.-sp_3072_mul_24 +#endif /* __APPLE__ */ +/* Add a to a into r. (r = a + a) + * + * r A single precision integer. + * a A single precision integer. + */ +#ifndef __APPLE__ +.globl sp_3072_dbl_12 +.type sp_3072_dbl_12,@function +.align 16 +sp_3072_dbl_12: +#else +.globl _sp_3072_dbl_12 +.p2align 4 +_sp_3072_dbl_12: +#endif /* __APPLE__ */ + movq (%rsi), %rdx + xorq %rax, %rax + addq %rdx, %rdx + movq 8(%rsi), %rcx + movq %rdx, (%rdi) + adcq %rcx, %rcx + movq 16(%rsi), %rdx + movq %rcx, 8(%rdi) + adcq %rdx, %rdx + movq 24(%rsi), %rcx + movq %rdx, 16(%rdi) + adcq %rcx, %rcx + movq 32(%rsi), %rdx + movq %rcx, 24(%rdi) + adcq %rdx, %rdx + movq 40(%rsi), %rcx + movq %rdx, 32(%rdi) + adcq %rcx, %rcx + movq 48(%rsi), %rdx + movq %rcx, 40(%rdi) + adcq %rdx, %rdx + movq 56(%rsi), %rcx + movq %rdx, 48(%rdi) + adcq %rcx, %rcx + movq 64(%rsi), %rdx + movq %rcx, 56(%rdi) + adcq %rdx, %rdx + movq 72(%rsi), %rcx + movq %rdx, 64(%rdi) + adcq %rcx, %rcx + movq 80(%rsi), %rdx + movq %rcx, 72(%rdi) + adcq %rdx, %rdx + movq 88(%rsi), %rcx + movq %rdx, 80(%rdi) + adcq %rcx, %rcx + movq %rcx, 88(%rdi) + adcq $0, %rax + repz retq +#ifndef __APPLE__ +.size sp_3072_dbl_12,.-sp_3072_dbl_12 +#endif /* __APPLE__ */ +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +#ifndef __APPLE__ +.globl sp_3072_sqr_24 +.type sp_3072_sqr_24,@function +.align 16 +sp_3072_sqr_24: +#else +.globl _sp_3072_sqr_24 +.p2align 4 +_sp_3072_sqr_24: +#endif /* __APPLE__ */ + subq $504, %rsp + movq %rdi, 480(%rsp) + movq %rsi, 488(%rsp) + leaq 384(%rsp), %r8 + leaq 96(%rsi), %r9 + # Add + movq (%rsi), %rdx + xorq %rcx, %rcx + addq (%r9), %rdx + movq 8(%rsi), %rax + movq %rdx, (%r8) + adcq 8(%r9), %rax + movq 16(%rsi), %rdx + movq %rax, 8(%r8) + adcq 16(%r9), %rdx + movq 24(%rsi), %rax + movq %rdx, 16(%r8) + adcq 24(%r9), %rax + movq 32(%rsi), %rdx + movq %rax, 24(%r8) + adcq 32(%r9), %rdx + movq 40(%rsi), %rax + movq %rdx, 32(%r8) + adcq 40(%r9), %rax + movq 48(%rsi), %rdx + movq %rax, 40(%r8) + adcq 48(%r9), %rdx + movq 56(%rsi), %rax + movq %rdx, 48(%r8) + adcq 56(%r9), %rax + movq 64(%rsi), %rdx + movq %rax, 56(%r8) + adcq 64(%r9), %rdx + movq 72(%rsi), %rax + movq %rdx, 64(%r8) + adcq 72(%r9), %rax + movq 80(%rsi), %rdx + movq %rax, 72(%r8) + adcq 80(%r9), %rdx + movq 88(%rsi), %rax + movq %rdx, 80(%r8) + adcq 88(%r9), %rax + movq %rax, 88(%r8) + adcq $0, %rcx + movq %rcx, 496(%rsp) + movq %r8, %rsi + movq %rsp, %rdi +#ifndef __APPLE__ + callq sp_3072_sqr_12@plt +#else + callq _sp_3072_sqr_12 +#endif /* __APPLE__ */ + movq 488(%rsp), %rsi + leaq 192(%rsp), %rdi + addq $96, %rsi +#ifndef __APPLE__ + callq sp_3072_sqr_12@plt +#else + callq _sp_3072_sqr_12 +#endif /* __APPLE__ */ + movq 488(%rsp), %rsi + movq 480(%rsp), %rdi +#ifndef __APPLE__ + callq sp_3072_sqr_12@plt +#else + callq _sp_3072_sqr_12 +#endif /* __APPLE__ */ + movq 496(%rsp), %r10 + movq %rdi, %r9 + leaq 384(%rsp), %r8 + movq %r10, %rcx + negq %r10 + addq $192, %r9 + movq (%r8), %rdx + movq 8(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, (%r9) + movq %rax, 8(%r9) + movq 16(%r8), %rdx + movq 24(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 16(%r9) + movq %rax, 24(%r9) + movq 32(%r8), %rdx + movq 40(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 32(%r9) + movq %rax, 40(%r9) + movq 48(%r8), %rdx + movq 56(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 48(%r9) + movq %rax, 56(%r9) + movq 64(%r8), %rdx + movq 72(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 64(%r9) + movq %rax, 72(%r9) + movq 80(%r8), %rdx + movq 88(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 80(%r9) + movq %rax, 88(%r9) + movq (%r9), %rdx + addq %rdx, %rdx + movq 8(%r9), %rax + movq %rdx, (%r9) + adcq %rax, %rax + movq 16(%r9), %rdx + movq %rax, 8(%r9) + adcq %rdx, %rdx + movq 24(%r9), %rax + movq %rdx, 16(%r9) + adcq %rax, %rax + movq 32(%r9), %rdx + movq %rax, 24(%r9) + adcq %rdx, %rdx + movq 40(%r9), %rax + movq %rdx, 32(%r9) + adcq %rax, %rax + movq 48(%r9), %rdx + movq %rax, 40(%r9) + adcq %rdx, %rdx + movq 56(%r9), %rax + movq %rdx, 48(%r9) + adcq %rax, %rax + movq 64(%r9), %rdx + movq %rax, 56(%r9) + adcq %rdx, %rdx + movq 72(%r9), %rax + movq %rdx, 64(%r9) + adcq %rax, %rax + movq 80(%r9), %rdx + movq %rax, 72(%r9) + adcq %rdx, %rdx + movq 88(%r9), %rax + movq %rdx, 80(%r9) + adcq %rax, %rax + movq %rax, 88(%r9) + adcq $0, %rcx + leaq 192(%rsp), %rsi + movq %rsp, %r8 + movq (%r8), %rdx + subq (%rsi), %rdx + movq 8(%r8), %rax + movq %rdx, (%r8) + sbbq 8(%rsi), %rax + movq 16(%r8), %rdx + movq %rax, 8(%r8) + sbbq 16(%rsi), %rdx + movq 24(%r8), %rax + movq %rdx, 16(%r8) + sbbq 24(%rsi), %rax + movq 32(%r8), %rdx + movq %rax, 24(%r8) + sbbq 32(%rsi), %rdx + movq 40(%r8), %rax + movq %rdx, 32(%r8) + sbbq 40(%rsi), %rax + movq 48(%r8), %rdx + movq %rax, 40(%r8) + sbbq 48(%rsi), %rdx + movq 56(%r8), %rax + movq %rdx, 48(%r8) + sbbq 56(%rsi), %rax + movq 64(%r8), %rdx + movq %rax, 56(%r8) + sbbq 64(%rsi), %rdx + movq 72(%r8), %rax + movq %rdx, 64(%r8) + sbbq 72(%rsi), %rax + movq 80(%r8), %rdx + movq %rax, 72(%r8) + sbbq 80(%rsi), %rdx + movq 88(%r8), %rax + movq %rdx, 80(%r8) + sbbq 88(%rsi), %rax + movq 96(%r8), %rdx + movq %rax, 88(%r8) + sbbq 96(%rsi), %rdx + movq 104(%r8), %rax + movq %rdx, 96(%r8) + sbbq 104(%rsi), %rax + movq 112(%r8), %rdx + movq %rax, 104(%r8) + sbbq 112(%rsi), %rdx + movq 120(%r8), %rax + movq %rdx, 112(%r8) + sbbq 120(%rsi), %rax + movq 128(%r8), %rdx + movq %rax, 120(%r8) + sbbq 128(%rsi), %rdx + movq 136(%r8), %rax + movq %rdx, 128(%r8) + sbbq 136(%rsi), %rax + movq 144(%r8), %rdx + movq %rax, 136(%r8) + sbbq 144(%rsi), %rdx + movq 152(%r8), %rax + movq %rdx, 144(%r8) + sbbq 152(%rsi), %rax + movq 160(%r8), %rdx + movq %rax, 152(%r8) + sbbq 160(%rsi), %rdx + movq 168(%r8), %rax + movq %rdx, 160(%r8) + sbbq 168(%rsi), %rax + movq 176(%r8), %rdx + movq %rax, 168(%r8) + sbbq 176(%rsi), %rdx + movq 184(%r8), %rax + movq %rdx, 176(%r8) + sbbq 184(%rsi), %rax + movq %rax, 184(%r8) + sbbq $0, %rcx + movq (%r8), %rdx + subq (%rdi), %rdx + movq 8(%r8), %rax + movq %rdx, (%r8) + sbbq 8(%rdi), %rax + movq 16(%r8), %rdx + movq %rax, 8(%r8) + sbbq 16(%rdi), %rdx + movq 24(%r8), %rax + movq %rdx, 16(%r8) + sbbq 24(%rdi), %rax + movq 32(%r8), %rdx + movq %rax, 24(%r8) + sbbq 32(%rdi), %rdx + movq 40(%r8), %rax + movq %rdx, 32(%r8) + sbbq 40(%rdi), %rax + movq 48(%r8), %rdx + movq %rax, 40(%r8) + sbbq 48(%rdi), %rdx + movq 56(%r8), %rax + movq %rdx, 48(%r8) + sbbq 56(%rdi), %rax + movq 64(%r8), %rdx + movq %rax, 56(%r8) + sbbq 64(%rdi), %rdx + movq 72(%r8), %rax + movq %rdx, 64(%r8) + sbbq 72(%rdi), %rax + movq 80(%r8), %rdx + movq %rax, 72(%r8) + sbbq 80(%rdi), %rdx + movq 88(%r8), %rax + movq %rdx, 80(%r8) + sbbq 88(%rdi), %rax + movq 96(%r8), %rdx + movq %rax, 88(%r8) + sbbq 96(%rdi), %rdx + movq 104(%r8), %rax + movq %rdx, 96(%r8) + sbbq 104(%rdi), %rax + movq 112(%r8), %rdx + movq %rax, 104(%r8) + sbbq 112(%rdi), %rdx + movq 120(%r8), %rax + movq %rdx, 112(%r8) + sbbq 120(%rdi), %rax + movq 128(%r8), %rdx + movq %rax, 120(%r8) + sbbq 128(%rdi), %rdx + movq 136(%r8), %rax + movq %rdx, 128(%r8) + sbbq 136(%rdi), %rax + movq 144(%r8), %rdx + movq %rax, 136(%r8) + sbbq 144(%rdi), %rdx + movq 152(%r8), %rax + movq %rdx, 144(%r8) + sbbq 152(%rdi), %rax + movq 160(%r8), %rdx + movq %rax, 152(%r8) + sbbq 160(%rdi), %rdx + movq 168(%r8), %rax + movq %rdx, 160(%r8) + sbbq 168(%rdi), %rax + movq 176(%r8), %rdx + movq %rax, 168(%r8) + sbbq 176(%rdi), %rdx + movq 184(%r8), %rax + movq %rdx, 176(%r8) + sbbq 184(%rdi), %rax + movq %rax, 184(%r8) + sbbq $0, %rcx + subq $96, %r9 + # Add in place + movq (%r9), %rdx + addq (%r8), %rdx + movq 8(%r9), %rax + movq %rdx, (%r9) + adcq 8(%r8), %rax + movq 16(%r9), %rdx + movq %rax, 8(%r9) + adcq 16(%r8), %rdx + movq 24(%r9), %rax + movq %rdx, 16(%r9) + adcq 24(%r8), %rax + movq 32(%r9), %rdx + movq %rax, 24(%r9) + adcq 32(%r8), %rdx + movq 40(%r9), %rax + movq %rdx, 32(%r9) + adcq 40(%r8), %rax + movq 48(%r9), %rdx + movq %rax, 40(%r9) + adcq 48(%r8), %rdx + movq 56(%r9), %rax + movq %rdx, 48(%r9) + adcq 56(%r8), %rax + movq 64(%r9), %rdx + movq %rax, 56(%r9) + adcq 64(%r8), %rdx + movq 72(%r9), %rax + movq %rdx, 64(%r9) + adcq 72(%r8), %rax + movq 80(%r9), %rdx + movq %rax, 72(%r9) + adcq 80(%r8), %rdx + movq 88(%r9), %rax + movq %rdx, 80(%r9) + adcq 88(%r8), %rax + movq 96(%r9), %rdx + movq %rax, 88(%r9) + adcq 96(%r8), %rdx + movq 104(%r9), %rax + movq %rdx, 96(%r9) + adcq 104(%r8), %rax + movq 112(%r9), %rdx + movq %rax, 104(%r9) + adcq 112(%r8), %rdx + movq 120(%r9), %rax + movq %rdx, 112(%r9) + adcq 120(%r8), %rax + movq 128(%r9), %rdx + movq %rax, 120(%r9) + adcq 128(%r8), %rdx + movq 136(%r9), %rax + movq %rdx, 128(%r9) + adcq 136(%r8), %rax + movq 144(%r9), %rdx + movq %rax, 136(%r9) + adcq 144(%r8), %rdx + movq 152(%r9), %rax + movq %rdx, 144(%r9) + adcq 152(%r8), %rax + movq 160(%r9), %rdx + movq %rax, 152(%r9) + adcq 160(%r8), %rdx + movq 168(%r9), %rax + movq %rdx, 160(%r9) + adcq 168(%r8), %rax + movq 176(%r9), %rdx + movq %rax, 168(%r9) + adcq 176(%r8), %rdx + movq 184(%r9), %rax + movq %rdx, 176(%r9) + adcq 184(%r8), %rax + movq %rax, 184(%r9) + adcq $0, %rcx + movq %rcx, 288(%rdi) + # Add in place + movq 96(%r9), %rdx + addq (%rsi), %rdx + movq 104(%r9), %rax + movq %rdx, 96(%r9) + adcq 8(%rsi), %rax + movq 112(%r9), %rdx + movq %rax, 104(%r9) + adcq 16(%rsi), %rdx + movq 120(%r9), %rax + movq %rdx, 112(%r9) + adcq 24(%rsi), %rax + movq 128(%r9), %rdx + movq %rax, 120(%r9) + adcq 32(%rsi), %rdx + movq 136(%r9), %rax + movq %rdx, 128(%r9) + adcq 40(%rsi), %rax + movq 144(%r9), %rdx + movq %rax, 136(%r9) + adcq 48(%rsi), %rdx + movq 152(%r9), %rax + movq %rdx, 144(%r9) + adcq 56(%rsi), %rax + movq 160(%r9), %rdx + movq %rax, 152(%r9) + adcq 64(%rsi), %rdx + movq 168(%r9), %rax + movq %rdx, 160(%r9) + adcq 72(%rsi), %rax + movq 176(%r9), %rdx + movq %rax, 168(%r9) + adcq 80(%rsi), %rdx + movq 184(%r9), %rax + movq %rdx, 176(%r9) + adcq 88(%rsi), %rax + movq 192(%r9), %rdx + movq %rax, 184(%r9) + adcq 96(%rsi), %rdx + movq %rdx, 192(%r9) + # Add to zero + movq 104(%rsi), %rdx + adcq $0, %rdx + movq 112(%rsi), %rax + movq %rdx, 200(%r9) + adcq $0, %rax + movq 120(%rsi), %rdx + movq %rax, 208(%r9) + adcq $0, %rdx + movq 128(%rsi), %rax + movq %rdx, 216(%r9) + adcq $0, %rax + movq 136(%rsi), %rdx + movq %rax, 224(%r9) + adcq $0, %rdx + movq 144(%rsi), %rax + movq %rdx, 232(%r9) + adcq $0, %rax + movq 152(%rsi), %rdx + movq %rax, 240(%r9) + adcq $0, %rdx + movq 160(%rsi), %rax + movq %rdx, 248(%r9) + adcq $0, %rax + movq 168(%rsi), %rdx + movq %rax, 256(%r9) + adcq $0, %rdx + movq 176(%rsi), %rax + movq %rdx, 264(%r9) + adcq $0, %rax + movq 184(%rsi), %rdx + movq %rax, 272(%r9) + adcq $0, %rdx + movq %rdx, 280(%r9) + addq $504, %rsp + repz retq +#ifndef __APPLE__ +.size sp_3072_sqr_24,.-sp_3072_sqr_24 +#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__ +.globl sp_3072_mul_avx2_24 +.type sp_3072_mul_avx2_24,@function +.align 16 +sp_3072_mul_avx2_24: +#else +.globl _sp_3072_mul_avx2_24 +.p2align 4 +_sp_3072_mul_avx2_24: +#endif /* __APPLE__ */ + push %r12 + push %r13 + push %r14 + push %r15 + subq $616, %rsp + movq %rdi, 576(%rsp) + movq %rsi, 584(%rsp) + movq %rdx, 592(%rsp) + leaq 384(%rsp), %r10 + leaq 96(%rsi), %r12 + # Add + movq (%rsi), %rax + xorq %r13, %r13 + addq (%r12), %rax + movq 8(%rsi), %rcx + movq %rax, (%r10) + adcq 8(%r12), %rcx + movq 16(%rsi), %r8 + movq %rcx, 8(%r10) + adcq 16(%r12), %r8 + movq 24(%rsi), %rax + movq %r8, 16(%r10) + adcq 24(%r12), %rax + movq 32(%rsi), %rcx + movq %rax, 24(%r10) + adcq 32(%r12), %rcx + movq 40(%rsi), %r8 + movq %rcx, 32(%r10) + adcq 40(%r12), %r8 + movq 48(%rsi), %rax + movq %r8, 40(%r10) + adcq 48(%r12), %rax + movq 56(%rsi), %rcx + movq %rax, 48(%r10) + adcq 56(%r12), %rcx + movq 64(%rsi), %r8 + movq %rcx, 56(%r10) + adcq 64(%r12), %r8 + movq 72(%rsi), %rax + movq %r8, 64(%r10) + adcq 72(%r12), %rax + movq 80(%rsi), %rcx + movq %rax, 72(%r10) + adcq 80(%r12), %rcx + movq 88(%rsi), %r8 + movq %rcx, 80(%r10) + adcq 88(%r12), %r8 + movq %r8, 88(%r10) + adcq $0, %r13 + movq %r13, 600(%rsp) + leaq 480(%rsp), %r11 + leaq 96(%rdx), %r12 + # Add + movq (%rdx), %rax + xorq %r14, %r14 + addq (%r12), %rax + movq 8(%rdx), %rcx + movq %rax, (%r11) + adcq 8(%r12), %rcx + movq 16(%rdx), %r8 + movq %rcx, 8(%r11) + adcq 16(%r12), %r8 + movq 24(%rdx), %rax + movq %r8, 16(%r11) + adcq 24(%r12), %rax + movq 32(%rdx), %rcx + movq %rax, 24(%r11) + adcq 32(%r12), %rcx + movq 40(%rdx), %r8 + movq %rcx, 32(%r11) + adcq 40(%r12), %r8 + movq 48(%rdx), %rax + movq %r8, 40(%r11) + adcq 48(%r12), %rax + movq 56(%rdx), %rcx + movq %rax, 48(%r11) + adcq 56(%r12), %rcx + movq 64(%rdx), %r8 + movq %rcx, 56(%r11) + adcq 64(%r12), %r8 + movq 72(%rdx), %rax + movq %r8, 64(%r11) + adcq 72(%r12), %rax + movq 80(%rdx), %rcx + movq %rax, 72(%r11) + adcq 80(%r12), %rcx + movq 88(%rdx), %r8 + movq %rcx, 80(%r11) + adcq 88(%r12), %r8 + movq %r8, 88(%r11) + adcq $0, %r14 + movq %r14, 608(%rsp) + movq %r11, %rdx + movq %r10, %rsi + movq %rsp, %rdi +#ifndef __APPLE__ + callq sp_3072_mul_avx2_12@plt +#else + callq _sp_3072_mul_avx2_12 +#endif /* __APPLE__ */ + movq 592(%rsp), %rdx + movq 584(%rsp), %rsi + leaq 192(%rsp), %rdi + addq $96, %rdx + addq $96, %rsi +#ifndef __APPLE__ + callq sp_3072_mul_avx2_12@plt +#else + callq _sp_3072_mul_avx2_12 +#endif /* __APPLE__ */ + movq 592(%rsp), %rdx + movq 584(%rsp), %rsi + movq 576(%rsp), %rdi +#ifndef __APPLE__ + callq sp_3072_mul_avx2_12@plt +#else + callq _sp_3072_mul_avx2_12 +#endif /* __APPLE__ */ + movq 600(%rsp), %r13 + movq 608(%rsp), %r14 + movq 576(%rsp), %r15 + movq %r13, %r9 + leaq 384(%rsp), %r10 + leaq 480(%rsp), %r11 + andq %r14, %r9 + negq %r13 + negq %r14 + addq $192, %r15 + movq (%r10), %rax + movq (%r11), %rcx + pextq %r14, %rax, %rax + pextq %r13, %rcx, %rcx + addq %rcx, %rax + movq 8(%r10), %rcx + movq 8(%r11), %r8 + pextq %r14, %rcx, %rcx + pextq %r13, %r8, %r8 + movq %rax, (%r15) + adcq %r8, %rcx + movq 16(%r10), %r8 + movq 16(%r11), %rax + pextq %r14, %r8, %r8 + pextq %r13, %rax, %rax + movq %rcx, 8(%r15) + adcq %rax, %r8 + movq 24(%r10), %rax + movq 24(%r11), %rcx + pextq %r14, %rax, %rax + pextq %r13, %rcx, %rcx + movq %r8, 16(%r15) + adcq %rcx, %rax + movq 32(%r10), %rcx + movq 32(%r11), %r8 + pextq %r14, %rcx, %rcx + pextq %r13, %r8, %r8 + movq %rax, 24(%r15) + adcq %r8, %rcx + movq 40(%r10), %r8 + movq 40(%r11), %rax + pextq %r14, %r8, %r8 + pextq %r13, %rax, %rax + movq %rcx, 32(%r15) + adcq %rax, %r8 + movq 48(%r10), %rax + movq 48(%r11), %rcx + pextq %r14, %rax, %rax + pextq %r13, %rcx, %rcx + movq %r8, 40(%r15) + adcq %rcx, %rax + movq 56(%r10), %rcx + movq 56(%r11), %r8 + pextq %r14, %rcx, %rcx + pextq %r13, %r8, %r8 + movq %rax, 48(%r15) + adcq %r8, %rcx + movq 64(%r10), %r8 + movq 64(%r11), %rax + pextq %r14, %r8, %r8 + pextq %r13, %rax, %rax + movq %rcx, 56(%r15) + adcq %rax, %r8 + movq 72(%r10), %rax + movq 72(%r11), %rcx + pextq %r14, %rax, %rax + pextq %r13, %rcx, %rcx + movq %r8, 64(%r15) + adcq %rcx, %rax + movq 80(%r10), %rcx + movq 80(%r11), %r8 + pextq %r14, %rcx, %rcx + pextq %r13, %r8, %r8 + movq %rax, 72(%r15) + adcq %r8, %rcx + movq 88(%r10), %r8 + movq 88(%r11), %rax + pextq %r14, %r8, %r8 + pextq %r13, %rax, %rax + movq %rcx, 80(%r15) + adcq %rax, %r8 + movq %r8, 88(%r15) + adcq $0, %r9 + leaq 192(%rsp), %r11 + movq %rsp, %r10 + movq (%r10), %rax + subq (%r11), %rax + movq 8(%r10), %rcx + movq %rax, (%r10) + sbbq 8(%r11), %rcx + movq 16(%r10), %r8 + movq %rcx, 8(%r10) + sbbq 16(%r11), %r8 + movq 24(%r10), %rax + movq %r8, 16(%r10) + sbbq 24(%r11), %rax + movq 32(%r10), %rcx + movq %rax, 24(%r10) + sbbq 32(%r11), %rcx + movq 40(%r10), %r8 + movq %rcx, 32(%r10) + sbbq 40(%r11), %r8 + movq 48(%r10), %rax + movq %r8, 40(%r10) + sbbq 48(%r11), %rax + movq 56(%r10), %rcx + movq %rax, 48(%r10) + sbbq 56(%r11), %rcx + movq 64(%r10), %r8 + movq %rcx, 56(%r10) + sbbq 64(%r11), %r8 + movq 72(%r10), %rax + movq %r8, 64(%r10) + sbbq 72(%r11), %rax + movq 80(%r10), %rcx + movq %rax, 72(%r10) + sbbq 80(%r11), %rcx + movq 88(%r10), %r8 + movq %rcx, 80(%r10) + sbbq 88(%r11), %r8 + movq 96(%r10), %rax + movq %r8, 88(%r10) + sbbq 96(%r11), %rax + movq 104(%r10), %rcx + movq %rax, 96(%r10) + sbbq 104(%r11), %rcx + movq 112(%r10), %r8 + movq %rcx, 104(%r10) + sbbq 112(%r11), %r8 + movq 120(%r10), %rax + movq %r8, 112(%r10) + sbbq 120(%r11), %rax + movq 128(%r10), %rcx + movq %rax, 120(%r10) + sbbq 128(%r11), %rcx + movq 136(%r10), %r8 + movq %rcx, 128(%r10) + sbbq 136(%r11), %r8 + movq 144(%r10), %rax + movq %r8, 136(%r10) + sbbq 144(%r11), %rax + movq 152(%r10), %rcx + movq %rax, 144(%r10) + sbbq 152(%r11), %rcx + movq 160(%r10), %r8 + movq %rcx, 152(%r10) + sbbq 160(%r11), %r8 + movq 168(%r10), %rax + movq %r8, 160(%r10) + sbbq 168(%r11), %rax + movq 176(%r10), %rcx + movq %rax, 168(%r10) + sbbq 176(%r11), %rcx + movq 184(%r10), %r8 + movq %rcx, 176(%r10) + sbbq 184(%r11), %r8 + movq %r8, 184(%r10) + sbbq $0, %r9 + movq (%r10), %rax + subq (%rdi), %rax + movq 8(%r10), %rcx + movq %rax, (%r10) + sbbq 8(%rdi), %rcx + movq 16(%r10), %r8 + movq %rcx, 8(%r10) + sbbq 16(%rdi), %r8 + movq 24(%r10), %rax + movq %r8, 16(%r10) + sbbq 24(%rdi), %rax + movq 32(%r10), %rcx + movq %rax, 24(%r10) + sbbq 32(%rdi), %rcx + movq 40(%r10), %r8 + movq %rcx, 32(%r10) + sbbq 40(%rdi), %r8 + movq 48(%r10), %rax + movq %r8, 40(%r10) + sbbq 48(%rdi), %rax + movq 56(%r10), %rcx + movq %rax, 48(%r10) + sbbq 56(%rdi), %rcx + movq 64(%r10), %r8 + movq %rcx, 56(%r10) + sbbq 64(%rdi), %r8 + movq 72(%r10), %rax + movq %r8, 64(%r10) + sbbq 72(%rdi), %rax + movq 80(%r10), %rcx + movq %rax, 72(%r10) + sbbq 80(%rdi), %rcx + movq 88(%r10), %r8 + movq %rcx, 80(%r10) + sbbq 88(%rdi), %r8 + movq 96(%r10), %rax + movq %r8, 88(%r10) + sbbq 96(%rdi), %rax + movq 104(%r10), %rcx + movq %rax, 96(%r10) + sbbq 104(%rdi), %rcx + movq 112(%r10), %r8 + movq %rcx, 104(%r10) + sbbq 112(%rdi), %r8 + movq 120(%r10), %rax + movq %r8, 112(%r10) + sbbq 120(%rdi), %rax + movq 128(%r10), %rcx + movq %rax, 120(%r10) + sbbq 128(%rdi), %rcx + movq 136(%r10), %r8 + movq %rcx, 128(%r10) + sbbq 136(%rdi), %r8 + movq 144(%r10), %rax + movq %r8, 136(%r10) + sbbq 144(%rdi), %rax + movq 152(%r10), %rcx + movq %rax, 144(%r10) + sbbq 152(%rdi), %rcx + movq 160(%r10), %r8 + movq %rcx, 152(%r10) + sbbq 160(%rdi), %r8 + movq 168(%r10), %rax + movq %r8, 160(%r10) + sbbq 168(%rdi), %rax + movq 176(%r10), %rcx + movq %rax, 168(%r10) + sbbq 176(%rdi), %rcx + movq 184(%r10), %r8 + movq %rcx, 176(%r10) + sbbq 184(%rdi), %r8 + movq %r8, 184(%r10) + sbbq $0, %r9 + subq $96, %r15 + # Add + movq (%r15), %rax + addq (%r10), %rax + movq 8(%r15), %rcx + movq %rax, (%r15) + adcq 8(%r10), %rcx + movq 16(%r15), %r8 + movq %rcx, 8(%r15) + adcq 16(%r10), %r8 + movq 24(%r15), %rax + movq %r8, 16(%r15) + adcq 24(%r10), %rax + movq 32(%r15), %rcx + movq %rax, 24(%r15) + adcq 32(%r10), %rcx + movq 40(%r15), %r8 + movq %rcx, 32(%r15) + adcq 40(%r10), %r8 + movq 48(%r15), %rax + movq %r8, 40(%r15) + adcq 48(%r10), %rax + movq 56(%r15), %rcx + movq %rax, 48(%r15) + adcq 56(%r10), %rcx + movq 64(%r15), %r8 + movq %rcx, 56(%r15) + adcq 64(%r10), %r8 + movq 72(%r15), %rax + movq %r8, 64(%r15) + adcq 72(%r10), %rax + movq 80(%r15), %rcx + movq %rax, 72(%r15) + adcq 80(%r10), %rcx + movq 88(%r15), %r8 + movq %rcx, 80(%r15) + adcq 88(%r10), %r8 + movq 96(%r15), %rax + movq %r8, 88(%r15) + adcq 96(%r10), %rax + movq 104(%r15), %rcx + movq %rax, 96(%r15) + adcq 104(%r10), %rcx + movq 112(%r15), %r8 + movq %rcx, 104(%r15) + adcq 112(%r10), %r8 + movq 120(%r15), %rax + movq %r8, 112(%r15) + adcq 120(%r10), %rax + movq 128(%r15), %rcx + movq %rax, 120(%r15) + adcq 128(%r10), %rcx + movq 136(%r15), %r8 + movq %rcx, 128(%r15) + adcq 136(%r10), %r8 + movq 144(%r15), %rax + movq %r8, 136(%r15) + adcq 144(%r10), %rax + movq 152(%r15), %rcx + movq %rax, 144(%r15) + adcq 152(%r10), %rcx + movq 160(%r15), %r8 + movq %rcx, 152(%r15) + adcq 160(%r10), %r8 + movq 168(%r15), %rax + movq %r8, 160(%r15) + adcq 168(%r10), %rax + movq 176(%r15), %rcx + movq %rax, 168(%r15) + adcq 176(%r10), %rcx + movq 184(%r15), %r8 + movq %rcx, 176(%r15) + adcq 184(%r10), %r8 + movq %r8, 184(%r15) + adcq $0, %r9 + movq %r9, 288(%rdi) + addq $96, %r15 + # Add + movq (%r15), %rax + addq (%r11), %rax + movq 8(%r15), %rcx + movq %rax, (%r15) + adcq 8(%r11), %rcx + movq 16(%r15), %r8 + movq %rcx, 8(%r15) + adcq 16(%r11), %r8 + movq 24(%r15), %rax + movq %r8, 16(%r15) + adcq 24(%r11), %rax + movq 32(%r15), %rcx + movq %rax, 24(%r15) + adcq 32(%r11), %rcx + movq 40(%r15), %r8 + movq %rcx, 32(%r15) + adcq 40(%r11), %r8 + movq 48(%r15), %rax + movq %r8, 40(%r15) + adcq 48(%r11), %rax + movq 56(%r15), %rcx + movq %rax, 48(%r15) + adcq 56(%r11), %rcx + movq 64(%r15), %r8 + movq %rcx, 56(%r15) + adcq 64(%r11), %r8 + movq 72(%r15), %rax + movq %r8, 64(%r15) + adcq 72(%r11), %rax + movq 80(%r15), %rcx + movq %rax, 72(%r15) + adcq 80(%r11), %rcx + movq 88(%r15), %r8 + movq %rcx, 80(%r15) + adcq 88(%r11), %r8 + movq 96(%r15), %rax + movq %r8, 88(%r15) + adcq 96(%r11), %rax + movq %rax, 96(%r15) + # Add to zero + movq 104(%r11), %rax + adcq $0, %rax + movq 112(%r11), %rcx + movq %rax, 104(%r15) + adcq $0, %rcx + movq 120(%r11), %r8 + movq %rcx, 112(%r15) + adcq $0, %r8 + movq 128(%r11), %rax + movq %r8, 120(%r15) + adcq $0, %rax + movq 136(%r11), %rcx + movq %rax, 128(%r15) + adcq $0, %rcx + movq 144(%r11), %r8 + movq %rcx, 136(%r15) + adcq $0, %r8 + movq 152(%r11), %rax + movq %r8, 144(%r15) + adcq $0, %rax + movq 160(%r11), %rcx + movq %rax, 152(%r15) + adcq $0, %rcx + movq 168(%r11), %r8 + movq %rcx, 160(%r15) + adcq $0, %r8 + movq 176(%r11), %rax + movq %r8, 168(%r15) + adcq $0, %rax + movq 184(%r11), %rcx + movq %rax, 176(%r15) + adcq $0, %rcx + movq %rcx, 184(%r15) + addq $616, %rsp + pop %r15 + pop %r14 + pop %r13 + pop %r12 + repz retq +#ifndef __APPLE__ +.size sp_3072_mul_avx2_24,.-sp_3072_mul_avx2_24 +#endif /* __APPLE__ */ +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +#ifndef __APPLE__ +.globl sp_3072_sqr_avx2_24 +.type sp_3072_sqr_avx2_24,@function +.align 16 +sp_3072_sqr_avx2_24: +#else +.globl _sp_3072_sqr_avx2_24 +.p2align 4 +_sp_3072_sqr_avx2_24: +#endif /* __APPLE__ */ + subq $504, %rsp + movq %rdi, 480(%rsp) + movq %rsi, 488(%rsp) + leaq 384(%rsp), %r8 + leaq 96(%rsi), %r9 + # Add + movq (%rsi), %rdx + xorq %rcx, %rcx + addq (%r9), %rdx + movq 8(%rsi), %rax + movq %rdx, (%r8) + adcq 8(%r9), %rax + movq 16(%rsi), %rdx + movq %rax, 8(%r8) + adcq 16(%r9), %rdx + movq 24(%rsi), %rax + movq %rdx, 16(%r8) + adcq 24(%r9), %rax + movq 32(%rsi), %rdx + movq %rax, 24(%r8) + adcq 32(%r9), %rdx + movq 40(%rsi), %rax + movq %rdx, 32(%r8) + adcq 40(%r9), %rax + movq 48(%rsi), %rdx + movq %rax, 40(%r8) + adcq 48(%r9), %rdx + movq 56(%rsi), %rax + movq %rdx, 48(%r8) + adcq 56(%r9), %rax + movq 64(%rsi), %rdx + movq %rax, 56(%r8) + adcq 64(%r9), %rdx + movq 72(%rsi), %rax + movq %rdx, 64(%r8) + adcq 72(%r9), %rax + movq 80(%rsi), %rdx + movq %rax, 72(%r8) + adcq 80(%r9), %rdx + movq 88(%rsi), %rax + movq %rdx, 80(%r8) + adcq 88(%r9), %rax + movq %rax, 88(%r8) + adcq $0, %rcx + movq %rcx, 496(%rsp) + movq %r8, %rsi + movq %rsp, %rdi +#ifndef __APPLE__ + callq sp_3072_sqr_avx2_12@plt +#else + callq _sp_3072_sqr_avx2_12 +#endif /* __APPLE__ */ + movq 488(%rsp), %rsi + leaq 192(%rsp), %rdi + addq $96, %rsi +#ifndef __APPLE__ + callq sp_3072_sqr_avx2_12@plt +#else + callq _sp_3072_sqr_avx2_12 +#endif /* __APPLE__ */ + movq 488(%rsp), %rsi + movq 480(%rsp), %rdi +#ifndef __APPLE__ + callq sp_3072_sqr_avx2_12@plt +#else + callq _sp_3072_sqr_avx2_12 +#endif /* __APPLE__ */ + movq 496(%rsp), %r10 + movq %rdi, %r9 + leaq 384(%rsp), %r8 + movq %r10, %rcx + negq %r10 + addq $192, %r9 + movq (%r8), %rdx + pextq %r10, %rdx, %rdx + addq %rdx, %rdx + movq 8(%r8), %rax + movq %rdx, (%r9) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 16(%r8), %rdx + movq %rax, 8(%r9) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 24(%r8), %rax + movq %rdx, 16(%r9) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 32(%r8), %rdx + movq %rax, 24(%r9) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 40(%r8), %rax + movq %rdx, 32(%r9) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 48(%r8), %rdx + movq %rax, 40(%r9) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 56(%r8), %rax + movq %rdx, 48(%r9) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 64(%r8), %rdx + movq %rax, 56(%r9) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 72(%r8), %rax + movq %rdx, 64(%r9) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 80(%r8), %rdx + movq %rax, 72(%r9) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 88(%r8), %rax + movq %rdx, 80(%r9) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq %rax, 88(%r9) + adcq $0, %rcx + leaq 192(%rsp), %rsi + movq %rsp, %r8 + movq (%r8), %rdx + subq (%rsi), %rdx + movq 8(%r8), %rax + movq %rdx, (%r8) + sbbq 8(%rsi), %rax + movq 16(%r8), %rdx + movq %rax, 8(%r8) + sbbq 16(%rsi), %rdx + movq 24(%r8), %rax + movq %rdx, 16(%r8) + sbbq 24(%rsi), %rax + movq 32(%r8), %rdx + movq %rax, 24(%r8) + sbbq 32(%rsi), %rdx + movq 40(%r8), %rax + movq %rdx, 32(%r8) + sbbq 40(%rsi), %rax + movq 48(%r8), %rdx + movq %rax, 40(%r8) + sbbq 48(%rsi), %rdx + movq 56(%r8), %rax + movq %rdx, 48(%r8) + sbbq 56(%rsi), %rax + movq 64(%r8), %rdx + movq %rax, 56(%r8) + sbbq 64(%rsi), %rdx + movq 72(%r8), %rax + movq %rdx, 64(%r8) + sbbq 72(%rsi), %rax + movq 80(%r8), %rdx + movq %rax, 72(%r8) + sbbq 80(%rsi), %rdx + movq 88(%r8), %rax + movq %rdx, 80(%r8) + sbbq 88(%rsi), %rax + movq 96(%r8), %rdx + movq %rax, 88(%r8) + sbbq 96(%rsi), %rdx + movq 104(%r8), %rax + movq %rdx, 96(%r8) + sbbq 104(%rsi), %rax + movq 112(%r8), %rdx + movq %rax, 104(%r8) + sbbq 112(%rsi), %rdx + movq 120(%r8), %rax + movq %rdx, 112(%r8) + sbbq 120(%rsi), %rax + movq 128(%r8), %rdx + movq %rax, 120(%r8) + sbbq 128(%rsi), %rdx + movq 136(%r8), %rax + movq %rdx, 128(%r8) + sbbq 136(%rsi), %rax + movq 144(%r8), %rdx + movq %rax, 136(%r8) + sbbq 144(%rsi), %rdx + movq 152(%r8), %rax + movq %rdx, 144(%r8) + sbbq 152(%rsi), %rax + movq 160(%r8), %rdx + movq %rax, 152(%r8) + sbbq 160(%rsi), %rdx + movq 168(%r8), %rax + movq %rdx, 160(%r8) + sbbq 168(%rsi), %rax + movq 176(%r8), %rdx + movq %rax, 168(%r8) + sbbq 176(%rsi), %rdx + movq 184(%r8), %rax + movq %rdx, 176(%r8) + sbbq 184(%rsi), %rax + movq %rax, 184(%r8) + sbbq $0, %rcx + movq (%r8), %rdx + subq (%rdi), %rdx + movq 8(%r8), %rax + movq %rdx, (%r8) + sbbq 8(%rdi), %rax + movq 16(%r8), %rdx + movq %rax, 8(%r8) + sbbq 16(%rdi), %rdx + movq 24(%r8), %rax + movq %rdx, 16(%r8) + sbbq 24(%rdi), %rax + movq 32(%r8), %rdx + movq %rax, 24(%r8) + sbbq 32(%rdi), %rdx + movq 40(%r8), %rax + movq %rdx, 32(%r8) + sbbq 40(%rdi), %rax + movq 48(%r8), %rdx + movq %rax, 40(%r8) + sbbq 48(%rdi), %rdx + movq 56(%r8), %rax + movq %rdx, 48(%r8) + sbbq 56(%rdi), %rax + movq 64(%r8), %rdx + movq %rax, 56(%r8) + sbbq 64(%rdi), %rdx + movq 72(%r8), %rax + movq %rdx, 64(%r8) + sbbq 72(%rdi), %rax + movq 80(%r8), %rdx + movq %rax, 72(%r8) + sbbq 80(%rdi), %rdx + movq 88(%r8), %rax + movq %rdx, 80(%r8) + sbbq 88(%rdi), %rax + movq 96(%r8), %rdx + movq %rax, 88(%r8) + sbbq 96(%rdi), %rdx + movq 104(%r8), %rax + movq %rdx, 96(%r8) + sbbq 104(%rdi), %rax + movq 112(%r8), %rdx + movq %rax, 104(%r8) + sbbq 112(%rdi), %rdx + movq 120(%r8), %rax + movq %rdx, 112(%r8) + sbbq 120(%rdi), %rax + movq 128(%r8), %rdx + movq %rax, 120(%r8) + sbbq 128(%rdi), %rdx + movq 136(%r8), %rax + movq %rdx, 128(%r8) + sbbq 136(%rdi), %rax + movq 144(%r8), %rdx + movq %rax, 136(%r8) + sbbq 144(%rdi), %rdx + movq 152(%r8), %rax + movq %rdx, 144(%r8) + sbbq 152(%rdi), %rax + movq 160(%r8), %rdx + movq %rax, 152(%r8) + sbbq 160(%rdi), %rdx + movq 168(%r8), %rax + movq %rdx, 160(%r8) + sbbq 168(%rdi), %rax + movq 176(%r8), %rdx + movq %rax, 168(%r8) + sbbq 176(%rdi), %rdx + movq 184(%r8), %rax + movq %rdx, 176(%r8) + sbbq 184(%rdi), %rax + movq %rax, 184(%r8) + sbbq $0, %rcx + subq $96, %r9 + # Add in place + movq (%r9), %rdx + addq (%r8), %rdx + movq 8(%r9), %rax + movq %rdx, (%r9) + adcq 8(%r8), %rax + movq 16(%r9), %rdx + movq %rax, 8(%r9) + adcq 16(%r8), %rdx + movq 24(%r9), %rax + movq %rdx, 16(%r9) + adcq 24(%r8), %rax + movq 32(%r9), %rdx + movq %rax, 24(%r9) + adcq 32(%r8), %rdx + movq 40(%r9), %rax + movq %rdx, 32(%r9) + adcq 40(%r8), %rax + movq 48(%r9), %rdx + movq %rax, 40(%r9) + adcq 48(%r8), %rdx + movq 56(%r9), %rax + movq %rdx, 48(%r9) + adcq 56(%r8), %rax + movq 64(%r9), %rdx + movq %rax, 56(%r9) + adcq 64(%r8), %rdx + movq 72(%r9), %rax + movq %rdx, 64(%r9) + adcq 72(%r8), %rax + movq 80(%r9), %rdx + movq %rax, 72(%r9) + adcq 80(%r8), %rdx + movq 88(%r9), %rax + movq %rdx, 80(%r9) + adcq 88(%r8), %rax + movq 96(%r9), %rdx + movq %rax, 88(%r9) + adcq 96(%r8), %rdx + movq 104(%r9), %rax + movq %rdx, 96(%r9) + adcq 104(%r8), %rax + movq 112(%r9), %rdx + movq %rax, 104(%r9) + adcq 112(%r8), %rdx + movq 120(%r9), %rax + movq %rdx, 112(%r9) + adcq 120(%r8), %rax + movq 128(%r9), %rdx + movq %rax, 120(%r9) + adcq 128(%r8), %rdx + movq 136(%r9), %rax + movq %rdx, 128(%r9) + adcq 136(%r8), %rax + movq 144(%r9), %rdx + movq %rax, 136(%r9) + adcq 144(%r8), %rdx + movq 152(%r9), %rax + movq %rdx, 144(%r9) + adcq 152(%r8), %rax + movq 160(%r9), %rdx + movq %rax, 152(%r9) + adcq 160(%r8), %rdx + movq 168(%r9), %rax + movq %rdx, 160(%r9) + adcq 168(%r8), %rax + movq 176(%r9), %rdx + movq %rax, 168(%r9) + adcq 176(%r8), %rdx + movq 184(%r9), %rax + movq %rdx, 176(%r9) + adcq 184(%r8), %rax + movq %rax, 184(%r9) + adcq $0, %rcx + movq %rcx, 288(%rdi) + # Add in place + movq 96(%r9), %rdx + addq (%rsi), %rdx + movq 104(%r9), %rax + movq %rdx, 96(%r9) + adcq 8(%rsi), %rax + movq 112(%r9), %rdx + movq %rax, 104(%r9) + adcq 16(%rsi), %rdx + movq 120(%r9), %rax + movq %rdx, 112(%r9) + adcq 24(%rsi), %rax + movq 128(%r9), %rdx + movq %rax, 120(%r9) + adcq 32(%rsi), %rdx + movq 136(%r9), %rax + movq %rdx, 128(%r9) + adcq 40(%rsi), %rax + movq 144(%r9), %rdx + movq %rax, 136(%r9) + adcq 48(%rsi), %rdx + movq 152(%r9), %rax + movq %rdx, 144(%r9) + adcq 56(%rsi), %rax + movq 160(%r9), %rdx + movq %rax, 152(%r9) + adcq 64(%rsi), %rdx + movq 168(%r9), %rax + movq %rdx, 160(%r9) + adcq 72(%rsi), %rax + movq 176(%r9), %rdx + movq %rax, 168(%r9) + adcq 80(%rsi), %rdx + movq 184(%r9), %rax + movq %rdx, 176(%r9) + adcq 88(%rsi), %rax + movq 192(%r9), %rdx + movq %rax, 184(%r9) + adcq 96(%rsi), %rdx + movq %rdx, 192(%r9) + # Add to zero + movq 104(%rsi), %rdx + adcq $0, %rdx + movq 112(%rsi), %rax + movq %rdx, 200(%r9) + adcq $0, %rax + movq 120(%rsi), %rdx + movq %rax, 208(%r9) + adcq $0, %rdx + movq 128(%rsi), %rax + movq %rdx, 216(%r9) + adcq $0, %rax + movq 136(%rsi), %rdx + movq %rax, 224(%r9) + adcq $0, %rdx + movq 144(%rsi), %rax + movq %rdx, 232(%r9) + adcq $0, %rax + movq 152(%rsi), %rdx + movq %rax, 240(%r9) + adcq $0, %rdx + movq 160(%rsi), %rax + movq %rdx, 248(%r9) + adcq $0, %rax + movq 168(%rsi), %rdx + movq %rax, 256(%r9) + adcq $0, %rdx + movq 176(%rsi), %rax + movq %rdx, 264(%r9) + adcq $0, %rax + movq 184(%rsi), %rdx + movq %rax, 272(%r9) + adcq $0, %rdx + movq %rdx, 280(%r9) + addq $504, %rsp + repz retq +#ifndef __APPLE__ +.size sp_3072_sqr_avx2_24,.-sp_3072_sqr_avx2_24 +#endif /* __APPLE__ */ /* Sub b from a into a. (a -= b) * * a A single precision integer and result. @@ -21161,6 +17945,7 @@ sp_3072_add_48: .p2align 4 _sp_3072_add_48: #endif /* __APPLE__ */ + # Add movq (%rsi), %rcx xorq %rax, %rax addq (%rdx), %rcx @@ -21311,6 +18096,1035 @@ _sp_3072_add_48: #ifndef __APPLE__ .size sp_3072_add_48,.-sp_3072_add_48 #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__ +.globl sp_3072_mul_48 +.type sp_3072_mul_48,@function +.align 16 +sp_3072_mul_48: +#else +.globl _sp_3072_mul_48 +.p2align 4 +_sp_3072_mul_48: +#endif /* __APPLE__ */ + push %r12 + push %r13 + push %r14 + push %r15 + subq $1192, %rsp + movq %rdi, 1152(%rsp) + movq %rsi, 1160(%rsp) + movq %rdx, 1168(%rsp) + leaq 768(%rsp), %r10 + leaq 192(%rsi), %r12 + # Add + movq (%rsi), %rax + xorq %r13, %r13 + addq (%r12), %rax + movq 8(%rsi), %rcx + movq %rax, (%r10) + adcq 8(%r12), %rcx + movq 16(%rsi), %r8 + movq %rcx, 8(%r10) + adcq 16(%r12), %r8 + movq 24(%rsi), %rax + movq %r8, 16(%r10) + adcq 24(%r12), %rax + movq 32(%rsi), %rcx + movq %rax, 24(%r10) + adcq 32(%r12), %rcx + movq 40(%rsi), %r8 + movq %rcx, 32(%r10) + adcq 40(%r12), %r8 + movq 48(%rsi), %rax + movq %r8, 40(%r10) + adcq 48(%r12), %rax + movq 56(%rsi), %rcx + movq %rax, 48(%r10) + adcq 56(%r12), %rcx + movq 64(%rsi), %r8 + movq %rcx, 56(%r10) + adcq 64(%r12), %r8 + movq 72(%rsi), %rax + movq %r8, 64(%r10) + adcq 72(%r12), %rax + movq 80(%rsi), %rcx + movq %rax, 72(%r10) + adcq 80(%r12), %rcx + movq 88(%rsi), %r8 + movq %rcx, 80(%r10) + adcq 88(%r12), %r8 + movq 96(%rsi), %rax + movq %r8, 88(%r10) + adcq 96(%r12), %rax + movq 104(%rsi), %rcx + movq %rax, 96(%r10) + adcq 104(%r12), %rcx + movq 112(%rsi), %r8 + movq %rcx, 104(%r10) + adcq 112(%r12), %r8 + movq 120(%rsi), %rax + movq %r8, 112(%r10) + adcq 120(%r12), %rax + movq 128(%rsi), %rcx + movq %rax, 120(%r10) + adcq 128(%r12), %rcx + movq 136(%rsi), %r8 + movq %rcx, 128(%r10) + adcq 136(%r12), %r8 + movq 144(%rsi), %rax + movq %r8, 136(%r10) + adcq 144(%r12), %rax + movq 152(%rsi), %rcx + movq %rax, 144(%r10) + adcq 152(%r12), %rcx + movq 160(%rsi), %r8 + movq %rcx, 152(%r10) + adcq 160(%r12), %r8 + movq 168(%rsi), %rax + movq %r8, 160(%r10) + adcq 168(%r12), %rax + movq 176(%rsi), %rcx + movq %rax, 168(%r10) + adcq 176(%r12), %rcx + movq 184(%rsi), %r8 + movq %rcx, 176(%r10) + adcq 184(%r12), %r8 + movq %r8, 184(%r10) + adcq $0, %r13 + movq %r13, 1176(%rsp) + leaq 960(%rsp), %r11 + leaq 192(%rdx), %r12 + # Add + movq (%rdx), %rax + xorq %r14, %r14 + addq (%r12), %rax + movq 8(%rdx), %rcx + movq %rax, (%r11) + adcq 8(%r12), %rcx + movq 16(%rdx), %r8 + movq %rcx, 8(%r11) + adcq 16(%r12), %r8 + movq 24(%rdx), %rax + movq %r8, 16(%r11) + adcq 24(%r12), %rax + movq 32(%rdx), %rcx + movq %rax, 24(%r11) + adcq 32(%r12), %rcx + movq 40(%rdx), %r8 + movq %rcx, 32(%r11) + adcq 40(%r12), %r8 + movq 48(%rdx), %rax + movq %r8, 40(%r11) + adcq 48(%r12), %rax + movq 56(%rdx), %rcx + movq %rax, 48(%r11) + adcq 56(%r12), %rcx + movq 64(%rdx), %r8 + movq %rcx, 56(%r11) + adcq 64(%r12), %r8 + movq 72(%rdx), %rax + movq %r8, 64(%r11) + adcq 72(%r12), %rax + movq 80(%rdx), %rcx + movq %rax, 72(%r11) + adcq 80(%r12), %rcx + movq 88(%rdx), %r8 + movq %rcx, 80(%r11) + adcq 88(%r12), %r8 + movq 96(%rdx), %rax + movq %r8, 88(%r11) + adcq 96(%r12), %rax + movq 104(%rdx), %rcx + movq %rax, 96(%r11) + adcq 104(%r12), %rcx + movq 112(%rdx), %r8 + movq %rcx, 104(%r11) + adcq 112(%r12), %r8 + movq 120(%rdx), %rax + movq %r8, 112(%r11) + adcq 120(%r12), %rax + movq 128(%rdx), %rcx + movq %rax, 120(%r11) + adcq 128(%r12), %rcx + movq 136(%rdx), %r8 + movq %rcx, 128(%r11) + adcq 136(%r12), %r8 + movq 144(%rdx), %rax + movq %r8, 136(%r11) + adcq 144(%r12), %rax + movq 152(%rdx), %rcx + movq %rax, 144(%r11) + adcq 152(%r12), %rcx + movq 160(%rdx), %r8 + movq %rcx, 152(%r11) + adcq 160(%r12), %r8 + movq 168(%rdx), %rax + movq %r8, 160(%r11) + adcq 168(%r12), %rax + movq 176(%rdx), %rcx + movq %rax, 168(%r11) + adcq 176(%r12), %rcx + movq 184(%rdx), %r8 + movq %rcx, 176(%r11) + adcq 184(%r12), %r8 + movq %r8, 184(%r11) + adcq $0, %r14 + movq %r14, 1184(%rsp) + movq %r11, %rdx + movq %r10, %rsi + movq %rsp, %rdi +#ifndef __APPLE__ + callq sp_3072_mul_24@plt +#else + callq _sp_3072_mul_24 +#endif /* __APPLE__ */ + movq 1168(%rsp), %rdx + movq 1160(%rsp), %rsi + leaq 384(%rsp), %rdi + addq $192, %rdx + addq $192, %rsi +#ifndef __APPLE__ + callq sp_3072_mul_24@plt +#else + callq _sp_3072_mul_24 +#endif /* __APPLE__ */ + movq 1168(%rsp), %rdx + movq 1160(%rsp), %rsi + movq 1152(%rsp), %rdi +#ifndef __APPLE__ + callq sp_3072_mul_24@plt +#else + callq _sp_3072_mul_24 +#endif /* __APPLE__ */ + movq 1176(%rsp), %r13 + movq 1184(%rsp), %r14 + movq 1152(%rsp), %r15 + movq %r13, %r9 + leaq 768(%rsp), %r10 + leaq 960(%rsp), %r11 + andq %r14, %r9 + negq %r13 + negq %r14 + addq $384, %r15 + movq (%r10), %rax + movq (%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, (%r10) + movq %rcx, (%r11) + movq 8(%r10), %rax + movq 8(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 8(%r10) + movq %rcx, 8(%r11) + movq 16(%r10), %rax + movq 16(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 16(%r10) + movq %rcx, 16(%r11) + movq 24(%r10), %rax + movq 24(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 24(%r10) + movq %rcx, 24(%r11) + movq 32(%r10), %rax + movq 32(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 32(%r10) + movq %rcx, 32(%r11) + movq 40(%r10), %rax + movq 40(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 40(%r10) + movq %rcx, 40(%r11) + movq 48(%r10), %rax + movq 48(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 48(%r10) + movq %rcx, 48(%r11) + movq 56(%r10), %rax + movq 56(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 56(%r10) + movq %rcx, 56(%r11) + movq 64(%r10), %rax + movq 64(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 64(%r10) + movq %rcx, 64(%r11) + movq 72(%r10), %rax + movq 72(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 72(%r10) + movq %rcx, 72(%r11) + movq 80(%r10), %rax + movq 80(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 80(%r10) + movq %rcx, 80(%r11) + movq 88(%r10), %rax + movq 88(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 88(%r10) + movq %rcx, 88(%r11) + movq 96(%r10), %rax + movq 96(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 96(%r10) + movq %rcx, 96(%r11) + movq 104(%r10), %rax + movq 104(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 104(%r10) + movq %rcx, 104(%r11) + movq 112(%r10), %rax + movq 112(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 112(%r10) + movq %rcx, 112(%r11) + movq 120(%r10), %rax + movq 120(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 120(%r10) + movq %rcx, 120(%r11) + movq 128(%r10), %rax + movq 128(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 128(%r10) + movq %rcx, 128(%r11) + movq 136(%r10), %rax + movq 136(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 136(%r10) + movq %rcx, 136(%r11) + movq 144(%r10), %rax + movq 144(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 144(%r10) + movq %rcx, 144(%r11) + movq 152(%r10), %rax + movq 152(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 152(%r10) + movq %rcx, 152(%r11) + movq 160(%r10), %rax + movq 160(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 160(%r10) + movq %rcx, 160(%r11) + movq 168(%r10), %rax + movq 168(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 168(%r10) + movq %rcx, 168(%r11) + movq 176(%r10), %rax + movq 176(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 176(%r10) + movq %rcx, 176(%r11) + movq 184(%r10), %rax + movq 184(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 184(%r10) + movq %rcx, 184(%r11) + movq (%r10), %rax + addq (%r11), %rax + movq 8(%r10), %rcx + movq %rax, (%r15) + adcq 8(%r11), %rcx + movq 16(%r10), %r8 + movq %rcx, 8(%r15) + adcq 16(%r11), %r8 + movq 24(%r10), %rax + movq %r8, 16(%r15) + adcq 24(%r11), %rax + movq 32(%r10), %rcx + movq %rax, 24(%r15) + adcq 32(%r11), %rcx + movq 40(%r10), %r8 + movq %rcx, 32(%r15) + adcq 40(%r11), %r8 + movq 48(%r10), %rax + movq %r8, 40(%r15) + adcq 48(%r11), %rax + movq 56(%r10), %rcx + movq %rax, 48(%r15) + adcq 56(%r11), %rcx + movq 64(%r10), %r8 + movq %rcx, 56(%r15) + adcq 64(%r11), %r8 + movq 72(%r10), %rax + movq %r8, 64(%r15) + adcq 72(%r11), %rax + movq 80(%r10), %rcx + movq %rax, 72(%r15) + adcq 80(%r11), %rcx + movq 88(%r10), %r8 + movq %rcx, 80(%r15) + adcq 88(%r11), %r8 + movq 96(%r10), %rax + movq %r8, 88(%r15) + adcq 96(%r11), %rax + movq 104(%r10), %rcx + movq %rax, 96(%r15) + adcq 104(%r11), %rcx + movq 112(%r10), %r8 + movq %rcx, 104(%r15) + adcq 112(%r11), %r8 + movq 120(%r10), %rax + movq %r8, 112(%r15) + adcq 120(%r11), %rax + movq 128(%r10), %rcx + movq %rax, 120(%r15) + adcq 128(%r11), %rcx + movq 136(%r10), %r8 + movq %rcx, 128(%r15) + adcq 136(%r11), %r8 + movq 144(%r10), %rax + movq %r8, 136(%r15) + adcq 144(%r11), %rax + movq 152(%r10), %rcx + movq %rax, 144(%r15) + adcq 152(%r11), %rcx + movq 160(%r10), %r8 + movq %rcx, 152(%r15) + adcq 160(%r11), %r8 + movq 168(%r10), %rax + movq %r8, 160(%r15) + adcq 168(%r11), %rax + movq 176(%r10), %rcx + movq %rax, 168(%r15) + adcq 176(%r11), %rcx + movq 184(%r10), %r8 + movq %rcx, 176(%r15) + adcq 184(%r11), %r8 + movq %r8, 184(%r15) + adcq $0, %r9 + leaq 384(%rsp), %r11 + movq %rsp, %r10 + movq (%r10), %rax + subq (%r11), %rax + movq 8(%r10), %rcx + movq %rax, (%r10) + sbbq 8(%r11), %rcx + movq 16(%r10), %r8 + movq %rcx, 8(%r10) + sbbq 16(%r11), %r8 + movq 24(%r10), %rax + movq %r8, 16(%r10) + sbbq 24(%r11), %rax + movq 32(%r10), %rcx + movq %rax, 24(%r10) + sbbq 32(%r11), %rcx + movq 40(%r10), %r8 + movq %rcx, 32(%r10) + sbbq 40(%r11), %r8 + movq 48(%r10), %rax + movq %r8, 40(%r10) + sbbq 48(%r11), %rax + movq 56(%r10), %rcx + movq %rax, 48(%r10) + sbbq 56(%r11), %rcx + movq 64(%r10), %r8 + movq %rcx, 56(%r10) + sbbq 64(%r11), %r8 + movq 72(%r10), %rax + movq %r8, 64(%r10) + sbbq 72(%r11), %rax + movq 80(%r10), %rcx + movq %rax, 72(%r10) + sbbq 80(%r11), %rcx + movq 88(%r10), %r8 + movq %rcx, 80(%r10) + sbbq 88(%r11), %r8 + movq 96(%r10), %rax + movq %r8, 88(%r10) + sbbq 96(%r11), %rax + movq 104(%r10), %rcx + movq %rax, 96(%r10) + sbbq 104(%r11), %rcx + movq 112(%r10), %r8 + movq %rcx, 104(%r10) + sbbq 112(%r11), %r8 + movq 120(%r10), %rax + movq %r8, 112(%r10) + sbbq 120(%r11), %rax + movq 128(%r10), %rcx + movq %rax, 120(%r10) + sbbq 128(%r11), %rcx + movq 136(%r10), %r8 + movq %rcx, 128(%r10) + sbbq 136(%r11), %r8 + movq 144(%r10), %rax + movq %r8, 136(%r10) + sbbq 144(%r11), %rax + movq 152(%r10), %rcx + movq %rax, 144(%r10) + sbbq 152(%r11), %rcx + movq 160(%r10), %r8 + movq %rcx, 152(%r10) + sbbq 160(%r11), %r8 + movq 168(%r10), %rax + movq %r8, 160(%r10) + sbbq 168(%r11), %rax + movq 176(%r10), %rcx + movq %rax, 168(%r10) + sbbq 176(%r11), %rcx + movq 184(%r10), %r8 + movq %rcx, 176(%r10) + sbbq 184(%r11), %r8 + movq 192(%r10), %rax + movq %r8, 184(%r10) + sbbq 192(%r11), %rax + movq 200(%r10), %rcx + movq %rax, 192(%r10) + sbbq 200(%r11), %rcx + movq 208(%r10), %r8 + movq %rcx, 200(%r10) + sbbq 208(%r11), %r8 + movq 216(%r10), %rax + movq %r8, 208(%r10) + sbbq 216(%r11), %rax + movq 224(%r10), %rcx + movq %rax, 216(%r10) + sbbq 224(%r11), %rcx + movq 232(%r10), %r8 + movq %rcx, 224(%r10) + sbbq 232(%r11), %r8 + movq 240(%r10), %rax + movq %r8, 232(%r10) + sbbq 240(%r11), %rax + movq 248(%r10), %rcx + movq %rax, 240(%r10) + sbbq 248(%r11), %rcx + movq 256(%r10), %r8 + movq %rcx, 248(%r10) + sbbq 256(%r11), %r8 + movq 264(%r10), %rax + movq %r8, 256(%r10) + sbbq 264(%r11), %rax + movq 272(%r10), %rcx + movq %rax, 264(%r10) + sbbq 272(%r11), %rcx + movq 280(%r10), %r8 + movq %rcx, 272(%r10) + sbbq 280(%r11), %r8 + movq 288(%r10), %rax + movq %r8, 280(%r10) + sbbq 288(%r11), %rax + movq 296(%r10), %rcx + movq %rax, 288(%r10) + sbbq 296(%r11), %rcx + movq 304(%r10), %r8 + movq %rcx, 296(%r10) + sbbq 304(%r11), %r8 + movq 312(%r10), %rax + movq %r8, 304(%r10) + sbbq 312(%r11), %rax + movq 320(%r10), %rcx + movq %rax, 312(%r10) + sbbq 320(%r11), %rcx + movq 328(%r10), %r8 + movq %rcx, 320(%r10) + sbbq 328(%r11), %r8 + movq 336(%r10), %rax + movq %r8, 328(%r10) + sbbq 336(%r11), %rax + movq 344(%r10), %rcx + movq %rax, 336(%r10) + sbbq 344(%r11), %rcx + movq 352(%r10), %r8 + movq %rcx, 344(%r10) + sbbq 352(%r11), %r8 + movq 360(%r10), %rax + movq %r8, 352(%r10) + sbbq 360(%r11), %rax + movq 368(%r10), %rcx + movq %rax, 360(%r10) + sbbq 368(%r11), %rcx + movq 376(%r10), %r8 + movq %rcx, 368(%r10) + sbbq 376(%r11), %r8 + movq %r8, 376(%r10) + sbbq $0, %r9 + movq (%r10), %rax + subq (%rdi), %rax + movq 8(%r10), %rcx + movq %rax, (%r10) + sbbq 8(%rdi), %rcx + movq 16(%r10), %r8 + movq %rcx, 8(%r10) + sbbq 16(%rdi), %r8 + movq 24(%r10), %rax + movq %r8, 16(%r10) + sbbq 24(%rdi), %rax + movq 32(%r10), %rcx + movq %rax, 24(%r10) + sbbq 32(%rdi), %rcx + movq 40(%r10), %r8 + movq %rcx, 32(%r10) + sbbq 40(%rdi), %r8 + movq 48(%r10), %rax + movq %r8, 40(%r10) + sbbq 48(%rdi), %rax + movq 56(%r10), %rcx + movq %rax, 48(%r10) + sbbq 56(%rdi), %rcx + movq 64(%r10), %r8 + movq %rcx, 56(%r10) + sbbq 64(%rdi), %r8 + movq 72(%r10), %rax + movq %r8, 64(%r10) + sbbq 72(%rdi), %rax + movq 80(%r10), %rcx + movq %rax, 72(%r10) + sbbq 80(%rdi), %rcx + movq 88(%r10), %r8 + movq %rcx, 80(%r10) + sbbq 88(%rdi), %r8 + movq 96(%r10), %rax + movq %r8, 88(%r10) + sbbq 96(%rdi), %rax + movq 104(%r10), %rcx + movq %rax, 96(%r10) + sbbq 104(%rdi), %rcx + movq 112(%r10), %r8 + movq %rcx, 104(%r10) + sbbq 112(%rdi), %r8 + movq 120(%r10), %rax + movq %r8, 112(%r10) + sbbq 120(%rdi), %rax + movq 128(%r10), %rcx + movq %rax, 120(%r10) + sbbq 128(%rdi), %rcx + movq 136(%r10), %r8 + movq %rcx, 128(%r10) + sbbq 136(%rdi), %r8 + movq 144(%r10), %rax + movq %r8, 136(%r10) + sbbq 144(%rdi), %rax + movq 152(%r10), %rcx + movq %rax, 144(%r10) + sbbq 152(%rdi), %rcx + movq 160(%r10), %r8 + movq %rcx, 152(%r10) + sbbq 160(%rdi), %r8 + movq 168(%r10), %rax + movq %r8, 160(%r10) + sbbq 168(%rdi), %rax + movq 176(%r10), %rcx + movq %rax, 168(%r10) + sbbq 176(%rdi), %rcx + movq 184(%r10), %r8 + movq %rcx, 176(%r10) + sbbq 184(%rdi), %r8 + movq 192(%r10), %rax + movq %r8, 184(%r10) + sbbq 192(%rdi), %rax + movq 200(%r10), %rcx + movq %rax, 192(%r10) + sbbq 200(%rdi), %rcx + movq 208(%r10), %r8 + movq %rcx, 200(%r10) + sbbq 208(%rdi), %r8 + movq 216(%r10), %rax + movq %r8, 208(%r10) + sbbq 216(%rdi), %rax + movq 224(%r10), %rcx + movq %rax, 216(%r10) + sbbq 224(%rdi), %rcx + movq 232(%r10), %r8 + movq %rcx, 224(%r10) + sbbq 232(%rdi), %r8 + movq 240(%r10), %rax + movq %r8, 232(%r10) + sbbq 240(%rdi), %rax + movq 248(%r10), %rcx + movq %rax, 240(%r10) + sbbq 248(%rdi), %rcx + movq 256(%r10), %r8 + movq %rcx, 248(%r10) + sbbq 256(%rdi), %r8 + movq 264(%r10), %rax + movq %r8, 256(%r10) + sbbq 264(%rdi), %rax + movq 272(%r10), %rcx + movq %rax, 264(%r10) + sbbq 272(%rdi), %rcx + movq 280(%r10), %r8 + movq %rcx, 272(%r10) + sbbq 280(%rdi), %r8 + movq 288(%r10), %rax + movq %r8, 280(%r10) + sbbq 288(%rdi), %rax + movq 296(%r10), %rcx + movq %rax, 288(%r10) + sbbq 296(%rdi), %rcx + movq 304(%r10), %r8 + movq %rcx, 296(%r10) + sbbq 304(%rdi), %r8 + movq 312(%r10), %rax + movq %r8, 304(%r10) + sbbq 312(%rdi), %rax + movq 320(%r10), %rcx + movq %rax, 312(%r10) + sbbq 320(%rdi), %rcx + movq 328(%r10), %r8 + movq %rcx, 320(%r10) + sbbq 328(%rdi), %r8 + movq 336(%r10), %rax + movq %r8, 328(%r10) + sbbq 336(%rdi), %rax + movq 344(%r10), %rcx + movq %rax, 336(%r10) + sbbq 344(%rdi), %rcx + movq 352(%r10), %r8 + movq %rcx, 344(%r10) + sbbq 352(%rdi), %r8 + movq 360(%r10), %rax + movq %r8, 352(%r10) + sbbq 360(%rdi), %rax + movq 368(%r10), %rcx + movq %rax, 360(%r10) + sbbq 368(%rdi), %rcx + movq 376(%r10), %r8 + movq %rcx, 368(%r10) + sbbq 376(%rdi), %r8 + movq %r8, 376(%r10) + sbbq $0, %r9 + subq $192, %r15 + # Add + movq (%r15), %rax + addq (%r10), %rax + movq 8(%r15), %rcx + movq %rax, (%r15) + adcq 8(%r10), %rcx + movq 16(%r15), %r8 + movq %rcx, 8(%r15) + adcq 16(%r10), %r8 + movq 24(%r15), %rax + movq %r8, 16(%r15) + adcq 24(%r10), %rax + movq 32(%r15), %rcx + movq %rax, 24(%r15) + adcq 32(%r10), %rcx + movq 40(%r15), %r8 + movq %rcx, 32(%r15) + adcq 40(%r10), %r8 + movq 48(%r15), %rax + movq %r8, 40(%r15) + adcq 48(%r10), %rax + movq 56(%r15), %rcx + movq %rax, 48(%r15) + adcq 56(%r10), %rcx + movq 64(%r15), %r8 + movq %rcx, 56(%r15) + adcq 64(%r10), %r8 + movq 72(%r15), %rax + movq %r8, 64(%r15) + adcq 72(%r10), %rax + movq 80(%r15), %rcx + movq %rax, 72(%r15) + adcq 80(%r10), %rcx + movq 88(%r15), %r8 + movq %rcx, 80(%r15) + adcq 88(%r10), %r8 + movq 96(%r15), %rax + movq %r8, 88(%r15) + adcq 96(%r10), %rax + movq 104(%r15), %rcx + movq %rax, 96(%r15) + adcq 104(%r10), %rcx + movq 112(%r15), %r8 + movq %rcx, 104(%r15) + adcq 112(%r10), %r8 + movq 120(%r15), %rax + movq %r8, 112(%r15) + adcq 120(%r10), %rax + movq 128(%r15), %rcx + movq %rax, 120(%r15) + adcq 128(%r10), %rcx + movq 136(%r15), %r8 + movq %rcx, 128(%r15) + adcq 136(%r10), %r8 + movq 144(%r15), %rax + movq %r8, 136(%r15) + adcq 144(%r10), %rax + movq 152(%r15), %rcx + movq %rax, 144(%r15) + adcq 152(%r10), %rcx + movq 160(%r15), %r8 + movq %rcx, 152(%r15) + adcq 160(%r10), %r8 + movq 168(%r15), %rax + movq %r8, 160(%r15) + adcq 168(%r10), %rax + movq 176(%r15), %rcx + movq %rax, 168(%r15) + adcq 176(%r10), %rcx + movq 184(%r15), %r8 + movq %rcx, 176(%r15) + adcq 184(%r10), %r8 + movq 192(%r15), %rax + movq %r8, 184(%r15) + adcq 192(%r10), %rax + movq 200(%r15), %rcx + movq %rax, 192(%r15) + adcq 200(%r10), %rcx + movq 208(%r15), %r8 + movq %rcx, 200(%r15) + adcq 208(%r10), %r8 + movq 216(%r15), %rax + movq %r8, 208(%r15) + adcq 216(%r10), %rax + movq 224(%r15), %rcx + movq %rax, 216(%r15) + adcq 224(%r10), %rcx + movq 232(%r15), %r8 + movq %rcx, 224(%r15) + adcq 232(%r10), %r8 + movq 240(%r15), %rax + movq %r8, 232(%r15) + adcq 240(%r10), %rax + movq 248(%r15), %rcx + movq %rax, 240(%r15) + adcq 248(%r10), %rcx + movq 256(%r15), %r8 + movq %rcx, 248(%r15) + adcq 256(%r10), %r8 + movq 264(%r15), %rax + movq %r8, 256(%r15) + adcq 264(%r10), %rax + movq 272(%r15), %rcx + movq %rax, 264(%r15) + adcq 272(%r10), %rcx + movq 280(%r15), %r8 + movq %rcx, 272(%r15) + adcq 280(%r10), %r8 + movq 288(%r15), %rax + movq %r8, 280(%r15) + adcq 288(%r10), %rax + movq 296(%r15), %rcx + movq %rax, 288(%r15) + adcq 296(%r10), %rcx + movq 304(%r15), %r8 + movq %rcx, 296(%r15) + adcq 304(%r10), %r8 + movq 312(%r15), %rax + movq %r8, 304(%r15) + adcq 312(%r10), %rax + movq 320(%r15), %rcx + movq %rax, 312(%r15) + adcq 320(%r10), %rcx + movq 328(%r15), %r8 + movq %rcx, 320(%r15) + adcq 328(%r10), %r8 + movq 336(%r15), %rax + movq %r8, 328(%r15) + adcq 336(%r10), %rax + movq 344(%r15), %rcx + movq %rax, 336(%r15) + adcq 344(%r10), %rcx + movq 352(%r15), %r8 + movq %rcx, 344(%r15) + adcq 352(%r10), %r8 + movq 360(%r15), %rax + movq %r8, 352(%r15) + adcq 360(%r10), %rax + movq 368(%r15), %rcx + movq %rax, 360(%r15) + adcq 368(%r10), %rcx + movq 376(%r15), %r8 + movq %rcx, 368(%r15) + adcq 376(%r10), %r8 + movq %r8, 376(%r15) + adcq $0, %r9 + movq %r9, 576(%rdi) + addq $192, %r15 + # Add + movq (%r15), %rax + addq (%r11), %rax + movq 8(%r15), %rcx + movq %rax, (%r15) + adcq 8(%r11), %rcx + movq 16(%r15), %r8 + movq %rcx, 8(%r15) + adcq 16(%r11), %r8 + movq 24(%r15), %rax + movq %r8, 16(%r15) + adcq 24(%r11), %rax + movq 32(%r15), %rcx + movq %rax, 24(%r15) + adcq 32(%r11), %rcx + movq 40(%r15), %r8 + movq %rcx, 32(%r15) + adcq 40(%r11), %r8 + movq 48(%r15), %rax + movq %r8, 40(%r15) + adcq 48(%r11), %rax + movq 56(%r15), %rcx + movq %rax, 48(%r15) + adcq 56(%r11), %rcx + movq 64(%r15), %r8 + movq %rcx, 56(%r15) + adcq 64(%r11), %r8 + movq 72(%r15), %rax + movq %r8, 64(%r15) + adcq 72(%r11), %rax + movq 80(%r15), %rcx + movq %rax, 72(%r15) + adcq 80(%r11), %rcx + movq 88(%r15), %r8 + movq %rcx, 80(%r15) + adcq 88(%r11), %r8 + movq 96(%r15), %rax + movq %r8, 88(%r15) + adcq 96(%r11), %rax + movq 104(%r15), %rcx + movq %rax, 96(%r15) + adcq 104(%r11), %rcx + movq 112(%r15), %r8 + movq %rcx, 104(%r15) + adcq 112(%r11), %r8 + movq 120(%r15), %rax + movq %r8, 112(%r15) + adcq 120(%r11), %rax + movq 128(%r15), %rcx + movq %rax, 120(%r15) + adcq 128(%r11), %rcx + movq 136(%r15), %r8 + movq %rcx, 128(%r15) + adcq 136(%r11), %r8 + movq 144(%r15), %rax + movq %r8, 136(%r15) + adcq 144(%r11), %rax + movq 152(%r15), %rcx + movq %rax, 144(%r15) + adcq 152(%r11), %rcx + movq 160(%r15), %r8 + movq %rcx, 152(%r15) + adcq 160(%r11), %r8 + movq 168(%r15), %rax + movq %r8, 160(%r15) + adcq 168(%r11), %rax + movq 176(%r15), %rcx + movq %rax, 168(%r15) + adcq 176(%r11), %rcx + movq 184(%r15), %r8 + movq %rcx, 176(%r15) + adcq 184(%r11), %r8 + movq 192(%r15), %rax + movq %r8, 184(%r15) + adcq 192(%r11), %rax + movq %rax, 192(%r15) + # Add to zero + movq 200(%r11), %rax + adcq $0, %rax + movq 208(%r11), %rcx + movq %rax, 200(%r15) + adcq $0, %rcx + movq 216(%r11), %r8 + movq %rcx, 208(%r15) + adcq $0, %r8 + movq 224(%r11), %rax + movq %r8, 216(%r15) + adcq $0, %rax + movq 232(%r11), %rcx + movq %rax, 224(%r15) + adcq $0, %rcx + movq 240(%r11), %r8 + movq %rcx, 232(%r15) + adcq $0, %r8 + movq 248(%r11), %rax + movq %r8, 240(%r15) + adcq $0, %rax + movq 256(%r11), %rcx + movq %rax, 248(%r15) + adcq $0, %rcx + movq 264(%r11), %r8 + movq %rcx, 256(%r15) + adcq $0, %r8 + movq 272(%r11), %rax + movq %r8, 264(%r15) + adcq $0, %rax + movq 280(%r11), %rcx + movq %rax, 272(%r15) + adcq $0, %rcx + movq 288(%r11), %r8 + movq %rcx, 280(%r15) + adcq $0, %r8 + movq 296(%r11), %rax + movq %r8, 288(%r15) + adcq $0, %rax + movq 304(%r11), %rcx + movq %rax, 296(%r15) + adcq $0, %rcx + movq 312(%r11), %r8 + movq %rcx, 304(%r15) + adcq $0, %r8 + movq 320(%r11), %rax + movq %r8, 312(%r15) + adcq $0, %rax + movq 328(%r11), %rcx + movq %rax, 320(%r15) + adcq $0, %rcx + movq 336(%r11), %r8 + movq %rcx, 328(%r15) + adcq $0, %r8 + movq 344(%r11), %rax + movq %r8, 336(%r15) + adcq $0, %rax + movq 352(%r11), %rcx + movq %rax, 344(%r15) + adcq $0, %rcx + movq 360(%r11), %r8 + movq %rcx, 352(%r15) + adcq $0, %r8 + movq 368(%r11), %rax + movq %r8, 360(%r15) + adcq $0, %rax + movq 376(%r11), %rcx + movq %rax, 368(%r15) + adcq $0, %rcx + movq %rcx, 376(%r15) + addq $1192, %rsp + pop %r15 + pop %r14 + pop %r13 + pop %r12 + repz retq +#ifndef __APPLE__ +.size sp_3072_mul_48,.-sp_3072_mul_48 +#endif /* __APPLE__ */ /* Add a to a into r. (r = a + a) * * r A single precision integer. @@ -21404,6 +19218,2635 @@ _sp_3072_dbl_24: #ifndef __APPLE__ .size sp_3072_dbl_24,.-sp_3072_dbl_24 #endif /* __APPLE__ */ +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +#ifndef __APPLE__ +.globl sp_3072_sqr_48 +.type sp_3072_sqr_48,@function +.align 16 +sp_3072_sqr_48: +#else +.globl _sp_3072_sqr_48 +.p2align 4 +_sp_3072_sqr_48: +#endif /* __APPLE__ */ + subq $984, %rsp + movq %rdi, 960(%rsp) + movq %rsi, 968(%rsp) + leaq 768(%rsp), %r8 + leaq 192(%rsi), %r9 + # Add + movq (%rsi), %rdx + xorq %rcx, %rcx + addq (%r9), %rdx + movq 8(%rsi), %rax + movq %rdx, (%r8) + adcq 8(%r9), %rax + movq 16(%rsi), %rdx + movq %rax, 8(%r8) + adcq 16(%r9), %rdx + movq 24(%rsi), %rax + movq %rdx, 16(%r8) + adcq 24(%r9), %rax + movq 32(%rsi), %rdx + movq %rax, 24(%r8) + adcq 32(%r9), %rdx + movq 40(%rsi), %rax + movq %rdx, 32(%r8) + adcq 40(%r9), %rax + movq 48(%rsi), %rdx + movq %rax, 40(%r8) + adcq 48(%r9), %rdx + movq 56(%rsi), %rax + movq %rdx, 48(%r8) + adcq 56(%r9), %rax + movq 64(%rsi), %rdx + movq %rax, 56(%r8) + adcq 64(%r9), %rdx + movq 72(%rsi), %rax + movq %rdx, 64(%r8) + adcq 72(%r9), %rax + movq 80(%rsi), %rdx + movq %rax, 72(%r8) + adcq 80(%r9), %rdx + movq 88(%rsi), %rax + movq %rdx, 80(%r8) + adcq 88(%r9), %rax + movq 96(%rsi), %rdx + movq %rax, 88(%r8) + adcq 96(%r9), %rdx + movq 104(%rsi), %rax + movq %rdx, 96(%r8) + adcq 104(%r9), %rax + movq 112(%rsi), %rdx + movq %rax, 104(%r8) + adcq 112(%r9), %rdx + movq 120(%rsi), %rax + movq %rdx, 112(%r8) + adcq 120(%r9), %rax + movq 128(%rsi), %rdx + movq %rax, 120(%r8) + adcq 128(%r9), %rdx + movq 136(%rsi), %rax + movq %rdx, 128(%r8) + adcq 136(%r9), %rax + movq 144(%rsi), %rdx + movq %rax, 136(%r8) + adcq 144(%r9), %rdx + movq 152(%rsi), %rax + movq %rdx, 144(%r8) + adcq 152(%r9), %rax + movq 160(%rsi), %rdx + movq %rax, 152(%r8) + adcq 160(%r9), %rdx + movq 168(%rsi), %rax + movq %rdx, 160(%r8) + adcq 168(%r9), %rax + movq 176(%rsi), %rdx + movq %rax, 168(%r8) + adcq 176(%r9), %rdx + movq 184(%rsi), %rax + movq %rdx, 176(%r8) + adcq 184(%r9), %rax + movq %rax, 184(%r8) + adcq $0, %rcx + movq %rcx, 976(%rsp) + movq %r8, %rsi + movq %rsp, %rdi +#ifndef __APPLE__ + callq sp_3072_sqr_24@plt +#else + callq _sp_3072_sqr_24 +#endif /* __APPLE__ */ + movq 968(%rsp), %rsi + leaq 384(%rsp), %rdi + addq $192, %rsi +#ifndef __APPLE__ + callq sp_3072_sqr_24@plt +#else + callq _sp_3072_sqr_24 +#endif /* __APPLE__ */ + movq 968(%rsp), %rsi + movq 960(%rsp), %rdi +#ifndef __APPLE__ + callq sp_3072_sqr_24@plt +#else + callq _sp_3072_sqr_24 +#endif /* __APPLE__ */ + movq 976(%rsp), %r10 + movq %rdi, %r9 + leaq 768(%rsp), %r8 + movq %r10, %rcx + negq %r10 + addq $384, %r9 + movq (%r8), %rdx + movq 8(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, (%r9) + movq %rax, 8(%r9) + movq 16(%r8), %rdx + movq 24(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 16(%r9) + movq %rax, 24(%r9) + movq 32(%r8), %rdx + movq 40(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 32(%r9) + movq %rax, 40(%r9) + movq 48(%r8), %rdx + movq 56(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 48(%r9) + movq %rax, 56(%r9) + movq 64(%r8), %rdx + movq 72(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 64(%r9) + movq %rax, 72(%r9) + movq 80(%r8), %rdx + movq 88(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 80(%r9) + movq %rax, 88(%r9) + movq 96(%r8), %rdx + movq 104(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 96(%r9) + movq %rax, 104(%r9) + movq 112(%r8), %rdx + movq 120(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 112(%r9) + movq %rax, 120(%r9) + movq 128(%r8), %rdx + movq 136(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 128(%r9) + movq %rax, 136(%r9) + movq 144(%r8), %rdx + movq 152(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 144(%r9) + movq %rax, 152(%r9) + movq 160(%r8), %rdx + movq 168(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 160(%r9) + movq %rax, 168(%r9) + movq 176(%r8), %rdx + movq 184(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 176(%r9) + movq %rax, 184(%r9) + movq (%r9), %rdx + addq %rdx, %rdx + movq 8(%r9), %rax + movq %rdx, (%r9) + adcq %rax, %rax + movq 16(%r9), %rdx + movq %rax, 8(%r9) + adcq %rdx, %rdx + movq 24(%r9), %rax + movq %rdx, 16(%r9) + adcq %rax, %rax + movq 32(%r9), %rdx + movq %rax, 24(%r9) + adcq %rdx, %rdx + movq 40(%r9), %rax + movq %rdx, 32(%r9) + adcq %rax, %rax + movq 48(%r9), %rdx + movq %rax, 40(%r9) + adcq %rdx, %rdx + movq 56(%r9), %rax + movq %rdx, 48(%r9) + adcq %rax, %rax + movq 64(%r9), %rdx + movq %rax, 56(%r9) + adcq %rdx, %rdx + movq 72(%r9), %rax + movq %rdx, 64(%r9) + adcq %rax, %rax + movq 80(%r9), %rdx + movq %rax, 72(%r9) + adcq %rdx, %rdx + movq 88(%r9), %rax + movq %rdx, 80(%r9) + adcq %rax, %rax + movq 96(%r9), %rdx + movq %rax, 88(%r9) + adcq %rdx, %rdx + movq 104(%r9), %rax + movq %rdx, 96(%r9) + adcq %rax, %rax + movq 112(%r9), %rdx + movq %rax, 104(%r9) + adcq %rdx, %rdx + movq 120(%r9), %rax + movq %rdx, 112(%r9) + adcq %rax, %rax + movq 128(%r9), %rdx + movq %rax, 120(%r9) + adcq %rdx, %rdx + movq 136(%r9), %rax + movq %rdx, 128(%r9) + adcq %rax, %rax + movq 144(%r9), %rdx + movq %rax, 136(%r9) + adcq %rdx, %rdx + movq 152(%r9), %rax + movq %rdx, 144(%r9) + adcq %rax, %rax + movq 160(%r9), %rdx + movq %rax, 152(%r9) + adcq %rdx, %rdx + movq 168(%r9), %rax + movq %rdx, 160(%r9) + adcq %rax, %rax + movq 176(%r9), %rdx + movq %rax, 168(%r9) + adcq %rdx, %rdx + movq 184(%r9), %rax + movq %rdx, 176(%r9) + adcq %rax, %rax + movq %rax, 184(%r9) + adcq $0, %rcx + leaq 384(%rsp), %rsi + movq %rsp, %r8 + movq (%r8), %rdx + subq (%rsi), %rdx + movq 8(%r8), %rax + movq %rdx, (%r8) + sbbq 8(%rsi), %rax + movq 16(%r8), %rdx + movq %rax, 8(%r8) + sbbq 16(%rsi), %rdx + movq 24(%r8), %rax + movq %rdx, 16(%r8) + sbbq 24(%rsi), %rax + movq 32(%r8), %rdx + movq %rax, 24(%r8) + sbbq 32(%rsi), %rdx + movq 40(%r8), %rax + movq %rdx, 32(%r8) + sbbq 40(%rsi), %rax + movq 48(%r8), %rdx + movq %rax, 40(%r8) + sbbq 48(%rsi), %rdx + movq 56(%r8), %rax + movq %rdx, 48(%r8) + sbbq 56(%rsi), %rax + movq 64(%r8), %rdx + movq %rax, 56(%r8) + sbbq 64(%rsi), %rdx + movq 72(%r8), %rax + movq %rdx, 64(%r8) + sbbq 72(%rsi), %rax + movq 80(%r8), %rdx + movq %rax, 72(%r8) + sbbq 80(%rsi), %rdx + movq 88(%r8), %rax + movq %rdx, 80(%r8) + sbbq 88(%rsi), %rax + movq 96(%r8), %rdx + movq %rax, 88(%r8) + sbbq 96(%rsi), %rdx + movq 104(%r8), %rax + movq %rdx, 96(%r8) + sbbq 104(%rsi), %rax + movq 112(%r8), %rdx + movq %rax, 104(%r8) + sbbq 112(%rsi), %rdx + movq 120(%r8), %rax + movq %rdx, 112(%r8) + sbbq 120(%rsi), %rax + movq 128(%r8), %rdx + movq %rax, 120(%r8) + sbbq 128(%rsi), %rdx + movq 136(%r8), %rax + movq %rdx, 128(%r8) + sbbq 136(%rsi), %rax + movq 144(%r8), %rdx + movq %rax, 136(%r8) + sbbq 144(%rsi), %rdx + movq 152(%r8), %rax + movq %rdx, 144(%r8) + sbbq 152(%rsi), %rax + movq 160(%r8), %rdx + movq %rax, 152(%r8) + sbbq 160(%rsi), %rdx + movq 168(%r8), %rax + movq %rdx, 160(%r8) + sbbq 168(%rsi), %rax + movq 176(%r8), %rdx + movq %rax, 168(%r8) + sbbq 176(%rsi), %rdx + movq 184(%r8), %rax + movq %rdx, 176(%r8) + sbbq 184(%rsi), %rax + movq 192(%r8), %rdx + movq %rax, 184(%r8) + sbbq 192(%rsi), %rdx + movq 200(%r8), %rax + movq %rdx, 192(%r8) + sbbq 200(%rsi), %rax + movq 208(%r8), %rdx + movq %rax, 200(%r8) + sbbq 208(%rsi), %rdx + movq 216(%r8), %rax + movq %rdx, 208(%r8) + sbbq 216(%rsi), %rax + movq 224(%r8), %rdx + movq %rax, 216(%r8) + sbbq 224(%rsi), %rdx + movq 232(%r8), %rax + movq %rdx, 224(%r8) + sbbq 232(%rsi), %rax + movq 240(%r8), %rdx + movq %rax, 232(%r8) + sbbq 240(%rsi), %rdx + movq 248(%r8), %rax + movq %rdx, 240(%r8) + sbbq 248(%rsi), %rax + movq 256(%r8), %rdx + movq %rax, 248(%r8) + sbbq 256(%rsi), %rdx + movq 264(%r8), %rax + movq %rdx, 256(%r8) + sbbq 264(%rsi), %rax + movq 272(%r8), %rdx + movq %rax, 264(%r8) + sbbq 272(%rsi), %rdx + movq 280(%r8), %rax + movq %rdx, 272(%r8) + sbbq 280(%rsi), %rax + movq 288(%r8), %rdx + movq %rax, 280(%r8) + sbbq 288(%rsi), %rdx + movq 296(%r8), %rax + movq %rdx, 288(%r8) + sbbq 296(%rsi), %rax + movq 304(%r8), %rdx + movq %rax, 296(%r8) + sbbq 304(%rsi), %rdx + movq 312(%r8), %rax + movq %rdx, 304(%r8) + sbbq 312(%rsi), %rax + movq 320(%r8), %rdx + movq %rax, 312(%r8) + sbbq 320(%rsi), %rdx + movq 328(%r8), %rax + movq %rdx, 320(%r8) + sbbq 328(%rsi), %rax + movq 336(%r8), %rdx + movq %rax, 328(%r8) + sbbq 336(%rsi), %rdx + movq 344(%r8), %rax + movq %rdx, 336(%r8) + sbbq 344(%rsi), %rax + movq 352(%r8), %rdx + movq %rax, 344(%r8) + sbbq 352(%rsi), %rdx + movq 360(%r8), %rax + movq %rdx, 352(%r8) + sbbq 360(%rsi), %rax + movq 368(%r8), %rdx + movq %rax, 360(%r8) + sbbq 368(%rsi), %rdx + movq 376(%r8), %rax + movq %rdx, 368(%r8) + sbbq 376(%rsi), %rax + movq %rax, 376(%r8) + sbbq $0, %rcx + movq (%r8), %rdx + subq (%rdi), %rdx + movq 8(%r8), %rax + movq %rdx, (%r8) + sbbq 8(%rdi), %rax + movq 16(%r8), %rdx + movq %rax, 8(%r8) + sbbq 16(%rdi), %rdx + movq 24(%r8), %rax + movq %rdx, 16(%r8) + sbbq 24(%rdi), %rax + movq 32(%r8), %rdx + movq %rax, 24(%r8) + sbbq 32(%rdi), %rdx + movq 40(%r8), %rax + movq %rdx, 32(%r8) + sbbq 40(%rdi), %rax + movq 48(%r8), %rdx + movq %rax, 40(%r8) + sbbq 48(%rdi), %rdx + movq 56(%r8), %rax + movq %rdx, 48(%r8) + sbbq 56(%rdi), %rax + movq 64(%r8), %rdx + movq %rax, 56(%r8) + sbbq 64(%rdi), %rdx + movq 72(%r8), %rax + movq %rdx, 64(%r8) + sbbq 72(%rdi), %rax + movq 80(%r8), %rdx + movq %rax, 72(%r8) + sbbq 80(%rdi), %rdx + movq 88(%r8), %rax + movq %rdx, 80(%r8) + sbbq 88(%rdi), %rax + movq 96(%r8), %rdx + movq %rax, 88(%r8) + sbbq 96(%rdi), %rdx + movq 104(%r8), %rax + movq %rdx, 96(%r8) + sbbq 104(%rdi), %rax + movq 112(%r8), %rdx + movq %rax, 104(%r8) + sbbq 112(%rdi), %rdx + movq 120(%r8), %rax + movq %rdx, 112(%r8) + sbbq 120(%rdi), %rax + movq 128(%r8), %rdx + movq %rax, 120(%r8) + sbbq 128(%rdi), %rdx + movq 136(%r8), %rax + movq %rdx, 128(%r8) + sbbq 136(%rdi), %rax + movq 144(%r8), %rdx + movq %rax, 136(%r8) + sbbq 144(%rdi), %rdx + movq 152(%r8), %rax + movq %rdx, 144(%r8) + sbbq 152(%rdi), %rax + movq 160(%r8), %rdx + movq %rax, 152(%r8) + sbbq 160(%rdi), %rdx + movq 168(%r8), %rax + movq %rdx, 160(%r8) + sbbq 168(%rdi), %rax + movq 176(%r8), %rdx + movq %rax, 168(%r8) + sbbq 176(%rdi), %rdx + movq 184(%r8), %rax + movq %rdx, 176(%r8) + sbbq 184(%rdi), %rax + movq 192(%r8), %rdx + movq %rax, 184(%r8) + sbbq 192(%rdi), %rdx + movq 200(%r8), %rax + movq %rdx, 192(%r8) + sbbq 200(%rdi), %rax + movq 208(%r8), %rdx + movq %rax, 200(%r8) + sbbq 208(%rdi), %rdx + movq 216(%r8), %rax + movq %rdx, 208(%r8) + sbbq 216(%rdi), %rax + movq 224(%r8), %rdx + movq %rax, 216(%r8) + sbbq 224(%rdi), %rdx + movq 232(%r8), %rax + movq %rdx, 224(%r8) + sbbq 232(%rdi), %rax + movq 240(%r8), %rdx + movq %rax, 232(%r8) + sbbq 240(%rdi), %rdx + movq 248(%r8), %rax + movq %rdx, 240(%r8) + sbbq 248(%rdi), %rax + movq 256(%r8), %rdx + movq %rax, 248(%r8) + sbbq 256(%rdi), %rdx + movq 264(%r8), %rax + movq %rdx, 256(%r8) + sbbq 264(%rdi), %rax + movq 272(%r8), %rdx + movq %rax, 264(%r8) + sbbq 272(%rdi), %rdx + movq 280(%r8), %rax + movq %rdx, 272(%r8) + sbbq 280(%rdi), %rax + movq 288(%r8), %rdx + movq %rax, 280(%r8) + sbbq 288(%rdi), %rdx + movq 296(%r8), %rax + movq %rdx, 288(%r8) + sbbq 296(%rdi), %rax + movq 304(%r8), %rdx + movq %rax, 296(%r8) + sbbq 304(%rdi), %rdx + movq 312(%r8), %rax + movq %rdx, 304(%r8) + sbbq 312(%rdi), %rax + movq 320(%r8), %rdx + movq %rax, 312(%r8) + sbbq 320(%rdi), %rdx + movq 328(%r8), %rax + movq %rdx, 320(%r8) + sbbq 328(%rdi), %rax + movq 336(%r8), %rdx + movq %rax, 328(%r8) + sbbq 336(%rdi), %rdx + movq 344(%r8), %rax + movq %rdx, 336(%r8) + sbbq 344(%rdi), %rax + movq 352(%r8), %rdx + movq %rax, 344(%r8) + sbbq 352(%rdi), %rdx + movq 360(%r8), %rax + movq %rdx, 352(%r8) + sbbq 360(%rdi), %rax + movq 368(%r8), %rdx + movq %rax, 360(%r8) + sbbq 368(%rdi), %rdx + movq 376(%r8), %rax + movq %rdx, 368(%r8) + sbbq 376(%rdi), %rax + movq %rax, 376(%r8) + sbbq $0, %rcx + subq $192, %r9 + # Add in place + movq (%r9), %rdx + addq (%r8), %rdx + movq 8(%r9), %rax + movq %rdx, (%r9) + adcq 8(%r8), %rax + movq 16(%r9), %rdx + movq %rax, 8(%r9) + adcq 16(%r8), %rdx + movq 24(%r9), %rax + movq %rdx, 16(%r9) + adcq 24(%r8), %rax + movq 32(%r9), %rdx + movq %rax, 24(%r9) + adcq 32(%r8), %rdx + movq 40(%r9), %rax + movq %rdx, 32(%r9) + adcq 40(%r8), %rax + movq 48(%r9), %rdx + movq %rax, 40(%r9) + adcq 48(%r8), %rdx + movq 56(%r9), %rax + movq %rdx, 48(%r9) + adcq 56(%r8), %rax + movq 64(%r9), %rdx + movq %rax, 56(%r9) + adcq 64(%r8), %rdx + movq 72(%r9), %rax + movq %rdx, 64(%r9) + adcq 72(%r8), %rax + movq 80(%r9), %rdx + movq %rax, 72(%r9) + adcq 80(%r8), %rdx + movq 88(%r9), %rax + movq %rdx, 80(%r9) + adcq 88(%r8), %rax + movq 96(%r9), %rdx + movq %rax, 88(%r9) + adcq 96(%r8), %rdx + movq 104(%r9), %rax + movq %rdx, 96(%r9) + adcq 104(%r8), %rax + movq 112(%r9), %rdx + movq %rax, 104(%r9) + adcq 112(%r8), %rdx + movq 120(%r9), %rax + movq %rdx, 112(%r9) + adcq 120(%r8), %rax + movq 128(%r9), %rdx + movq %rax, 120(%r9) + adcq 128(%r8), %rdx + movq 136(%r9), %rax + movq %rdx, 128(%r9) + adcq 136(%r8), %rax + movq 144(%r9), %rdx + movq %rax, 136(%r9) + adcq 144(%r8), %rdx + movq 152(%r9), %rax + movq %rdx, 144(%r9) + adcq 152(%r8), %rax + movq 160(%r9), %rdx + movq %rax, 152(%r9) + adcq 160(%r8), %rdx + movq 168(%r9), %rax + movq %rdx, 160(%r9) + adcq 168(%r8), %rax + movq 176(%r9), %rdx + movq %rax, 168(%r9) + adcq 176(%r8), %rdx + movq 184(%r9), %rax + movq %rdx, 176(%r9) + adcq 184(%r8), %rax + movq 192(%r9), %rdx + movq %rax, 184(%r9) + adcq 192(%r8), %rdx + movq 200(%r9), %rax + movq %rdx, 192(%r9) + adcq 200(%r8), %rax + movq 208(%r9), %rdx + movq %rax, 200(%r9) + adcq 208(%r8), %rdx + movq 216(%r9), %rax + movq %rdx, 208(%r9) + adcq 216(%r8), %rax + movq 224(%r9), %rdx + movq %rax, 216(%r9) + adcq 224(%r8), %rdx + movq 232(%r9), %rax + movq %rdx, 224(%r9) + adcq 232(%r8), %rax + movq 240(%r9), %rdx + movq %rax, 232(%r9) + adcq 240(%r8), %rdx + movq 248(%r9), %rax + movq %rdx, 240(%r9) + adcq 248(%r8), %rax + movq 256(%r9), %rdx + movq %rax, 248(%r9) + adcq 256(%r8), %rdx + movq 264(%r9), %rax + movq %rdx, 256(%r9) + adcq 264(%r8), %rax + movq 272(%r9), %rdx + movq %rax, 264(%r9) + adcq 272(%r8), %rdx + movq 280(%r9), %rax + movq %rdx, 272(%r9) + adcq 280(%r8), %rax + movq 288(%r9), %rdx + movq %rax, 280(%r9) + adcq 288(%r8), %rdx + movq 296(%r9), %rax + movq %rdx, 288(%r9) + adcq 296(%r8), %rax + movq 304(%r9), %rdx + movq %rax, 296(%r9) + adcq 304(%r8), %rdx + movq 312(%r9), %rax + movq %rdx, 304(%r9) + adcq 312(%r8), %rax + movq 320(%r9), %rdx + movq %rax, 312(%r9) + adcq 320(%r8), %rdx + movq 328(%r9), %rax + movq %rdx, 320(%r9) + adcq 328(%r8), %rax + movq 336(%r9), %rdx + movq %rax, 328(%r9) + adcq 336(%r8), %rdx + movq 344(%r9), %rax + movq %rdx, 336(%r9) + adcq 344(%r8), %rax + movq 352(%r9), %rdx + movq %rax, 344(%r9) + adcq 352(%r8), %rdx + movq 360(%r9), %rax + movq %rdx, 352(%r9) + adcq 360(%r8), %rax + movq 368(%r9), %rdx + movq %rax, 360(%r9) + adcq 368(%r8), %rdx + movq 376(%r9), %rax + movq %rdx, 368(%r9) + adcq 376(%r8), %rax + movq %rax, 376(%r9) + adcq $0, %rcx + movq %rcx, 576(%rdi) + # Add in place + movq 192(%r9), %rdx + addq (%rsi), %rdx + movq 200(%r9), %rax + movq %rdx, 192(%r9) + adcq 8(%rsi), %rax + movq 208(%r9), %rdx + movq %rax, 200(%r9) + adcq 16(%rsi), %rdx + movq 216(%r9), %rax + movq %rdx, 208(%r9) + adcq 24(%rsi), %rax + movq 224(%r9), %rdx + movq %rax, 216(%r9) + adcq 32(%rsi), %rdx + movq 232(%r9), %rax + movq %rdx, 224(%r9) + adcq 40(%rsi), %rax + movq 240(%r9), %rdx + movq %rax, 232(%r9) + adcq 48(%rsi), %rdx + movq 248(%r9), %rax + movq %rdx, 240(%r9) + adcq 56(%rsi), %rax + movq 256(%r9), %rdx + movq %rax, 248(%r9) + adcq 64(%rsi), %rdx + movq 264(%r9), %rax + movq %rdx, 256(%r9) + adcq 72(%rsi), %rax + movq 272(%r9), %rdx + movq %rax, 264(%r9) + adcq 80(%rsi), %rdx + movq 280(%r9), %rax + movq %rdx, 272(%r9) + adcq 88(%rsi), %rax + movq 288(%r9), %rdx + movq %rax, 280(%r9) + adcq 96(%rsi), %rdx + movq 296(%r9), %rax + movq %rdx, 288(%r9) + adcq 104(%rsi), %rax + movq 304(%r9), %rdx + movq %rax, 296(%r9) + adcq 112(%rsi), %rdx + movq 312(%r9), %rax + movq %rdx, 304(%r9) + adcq 120(%rsi), %rax + movq 320(%r9), %rdx + movq %rax, 312(%r9) + adcq 128(%rsi), %rdx + movq 328(%r9), %rax + movq %rdx, 320(%r9) + adcq 136(%rsi), %rax + movq 336(%r9), %rdx + movq %rax, 328(%r9) + adcq 144(%rsi), %rdx + movq 344(%r9), %rax + movq %rdx, 336(%r9) + adcq 152(%rsi), %rax + movq 352(%r9), %rdx + movq %rax, 344(%r9) + adcq 160(%rsi), %rdx + movq 360(%r9), %rax + movq %rdx, 352(%r9) + adcq 168(%rsi), %rax + movq 368(%r9), %rdx + movq %rax, 360(%r9) + adcq 176(%rsi), %rdx + movq 376(%r9), %rax + movq %rdx, 368(%r9) + adcq 184(%rsi), %rax + movq 384(%r9), %rdx + movq %rax, 376(%r9) + adcq 192(%rsi), %rdx + movq %rdx, 384(%r9) + # Add to zero + movq 200(%rsi), %rdx + adcq $0, %rdx + movq 208(%rsi), %rax + movq %rdx, 392(%r9) + adcq $0, %rax + movq 216(%rsi), %rdx + movq %rax, 400(%r9) + adcq $0, %rdx + movq 224(%rsi), %rax + movq %rdx, 408(%r9) + adcq $0, %rax + movq 232(%rsi), %rdx + movq %rax, 416(%r9) + adcq $0, %rdx + movq 240(%rsi), %rax + movq %rdx, 424(%r9) + adcq $0, %rax + movq 248(%rsi), %rdx + movq %rax, 432(%r9) + adcq $0, %rdx + movq 256(%rsi), %rax + movq %rdx, 440(%r9) + adcq $0, %rax + movq 264(%rsi), %rdx + movq %rax, 448(%r9) + adcq $0, %rdx + movq 272(%rsi), %rax + movq %rdx, 456(%r9) + adcq $0, %rax + movq 280(%rsi), %rdx + movq %rax, 464(%r9) + adcq $0, %rdx + movq 288(%rsi), %rax + movq %rdx, 472(%r9) + adcq $0, %rax + movq 296(%rsi), %rdx + movq %rax, 480(%r9) + adcq $0, %rdx + movq 304(%rsi), %rax + movq %rdx, 488(%r9) + adcq $0, %rax + movq 312(%rsi), %rdx + movq %rax, 496(%r9) + adcq $0, %rdx + movq 320(%rsi), %rax + movq %rdx, 504(%r9) + adcq $0, %rax + movq 328(%rsi), %rdx + movq %rax, 512(%r9) + adcq $0, %rdx + movq 336(%rsi), %rax + movq %rdx, 520(%r9) + adcq $0, %rax + movq 344(%rsi), %rdx + movq %rax, 528(%r9) + adcq $0, %rdx + movq 352(%rsi), %rax + movq %rdx, 536(%r9) + adcq $0, %rax + movq 360(%rsi), %rdx + movq %rax, 544(%r9) + adcq $0, %rdx + movq 368(%rsi), %rax + movq %rdx, 552(%r9) + adcq $0, %rax + movq 376(%rsi), %rdx + movq %rax, 560(%r9) + adcq $0, %rdx + movq %rdx, 568(%r9) + addq $984, %rsp + repz retq +#ifndef __APPLE__ +.size sp_3072_sqr_48,.-sp_3072_sqr_48 +#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__ +.globl sp_3072_mul_avx2_48 +.type sp_3072_mul_avx2_48,@function +.align 16 +sp_3072_mul_avx2_48: +#else +.globl _sp_3072_mul_avx2_48 +.p2align 4 +_sp_3072_mul_avx2_48: +#endif /* __APPLE__ */ + push %r12 + push %r13 + push %r14 + push %r15 + subq $1192, %rsp + movq %rdi, 1152(%rsp) + movq %rsi, 1160(%rsp) + movq %rdx, 1168(%rsp) + leaq 768(%rsp), %r10 + leaq 192(%rsi), %r12 + # Add + movq (%rsi), %rax + xorq %r13, %r13 + addq (%r12), %rax + movq 8(%rsi), %rcx + movq %rax, (%r10) + adcq 8(%r12), %rcx + movq 16(%rsi), %r8 + movq %rcx, 8(%r10) + adcq 16(%r12), %r8 + movq 24(%rsi), %rax + movq %r8, 16(%r10) + adcq 24(%r12), %rax + movq 32(%rsi), %rcx + movq %rax, 24(%r10) + adcq 32(%r12), %rcx + movq 40(%rsi), %r8 + movq %rcx, 32(%r10) + adcq 40(%r12), %r8 + movq 48(%rsi), %rax + movq %r8, 40(%r10) + adcq 48(%r12), %rax + movq 56(%rsi), %rcx + movq %rax, 48(%r10) + adcq 56(%r12), %rcx + movq 64(%rsi), %r8 + movq %rcx, 56(%r10) + adcq 64(%r12), %r8 + movq 72(%rsi), %rax + movq %r8, 64(%r10) + adcq 72(%r12), %rax + movq 80(%rsi), %rcx + movq %rax, 72(%r10) + adcq 80(%r12), %rcx + movq 88(%rsi), %r8 + movq %rcx, 80(%r10) + adcq 88(%r12), %r8 + movq 96(%rsi), %rax + movq %r8, 88(%r10) + adcq 96(%r12), %rax + movq 104(%rsi), %rcx + movq %rax, 96(%r10) + adcq 104(%r12), %rcx + movq 112(%rsi), %r8 + movq %rcx, 104(%r10) + adcq 112(%r12), %r8 + movq 120(%rsi), %rax + movq %r8, 112(%r10) + adcq 120(%r12), %rax + movq 128(%rsi), %rcx + movq %rax, 120(%r10) + adcq 128(%r12), %rcx + movq 136(%rsi), %r8 + movq %rcx, 128(%r10) + adcq 136(%r12), %r8 + movq 144(%rsi), %rax + movq %r8, 136(%r10) + adcq 144(%r12), %rax + movq 152(%rsi), %rcx + movq %rax, 144(%r10) + adcq 152(%r12), %rcx + movq 160(%rsi), %r8 + movq %rcx, 152(%r10) + adcq 160(%r12), %r8 + movq 168(%rsi), %rax + movq %r8, 160(%r10) + adcq 168(%r12), %rax + movq 176(%rsi), %rcx + movq %rax, 168(%r10) + adcq 176(%r12), %rcx + movq 184(%rsi), %r8 + movq %rcx, 176(%r10) + adcq 184(%r12), %r8 + movq %r8, 184(%r10) + adcq $0, %r13 + movq %r13, 1176(%rsp) + leaq 960(%rsp), %r11 + leaq 192(%rdx), %r12 + # Add + movq (%rdx), %rax + xorq %r14, %r14 + addq (%r12), %rax + movq 8(%rdx), %rcx + movq %rax, (%r11) + adcq 8(%r12), %rcx + movq 16(%rdx), %r8 + movq %rcx, 8(%r11) + adcq 16(%r12), %r8 + movq 24(%rdx), %rax + movq %r8, 16(%r11) + adcq 24(%r12), %rax + movq 32(%rdx), %rcx + movq %rax, 24(%r11) + adcq 32(%r12), %rcx + movq 40(%rdx), %r8 + movq %rcx, 32(%r11) + adcq 40(%r12), %r8 + movq 48(%rdx), %rax + movq %r8, 40(%r11) + adcq 48(%r12), %rax + movq 56(%rdx), %rcx + movq %rax, 48(%r11) + adcq 56(%r12), %rcx + movq 64(%rdx), %r8 + movq %rcx, 56(%r11) + adcq 64(%r12), %r8 + movq 72(%rdx), %rax + movq %r8, 64(%r11) + adcq 72(%r12), %rax + movq 80(%rdx), %rcx + movq %rax, 72(%r11) + adcq 80(%r12), %rcx + movq 88(%rdx), %r8 + movq %rcx, 80(%r11) + adcq 88(%r12), %r8 + movq 96(%rdx), %rax + movq %r8, 88(%r11) + adcq 96(%r12), %rax + movq 104(%rdx), %rcx + movq %rax, 96(%r11) + adcq 104(%r12), %rcx + movq 112(%rdx), %r8 + movq %rcx, 104(%r11) + adcq 112(%r12), %r8 + movq 120(%rdx), %rax + movq %r8, 112(%r11) + adcq 120(%r12), %rax + movq 128(%rdx), %rcx + movq %rax, 120(%r11) + adcq 128(%r12), %rcx + movq 136(%rdx), %r8 + movq %rcx, 128(%r11) + adcq 136(%r12), %r8 + movq 144(%rdx), %rax + movq %r8, 136(%r11) + adcq 144(%r12), %rax + movq 152(%rdx), %rcx + movq %rax, 144(%r11) + adcq 152(%r12), %rcx + movq 160(%rdx), %r8 + movq %rcx, 152(%r11) + adcq 160(%r12), %r8 + movq 168(%rdx), %rax + movq %r8, 160(%r11) + adcq 168(%r12), %rax + movq 176(%rdx), %rcx + movq %rax, 168(%r11) + adcq 176(%r12), %rcx + movq 184(%rdx), %r8 + movq %rcx, 176(%r11) + adcq 184(%r12), %r8 + movq %r8, 184(%r11) + adcq $0, %r14 + movq %r14, 1184(%rsp) + movq %r11, %rdx + movq %r10, %rsi + movq %rsp, %rdi +#ifndef __APPLE__ + callq sp_3072_mul_avx2_24@plt +#else + callq _sp_3072_mul_avx2_24 +#endif /* __APPLE__ */ + movq 1168(%rsp), %rdx + movq 1160(%rsp), %rsi + leaq 384(%rsp), %rdi + addq $192, %rdx + addq $192, %rsi +#ifndef __APPLE__ + callq sp_3072_mul_avx2_24@plt +#else + callq _sp_3072_mul_avx2_24 +#endif /* __APPLE__ */ + movq 1168(%rsp), %rdx + movq 1160(%rsp), %rsi + movq 1152(%rsp), %rdi +#ifndef __APPLE__ + callq sp_3072_mul_avx2_24@plt +#else + callq _sp_3072_mul_avx2_24 +#endif /* __APPLE__ */ + movq 1176(%rsp), %r13 + movq 1184(%rsp), %r14 + movq 1152(%rsp), %r15 + movq %r13, %r9 + leaq 768(%rsp), %r10 + leaq 960(%rsp), %r11 + andq %r14, %r9 + negq %r13 + negq %r14 + addq $384, %r15 + movq (%r10), %rax + movq (%r11), %rcx + pextq %r14, %rax, %rax + pextq %r13, %rcx, %rcx + addq %rcx, %rax + movq 8(%r10), %rcx + movq 8(%r11), %r8 + pextq %r14, %rcx, %rcx + pextq %r13, %r8, %r8 + movq %rax, (%r15) + adcq %r8, %rcx + movq 16(%r10), %r8 + movq 16(%r11), %rax + pextq %r14, %r8, %r8 + pextq %r13, %rax, %rax + movq %rcx, 8(%r15) + adcq %rax, %r8 + movq 24(%r10), %rax + movq 24(%r11), %rcx + pextq %r14, %rax, %rax + pextq %r13, %rcx, %rcx + movq %r8, 16(%r15) + adcq %rcx, %rax + movq 32(%r10), %rcx + movq 32(%r11), %r8 + pextq %r14, %rcx, %rcx + pextq %r13, %r8, %r8 + movq %rax, 24(%r15) + adcq %r8, %rcx + movq 40(%r10), %r8 + movq 40(%r11), %rax + pextq %r14, %r8, %r8 + pextq %r13, %rax, %rax + movq %rcx, 32(%r15) + adcq %rax, %r8 + movq 48(%r10), %rax + movq 48(%r11), %rcx + pextq %r14, %rax, %rax + pextq %r13, %rcx, %rcx + movq %r8, 40(%r15) + adcq %rcx, %rax + movq 56(%r10), %rcx + movq 56(%r11), %r8 + pextq %r14, %rcx, %rcx + pextq %r13, %r8, %r8 + movq %rax, 48(%r15) + adcq %r8, %rcx + movq 64(%r10), %r8 + movq 64(%r11), %rax + pextq %r14, %r8, %r8 + pextq %r13, %rax, %rax + movq %rcx, 56(%r15) + adcq %rax, %r8 + movq 72(%r10), %rax + movq 72(%r11), %rcx + pextq %r14, %rax, %rax + pextq %r13, %rcx, %rcx + movq %r8, 64(%r15) + adcq %rcx, %rax + movq 80(%r10), %rcx + movq 80(%r11), %r8 + pextq %r14, %rcx, %rcx + pextq %r13, %r8, %r8 + movq %rax, 72(%r15) + adcq %r8, %rcx + movq 88(%r10), %r8 + movq 88(%r11), %rax + pextq %r14, %r8, %r8 + pextq %r13, %rax, %rax + movq %rcx, 80(%r15) + adcq %rax, %r8 + movq 96(%r10), %rax + movq 96(%r11), %rcx + pextq %r14, %rax, %rax + pextq %r13, %rcx, %rcx + movq %r8, 88(%r15) + adcq %rcx, %rax + movq 104(%r10), %rcx + movq 104(%r11), %r8 + pextq %r14, %rcx, %rcx + pextq %r13, %r8, %r8 + movq %rax, 96(%r15) + adcq %r8, %rcx + movq 112(%r10), %r8 + movq 112(%r11), %rax + pextq %r14, %r8, %r8 + pextq %r13, %rax, %rax + movq %rcx, 104(%r15) + adcq %rax, %r8 + movq 120(%r10), %rax + movq 120(%r11), %rcx + pextq %r14, %rax, %rax + pextq %r13, %rcx, %rcx + movq %r8, 112(%r15) + adcq %rcx, %rax + movq 128(%r10), %rcx + movq 128(%r11), %r8 + pextq %r14, %rcx, %rcx + pextq %r13, %r8, %r8 + movq %rax, 120(%r15) + adcq %r8, %rcx + movq 136(%r10), %r8 + movq 136(%r11), %rax + pextq %r14, %r8, %r8 + pextq %r13, %rax, %rax + movq %rcx, 128(%r15) + adcq %rax, %r8 + movq 144(%r10), %rax + movq 144(%r11), %rcx + pextq %r14, %rax, %rax + pextq %r13, %rcx, %rcx + movq %r8, 136(%r15) + adcq %rcx, %rax + movq 152(%r10), %rcx + movq 152(%r11), %r8 + pextq %r14, %rcx, %rcx + pextq %r13, %r8, %r8 + movq %rax, 144(%r15) + adcq %r8, %rcx + movq 160(%r10), %r8 + movq 160(%r11), %rax + pextq %r14, %r8, %r8 + pextq %r13, %rax, %rax + movq %rcx, 152(%r15) + adcq %rax, %r8 + movq 168(%r10), %rax + movq 168(%r11), %rcx + pextq %r14, %rax, %rax + pextq %r13, %rcx, %rcx + movq %r8, 160(%r15) + adcq %rcx, %rax + movq 176(%r10), %rcx + movq 176(%r11), %r8 + pextq %r14, %rcx, %rcx + pextq %r13, %r8, %r8 + movq %rax, 168(%r15) + adcq %r8, %rcx + movq 184(%r10), %r8 + movq 184(%r11), %rax + pextq %r14, %r8, %r8 + pextq %r13, %rax, %rax + movq %rcx, 176(%r15) + adcq %rax, %r8 + movq %r8, 184(%r15) + adcq $0, %r9 + leaq 384(%rsp), %r11 + movq %rsp, %r10 + movq (%r10), %rax + subq (%r11), %rax + movq 8(%r10), %rcx + movq %rax, (%r10) + sbbq 8(%r11), %rcx + movq 16(%r10), %r8 + movq %rcx, 8(%r10) + sbbq 16(%r11), %r8 + movq 24(%r10), %rax + movq %r8, 16(%r10) + sbbq 24(%r11), %rax + movq 32(%r10), %rcx + movq %rax, 24(%r10) + sbbq 32(%r11), %rcx + movq 40(%r10), %r8 + movq %rcx, 32(%r10) + sbbq 40(%r11), %r8 + movq 48(%r10), %rax + movq %r8, 40(%r10) + sbbq 48(%r11), %rax + movq 56(%r10), %rcx + movq %rax, 48(%r10) + sbbq 56(%r11), %rcx + movq 64(%r10), %r8 + movq %rcx, 56(%r10) + sbbq 64(%r11), %r8 + movq 72(%r10), %rax + movq %r8, 64(%r10) + sbbq 72(%r11), %rax + movq 80(%r10), %rcx + movq %rax, 72(%r10) + sbbq 80(%r11), %rcx + movq 88(%r10), %r8 + movq %rcx, 80(%r10) + sbbq 88(%r11), %r8 + movq 96(%r10), %rax + movq %r8, 88(%r10) + sbbq 96(%r11), %rax + movq 104(%r10), %rcx + movq %rax, 96(%r10) + sbbq 104(%r11), %rcx + movq 112(%r10), %r8 + movq %rcx, 104(%r10) + sbbq 112(%r11), %r8 + movq 120(%r10), %rax + movq %r8, 112(%r10) + sbbq 120(%r11), %rax + movq 128(%r10), %rcx + movq %rax, 120(%r10) + sbbq 128(%r11), %rcx + movq 136(%r10), %r8 + movq %rcx, 128(%r10) + sbbq 136(%r11), %r8 + movq 144(%r10), %rax + movq %r8, 136(%r10) + sbbq 144(%r11), %rax + movq 152(%r10), %rcx + movq %rax, 144(%r10) + sbbq 152(%r11), %rcx + movq 160(%r10), %r8 + movq %rcx, 152(%r10) + sbbq 160(%r11), %r8 + movq 168(%r10), %rax + movq %r8, 160(%r10) + sbbq 168(%r11), %rax + movq 176(%r10), %rcx + movq %rax, 168(%r10) + sbbq 176(%r11), %rcx + movq 184(%r10), %r8 + movq %rcx, 176(%r10) + sbbq 184(%r11), %r8 + movq 192(%r10), %rax + movq %r8, 184(%r10) + sbbq 192(%r11), %rax + movq 200(%r10), %rcx + movq %rax, 192(%r10) + sbbq 200(%r11), %rcx + movq 208(%r10), %r8 + movq %rcx, 200(%r10) + sbbq 208(%r11), %r8 + movq 216(%r10), %rax + movq %r8, 208(%r10) + sbbq 216(%r11), %rax + movq 224(%r10), %rcx + movq %rax, 216(%r10) + sbbq 224(%r11), %rcx + movq 232(%r10), %r8 + movq %rcx, 224(%r10) + sbbq 232(%r11), %r8 + movq 240(%r10), %rax + movq %r8, 232(%r10) + sbbq 240(%r11), %rax + movq 248(%r10), %rcx + movq %rax, 240(%r10) + sbbq 248(%r11), %rcx + movq 256(%r10), %r8 + movq %rcx, 248(%r10) + sbbq 256(%r11), %r8 + movq 264(%r10), %rax + movq %r8, 256(%r10) + sbbq 264(%r11), %rax + movq 272(%r10), %rcx + movq %rax, 264(%r10) + sbbq 272(%r11), %rcx + movq 280(%r10), %r8 + movq %rcx, 272(%r10) + sbbq 280(%r11), %r8 + movq 288(%r10), %rax + movq %r8, 280(%r10) + sbbq 288(%r11), %rax + movq 296(%r10), %rcx + movq %rax, 288(%r10) + sbbq 296(%r11), %rcx + movq 304(%r10), %r8 + movq %rcx, 296(%r10) + sbbq 304(%r11), %r8 + movq 312(%r10), %rax + movq %r8, 304(%r10) + sbbq 312(%r11), %rax + movq 320(%r10), %rcx + movq %rax, 312(%r10) + sbbq 320(%r11), %rcx + movq 328(%r10), %r8 + movq %rcx, 320(%r10) + sbbq 328(%r11), %r8 + movq 336(%r10), %rax + movq %r8, 328(%r10) + sbbq 336(%r11), %rax + movq 344(%r10), %rcx + movq %rax, 336(%r10) + sbbq 344(%r11), %rcx + movq 352(%r10), %r8 + movq %rcx, 344(%r10) + sbbq 352(%r11), %r8 + movq 360(%r10), %rax + movq %r8, 352(%r10) + sbbq 360(%r11), %rax + movq 368(%r10), %rcx + movq %rax, 360(%r10) + sbbq 368(%r11), %rcx + movq 376(%r10), %r8 + movq %rcx, 368(%r10) + sbbq 376(%r11), %r8 + movq %r8, 376(%r10) + sbbq $0, %r9 + movq (%r10), %rax + subq (%rdi), %rax + movq 8(%r10), %rcx + movq %rax, (%r10) + sbbq 8(%rdi), %rcx + movq 16(%r10), %r8 + movq %rcx, 8(%r10) + sbbq 16(%rdi), %r8 + movq 24(%r10), %rax + movq %r8, 16(%r10) + sbbq 24(%rdi), %rax + movq 32(%r10), %rcx + movq %rax, 24(%r10) + sbbq 32(%rdi), %rcx + movq 40(%r10), %r8 + movq %rcx, 32(%r10) + sbbq 40(%rdi), %r8 + movq 48(%r10), %rax + movq %r8, 40(%r10) + sbbq 48(%rdi), %rax + movq 56(%r10), %rcx + movq %rax, 48(%r10) + sbbq 56(%rdi), %rcx + movq 64(%r10), %r8 + movq %rcx, 56(%r10) + sbbq 64(%rdi), %r8 + movq 72(%r10), %rax + movq %r8, 64(%r10) + sbbq 72(%rdi), %rax + movq 80(%r10), %rcx + movq %rax, 72(%r10) + sbbq 80(%rdi), %rcx + movq 88(%r10), %r8 + movq %rcx, 80(%r10) + sbbq 88(%rdi), %r8 + movq 96(%r10), %rax + movq %r8, 88(%r10) + sbbq 96(%rdi), %rax + movq 104(%r10), %rcx + movq %rax, 96(%r10) + sbbq 104(%rdi), %rcx + movq 112(%r10), %r8 + movq %rcx, 104(%r10) + sbbq 112(%rdi), %r8 + movq 120(%r10), %rax + movq %r8, 112(%r10) + sbbq 120(%rdi), %rax + movq 128(%r10), %rcx + movq %rax, 120(%r10) + sbbq 128(%rdi), %rcx + movq 136(%r10), %r8 + movq %rcx, 128(%r10) + sbbq 136(%rdi), %r8 + movq 144(%r10), %rax + movq %r8, 136(%r10) + sbbq 144(%rdi), %rax + movq 152(%r10), %rcx + movq %rax, 144(%r10) + sbbq 152(%rdi), %rcx + movq 160(%r10), %r8 + movq %rcx, 152(%r10) + sbbq 160(%rdi), %r8 + movq 168(%r10), %rax + movq %r8, 160(%r10) + sbbq 168(%rdi), %rax + movq 176(%r10), %rcx + movq %rax, 168(%r10) + sbbq 176(%rdi), %rcx + movq 184(%r10), %r8 + movq %rcx, 176(%r10) + sbbq 184(%rdi), %r8 + movq 192(%r10), %rax + movq %r8, 184(%r10) + sbbq 192(%rdi), %rax + movq 200(%r10), %rcx + movq %rax, 192(%r10) + sbbq 200(%rdi), %rcx + movq 208(%r10), %r8 + movq %rcx, 200(%r10) + sbbq 208(%rdi), %r8 + movq 216(%r10), %rax + movq %r8, 208(%r10) + sbbq 216(%rdi), %rax + movq 224(%r10), %rcx + movq %rax, 216(%r10) + sbbq 224(%rdi), %rcx + movq 232(%r10), %r8 + movq %rcx, 224(%r10) + sbbq 232(%rdi), %r8 + movq 240(%r10), %rax + movq %r8, 232(%r10) + sbbq 240(%rdi), %rax + movq 248(%r10), %rcx + movq %rax, 240(%r10) + sbbq 248(%rdi), %rcx + movq 256(%r10), %r8 + movq %rcx, 248(%r10) + sbbq 256(%rdi), %r8 + movq 264(%r10), %rax + movq %r8, 256(%r10) + sbbq 264(%rdi), %rax + movq 272(%r10), %rcx + movq %rax, 264(%r10) + sbbq 272(%rdi), %rcx + movq 280(%r10), %r8 + movq %rcx, 272(%r10) + sbbq 280(%rdi), %r8 + movq 288(%r10), %rax + movq %r8, 280(%r10) + sbbq 288(%rdi), %rax + movq 296(%r10), %rcx + movq %rax, 288(%r10) + sbbq 296(%rdi), %rcx + movq 304(%r10), %r8 + movq %rcx, 296(%r10) + sbbq 304(%rdi), %r8 + movq 312(%r10), %rax + movq %r8, 304(%r10) + sbbq 312(%rdi), %rax + movq 320(%r10), %rcx + movq %rax, 312(%r10) + sbbq 320(%rdi), %rcx + movq 328(%r10), %r8 + movq %rcx, 320(%r10) + sbbq 328(%rdi), %r8 + movq 336(%r10), %rax + movq %r8, 328(%r10) + sbbq 336(%rdi), %rax + movq 344(%r10), %rcx + movq %rax, 336(%r10) + sbbq 344(%rdi), %rcx + movq 352(%r10), %r8 + movq %rcx, 344(%r10) + sbbq 352(%rdi), %r8 + movq 360(%r10), %rax + movq %r8, 352(%r10) + sbbq 360(%rdi), %rax + movq 368(%r10), %rcx + movq %rax, 360(%r10) + sbbq 368(%rdi), %rcx + movq 376(%r10), %r8 + movq %rcx, 368(%r10) + sbbq 376(%rdi), %r8 + movq %r8, 376(%r10) + sbbq $0, %r9 + subq $192, %r15 + # Add + movq (%r15), %rax + addq (%r10), %rax + movq 8(%r15), %rcx + movq %rax, (%r15) + adcq 8(%r10), %rcx + movq 16(%r15), %r8 + movq %rcx, 8(%r15) + adcq 16(%r10), %r8 + movq 24(%r15), %rax + movq %r8, 16(%r15) + adcq 24(%r10), %rax + movq 32(%r15), %rcx + movq %rax, 24(%r15) + adcq 32(%r10), %rcx + movq 40(%r15), %r8 + movq %rcx, 32(%r15) + adcq 40(%r10), %r8 + movq 48(%r15), %rax + movq %r8, 40(%r15) + adcq 48(%r10), %rax + movq 56(%r15), %rcx + movq %rax, 48(%r15) + adcq 56(%r10), %rcx + movq 64(%r15), %r8 + movq %rcx, 56(%r15) + adcq 64(%r10), %r8 + movq 72(%r15), %rax + movq %r8, 64(%r15) + adcq 72(%r10), %rax + movq 80(%r15), %rcx + movq %rax, 72(%r15) + adcq 80(%r10), %rcx + movq 88(%r15), %r8 + movq %rcx, 80(%r15) + adcq 88(%r10), %r8 + movq 96(%r15), %rax + movq %r8, 88(%r15) + adcq 96(%r10), %rax + movq 104(%r15), %rcx + movq %rax, 96(%r15) + adcq 104(%r10), %rcx + movq 112(%r15), %r8 + movq %rcx, 104(%r15) + adcq 112(%r10), %r8 + movq 120(%r15), %rax + movq %r8, 112(%r15) + adcq 120(%r10), %rax + movq 128(%r15), %rcx + movq %rax, 120(%r15) + adcq 128(%r10), %rcx + movq 136(%r15), %r8 + movq %rcx, 128(%r15) + adcq 136(%r10), %r8 + movq 144(%r15), %rax + movq %r8, 136(%r15) + adcq 144(%r10), %rax + movq 152(%r15), %rcx + movq %rax, 144(%r15) + adcq 152(%r10), %rcx + movq 160(%r15), %r8 + movq %rcx, 152(%r15) + adcq 160(%r10), %r8 + movq 168(%r15), %rax + movq %r8, 160(%r15) + adcq 168(%r10), %rax + movq 176(%r15), %rcx + movq %rax, 168(%r15) + adcq 176(%r10), %rcx + movq 184(%r15), %r8 + movq %rcx, 176(%r15) + adcq 184(%r10), %r8 + movq 192(%r15), %rax + movq %r8, 184(%r15) + adcq 192(%r10), %rax + movq 200(%r15), %rcx + movq %rax, 192(%r15) + adcq 200(%r10), %rcx + movq 208(%r15), %r8 + movq %rcx, 200(%r15) + adcq 208(%r10), %r8 + movq 216(%r15), %rax + movq %r8, 208(%r15) + adcq 216(%r10), %rax + movq 224(%r15), %rcx + movq %rax, 216(%r15) + adcq 224(%r10), %rcx + movq 232(%r15), %r8 + movq %rcx, 224(%r15) + adcq 232(%r10), %r8 + movq 240(%r15), %rax + movq %r8, 232(%r15) + adcq 240(%r10), %rax + movq 248(%r15), %rcx + movq %rax, 240(%r15) + adcq 248(%r10), %rcx + movq 256(%r15), %r8 + movq %rcx, 248(%r15) + adcq 256(%r10), %r8 + movq 264(%r15), %rax + movq %r8, 256(%r15) + adcq 264(%r10), %rax + movq 272(%r15), %rcx + movq %rax, 264(%r15) + adcq 272(%r10), %rcx + movq 280(%r15), %r8 + movq %rcx, 272(%r15) + adcq 280(%r10), %r8 + movq 288(%r15), %rax + movq %r8, 280(%r15) + adcq 288(%r10), %rax + movq 296(%r15), %rcx + movq %rax, 288(%r15) + adcq 296(%r10), %rcx + movq 304(%r15), %r8 + movq %rcx, 296(%r15) + adcq 304(%r10), %r8 + movq 312(%r15), %rax + movq %r8, 304(%r15) + adcq 312(%r10), %rax + movq 320(%r15), %rcx + movq %rax, 312(%r15) + adcq 320(%r10), %rcx + movq 328(%r15), %r8 + movq %rcx, 320(%r15) + adcq 328(%r10), %r8 + movq 336(%r15), %rax + movq %r8, 328(%r15) + adcq 336(%r10), %rax + movq 344(%r15), %rcx + movq %rax, 336(%r15) + adcq 344(%r10), %rcx + movq 352(%r15), %r8 + movq %rcx, 344(%r15) + adcq 352(%r10), %r8 + movq 360(%r15), %rax + movq %r8, 352(%r15) + adcq 360(%r10), %rax + movq 368(%r15), %rcx + movq %rax, 360(%r15) + adcq 368(%r10), %rcx + movq 376(%r15), %r8 + movq %rcx, 368(%r15) + adcq 376(%r10), %r8 + movq %r8, 376(%r15) + adcq $0, %r9 + movq %r9, 576(%rdi) + addq $192, %r15 + # Add + movq (%r15), %rax + addq (%r11), %rax + movq 8(%r15), %rcx + movq %rax, (%r15) + adcq 8(%r11), %rcx + movq 16(%r15), %r8 + movq %rcx, 8(%r15) + adcq 16(%r11), %r8 + movq 24(%r15), %rax + movq %r8, 16(%r15) + adcq 24(%r11), %rax + movq 32(%r15), %rcx + movq %rax, 24(%r15) + adcq 32(%r11), %rcx + movq 40(%r15), %r8 + movq %rcx, 32(%r15) + adcq 40(%r11), %r8 + movq 48(%r15), %rax + movq %r8, 40(%r15) + adcq 48(%r11), %rax + movq 56(%r15), %rcx + movq %rax, 48(%r15) + adcq 56(%r11), %rcx + movq 64(%r15), %r8 + movq %rcx, 56(%r15) + adcq 64(%r11), %r8 + movq 72(%r15), %rax + movq %r8, 64(%r15) + adcq 72(%r11), %rax + movq 80(%r15), %rcx + movq %rax, 72(%r15) + adcq 80(%r11), %rcx + movq 88(%r15), %r8 + movq %rcx, 80(%r15) + adcq 88(%r11), %r8 + movq 96(%r15), %rax + movq %r8, 88(%r15) + adcq 96(%r11), %rax + movq 104(%r15), %rcx + movq %rax, 96(%r15) + adcq 104(%r11), %rcx + movq 112(%r15), %r8 + movq %rcx, 104(%r15) + adcq 112(%r11), %r8 + movq 120(%r15), %rax + movq %r8, 112(%r15) + adcq 120(%r11), %rax + movq 128(%r15), %rcx + movq %rax, 120(%r15) + adcq 128(%r11), %rcx + movq 136(%r15), %r8 + movq %rcx, 128(%r15) + adcq 136(%r11), %r8 + movq 144(%r15), %rax + movq %r8, 136(%r15) + adcq 144(%r11), %rax + movq 152(%r15), %rcx + movq %rax, 144(%r15) + adcq 152(%r11), %rcx + movq 160(%r15), %r8 + movq %rcx, 152(%r15) + adcq 160(%r11), %r8 + movq 168(%r15), %rax + movq %r8, 160(%r15) + adcq 168(%r11), %rax + movq 176(%r15), %rcx + movq %rax, 168(%r15) + adcq 176(%r11), %rcx + movq 184(%r15), %r8 + movq %rcx, 176(%r15) + adcq 184(%r11), %r8 + movq 192(%r15), %rax + movq %r8, 184(%r15) + adcq 192(%r11), %rax + movq %rax, 192(%r15) + # Add to zero + movq 200(%r11), %rax + adcq $0, %rax + movq 208(%r11), %rcx + movq %rax, 200(%r15) + adcq $0, %rcx + movq 216(%r11), %r8 + movq %rcx, 208(%r15) + adcq $0, %r8 + movq 224(%r11), %rax + movq %r8, 216(%r15) + adcq $0, %rax + movq 232(%r11), %rcx + movq %rax, 224(%r15) + adcq $0, %rcx + movq 240(%r11), %r8 + movq %rcx, 232(%r15) + adcq $0, %r8 + movq 248(%r11), %rax + movq %r8, 240(%r15) + adcq $0, %rax + movq 256(%r11), %rcx + movq %rax, 248(%r15) + adcq $0, %rcx + movq 264(%r11), %r8 + movq %rcx, 256(%r15) + adcq $0, %r8 + movq 272(%r11), %rax + movq %r8, 264(%r15) + adcq $0, %rax + movq 280(%r11), %rcx + movq %rax, 272(%r15) + adcq $0, %rcx + movq 288(%r11), %r8 + movq %rcx, 280(%r15) + adcq $0, %r8 + movq 296(%r11), %rax + movq %r8, 288(%r15) + adcq $0, %rax + movq 304(%r11), %rcx + movq %rax, 296(%r15) + adcq $0, %rcx + movq 312(%r11), %r8 + movq %rcx, 304(%r15) + adcq $0, %r8 + movq 320(%r11), %rax + movq %r8, 312(%r15) + adcq $0, %rax + movq 328(%r11), %rcx + movq %rax, 320(%r15) + adcq $0, %rcx + movq 336(%r11), %r8 + movq %rcx, 328(%r15) + adcq $0, %r8 + movq 344(%r11), %rax + movq %r8, 336(%r15) + adcq $0, %rax + movq 352(%r11), %rcx + movq %rax, 344(%r15) + adcq $0, %rcx + movq 360(%r11), %r8 + movq %rcx, 352(%r15) + adcq $0, %r8 + movq 368(%r11), %rax + movq %r8, 360(%r15) + adcq $0, %rax + movq 376(%r11), %rcx + movq %rax, 368(%r15) + adcq $0, %rcx + movq %rcx, 376(%r15) + addq $1192, %rsp + pop %r15 + pop %r14 + pop %r13 + pop %r12 + repz retq +#ifndef __APPLE__ +.size sp_3072_mul_avx2_48,.-sp_3072_mul_avx2_48 +#endif /* __APPLE__ */ +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +#ifndef __APPLE__ +.globl sp_3072_sqr_avx2_48 +.type sp_3072_sqr_avx2_48,@function +.align 16 +sp_3072_sqr_avx2_48: +#else +.globl _sp_3072_sqr_avx2_48 +.p2align 4 +_sp_3072_sqr_avx2_48: +#endif /* __APPLE__ */ + subq $984, %rsp + movq %rdi, 960(%rsp) + movq %rsi, 968(%rsp) + leaq 768(%rsp), %r8 + leaq 192(%rsi), %r9 + # Add + movq (%rsi), %rdx + xorq %rcx, %rcx + addq (%r9), %rdx + movq 8(%rsi), %rax + movq %rdx, (%r8) + adcq 8(%r9), %rax + movq 16(%rsi), %rdx + movq %rax, 8(%r8) + adcq 16(%r9), %rdx + movq 24(%rsi), %rax + movq %rdx, 16(%r8) + adcq 24(%r9), %rax + movq 32(%rsi), %rdx + movq %rax, 24(%r8) + adcq 32(%r9), %rdx + movq 40(%rsi), %rax + movq %rdx, 32(%r8) + adcq 40(%r9), %rax + movq 48(%rsi), %rdx + movq %rax, 40(%r8) + adcq 48(%r9), %rdx + movq 56(%rsi), %rax + movq %rdx, 48(%r8) + adcq 56(%r9), %rax + movq 64(%rsi), %rdx + movq %rax, 56(%r8) + adcq 64(%r9), %rdx + movq 72(%rsi), %rax + movq %rdx, 64(%r8) + adcq 72(%r9), %rax + movq 80(%rsi), %rdx + movq %rax, 72(%r8) + adcq 80(%r9), %rdx + movq 88(%rsi), %rax + movq %rdx, 80(%r8) + adcq 88(%r9), %rax + movq 96(%rsi), %rdx + movq %rax, 88(%r8) + adcq 96(%r9), %rdx + movq 104(%rsi), %rax + movq %rdx, 96(%r8) + adcq 104(%r9), %rax + movq 112(%rsi), %rdx + movq %rax, 104(%r8) + adcq 112(%r9), %rdx + movq 120(%rsi), %rax + movq %rdx, 112(%r8) + adcq 120(%r9), %rax + movq 128(%rsi), %rdx + movq %rax, 120(%r8) + adcq 128(%r9), %rdx + movq 136(%rsi), %rax + movq %rdx, 128(%r8) + adcq 136(%r9), %rax + movq 144(%rsi), %rdx + movq %rax, 136(%r8) + adcq 144(%r9), %rdx + movq 152(%rsi), %rax + movq %rdx, 144(%r8) + adcq 152(%r9), %rax + movq 160(%rsi), %rdx + movq %rax, 152(%r8) + adcq 160(%r9), %rdx + movq 168(%rsi), %rax + movq %rdx, 160(%r8) + adcq 168(%r9), %rax + movq 176(%rsi), %rdx + movq %rax, 168(%r8) + adcq 176(%r9), %rdx + movq 184(%rsi), %rax + movq %rdx, 176(%r8) + adcq 184(%r9), %rax + movq %rax, 184(%r8) + adcq $0, %rcx + movq %rcx, 976(%rsp) + movq %r8, %rsi + movq %rsp, %rdi +#ifndef __APPLE__ + callq sp_3072_sqr_avx2_24@plt +#else + callq _sp_3072_sqr_avx2_24 +#endif /* __APPLE__ */ + movq 968(%rsp), %rsi + leaq 384(%rsp), %rdi + addq $192, %rsi +#ifndef __APPLE__ + callq sp_3072_sqr_avx2_24@plt +#else + callq _sp_3072_sqr_avx2_24 +#endif /* __APPLE__ */ + movq 968(%rsp), %rsi + movq 960(%rsp), %rdi +#ifndef __APPLE__ + callq sp_3072_sqr_avx2_24@plt +#else + callq _sp_3072_sqr_avx2_24 +#endif /* __APPLE__ */ + movq 976(%rsp), %r10 + movq %rdi, %r9 + leaq 768(%rsp), %r8 + movq %r10, %rcx + negq %r10 + addq $384, %r9 + movq (%r8), %rdx + pextq %r10, %rdx, %rdx + addq %rdx, %rdx + movq 8(%r8), %rax + movq %rdx, (%r9) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 16(%r8), %rdx + movq %rax, 8(%r9) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 24(%r8), %rax + movq %rdx, 16(%r9) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 32(%r8), %rdx + movq %rax, 24(%r9) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 40(%r8), %rax + movq %rdx, 32(%r9) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 48(%r8), %rdx + movq %rax, 40(%r9) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 56(%r8), %rax + movq %rdx, 48(%r9) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 64(%r8), %rdx + movq %rax, 56(%r9) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 72(%r8), %rax + movq %rdx, 64(%r9) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 80(%r8), %rdx + movq %rax, 72(%r9) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 88(%r8), %rax + movq %rdx, 80(%r9) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 96(%r8), %rdx + movq %rax, 88(%r9) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 104(%r8), %rax + movq %rdx, 96(%r9) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 112(%r8), %rdx + movq %rax, 104(%r9) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 120(%r8), %rax + movq %rdx, 112(%r9) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 128(%r8), %rdx + movq %rax, 120(%r9) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 136(%r8), %rax + movq %rdx, 128(%r9) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 144(%r8), %rdx + movq %rax, 136(%r9) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 152(%r8), %rax + movq %rdx, 144(%r9) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 160(%r8), %rdx + movq %rax, 152(%r9) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 168(%r8), %rax + movq %rdx, 160(%r9) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 176(%r8), %rdx + movq %rax, 168(%r9) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 184(%r8), %rax + movq %rdx, 176(%r9) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq %rax, 184(%r9) + adcq $0, %rcx + leaq 384(%rsp), %rsi + movq %rsp, %r8 + movq (%r8), %rdx + subq (%rsi), %rdx + movq 8(%r8), %rax + movq %rdx, (%r8) + sbbq 8(%rsi), %rax + movq 16(%r8), %rdx + movq %rax, 8(%r8) + sbbq 16(%rsi), %rdx + movq 24(%r8), %rax + movq %rdx, 16(%r8) + sbbq 24(%rsi), %rax + movq 32(%r8), %rdx + movq %rax, 24(%r8) + sbbq 32(%rsi), %rdx + movq 40(%r8), %rax + movq %rdx, 32(%r8) + sbbq 40(%rsi), %rax + movq 48(%r8), %rdx + movq %rax, 40(%r8) + sbbq 48(%rsi), %rdx + movq 56(%r8), %rax + movq %rdx, 48(%r8) + sbbq 56(%rsi), %rax + movq 64(%r8), %rdx + movq %rax, 56(%r8) + sbbq 64(%rsi), %rdx + movq 72(%r8), %rax + movq %rdx, 64(%r8) + sbbq 72(%rsi), %rax + movq 80(%r8), %rdx + movq %rax, 72(%r8) + sbbq 80(%rsi), %rdx + movq 88(%r8), %rax + movq %rdx, 80(%r8) + sbbq 88(%rsi), %rax + movq 96(%r8), %rdx + movq %rax, 88(%r8) + sbbq 96(%rsi), %rdx + movq 104(%r8), %rax + movq %rdx, 96(%r8) + sbbq 104(%rsi), %rax + movq 112(%r8), %rdx + movq %rax, 104(%r8) + sbbq 112(%rsi), %rdx + movq 120(%r8), %rax + movq %rdx, 112(%r8) + sbbq 120(%rsi), %rax + movq 128(%r8), %rdx + movq %rax, 120(%r8) + sbbq 128(%rsi), %rdx + movq 136(%r8), %rax + movq %rdx, 128(%r8) + sbbq 136(%rsi), %rax + movq 144(%r8), %rdx + movq %rax, 136(%r8) + sbbq 144(%rsi), %rdx + movq 152(%r8), %rax + movq %rdx, 144(%r8) + sbbq 152(%rsi), %rax + movq 160(%r8), %rdx + movq %rax, 152(%r8) + sbbq 160(%rsi), %rdx + movq 168(%r8), %rax + movq %rdx, 160(%r8) + sbbq 168(%rsi), %rax + movq 176(%r8), %rdx + movq %rax, 168(%r8) + sbbq 176(%rsi), %rdx + movq 184(%r8), %rax + movq %rdx, 176(%r8) + sbbq 184(%rsi), %rax + movq 192(%r8), %rdx + movq %rax, 184(%r8) + sbbq 192(%rsi), %rdx + movq 200(%r8), %rax + movq %rdx, 192(%r8) + sbbq 200(%rsi), %rax + movq 208(%r8), %rdx + movq %rax, 200(%r8) + sbbq 208(%rsi), %rdx + movq 216(%r8), %rax + movq %rdx, 208(%r8) + sbbq 216(%rsi), %rax + movq 224(%r8), %rdx + movq %rax, 216(%r8) + sbbq 224(%rsi), %rdx + movq 232(%r8), %rax + movq %rdx, 224(%r8) + sbbq 232(%rsi), %rax + movq 240(%r8), %rdx + movq %rax, 232(%r8) + sbbq 240(%rsi), %rdx + movq 248(%r8), %rax + movq %rdx, 240(%r8) + sbbq 248(%rsi), %rax + movq 256(%r8), %rdx + movq %rax, 248(%r8) + sbbq 256(%rsi), %rdx + movq 264(%r8), %rax + movq %rdx, 256(%r8) + sbbq 264(%rsi), %rax + movq 272(%r8), %rdx + movq %rax, 264(%r8) + sbbq 272(%rsi), %rdx + movq 280(%r8), %rax + movq %rdx, 272(%r8) + sbbq 280(%rsi), %rax + movq 288(%r8), %rdx + movq %rax, 280(%r8) + sbbq 288(%rsi), %rdx + movq 296(%r8), %rax + movq %rdx, 288(%r8) + sbbq 296(%rsi), %rax + movq 304(%r8), %rdx + movq %rax, 296(%r8) + sbbq 304(%rsi), %rdx + movq 312(%r8), %rax + movq %rdx, 304(%r8) + sbbq 312(%rsi), %rax + movq 320(%r8), %rdx + movq %rax, 312(%r8) + sbbq 320(%rsi), %rdx + movq 328(%r8), %rax + movq %rdx, 320(%r8) + sbbq 328(%rsi), %rax + movq 336(%r8), %rdx + movq %rax, 328(%r8) + sbbq 336(%rsi), %rdx + movq 344(%r8), %rax + movq %rdx, 336(%r8) + sbbq 344(%rsi), %rax + movq 352(%r8), %rdx + movq %rax, 344(%r8) + sbbq 352(%rsi), %rdx + movq 360(%r8), %rax + movq %rdx, 352(%r8) + sbbq 360(%rsi), %rax + movq 368(%r8), %rdx + movq %rax, 360(%r8) + sbbq 368(%rsi), %rdx + movq 376(%r8), %rax + movq %rdx, 368(%r8) + sbbq 376(%rsi), %rax + movq %rax, 376(%r8) + sbbq $0, %rcx + movq (%r8), %rdx + subq (%rdi), %rdx + movq 8(%r8), %rax + movq %rdx, (%r8) + sbbq 8(%rdi), %rax + movq 16(%r8), %rdx + movq %rax, 8(%r8) + sbbq 16(%rdi), %rdx + movq 24(%r8), %rax + movq %rdx, 16(%r8) + sbbq 24(%rdi), %rax + movq 32(%r8), %rdx + movq %rax, 24(%r8) + sbbq 32(%rdi), %rdx + movq 40(%r8), %rax + movq %rdx, 32(%r8) + sbbq 40(%rdi), %rax + movq 48(%r8), %rdx + movq %rax, 40(%r8) + sbbq 48(%rdi), %rdx + movq 56(%r8), %rax + movq %rdx, 48(%r8) + sbbq 56(%rdi), %rax + movq 64(%r8), %rdx + movq %rax, 56(%r8) + sbbq 64(%rdi), %rdx + movq 72(%r8), %rax + movq %rdx, 64(%r8) + sbbq 72(%rdi), %rax + movq 80(%r8), %rdx + movq %rax, 72(%r8) + sbbq 80(%rdi), %rdx + movq 88(%r8), %rax + movq %rdx, 80(%r8) + sbbq 88(%rdi), %rax + movq 96(%r8), %rdx + movq %rax, 88(%r8) + sbbq 96(%rdi), %rdx + movq 104(%r8), %rax + movq %rdx, 96(%r8) + sbbq 104(%rdi), %rax + movq 112(%r8), %rdx + movq %rax, 104(%r8) + sbbq 112(%rdi), %rdx + movq 120(%r8), %rax + movq %rdx, 112(%r8) + sbbq 120(%rdi), %rax + movq 128(%r8), %rdx + movq %rax, 120(%r8) + sbbq 128(%rdi), %rdx + movq 136(%r8), %rax + movq %rdx, 128(%r8) + sbbq 136(%rdi), %rax + movq 144(%r8), %rdx + movq %rax, 136(%r8) + sbbq 144(%rdi), %rdx + movq 152(%r8), %rax + movq %rdx, 144(%r8) + sbbq 152(%rdi), %rax + movq 160(%r8), %rdx + movq %rax, 152(%r8) + sbbq 160(%rdi), %rdx + movq 168(%r8), %rax + movq %rdx, 160(%r8) + sbbq 168(%rdi), %rax + movq 176(%r8), %rdx + movq %rax, 168(%r8) + sbbq 176(%rdi), %rdx + movq 184(%r8), %rax + movq %rdx, 176(%r8) + sbbq 184(%rdi), %rax + movq 192(%r8), %rdx + movq %rax, 184(%r8) + sbbq 192(%rdi), %rdx + movq 200(%r8), %rax + movq %rdx, 192(%r8) + sbbq 200(%rdi), %rax + movq 208(%r8), %rdx + movq %rax, 200(%r8) + sbbq 208(%rdi), %rdx + movq 216(%r8), %rax + movq %rdx, 208(%r8) + sbbq 216(%rdi), %rax + movq 224(%r8), %rdx + movq %rax, 216(%r8) + sbbq 224(%rdi), %rdx + movq 232(%r8), %rax + movq %rdx, 224(%r8) + sbbq 232(%rdi), %rax + movq 240(%r8), %rdx + movq %rax, 232(%r8) + sbbq 240(%rdi), %rdx + movq 248(%r8), %rax + movq %rdx, 240(%r8) + sbbq 248(%rdi), %rax + movq 256(%r8), %rdx + movq %rax, 248(%r8) + sbbq 256(%rdi), %rdx + movq 264(%r8), %rax + movq %rdx, 256(%r8) + sbbq 264(%rdi), %rax + movq 272(%r8), %rdx + movq %rax, 264(%r8) + sbbq 272(%rdi), %rdx + movq 280(%r8), %rax + movq %rdx, 272(%r8) + sbbq 280(%rdi), %rax + movq 288(%r8), %rdx + movq %rax, 280(%r8) + sbbq 288(%rdi), %rdx + movq 296(%r8), %rax + movq %rdx, 288(%r8) + sbbq 296(%rdi), %rax + movq 304(%r8), %rdx + movq %rax, 296(%r8) + sbbq 304(%rdi), %rdx + movq 312(%r8), %rax + movq %rdx, 304(%r8) + sbbq 312(%rdi), %rax + movq 320(%r8), %rdx + movq %rax, 312(%r8) + sbbq 320(%rdi), %rdx + movq 328(%r8), %rax + movq %rdx, 320(%r8) + sbbq 328(%rdi), %rax + movq 336(%r8), %rdx + movq %rax, 328(%r8) + sbbq 336(%rdi), %rdx + movq 344(%r8), %rax + movq %rdx, 336(%r8) + sbbq 344(%rdi), %rax + movq 352(%r8), %rdx + movq %rax, 344(%r8) + sbbq 352(%rdi), %rdx + movq 360(%r8), %rax + movq %rdx, 352(%r8) + sbbq 360(%rdi), %rax + movq 368(%r8), %rdx + movq %rax, 360(%r8) + sbbq 368(%rdi), %rdx + movq 376(%r8), %rax + movq %rdx, 368(%r8) + sbbq 376(%rdi), %rax + movq %rax, 376(%r8) + sbbq $0, %rcx + subq $192, %r9 + # Add in place + movq (%r9), %rdx + addq (%r8), %rdx + movq 8(%r9), %rax + movq %rdx, (%r9) + adcq 8(%r8), %rax + movq 16(%r9), %rdx + movq %rax, 8(%r9) + adcq 16(%r8), %rdx + movq 24(%r9), %rax + movq %rdx, 16(%r9) + adcq 24(%r8), %rax + movq 32(%r9), %rdx + movq %rax, 24(%r9) + adcq 32(%r8), %rdx + movq 40(%r9), %rax + movq %rdx, 32(%r9) + adcq 40(%r8), %rax + movq 48(%r9), %rdx + movq %rax, 40(%r9) + adcq 48(%r8), %rdx + movq 56(%r9), %rax + movq %rdx, 48(%r9) + adcq 56(%r8), %rax + movq 64(%r9), %rdx + movq %rax, 56(%r9) + adcq 64(%r8), %rdx + movq 72(%r9), %rax + movq %rdx, 64(%r9) + adcq 72(%r8), %rax + movq 80(%r9), %rdx + movq %rax, 72(%r9) + adcq 80(%r8), %rdx + movq 88(%r9), %rax + movq %rdx, 80(%r9) + adcq 88(%r8), %rax + movq 96(%r9), %rdx + movq %rax, 88(%r9) + adcq 96(%r8), %rdx + movq 104(%r9), %rax + movq %rdx, 96(%r9) + adcq 104(%r8), %rax + movq 112(%r9), %rdx + movq %rax, 104(%r9) + adcq 112(%r8), %rdx + movq 120(%r9), %rax + movq %rdx, 112(%r9) + adcq 120(%r8), %rax + movq 128(%r9), %rdx + movq %rax, 120(%r9) + adcq 128(%r8), %rdx + movq 136(%r9), %rax + movq %rdx, 128(%r9) + adcq 136(%r8), %rax + movq 144(%r9), %rdx + movq %rax, 136(%r9) + adcq 144(%r8), %rdx + movq 152(%r9), %rax + movq %rdx, 144(%r9) + adcq 152(%r8), %rax + movq 160(%r9), %rdx + movq %rax, 152(%r9) + adcq 160(%r8), %rdx + movq 168(%r9), %rax + movq %rdx, 160(%r9) + adcq 168(%r8), %rax + movq 176(%r9), %rdx + movq %rax, 168(%r9) + adcq 176(%r8), %rdx + movq 184(%r9), %rax + movq %rdx, 176(%r9) + adcq 184(%r8), %rax + movq 192(%r9), %rdx + movq %rax, 184(%r9) + adcq 192(%r8), %rdx + movq 200(%r9), %rax + movq %rdx, 192(%r9) + adcq 200(%r8), %rax + movq 208(%r9), %rdx + movq %rax, 200(%r9) + adcq 208(%r8), %rdx + movq 216(%r9), %rax + movq %rdx, 208(%r9) + adcq 216(%r8), %rax + movq 224(%r9), %rdx + movq %rax, 216(%r9) + adcq 224(%r8), %rdx + movq 232(%r9), %rax + movq %rdx, 224(%r9) + adcq 232(%r8), %rax + movq 240(%r9), %rdx + movq %rax, 232(%r9) + adcq 240(%r8), %rdx + movq 248(%r9), %rax + movq %rdx, 240(%r9) + adcq 248(%r8), %rax + movq 256(%r9), %rdx + movq %rax, 248(%r9) + adcq 256(%r8), %rdx + movq 264(%r9), %rax + movq %rdx, 256(%r9) + adcq 264(%r8), %rax + movq 272(%r9), %rdx + movq %rax, 264(%r9) + adcq 272(%r8), %rdx + movq 280(%r9), %rax + movq %rdx, 272(%r9) + adcq 280(%r8), %rax + movq 288(%r9), %rdx + movq %rax, 280(%r9) + adcq 288(%r8), %rdx + movq 296(%r9), %rax + movq %rdx, 288(%r9) + adcq 296(%r8), %rax + movq 304(%r9), %rdx + movq %rax, 296(%r9) + adcq 304(%r8), %rdx + movq 312(%r9), %rax + movq %rdx, 304(%r9) + adcq 312(%r8), %rax + movq 320(%r9), %rdx + movq %rax, 312(%r9) + adcq 320(%r8), %rdx + movq 328(%r9), %rax + movq %rdx, 320(%r9) + adcq 328(%r8), %rax + movq 336(%r9), %rdx + movq %rax, 328(%r9) + adcq 336(%r8), %rdx + movq 344(%r9), %rax + movq %rdx, 336(%r9) + adcq 344(%r8), %rax + movq 352(%r9), %rdx + movq %rax, 344(%r9) + adcq 352(%r8), %rdx + movq 360(%r9), %rax + movq %rdx, 352(%r9) + adcq 360(%r8), %rax + movq 368(%r9), %rdx + movq %rax, 360(%r9) + adcq 368(%r8), %rdx + movq 376(%r9), %rax + movq %rdx, 368(%r9) + adcq 376(%r8), %rax + movq %rax, 376(%r9) + adcq $0, %rcx + movq %rcx, 576(%rdi) + # Add in place + movq 192(%r9), %rdx + addq (%rsi), %rdx + movq 200(%r9), %rax + movq %rdx, 192(%r9) + adcq 8(%rsi), %rax + movq 208(%r9), %rdx + movq %rax, 200(%r9) + adcq 16(%rsi), %rdx + movq 216(%r9), %rax + movq %rdx, 208(%r9) + adcq 24(%rsi), %rax + movq 224(%r9), %rdx + movq %rax, 216(%r9) + adcq 32(%rsi), %rdx + movq 232(%r9), %rax + movq %rdx, 224(%r9) + adcq 40(%rsi), %rax + movq 240(%r9), %rdx + movq %rax, 232(%r9) + adcq 48(%rsi), %rdx + movq 248(%r9), %rax + movq %rdx, 240(%r9) + adcq 56(%rsi), %rax + movq 256(%r9), %rdx + movq %rax, 248(%r9) + adcq 64(%rsi), %rdx + movq 264(%r9), %rax + movq %rdx, 256(%r9) + adcq 72(%rsi), %rax + movq 272(%r9), %rdx + movq %rax, 264(%r9) + adcq 80(%rsi), %rdx + movq 280(%r9), %rax + movq %rdx, 272(%r9) + adcq 88(%rsi), %rax + movq 288(%r9), %rdx + movq %rax, 280(%r9) + adcq 96(%rsi), %rdx + movq 296(%r9), %rax + movq %rdx, 288(%r9) + adcq 104(%rsi), %rax + movq 304(%r9), %rdx + movq %rax, 296(%r9) + adcq 112(%rsi), %rdx + movq 312(%r9), %rax + movq %rdx, 304(%r9) + adcq 120(%rsi), %rax + movq 320(%r9), %rdx + movq %rax, 312(%r9) + adcq 128(%rsi), %rdx + movq 328(%r9), %rax + movq %rdx, 320(%r9) + adcq 136(%rsi), %rax + movq 336(%r9), %rdx + movq %rax, 328(%r9) + adcq 144(%rsi), %rdx + movq 344(%r9), %rax + movq %rdx, 336(%r9) + adcq 152(%rsi), %rax + movq 352(%r9), %rdx + movq %rax, 344(%r9) + adcq 160(%rsi), %rdx + movq 360(%r9), %rax + movq %rdx, 352(%r9) + adcq 168(%rsi), %rax + movq 368(%r9), %rdx + movq %rax, 360(%r9) + adcq 176(%rsi), %rdx + movq 376(%r9), %rax + movq %rdx, 368(%r9) + adcq 184(%rsi), %rax + movq 384(%r9), %rdx + movq %rax, 376(%r9) + adcq 192(%rsi), %rdx + movq %rdx, 384(%r9) + # Add to zero + movq 200(%rsi), %rdx + adcq $0, %rdx + movq 208(%rsi), %rax + movq %rdx, 392(%r9) + adcq $0, %rax + movq 216(%rsi), %rdx + movq %rax, 400(%r9) + adcq $0, %rdx + movq 224(%rsi), %rax + movq %rdx, 408(%r9) + adcq $0, %rax + movq 232(%rsi), %rdx + movq %rax, 416(%r9) + adcq $0, %rdx + movq 240(%rsi), %rax + movq %rdx, 424(%r9) + adcq $0, %rax + movq 248(%rsi), %rdx + movq %rax, 432(%r9) + adcq $0, %rdx + movq 256(%rsi), %rax + movq %rdx, 440(%r9) + adcq $0, %rax + movq 264(%rsi), %rdx + movq %rax, 448(%r9) + adcq $0, %rdx + movq 272(%rsi), %rax + movq %rdx, 456(%r9) + adcq $0, %rax + movq 280(%rsi), %rdx + movq %rax, 464(%r9) + adcq $0, %rdx + movq 288(%rsi), %rax + movq %rdx, 472(%r9) + adcq $0, %rax + movq 296(%rsi), %rdx + movq %rax, 480(%r9) + adcq $0, %rdx + movq 304(%rsi), %rax + movq %rdx, 488(%r9) + adcq $0, %rax + movq 312(%rsi), %rdx + movq %rax, 496(%r9) + adcq $0, %rdx + movq 320(%rsi), %rax + movq %rdx, 504(%r9) + adcq $0, %rax + movq 328(%rsi), %rdx + movq %rax, 512(%r9) + adcq $0, %rdx + movq 336(%rsi), %rax + movq %rdx, 520(%r9) + adcq $0, %rax + movq 344(%rsi), %rdx + movq %rax, 528(%r9) + adcq $0, %rdx + movq 352(%rsi), %rax + movq %rdx, 536(%r9) + adcq $0, %rax + movq 360(%rsi), %rdx + movq %rax, 544(%r9) + adcq $0, %rdx + movq 368(%rsi), %rax + movq %rdx, 552(%r9) + adcq $0, %rax + movq 376(%rsi), %rdx + movq %rax, 560(%r9) + adcq $0, %rdx + movq %rdx, 568(%r9) + addq $984, %rsp + repz retq +#ifndef __APPLE__ +.size sp_3072_sqr_avx2_48,.-sp_3072_sqr_avx2_48 +#endif /* __APPLE__ */ /* Mul a by digit b into r. (r = a * b) * * r A single precision integer. @@ -21807,99 +22250,6 @@ _sp_3072_mul_d_48: #ifndef __APPLE__ .size sp_3072_mul_d_48,.-sp_3072_mul_d_48 #endif /* __APPLE__ */ -/* Sub b from a into a. (a -= b) - * - * a A single precision integer and result. - * b A single precision integer. - */ -#ifndef __APPLE__ -.globl sp_3072_sub_in_place_24 -.type sp_3072_sub_in_place_24,@function -.align 16 -sp_3072_sub_in_place_24: -#else -.globl _sp_3072_sub_in_place_24 -.p2align 4 -_sp_3072_sub_in_place_24: -#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 128(%rdi), %rdx - movq %rcx, 120(%rdi) - sbbq 128(%rsi), %rdx - movq 136(%rdi), %rcx - movq %rdx, 128(%rdi) - sbbq 136(%rsi), %rcx - movq 144(%rdi), %rdx - movq %rcx, 136(%rdi) - sbbq 144(%rsi), %rdx - movq 152(%rdi), %rcx - movq %rdx, 144(%rdi) - sbbq 152(%rsi), %rcx - movq 160(%rdi), %rdx - movq %rcx, 152(%rdi) - sbbq 160(%rsi), %rdx - movq 168(%rdi), %rcx - movq %rdx, 160(%rdi) - sbbq 168(%rsi), %rcx - movq 176(%rdi), %rdx - movq %rcx, 168(%rdi) - sbbq 176(%rsi), %rdx - movq 184(%rdi), %rcx - movq %rdx, 176(%rdi) - sbbq 184(%rsi), %rcx - movq %rcx, 184(%rdi) - sbbq $0, %rax - repz retq -#ifndef __APPLE__ -.size sp_3072_sub_in_place_24,.-sp_3072_sub_in_place_24 -#endif /* __APPLE__ */ /* Conditionally subtract b from a using the mask m. * m is -1 to subtract and 0 when not copying. * @@ -22403,126 +22753,126 @@ sp_3072_cond_sub_avx2_24: _sp_3072_cond_sub_avx2_24: #endif /* __APPLE__ */ movq $0, %rax - movq (%rsi), %r8 movq (%rdx), %r10 + movq (%rsi), %r8 pextq %rcx, %r10, %r10 subq %r10, %r8 - movq 8(%rsi), %r9 movq 8(%rdx), %r10 + movq 8(%rsi), %r9 pextq %rcx, %r10, %r10 movq %r8, (%rdi) sbbq %r10, %r9 - movq 16(%rsi), %r8 - movq 16(%rdx), %r10 - pextq %rcx, %r10, %r10 + movq 16(%rdx), %r8 + movq 16(%rsi), %r10 + pextq %rcx, %r8, %r8 movq %r9, 8(%rdi) - sbbq %r10, %r8 - movq 24(%rsi), %r9 - movq 24(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 16(%rdi) - sbbq %r10, %r9 - movq 32(%rsi), %r8 + 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 %r9, 24(%rdi) - sbbq %r10, %r8 - movq 40(%rsi), %r9 - movq 40(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 32(%rdi) + 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 - movq 48(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r9, 40(%rdi) - sbbq %r10, %r8 - movq 56(%rsi), %r9 + 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(%rsi), %r8 - movq 64(%rdx), %r10 - pextq %rcx, %r10, %r10 + movq 64(%rdx), %r8 + movq 64(%rsi), %r10 + pextq %rcx, %r8, %r8 movq %r9, 56(%rdi) - sbbq %r10, %r8 - movq 72(%rsi), %r9 - movq 72(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 64(%rdi) - sbbq %r10, %r9 - movq 80(%rsi), %r8 + 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 %r9, 72(%rdi) - sbbq %r10, %r8 - movq 88(%rsi), %r9 - movq 88(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 80(%rdi) + 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 - movq 96(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r9, 88(%rdi) - sbbq %r10, %r8 - movq 104(%rsi), %r9 + 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(%rsi), %r8 - movq 112(%rdx), %r10 - pextq %rcx, %r10, %r10 + movq 112(%rdx), %r8 + movq 112(%rsi), %r10 + pextq %rcx, %r8, %r8 movq %r9, 104(%rdi) - sbbq %r10, %r8 - movq 120(%rsi), %r9 - movq 120(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 112(%rdi) - sbbq %r10, %r9 - movq 128(%rsi), %r8 + sbbq %r8, %r10 + movq 120(%rdx), %r9 + movq 120(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 112(%rdi) + sbbq %r9, %r8 movq 128(%rdx), %r10 + movq 128(%rsi), %r9 pextq %rcx, %r10, %r10 - movq %r9, 120(%rdi) - sbbq %r10, %r8 - movq 136(%rsi), %r9 - movq 136(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 128(%rdi) + movq %r8, 120(%rdi) sbbq %r10, %r9 + movq 136(%rdx), %r8 + movq 136(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 128(%rdi) + sbbq %r8, %r10 + movq 144(%rdx), %r9 movq 144(%rsi), %r8 - movq 144(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r9, 136(%rdi) - sbbq %r10, %r8 - movq 152(%rsi), %r9 + pextq %rcx, %r9, %r9 + movq %r10, 136(%rdi) + sbbq %r9, %r8 movq 152(%rdx), %r10 + movq 152(%rsi), %r9 pextq %rcx, %r10, %r10 movq %r8, 144(%rdi) sbbq %r10, %r9 - movq 160(%rsi), %r8 - movq 160(%rdx), %r10 - pextq %rcx, %r10, %r10 + movq 160(%rdx), %r8 + movq 160(%rsi), %r10 + pextq %rcx, %r8, %r8 movq %r9, 152(%rdi) - sbbq %r10, %r8 - movq 168(%rsi), %r9 - movq 168(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 160(%rdi) - sbbq %r10, %r9 - movq 176(%rsi), %r8 + sbbq %r8, %r10 + movq 168(%rdx), %r9 + movq 168(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 160(%rdi) + sbbq %r9, %r8 movq 176(%rdx), %r10 + movq 176(%rsi), %r9 pextq %rcx, %r10, %r10 - movq %r9, 168(%rdi) - sbbq %r10, %r8 - movq 184(%rsi), %r9 - movq 184(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 176(%rdi) + movq %r8, 168(%rdi) sbbq %r10, %r9 - movq %r9, 184(%rdi) + movq 184(%rdx), %r8 + movq 184(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 176(%rdi) + sbbq %r8, %r10 + movq %r10, 184(%rdi) sbbq $0, %rax repz retq #ifndef __APPLE__ @@ -22756,150 +23106,152 @@ sp_3072_mul_d_avx2_24: .p2align 4 _sp_3072_mul_d_avx2_24: #endif /* __APPLE__ */ + movq %rdx, %rax # A[0] * B - xorq %r10, %r10 - mulxq (%rsi), %r8, %r9 - movq %r8, (%rdi) + movq %rax, %rdx + xorq %r11, %r11 + mulxq (%rsi), %r9, %r10 + movq %r9, (%rdi) # A[1] * B - mulxq 8(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 8(%rdi) - adoxq %rcx, %r8 + mulxq 8(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 8(%rdi) + adoxq %r8, %r9 # A[2] * B - mulxq 16(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 16(%rdi) - adoxq %rcx, %r9 + mulxq 16(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 16(%rdi) + adoxq %r8, %r10 # A[3] * B - mulxq 24(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 24(%rdi) - adoxq %rcx, %r8 + mulxq 24(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 24(%rdi) + adoxq %r8, %r9 # A[4] * B - mulxq 32(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 32(%rdi) - adoxq %rcx, %r9 + mulxq 32(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 32(%rdi) + adoxq %r8, %r10 # A[5] * B - mulxq 40(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 40(%rdi) - adoxq %rcx, %r8 + mulxq 40(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 40(%rdi) + adoxq %r8, %r9 # A[6] * B - mulxq 48(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 48(%rdi) - adoxq %rcx, %r9 + mulxq 48(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 48(%rdi) + adoxq %r8, %r10 # A[7] * B - mulxq 56(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 56(%rdi) - adoxq %rcx, %r8 + mulxq 56(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 56(%rdi) + adoxq %r8, %r9 # A[8] * B - mulxq 64(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 64(%rdi) - adoxq %rcx, %r9 + mulxq 64(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 64(%rdi) + adoxq %r8, %r10 # A[9] * B - mulxq 72(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 72(%rdi) - adoxq %rcx, %r8 + mulxq 72(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 72(%rdi) + adoxq %r8, %r9 # A[10] * B - mulxq 80(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 80(%rdi) - adoxq %rcx, %r9 + mulxq 80(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 80(%rdi) + adoxq %r8, %r10 # A[11] * B - mulxq 88(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 88(%rdi) - adoxq %rcx, %r8 + mulxq 88(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 88(%rdi) + adoxq %r8, %r9 # A[12] * B - mulxq 96(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 96(%rdi) - adoxq %rcx, %r9 + mulxq 96(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 96(%rdi) + adoxq %r8, %r10 # A[13] * B - mulxq 104(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 104(%rdi) - adoxq %rcx, %r8 + mulxq 104(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 104(%rdi) + adoxq %r8, %r9 # A[14] * B - mulxq 112(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 112(%rdi) - adoxq %rcx, %r9 + mulxq 112(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 112(%rdi) + adoxq %r8, %r10 # A[15] * B - mulxq 120(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 120(%rdi) - adoxq %rcx, %r8 + mulxq 120(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 120(%rdi) + adoxq %r8, %r9 # A[16] * B - mulxq 128(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 128(%rdi) - adoxq %rcx, %r9 + mulxq 128(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 128(%rdi) + adoxq %r8, %r10 # A[17] * B - mulxq 136(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 136(%rdi) - adoxq %rcx, %r8 + mulxq 136(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 136(%rdi) + adoxq %r8, %r9 # A[18] * B - mulxq 144(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 144(%rdi) - adoxq %rcx, %r9 + mulxq 144(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 144(%rdi) + adoxq %r8, %r10 # A[19] * B - mulxq 152(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 152(%rdi) - adoxq %rcx, %r8 + mulxq 152(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 152(%rdi) + adoxq %r8, %r9 # A[20] * B - mulxq 160(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 160(%rdi) - adoxq %rcx, %r9 + mulxq 160(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 160(%rdi) + adoxq %r8, %r10 # A[21] * B - mulxq 168(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 168(%rdi) - adoxq %rcx, %r8 + mulxq 168(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 168(%rdi) + adoxq %r8, %r9 # A[22] * B - mulxq 176(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 176(%rdi) - adoxq %rcx, %r9 + mulxq 176(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 176(%rdi) + adoxq %r8, %r10 # A[23] * B - mulxq 184(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - adoxq %rcx, %r8 - adcxq %r10, %r8 - movq %r9, 184(%rdi) - movq %r8, 192(%rdi) + mulxq 184(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + adoxq %r8, %r9 + adcxq %r11, %r9 + movq %r10, 184(%rdi) + movq %r9, 192(%rdi) repz retq #ifndef __APPLE__ .size sp_3072_mul_d_avx2_24,.-sp_3072_mul_d_avx2_24 @@ -23143,179 +23495,295 @@ _sp_3072_mont_reduce_avx2_24: push %r12 push %r13 push %r14 - movq %rdx, %rax + movq %rdx, %r8 xorq %r14, %r14 # i = 24 movq $24, %r9 movq (%rdi), %r13 + addq $96, %rdi xorq %r12, %r12 L_mont_loop_avx2_24: # mu = a[i] * mp movq %r13, %rdx - mulxq %rax, %rdx, %r8 movq %r13, %r10 + imulq %r8, %rdx + xorq %r12, %r12 # a[i+0] += m[0] * mu - mulxq (%rsi), %rcx, %r8 - movq 8(%rdi), %r13 - adcxq %rcx, %r10 - adoxq %r8, %r13 + mulxq (%rsi), %rax, %rcx + movq -88(%rdi), %r13 + adcxq %rax, %r10 + adoxq %rcx, %r13 # a[i+1] += m[1] * mu - mulxq 8(%rsi), %rcx, %r8 - movq 16(%rdi), %r10 - adcxq %rcx, %r13 - adoxq %r8, %r10 + mulxq 8(%rsi), %rax, %rcx + movq -80(%rdi), %r10 + adcxq %rax, %r13 + adoxq %rcx, %r10 # a[i+2] += m[2] * mu - mulxq 16(%rsi), %rcx, %r8 - movq 24(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 16(%rdi) + mulxq 16(%rsi), %rax, %rcx + movq -72(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -80(%rdi) # a[i+3] += m[3] * mu - mulxq 24(%rsi), %rcx, %r8 - movq 32(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 24(%rdi) + mulxq 24(%rsi), %rax, %rcx + movq -64(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -72(%rdi) # a[i+4] += m[4] * mu - mulxq 32(%rsi), %rcx, %r8 - movq 40(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 32(%rdi) + mulxq 32(%rsi), %rax, %rcx + movq -56(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -64(%rdi) # a[i+5] += m[5] * mu - mulxq 40(%rsi), %rcx, %r8 - movq 48(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 40(%rdi) + mulxq 40(%rsi), %rax, %rcx + movq -48(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -56(%rdi) # a[i+6] += m[6] * mu - mulxq 48(%rsi), %rcx, %r8 - movq 56(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 48(%rdi) + mulxq 48(%rsi), %rax, %rcx + movq -40(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -48(%rdi) # a[i+7] += m[7] * mu - mulxq 56(%rsi), %rcx, %r8 - movq 64(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 56(%rdi) + mulxq 56(%rsi), %rax, %rcx + movq -32(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -40(%rdi) # a[i+8] += m[8] * mu - mulxq 64(%rsi), %rcx, %r8 - movq 72(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 64(%rdi) + mulxq 64(%rsi), %rax, %rcx + movq -24(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -32(%rdi) # a[i+9] += m[9] * mu - mulxq 72(%rsi), %rcx, %r8 - movq 80(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 72(%rdi) + mulxq 72(%rsi), %rax, %rcx + movq -16(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -24(%rdi) # a[i+10] += m[10] * mu - mulxq 80(%rsi), %rcx, %r8 - movq 88(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 80(%rdi) + mulxq 80(%rsi), %rax, %rcx + movq -8(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -16(%rdi) # a[i+11] += m[11] * mu - mulxq 88(%rsi), %rcx, %r8 - movq 96(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 88(%rdi) + mulxq 88(%rsi), %rax, %rcx + movq (%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -8(%rdi) # a[i+12] += m[12] * mu - mulxq 96(%rsi), %rcx, %r8 - movq 104(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 96(%rdi) + mulxq 96(%rsi), %rax, %rcx + movq 8(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, (%rdi) # a[i+13] += m[13] * mu - mulxq 104(%rsi), %rcx, %r8 - movq 112(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 104(%rdi) + mulxq 104(%rsi), %rax, %rcx + movq 16(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 8(%rdi) # a[i+14] += m[14] * mu - mulxq 112(%rsi), %rcx, %r8 - movq 120(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 112(%rdi) + mulxq 112(%rsi), %rax, %rcx + movq 24(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 16(%rdi) # a[i+15] += m[15] * mu - mulxq 120(%rsi), %rcx, %r8 - movq 128(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 120(%rdi) + mulxq 120(%rsi), %rax, %rcx + movq 32(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 24(%rdi) # a[i+16] += m[16] * mu - mulxq 128(%rsi), %rcx, %r8 - movq 136(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 128(%rdi) + mulxq 128(%rsi), %rax, %rcx + movq 40(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 32(%rdi) # a[i+17] += m[17] * mu - mulxq 136(%rsi), %rcx, %r8 - movq 144(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 136(%rdi) + mulxq 136(%rsi), %rax, %rcx + movq 48(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 40(%rdi) # a[i+18] += m[18] * mu - mulxq 144(%rsi), %rcx, %r8 - movq 152(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 144(%rdi) + mulxq 144(%rsi), %rax, %rcx + movq 56(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 48(%rdi) # a[i+19] += m[19] * mu - mulxq 152(%rsi), %rcx, %r8 - movq 160(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 152(%rdi) + mulxq 152(%rsi), %rax, %rcx + movq 64(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 56(%rdi) # a[i+20] += m[20] * mu - mulxq 160(%rsi), %rcx, %r8 - movq 168(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 160(%rdi) + mulxq 160(%rsi), %rax, %rcx + movq 72(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 64(%rdi) # a[i+21] += m[21] * mu - mulxq 168(%rsi), %rcx, %r8 - movq 176(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 168(%rdi) + mulxq 168(%rsi), %rax, %rcx + movq 80(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 72(%rdi) # a[i+22] += m[22] * mu - mulxq 176(%rsi), %rcx, %r8 - movq 184(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 176(%rdi) + mulxq 176(%rsi), %rax, %rcx + movq 88(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 80(%rdi) # a[i+23] += m[23] * mu - mulxq 184(%rsi), %rcx, %r8 - movq 192(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 184(%rdi) + mulxq 184(%rsi), %rax, %rcx + movq 96(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 88(%rdi) adcxq %r14, %r10 + movq %r10, 96(%rdi) movq %r12, %r14 - movq %r10, 192(%rdi) adoxq %r12, %r14 adcxq %r12, %r14 - # i -= 1 + # a += 1 addq $8, %rdi - decq %r9 + # i -= 1 + subq $1, %r9 jnz L_mont_loop_avx2_24 - movq %r13, (%rdi) + subq $96, %rdi negq %r14 - movq %r14, %rcx - movq %rsi, %rdx - movq %rdi, %rsi + movq %rdi, %r8 subq $192, %rdi -#ifndef __APPLE__ - callq sp_3072_cond_sub_avx2_24@plt -#else - callq _sp_3072_cond_sub_avx2_24 -#endif /* __APPLE__ */ + movq (%rsi), %rcx + movq %r13, %rdx + pextq %r14, %rcx, %rcx + subq %rcx, %rdx + movq 8(%rsi), %rcx + movq 8(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, (%rdi) + sbbq %rcx, %rax + movq 16(%rsi), %rdx + movq 16(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 8(%rdi) + sbbq %rdx, %rcx + movq 24(%rsi), %rax + movq 24(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 16(%rdi) + sbbq %rax, %rdx + movq 32(%rsi), %rcx + movq 32(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 24(%rdi) + sbbq %rcx, %rax + movq 40(%rsi), %rdx + movq 40(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 32(%rdi) + sbbq %rdx, %rcx + movq 48(%rsi), %rax + movq 48(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 40(%rdi) + sbbq %rax, %rdx + movq 56(%rsi), %rcx + movq 56(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 48(%rdi) + sbbq %rcx, %rax + movq 64(%rsi), %rdx + movq 64(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 56(%rdi) + sbbq %rdx, %rcx + movq 72(%rsi), %rax + movq 72(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 64(%rdi) + sbbq %rax, %rdx + movq 80(%rsi), %rcx + movq 80(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 72(%rdi) + sbbq %rcx, %rax + movq 88(%rsi), %rdx + movq 88(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 80(%rdi) + sbbq %rdx, %rcx + movq 96(%rsi), %rax + movq 96(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 88(%rdi) + sbbq %rax, %rdx + movq 104(%rsi), %rcx + movq 104(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 96(%rdi) + sbbq %rcx, %rax + movq 112(%rsi), %rdx + movq 112(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 104(%rdi) + sbbq %rdx, %rcx + movq 120(%rsi), %rax + movq 120(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 112(%rdi) + sbbq %rax, %rdx + movq 128(%rsi), %rcx + movq 128(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 120(%rdi) + sbbq %rcx, %rax + movq 136(%rsi), %rdx + movq 136(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 128(%rdi) + sbbq %rdx, %rcx + movq 144(%rsi), %rax + movq 144(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 136(%rdi) + sbbq %rax, %rdx + movq 152(%rsi), %rcx + movq 152(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 144(%rdi) + sbbq %rcx, %rax + movq 160(%rsi), %rdx + movq 160(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 152(%rdi) + sbbq %rdx, %rcx + movq 168(%rsi), %rax + movq 168(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 160(%rdi) + sbbq %rax, %rdx + movq 176(%rsi), %rcx + movq 176(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 168(%rdi) + sbbq %rcx, %rax + movq 184(%rsi), %rdx + movq 184(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 176(%rdi) + sbbq %rdx, %rcx + movq %rcx, 184(%rdi) pop %r14 pop %r13 pop %r12 @@ -24235,246 +24703,246 @@ sp_3072_cond_sub_avx2_48: _sp_3072_cond_sub_avx2_48: #endif /* __APPLE__ */ movq $0, %rax - movq (%rsi), %r8 movq (%rdx), %r10 + movq (%rsi), %r8 pextq %rcx, %r10, %r10 subq %r10, %r8 - movq 8(%rsi), %r9 movq 8(%rdx), %r10 + movq 8(%rsi), %r9 pextq %rcx, %r10, %r10 movq %r8, (%rdi) sbbq %r10, %r9 - movq 16(%rsi), %r8 - movq 16(%rdx), %r10 - pextq %rcx, %r10, %r10 + movq 16(%rdx), %r8 + movq 16(%rsi), %r10 + pextq %rcx, %r8, %r8 movq %r9, 8(%rdi) - sbbq %r10, %r8 - movq 24(%rsi), %r9 - movq 24(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 16(%rdi) - sbbq %r10, %r9 - movq 32(%rsi), %r8 + 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 %r9, 24(%rdi) - sbbq %r10, %r8 - movq 40(%rsi), %r9 - movq 40(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 32(%rdi) + 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 - movq 48(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r9, 40(%rdi) - sbbq %r10, %r8 - movq 56(%rsi), %r9 + 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(%rsi), %r8 - movq 64(%rdx), %r10 - pextq %rcx, %r10, %r10 + movq 64(%rdx), %r8 + movq 64(%rsi), %r10 + pextq %rcx, %r8, %r8 movq %r9, 56(%rdi) - sbbq %r10, %r8 - movq 72(%rsi), %r9 - movq 72(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 64(%rdi) - sbbq %r10, %r9 - movq 80(%rsi), %r8 + 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 %r9, 72(%rdi) - sbbq %r10, %r8 - movq 88(%rsi), %r9 - movq 88(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 80(%rdi) + 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 - movq 96(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r9, 88(%rdi) - sbbq %r10, %r8 - movq 104(%rsi), %r9 + 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(%rsi), %r8 - movq 112(%rdx), %r10 - pextq %rcx, %r10, %r10 + movq 112(%rdx), %r8 + movq 112(%rsi), %r10 + pextq %rcx, %r8, %r8 movq %r9, 104(%rdi) - sbbq %r10, %r8 - movq 120(%rsi), %r9 - movq 120(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 112(%rdi) - sbbq %r10, %r9 - movq 128(%rsi), %r8 + sbbq %r8, %r10 + movq 120(%rdx), %r9 + movq 120(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 112(%rdi) + sbbq %r9, %r8 movq 128(%rdx), %r10 + movq 128(%rsi), %r9 pextq %rcx, %r10, %r10 - movq %r9, 120(%rdi) - sbbq %r10, %r8 - movq 136(%rsi), %r9 - movq 136(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 128(%rdi) + movq %r8, 120(%rdi) sbbq %r10, %r9 + movq 136(%rdx), %r8 + movq 136(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 128(%rdi) + sbbq %r8, %r10 + movq 144(%rdx), %r9 movq 144(%rsi), %r8 - movq 144(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r9, 136(%rdi) - sbbq %r10, %r8 - movq 152(%rsi), %r9 + pextq %rcx, %r9, %r9 + movq %r10, 136(%rdi) + sbbq %r9, %r8 movq 152(%rdx), %r10 + movq 152(%rsi), %r9 pextq %rcx, %r10, %r10 movq %r8, 144(%rdi) sbbq %r10, %r9 - movq 160(%rsi), %r8 - movq 160(%rdx), %r10 - pextq %rcx, %r10, %r10 + movq 160(%rdx), %r8 + movq 160(%rsi), %r10 + pextq %rcx, %r8, %r8 movq %r9, 152(%rdi) - sbbq %r10, %r8 - movq 168(%rsi), %r9 - movq 168(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 160(%rdi) - sbbq %r10, %r9 - movq 176(%rsi), %r8 + sbbq %r8, %r10 + movq 168(%rdx), %r9 + movq 168(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 160(%rdi) + sbbq %r9, %r8 movq 176(%rdx), %r10 + movq 176(%rsi), %r9 pextq %rcx, %r10, %r10 - movq %r9, 168(%rdi) - sbbq %r10, %r8 - movq 184(%rsi), %r9 - movq 184(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 176(%rdi) + movq %r8, 168(%rdi) sbbq %r10, %r9 + movq 184(%rdx), %r8 + movq 184(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 176(%rdi) + sbbq %r8, %r10 + movq 192(%rdx), %r9 movq 192(%rsi), %r8 - movq 192(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r9, 184(%rdi) - sbbq %r10, %r8 - movq 200(%rsi), %r9 + pextq %rcx, %r9, %r9 + movq %r10, 184(%rdi) + sbbq %r9, %r8 movq 200(%rdx), %r10 + movq 200(%rsi), %r9 pextq %rcx, %r10, %r10 movq %r8, 192(%rdi) sbbq %r10, %r9 - movq 208(%rsi), %r8 - movq 208(%rdx), %r10 - pextq %rcx, %r10, %r10 + movq 208(%rdx), %r8 + movq 208(%rsi), %r10 + pextq %rcx, %r8, %r8 movq %r9, 200(%rdi) - sbbq %r10, %r8 - movq 216(%rsi), %r9 - movq 216(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 208(%rdi) - sbbq %r10, %r9 - movq 224(%rsi), %r8 + sbbq %r8, %r10 + movq 216(%rdx), %r9 + movq 216(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 208(%rdi) + sbbq %r9, %r8 movq 224(%rdx), %r10 + movq 224(%rsi), %r9 pextq %rcx, %r10, %r10 - movq %r9, 216(%rdi) - sbbq %r10, %r8 - movq 232(%rsi), %r9 - movq 232(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 224(%rdi) + movq %r8, 216(%rdi) sbbq %r10, %r9 + movq 232(%rdx), %r8 + movq 232(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 224(%rdi) + sbbq %r8, %r10 + movq 240(%rdx), %r9 movq 240(%rsi), %r8 - movq 240(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r9, 232(%rdi) - sbbq %r10, %r8 - movq 248(%rsi), %r9 + pextq %rcx, %r9, %r9 + movq %r10, 232(%rdi) + sbbq %r9, %r8 movq 248(%rdx), %r10 + movq 248(%rsi), %r9 pextq %rcx, %r10, %r10 movq %r8, 240(%rdi) sbbq %r10, %r9 - movq 256(%rsi), %r8 - movq 256(%rdx), %r10 - pextq %rcx, %r10, %r10 + movq 256(%rdx), %r8 + movq 256(%rsi), %r10 + pextq %rcx, %r8, %r8 movq %r9, 248(%rdi) - sbbq %r10, %r8 - movq 264(%rsi), %r9 - movq 264(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 256(%rdi) - sbbq %r10, %r9 - movq 272(%rsi), %r8 + sbbq %r8, %r10 + movq 264(%rdx), %r9 + movq 264(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 256(%rdi) + sbbq %r9, %r8 movq 272(%rdx), %r10 + movq 272(%rsi), %r9 pextq %rcx, %r10, %r10 - movq %r9, 264(%rdi) - sbbq %r10, %r8 - movq 280(%rsi), %r9 - movq 280(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 272(%rdi) + movq %r8, 264(%rdi) sbbq %r10, %r9 + movq 280(%rdx), %r8 + movq 280(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 272(%rdi) + sbbq %r8, %r10 + movq 288(%rdx), %r9 movq 288(%rsi), %r8 - movq 288(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r9, 280(%rdi) - sbbq %r10, %r8 - movq 296(%rsi), %r9 + pextq %rcx, %r9, %r9 + movq %r10, 280(%rdi) + sbbq %r9, %r8 movq 296(%rdx), %r10 + movq 296(%rsi), %r9 pextq %rcx, %r10, %r10 movq %r8, 288(%rdi) sbbq %r10, %r9 - movq 304(%rsi), %r8 - movq 304(%rdx), %r10 - pextq %rcx, %r10, %r10 + movq 304(%rdx), %r8 + movq 304(%rsi), %r10 + pextq %rcx, %r8, %r8 movq %r9, 296(%rdi) - sbbq %r10, %r8 - movq 312(%rsi), %r9 - movq 312(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 304(%rdi) - sbbq %r10, %r9 - movq 320(%rsi), %r8 + sbbq %r8, %r10 + movq 312(%rdx), %r9 + movq 312(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 304(%rdi) + sbbq %r9, %r8 movq 320(%rdx), %r10 + movq 320(%rsi), %r9 pextq %rcx, %r10, %r10 - movq %r9, 312(%rdi) - sbbq %r10, %r8 - movq 328(%rsi), %r9 - movq 328(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 320(%rdi) + movq %r8, 312(%rdi) sbbq %r10, %r9 + movq 328(%rdx), %r8 + movq 328(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 320(%rdi) + sbbq %r8, %r10 + movq 336(%rdx), %r9 movq 336(%rsi), %r8 - movq 336(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r9, 328(%rdi) - sbbq %r10, %r8 - movq 344(%rsi), %r9 + pextq %rcx, %r9, %r9 + movq %r10, 328(%rdi) + sbbq %r9, %r8 movq 344(%rdx), %r10 + movq 344(%rsi), %r9 pextq %rcx, %r10, %r10 movq %r8, 336(%rdi) sbbq %r10, %r9 - movq 352(%rsi), %r8 - movq 352(%rdx), %r10 - pextq %rcx, %r10, %r10 + movq 352(%rdx), %r8 + movq 352(%rsi), %r10 + pextq %rcx, %r8, %r8 movq %r9, 344(%rdi) - sbbq %r10, %r8 - movq 360(%rsi), %r9 - movq 360(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 352(%rdi) - sbbq %r10, %r9 - movq 368(%rsi), %r8 + sbbq %r8, %r10 + movq 360(%rdx), %r9 + movq 360(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 352(%rdi) + sbbq %r9, %r8 movq 368(%rdx), %r10 + movq 368(%rsi), %r9 pextq %rcx, %r10, %r10 - movq %r9, 360(%rdi) - sbbq %r10, %r8 - movq 376(%rsi), %r9 - movq 376(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 368(%rdi) + movq %r8, 360(%rdi) sbbq %r10, %r9 - movq %r9, 376(%rdi) + movq 376(%rdx), %r8 + movq 376(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 368(%rdi) + sbbq %r8, %r10 + movq %r10, 376(%rdi) sbbq $0, %rax repz retq #ifndef __APPLE__ @@ -24497,294 +24965,296 @@ sp_3072_mul_d_avx2_48: .p2align 4 _sp_3072_mul_d_avx2_48: #endif /* __APPLE__ */ + movq %rdx, %rax # A[0] * B - xorq %r10, %r10 - mulxq (%rsi), %r8, %r9 - movq %r8, (%rdi) + movq %rax, %rdx + xorq %r11, %r11 + mulxq (%rsi), %r9, %r10 + movq %r9, (%rdi) # A[1] * B - mulxq 8(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 8(%rdi) - adoxq %rcx, %r8 + mulxq 8(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 8(%rdi) + adoxq %r8, %r9 # A[2] * B - mulxq 16(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 16(%rdi) - adoxq %rcx, %r9 + mulxq 16(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 16(%rdi) + adoxq %r8, %r10 # A[3] * B - mulxq 24(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 24(%rdi) - adoxq %rcx, %r8 + mulxq 24(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 24(%rdi) + adoxq %r8, %r9 # A[4] * B - mulxq 32(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 32(%rdi) - adoxq %rcx, %r9 + mulxq 32(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 32(%rdi) + adoxq %r8, %r10 # A[5] * B - mulxq 40(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 40(%rdi) - adoxq %rcx, %r8 + mulxq 40(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 40(%rdi) + adoxq %r8, %r9 # A[6] * B - mulxq 48(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 48(%rdi) - adoxq %rcx, %r9 + mulxq 48(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 48(%rdi) + adoxq %r8, %r10 # A[7] * B - mulxq 56(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 56(%rdi) - adoxq %rcx, %r8 + mulxq 56(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 56(%rdi) + adoxq %r8, %r9 # A[8] * B - mulxq 64(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 64(%rdi) - adoxq %rcx, %r9 + mulxq 64(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 64(%rdi) + adoxq %r8, %r10 # A[9] * B - mulxq 72(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 72(%rdi) - adoxq %rcx, %r8 + mulxq 72(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 72(%rdi) + adoxq %r8, %r9 # A[10] * B - mulxq 80(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 80(%rdi) - adoxq %rcx, %r9 + mulxq 80(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 80(%rdi) + adoxq %r8, %r10 # A[11] * B - mulxq 88(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 88(%rdi) - adoxq %rcx, %r8 + mulxq 88(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 88(%rdi) + adoxq %r8, %r9 # A[12] * B - mulxq 96(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 96(%rdi) - adoxq %rcx, %r9 + mulxq 96(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 96(%rdi) + adoxq %r8, %r10 # A[13] * B - mulxq 104(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 104(%rdi) - adoxq %rcx, %r8 + mulxq 104(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 104(%rdi) + adoxq %r8, %r9 # A[14] * B - mulxq 112(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 112(%rdi) - adoxq %rcx, %r9 + mulxq 112(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 112(%rdi) + adoxq %r8, %r10 # A[15] * B - mulxq 120(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 120(%rdi) - adoxq %rcx, %r8 + mulxq 120(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 120(%rdi) + adoxq %r8, %r9 # A[16] * B - mulxq 128(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 128(%rdi) - adoxq %rcx, %r9 + mulxq 128(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 128(%rdi) + adoxq %r8, %r10 # A[17] * B - mulxq 136(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 136(%rdi) - adoxq %rcx, %r8 + mulxq 136(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 136(%rdi) + adoxq %r8, %r9 # A[18] * B - mulxq 144(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 144(%rdi) - adoxq %rcx, %r9 + mulxq 144(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 144(%rdi) + adoxq %r8, %r10 # A[19] * B - mulxq 152(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 152(%rdi) - adoxq %rcx, %r8 + mulxq 152(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 152(%rdi) + adoxq %r8, %r9 # A[20] * B - mulxq 160(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 160(%rdi) - adoxq %rcx, %r9 + mulxq 160(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 160(%rdi) + adoxq %r8, %r10 # A[21] * B - mulxq 168(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 168(%rdi) - adoxq %rcx, %r8 + mulxq 168(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 168(%rdi) + adoxq %r8, %r9 # A[22] * B - mulxq 176(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 176(%rdi) - adoxq %rcx, %r9 + mulxq 176(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 176(%rdi) + adoxq %r8, %r10 # A[23] * B - mulxq 184(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 184(%rdi) - adoxq %rcx, %r8 + mulxq 184(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 184(%rdi) + adoxq %r8, %r9 # A[24] * B - mulxq 192(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 192(%rdi) - adoxq %rcx, %r9 + mulxq 192(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 192(%rdi) + adoxq %r8, %r10 # A[25] * B - mulxq 200(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 200(%rdi) - adoxq %rcx, %r8 + mulxq 200(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 200(%rdi) + adoxq %r8, %r9 # A[26] * B - mulxq 208(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 208(%rdi) - adoxq %rcx, %r9 + mulxq 208(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 208(%rdi) + adoxq %r8, %r10 # A[27] * B - mulxq 216(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 216(%rdi) - adoxq %rcx, %r8 + mulxq 216(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 216(%rdi) + adoxq %r8, %r9 # A[28] * B - mulxq 224(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 224(%rdi) - adoxq %rcx, %r9 + mulxq 224(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 224(%rdi) + adoxq %r8, %r10 # A[29] * B - mulxq 232(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 232(%rdi) - adoxq %rcx, %r8 + mulxq 232(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 232(%rdi) + adoxq %r8, %r9 # A[30] * B - mulxq 240(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 240(%rdi) - adoxq %rcx, %r9 + mulxq 240(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 240(%rdi) + adoxq %r8, %r10 # A[31] * B - mulxq 248(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 248(%rdi) - adoxq %rcx, %r8 + mulxq 248(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 248(%rdi) + adoxq %r8, %r9 # A[32] * B - mulxq 256(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 256(%rdi) - adoxq %rcx, %r9 + mulxq 256(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 256(%rdi) + adoxq %r8, %r10 # A[33] * B - mulxq 264(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 264(%rdi) - adoxq %rcx, %r8 + mulxq 264(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 264(%rdi) + adoxq %r8, %r9 # A[34] * B - mulxq 272(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 272(%rdi) - adoxq %rcx, %r9 + mulxq 272(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 272(%rdi) + adoxq %r8, %r10 # A[35] * B - mulxq 280(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 280(%rdi) - adoxq %rcx, %r8 + mulxq 280(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 280(%rdi) + adoxq %r8, %r9 # A[36] * B - mulxq 288(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 288(%rdi) - adoxq %rcx, %r9 + mulxq 288(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 288(%rdi) + adoxq %r8, %r10 # A[37] * B - mulxq 296(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 296(%rdi) - adoxq %rcx, %r8 + mulxq 296(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 296(%rdi) + adoxq %r8, %r9 # A[38] * B - mulxq 304(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 304(%rdi) - adoxq %rcx, %r9 + mulxq 304(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 304(%rdi) + adoxq %r8, %r10 # A[39] * B - mulxq 312(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 312(%rdi) - adoxq %rcx, %r8 + mulxq 312(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 312(%rdi) + adoxq %r8, %r9 # A[40] * B - mulxq 320(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 320(%rdi) - adoxq %rcx, %r9 + mulxq 320(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 320(%rdi) + adoxq %r8, %r10 # A[41] * B - mulxq 328(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 328(%rdi) - adoxq %rcx, %r8 + mulxq 328(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 328(%rdi) + adoxq %r8, %r9 # A[42] * B - mulxq 336(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 336(%rdi) - adoxq %rcx, %r9 + mulxq 336(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 336(%rdi) + adoxq %r8, %r10 # A[43] * B - mulxq 344(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 344(%rdi) - adoxq %rcx, %r8 + mulxq 344(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 344(%rdi) + adoxq %r8, %r9 # A[44] * B - mulxq 352(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 352(%rdi) - adoxq %rcx, %r9 + mulxq 352(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 352(%rdi) + adoxq %r8, %r10 # A[45] * B - mulxq 360(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 360(%rdi) - adoxq %rcx, %r8 + mulxq 360(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 360(%rdi) + adoxq %r8, %r9 # A[46] * B - mulxq 368(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 368(%rdi) - adoxq %rcx, %r9 + mulxq 368(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 368(%rdi) + adoxq %r8, %r10 # A[47] * B - mulxq 376(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - adoxq %rcx, %r8 - adcxq %r10, %r8 - movq %r9, 376(%rdi) - movq %r8, 384(%rdi) + mulxq 376(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + adoxq %r8, %r9 + adcxq %r11, %r9 + movq %r10, 376(%rdi) + movq %r9, 384(%rdi) repz retq #ifndef __APPLE__ .size sp_3072_mul_d_avx2_48,.-sp_3072_mul_d_avx2_48 @@ -25386,323 +25856,559 @@ _sp_3072_mont_reduce_avx2_48: push %r12 push %r13 push %r14 - movq %rdx, %rax + movq %rdx, %r8 xorq %r14, %r14 # i = 48 movq $48, %r9 movq (%rdi), %r13 + addq $192, %rdi xorq %r12, %r12 L_mont_loop_avx2_48: # mu = a[i] * mp movq %r13, %rdx - mulxq %rax, %rdx, %r8 movq %r13, %r10 + imulq %r8, %rdx + xorq %r12, %r12 # a[i+0] += m[0] * mu - mulxq (%rsi), %rcx, %r8 - movq 8(%rdi), %r13 - adcxq %rcx, %r10 - adoxq %r8, %r13 + mulxq (%rsi), %rax, %rcx + movq -184(%rdi), %r13 + adcxq %rax, %r10 + adoxq %rcx, %r13 # a[i+1] += m[1] * mu - mulxq 8(%rsi), %rcx, %r8 - movq 16(%rdi), %r10 - adcxq %rcx, %r13 - adoxq %r8, %r10 + mulxq 8(%rsi), %rax, %rcx + movq -176(%rdi), %r10 + adcxq %rax, %r13 + adoxq %rcx, %r10 # a[i+2] += m[2] * mu - mulxq 16(%rsi), %rcx, %r8 - movq 24(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 16(%rdi) + mulxq 16(%rsi), %rax, %rcx + movq -168(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -176(%rdi) # a[i+3] += m[3] * mu - mulxq 24(%rsi), %rcx, %r8 - movq 32(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 24(%rdi) + mulxq 24(%rsi), %rax, %rcx + movq -160(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -168(%rdi) # a[i+4] += m[4] * mu - mulxq 32(%rsi), %rcx, %r8 - movq 40(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 32(%rdi) + mulxq 32(%rsi), %rax, %rcx + movq -152(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -160(%rdi) # a[i+5] += m[5] * mu - mulxq 40(%rsi), %rcx, %r8 - movq 48(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 40(%rdi) + mulxq 40(%rsi), %rax, %rcx + movq -144(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -152(%rdi) # a[i+6] += m[6] * mu - mulxq 48(%rsi), %rcx, %r8 - movq 56(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 48(%rdi) + mulxq 48(%rsi), %rax, %rcx + movq -136(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -144(%rdi) # a[i+7] += m[7] * mu - mulxq 56(%rsi), %rcx, %r8 - movq 64(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 56(%rdi) + mulxq 56(%rsi), %rax, %rcx + movq -128(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -136(%rdi) # a[i+8] += m[8] * mu - mulxq 64(%rsi), %rcx, %r8 - movq 72(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 64(%rdi) + mulxq 64(%rsi), %rax, %rcx + movq -120(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -128(%rdi) # a[i+9] += m[9] * mu - mulxq 72(%rsi), %rcx, %r8 - movq 80(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 72(%rdi) + mulxq 72(%rsi), %rax, %rcx + movq -112(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -120(%rdi) # a[i+10] += m[10] * mu - mulxq 80(%rsi), %rcx, %r8 - movq 88(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 80(%rdi) + mulxq 80(%rsi), %rax, %rcx + movq -104(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -112(%rdi) # a[i+11] += m[11] * mu - mulxq 88(%rsi), %rcx, %r8 - movq 96(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 88(%rdi) + mulxq 88(%rsi), %rax, %rcx + movq -96(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -104(%rdi) # a[i+12] += m[12] * mu - mulxq 96(%rsi), %rcx, %r8 - movq 104(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 96(%rdi) + mulxq 96(%rsi), %rax, %rcx + movq -88(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -96(%rdi) # a[i+13] += m[13] * mu - mulxq 104(%rsi), %rcx, %r8 - movq 112(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 104(%rdi) + mulxq 104(%rsi), %rax, %rcx + movq -80(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -88(%rdi) # a[i+14] += m[14] * mu - mulxq 112(%rsi), %rcx, %r8 - movq 120(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 112(%rdi) + mulxq 112(%rsi), %rax, %rcx + movq -72(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -80(%rdi) # a[i+15] += m[15] * mu - mulxq 120(%rsi), %rcx, %r8 - movq 128(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 120(%rdi) + mulxq 120(%rsi), %rax, %rcx + movq -64(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -72(%rdi) # a[i+16] += m[16] * mu - mulxq 128(%rsi), %rcx, %r8 - movq 136(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 128(%rdi) + mulxq 128(%rsi), %rax, %rcx + movq -56(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -64(%rdi) # a[i+17] += m[17] * mu - mulxq 136(%rsi), %rcx, %r8 - movq 144(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 136(%rdi) + mulxq 136(%rsi), %rax, %rcx + movq -48(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -56(%rdi) # a[i+18] += m[18] * mu - mulxq 144(%rsi), %rcx, %r8 - movq 152(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 144(%rdi) + mulxq 144(%rsi), %rax, %rcx + movq -40(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -48(%rdi) # a[i+19] += m[19] * mu - mulxq 152(%rsi), %rcx, %r8 - movq 160(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 152(%rdi) + mulxq 152(%rsi), %rax, %rcx + movq -32(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -40(%rdi) # a[i+20] += m[20] * mu - mulxq 160(%rsi), %rcx, %r8 - movq 168(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 160(%rdi) + mulxq 160(%rsi), %rax, %rcx + movq -24(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -32(%rdi) # a[i+21] += m[21] * mu - mulxq 168(%rsi), %rcx, %r8 - movq 176(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 168(%rdi) + mulxq 168(%rsi), %rax, %rcx + movq -16(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -24(%rdi) # a[i+22] += m[22] * mu - mulxq 176(%rsi), %rcx, %r8 - movq 184(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 176(%rdi) + mulxq 176(%rsi), %rax, %rcx + movq -8(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -16(%rdi) # a[i+23] += m[23] * mu - mulxq 184(%rsi), %rcx, %r8 - movq 192(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 184(%rdi) + mulxq 184(%rsi), %rax, %rcx + movq (%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -8(%rdi) # a[i+24] += m[24] * mu - mulxq 192(%rsi), %rcx, %r8 - movq 200(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 192(%rdi) + mulxq 192(%rsi), %rax, %rcx + movq 8(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, (%rdi) # a[i+25] += m[25] * mu - mulxq 200(%rsi), %rcx, %r8 - movq 208(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 200(%rdi) + mulxq 200(%rsi), %rax, %rcx + movq 16(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 8(%rdi) # a[i+26] += m[26] * mu - mulxq 208(%rsi), %rcx, %r8 - movq 216(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 208(%rdi) + mulxq 208(%rsi), %rax, %rcx + movq 24(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 16(%rdi) # a[i+27] += m[27] * mu - mulxq 216(%rsi), %rcx, %r8 - movq 224(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 216(%rdi) + mulxq 216(%rsi), %rax, %rcx + movq 32(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 24(%rdi) # a[i+28] += m[28] * mu - mulxq 224(%rsi), %rcx, %r8 - movq 232(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 224(%rdi) + mulxq 224(%rsi), %rax, %rcx + movq 40(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 32(%rdi) # a[i+29] += m[29] * mu - mulxq 232(%rsi), %rcx, %r8 - movq 240(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 232(%rdi) + mulxq 232(%rsi), %rax, %rcx + movq 48(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 40(%rdi) # a[i+30] += m[30] * mu - mulxq 240(%rsi), %rcx, %r8 - movq 248(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 240(%rdi) + mulxq 240(%rsi), %rax, %rcx + movq 56(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 48(%rdi) # a[i+31] += m[31] * mu - mulxq 248(%rsi), %rcx, %r8 - movq 256(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 248(%rdi) + mulxq 248(%rsi), %rax, %rcx + movq 64(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 56(%rdi) # a[i+32] += m[32] * mu - mulxq 256(%rsi), %rcx, %r8 - movq 264(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 256(%rdi) + mulxq 256(%rsi), %rax, %rcx + movq 72(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 64(%rdi) # a[i+33] += m[33] * mu - mulxq 264(%rsi), %rcx, %r8 - movq 272(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 264(%rdi) + mulxq 264(%rsi), %rax, %rcx + movq 80(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 72(%rdi) # a[i+34] += m[34] * mu - mulxq 272(%rsi), %rcx, %r8 - movq 280(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 272(%rdi) + mulxq 272(%rsi), %rax, %rcx + movq 88(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 80(%rdi) # a[i+35] += m[35] * mu - mulxq 280(%rsi), %rcx, %r8 - movq 288(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 280(%rdi) + mulxq 280(%rsi), %rax, %rcx + movq 96(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 88(%rdi) # a[i+36] += m[36] * mu - mulxq 288(%rsi), %rcx, %r8 - movq 296(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 288(%rdi) + mulxq 288(%rsi), %rax, %rcx + movq 104(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 96(%rdi) # a[i+37] += m[37] * mu - mulxq 296(%rsi), %rcx, %r8 - movq 304(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 296(%rdi) + mulxq 296(%rsi), %rax, %rcx + movq 112(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 104(%rdi) # a[i+38] += m[38] * mu - mulxq 304(%rsi), %rcx, %r8 - movq 312(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 304(%rdi) + mulxq 304(%rsi), %rax, %rcx + movq 120(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 112(%rdi) # a[i+39] += m[39] * mu - mulxq 312(%rsi), %rcx, %r8 - movq 320(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 312(%rdi) + mulxq 312(%rsi), %rax, %rcx + movq 128(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 120(%rdi) # a[i+40] += m[40] * mu - mulxq 320(%rsi), %rcx, %r8 - movq 328(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 320(%rdi) + mulxq 320(%rsi), %rax, %rcx + movq 136(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 128(%rdi) # a[i+41] += m[41] * mu - mulxq 328(%rsi), %rcx, %r8 - movq 336(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 328(%rdi) + mulxq 328(%rsi), %rax, %rcx + movq 144(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 136(%rdi) # a[i+42] += m[42] * mu - mulxq 336(%rsi), %rcx, %r8 - movq 344(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 336(%rdi) + mulxq 336(%rsi), %rax, %rcx + movq 152(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 144(%rdi) # a[i+43] += m[43] * mu - mulxq 344(%rsi), %rcx, %r8 - movq 352(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 344(%rdi) + mulxq 344(%rsi), %rax, %rcx + movq 160(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 152(%rdi) # a[i+44] += m[44] * mu - mulxq 352(%rsi), %rcx, %r8 - movq 360(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 352(%rdi) + mulxq 352(%rsi), %rax, %rcx + movq 168(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 160(%rdi) # a[i+45] += m[45] * mu - mulxq 360(%rsi), %rcx, %r8 - movq 368(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 360(%rdi) + mulxq 360(%rsi), %rax, %rcx + movq 176(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 168(%rdi) # a[i+46] += m[46] * mu - mulxq 368(%rsi), %rcx, %r8 - movq 376(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 368(%rdi) + mulxq 368(%rsi), %rax, %rcx + movq 184(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 176(%rdi) # a[i+47] += m[47] * mu - mulxq 376(%rsi), %rcx, %r8 - movq 384(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 376(%rdi) + mulxq 376(%rsi), %rax, %rcx + movq 192(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 184(%rdi) adcxq %r14, %r10 + movq %r10, 192(%rdi) movq %r12, %r14 - movq %r10, 384(%rdi) adoxq %r12, %r14 adcxq %r12, %r14 - # i -= 1 + # a += 1 addq $8, %rdi - decq %r9 + # i -= 1 + subq $1, %r9 jnz L_mont_loop_avx2_48 - movq %r13, (%rdi) + subq $192, %rdi negq %r14 - movq %r14, %rcx - movq %rsi, %rdx - movq %rdi, %rsi + movq %rdi, %r8 subq $384, %rdi -#ifndef __APPLE__ - callq sp_3072_cond_sub_avx2_48@plt -#else - callq _sp_3072_cond_sub_avx2_48 -#endif /* __APPLE__ */ + movq (%rsi), %rcx + movq %r13, %rdx + pextq %r14, %rcx, %rcx + subq %rcx, %rdx + movq 8(%rsi), %rcx + movq 8(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, (%rdi) + sbbq %rcx, %rax + movq 16(%rsi), %rdx + movq 16(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 8(%rdi) + sbbq %rdx, %rcx + movq 24(%rsi), %rax + movq 24(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 16(%rdi) + sbbq %rax, %rdx + movq 32(%rsi), %rcx + movq 32(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 24(%rdi) + sbbq %rcx, %rax + movq 40(%rsi), %rdx + movq 40(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 32(%rdi) + sbbq %rdx, %rcx + movq 48(%rsi), %rax + movq 48(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 40(%rdi) + sbbq %rax, %rdx + movq 56(%rsi), %rcx + movq 56(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 48(%rdi) + sbbq %rcx, %rax + movq 64(%rsi), %rdx + movq 64(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 56(%rdi) + sbbq %rdx, %rcx + movq 72(%rsi), %rax + movq 72(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 64(%rdi) + sbbq %rax, %rdx + movq 80(%rsi), %rcx + movq 80(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 72(%rdi) + sbbq %rcx, %rax + movq 88(%rsi), %rdx + movq 88(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 80(%rdi) + sbbq %rdx, %rcx + movq 96(%rsi), %rax + movq 96(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 88(%rdi) + sbbq %rax, %rdx + movq 104(%rsi), %rcx + movq 104(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 96(%rdi) + sbbq %rcx, %rax + movq 112(%rsi), %rdx + movq 112(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 104(%rdi) + sbbq %rdx, %rcx + movq 120(%rsi), %rax + movq 120(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 112(%rdi) + sbbq %rax, %rdx + movq 128(%rsi), %rcx + movq 128(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 120(%rdi) + sbbq %rcx, %rax + movq 136(%rsi), %rdx + movq 136(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 128(%rdi) + sbbq %rdx, %rcx + movq 144(%rsi), %rax + movq 144(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 136(%rdi) + sbbq %rax, %rdx + movq 152(%rsi), %rcx + movq 152(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 144(%rdi) + sbbq %rcx, %rax + movq 160(%rsi), %rdx + movq 160(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 152(%rdi) + sbbq %rdx, %rcx + movq 168(%rsi), %rax + movq 168(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 160(%rdi) + sbbq %rax, %rdx + movq 176(%rsi), %rcx + movq 176(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 168(%rdi) + sbbq %rcx, %rax + movq 184(%rsi), %rdx + movq 184(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 176(%rdi) + sbbq %rdx, %rcx + movq 192(%rsi), %rax + movq 192(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 184(%rdi) + sbbq %rax, %rdx + movq 200(%rsi), %rcx + movq 200(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 192(%rdi) + sbbq %rcx, %rax + movq 208(%rsi), %rdx + movq 208(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 200(%rdi) + sbbq %rdx, %rcx + movq 216(%rsi), %rax + movq 216(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 208(%rdi) + sbbq %rax, %rdx + movq 224(%rsi), %rcx + movq 224(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 216(%rdi) + sbbq %rcx, %rax + movq 232(%rsi), %rdx + movq 232(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 224(%rdi) + sbbq %rdx, %rcx + movq 240(%rsi), %rax + movq 240(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 232(%rdi) + sbbq %rax, %rdx + movq 248(%rsi), %rcx + movq 248(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 240(%rdi) + sbbq %rcx, %rax + movq 256(%rsi), %rdx + movq 256(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 248(%rdi) + sbbq %rdx, %rcx + movq 264(%rsi), %rax + movq 264(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 256(%rdi) + sbbq %rax, %rdx + movq 272(%rsi), %rcx + movq 272(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 264(%rdi) + sbbq %rcx, %rax + movq 280(%rsi), %rdx + movq 280(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 272(%rdi) + sbbq %rdx, %rcx + movq 288(%rsi), %rax + movq 288(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 280(%rdi) + sbbq %rax, %rdx + movq 296(%rsi), %rcx + movq 296(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 288(%rdi) + sbbq %rcx, %rax + movq 304(%rsi), %rdx + movq 304(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 296(%rdi) + sbbq %rdx, %rcx + movq 312(%rsi), %rax + movq 312(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 304(%rdi) + sbbq %rax, %rdx + movq 320(%rsi), %rcx + movq 320(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 312(%rdi) + sbbq %rcx, %rax + movq 328(%rsi), %rdx + movq 328(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 320(%rdi) + sbbq %rdx, %rcx + movq 336(%rsi), %rax + movq 336(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 328(%rdi) + sbbq %rax, %rdx + movq 344(%rsi), %rcx + movq 344(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 336(%rdi) + sbbq %rcx, %rax + movq 352(%rsi), %rdx + movq 352(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 344(%rdi) + sbbq %rdx, %rcx + movq 360(%rsi), %rax + movq 360(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 352(%rdi) + sbbq %rax, %rdx + movq 368(%rsi), %rcx + movq 368(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 360(%rdi) + sbbq %rcx, %rax + movq 376(%rsi), %rdx + movq 376(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 368(%rdi) + sbbq %rdx, %rcx + movq %rcx, 376(%rdi) pop %r14 pop %r13 pop %r12 @@ -26339,6 +27045,7 @@ sp_4096_add_64: .p2align 4 _sp_4096_add_64: #endif /* __APPLE__ */ + # Add movq (%rsi), %rcx xorq %rax, %rax addq (%rdx), %rcx @@ -26537,6 +27244,1349 @@ _sp_4096_add_64: #ifndef __APPLE__ .size sp_4096_add_64,.-sp_4096_add_64 #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__ +.globl sp_4096_mul_64 +.type sp_4096_mul_64,@function +.align 16 +sp_4096_mul_64: +#else +.globl _sp_4096_mul_64 +.p2align 4 +_sp_4096_mul_64: +#endif /* __APPLE__ */ + push %r12 + push %r13 + push %r14 + push %r15 + subq $1576, %rsp + movq %rdi, 1536(%rsp) + movq %rsi, 1544(%rsp) + movq %rdx, 1552(%rsp) + leaq 1024(%rsp), %r10 + leaq 256(%rsi), %r12 + # Add + movq (%rsi), %rax + xorq %r13, %r13 + addq (%r12), %rax + movq 8(%rsi), %rcx + movq %rax, (%r10) + adcq 8(%r12), %rcx + movq 16(%rsi), %r8 + movq %rcx, 8(%r10) + adcq 16(%r12), %r8 + movq 24(%rsi), %rax + movq %r8, 16(%r10) + adcq 24(%r12), %rax + movq 32(%rsi), %rcx + movq %rax, 24(%r10) + adcq 32(%r12), %rcx + movq 40(%rsi), %r8 + movq %rcx, 32(%r10) + adcq 40(%r12), %r8 + movq 48(%rsi), %rax + movq %r8, 40(%r10) + adcq 48(%r12), %rax + movq 56(%rsi), %rcx + movq %rax, 48(%r10) + adcq 56(%r12), %rcx + movq 64(%rsi), %r8 + movq %rcx, 56(%r10) + adcq 64(%r12), %r8 + movq 72(%rsi), %rax + movq %r8, 64(%r10) + adcq 72(%r12), %rax + movq 80(%rsi), %rcx + movq %rax, 72(%r10) + adcq 80(%r12), %rcx + movq 88(%rsi), %r8 + movq %rcx, 80(%r10) + adcq 88(%r12), %r8 + movq 96(%rsi), %rax + movq %r8, 88(%r10) + adcq 96(%r12), %rax + movq 104(%rsi), %rcx + movq %rax, 96(%r10) + adcq 104(%r12), %rcx + movq 112(%rsi), %r8 + movq %rcx, 104(%r10) + adcq 112(%r12), %r8 + movq 120(%rsi), %rax + movq %r8, 112(%r10) + adcq 120(%r12), %rax + movq 128(%rsi), %rcx + movq %rax, 120(%r10) + adcq 128(%r12), %rcx + movq 136(%rsi), %r8 + movq %rcx, 128(%r10) + adcq 136(%r12), %r8 + movq 144(%rsi), %rax + movq %r8, 136(%r10) + adcq 144(%r12), %rax + movq 152(%rsi), %rcx + movq %rax, 144(%r10) + adcq 152(%r12), %rcx + movq 160(%rsi), %r8 + movq %rcx, 152(%r10) + adcq 160(%r12), %r8 + movq 168(%rsi), %rax + movq %r8, 160(%r10) + adcq 168(%r12), %rax + movq 176(%rsi), %rcx + movq %rax, 168(%r10) + adcq 176(%r12), %rcx + movq 184(%rsi), %r8 + movq %rcx, 176(%r10) + adcq 184(%r12), %r8 + movq 192(%rsi), %rax + movq %r8, 184(%r10) + adcq 192(%r12), %rax + movq 200(%rsi), %rcx + movq %rax, 192(%r10) + adcq 200(%r12), %rcx + movq 208(%rsi), %r8 + movq %rcx, 200(%r10) + adcq 208(%r12), %r8 + movq 216(%rsi), %rax + movq %r8, 208(%r10) + adcq 216(%r12), %rax + movq 224(%rsi), %rcx + movq %rax, 216(%r10) + adcq 224(%r12), %rcx + movq 232(%rsi), %r8 + movq %rcx, 224(%r10) + adcq 232(%r12), %r8 + movq 240(%rsi), %rax + movq %r8, 232(%r10) + adcq 240(%r12), %rax + movq 248(%rsi), %rcx + movq %rax, 240(%r10) + adcq 248(%r12), %rcx + movq %rcx, 248(%r10) + adcq $0, %r13 + movq %r13, 1560(%rsp) + leaq 1280(%rsp), %r11 + leaq 256(%rdx), %r12 + # Add + movq (%rdx), %rax + xorq %r14, %r14 + addq (%r12), %rax + movq 8(%rdx), %rcx + movq %rax, (%r11) + adcq 8(%r12), %rcx + movq 16(%rdx), %r8 + movq %rcx, 8(%r11) + adcq 16(%r12), %r8 + movq 24(%rdx), %rax + movq %r8, 16(%r11) + adcq 24(%r12), %rax + movq 32(%rdx), %rcx + movq %rax, 24(%r11) + adcq 32(%r12), %rcx + movq 40(%rdx), %r8 + movq %rcx, 32(%r11) + adcq 40(%r12), %r8 + movq 48(%rdx), %rax + movq %r8, 40(%r11) + adcq 48(%r12), %rax + movq 56(%rdx), %rcx + movq %rax, 48(%r11) + adcq 56(%r12), %rcx + movq 64(%rdx), %r8 + movq %rcx, 56(%r11) + adcq 64(%r12), %r8 + movq 72(%rdx), %rax + movq %r8, 64(%r11) + adcq 72(%r12), %rax + movq 80(%rdx), %rcx + movq %rax, 72(%r11) + adcq 80(%r12), %rcx + movq 88(%rdx), %r8 + movq %rcx, 80(%r11) + adcq 88(%r12), %r8 + movq 96(%rdx), %rax + movq %r8, 88(%r11) + adcq 96(%r12), %rax + movq 104(%rdx), %rcx + movq %rax, 96(%r11) + adcq 104(%r12), %rcx + movq 112(%rdx), %r8 + movq %rcx, 104(%r11) + adcq 112(%r12), %r8 + movq 120(%rdx), %rax + movq %r8, 112(%r11) + adcq 120(%r12), %rax + movq 128(%rdx), %rcx + movq %rax, 120(%r11) + adcq 128(%r12), %rcx + movq 136(%rdx), %r8 + movq %rcx, 128(%r11) + adcq 136(%r12), %r8 + movq 144(%rdx), %rax + movq %r8, 136(%r11) + adcq 144(%r12), %rax + movq 152(%rdx), %rcx + movq %rax, 144(%r11) + adcq 152(%r12), %rcx + movq 160(%rdx), %r8 + movq %rcx, 152(%r11) + adcq 160(%r12), %r8 + movq 168(%rdx), %rax + movq %r8, 160(%r11) + adcq 168(%r12), %rax + movq 176(%rdx), %rcx + movq %rax, 168(%r11) + adcq 176(%r12), %rcx + movq 184(%rdx), %r8 + movq %rcx, 176(%r11) + adcq 184(%r12), %r8 + movq 192(%rdx), %rax + movq %r8, 184(%r11) + adcq 192(%r12), %rax + movq 200(%rdx), %rcx + movq %rax, 192(%r11) + adcq 200(%r12), %rcx + movq 208(%rdx), %r8 + movq %rcx, 200(%r11) + adcq 208(%r12), %r8 + movq 216(%rdx), %rax + movq %r8, 208(%r11) + adcq 216(%r12), %rax + movq 224(%rdx), %rcx + movq %rax, 216(%r11) + adcq 224(%r12), %rcx + movq 232(%rdx), %r8 + movq %rcx, 224(%r11) + adcq 232(%r12), %r8 + movq 240(%rdx), %rax + movq %r8, 232(%r11) + adcq 240(%r12), %rax + movq 248(%rdx), %rcx + movq %rax, 240(%r11) + adcq 248(%r12), %rcx + movq %rcx, 248(%r11) + adcq $0, %r14 + movq %r14, 1568(%rsp) + movq %r11, %rdx + movq %r10, %rsi + movq %rsp, %rdi +#ifndef __APPLE__ + callq sp_2048_mul_32@plt +#else + callq _sp_2048_mul_32 +#endif /* __APPLE__ */ + movq 1552(%rsp), %rdx + movq 1544(%rsp), %rsi + leaq 512(%rsp), %rdi + addq $256, %rdx + addq $256, %rsi +#ifndef __APPLE__ + callq sp_2048_mul_32@plt +#else + callq _sp_2048_mul_32 +#endif /* __APPLE__ */ + movq 1552(%rsp), %rdx + movq 1544(%rsp), %rsi + movq 1536(%rsp), %rdi +#ifndef __APPLE__ + callq sp_2048_mul_32@plt +#else + callq _sp_2048_mul_32 +#endif /* __APPLE__ */ + movq 1560(%rsp), %r13 + movq 1568(%rsp), %r14 + movq 1536(%rsp), %r15 + movq %r13, %r9 + leaq 1024(%rsp), %r10 + leaq 1280(%rsp), %r11 + andq %r14, %r9 + negq %r13 + negq %r14 + addq $512, %r15 + movq (%r10), %rax + movq (%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, (%r10) + movq %rcx, (%r11) + movq 8(%r10), %rax + movq 8(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 8(%r10) + movq %rcx, 8(%r11) + movq 16(%r10), %rax + movq 16(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 16(%r10) + movq %rcx, 16(%r11) + movq 24(%r10), %rax + movq 24(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 24(%r10) + movq %rcx, 24(%r11) + movq 32(%r10), %rax + movq 32(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 32(%r10) + movq %rcx, 32(%r11) + movq 40(%r10), %rax + movq 40(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 40(%r10) + movq %rcx, 40(%r11) + movq 48(%r10), %rax + movq 48(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 48(%r10) + movq %rcx, 48(%r11) + movq 56(%r10), %rax + movq 56(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 56(%r10) + movq %rcx, 56(%r11) + movq 64(%r10), %rax + movq 64(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 64(%r10) + movq %rcx, 64(%r11) + movq 72(%r10), %rax + movq 72(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 72(%r10) + movq %rcx, 72(%r11) + movq 80(%r10), %rax + movq 80(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 80(%r10) + movq %rcx, 80(%r11) + movq 88(%r10), %rax + movq 88(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 88(%r10) + movq %rcx, 88(%r11) + movq 96(%r10), %rax + movq 96(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 96(%r10) + movq %rcx, 96(%r11) + movq 104(%r10), %rax + movq 104(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 104(%r10) + movq %rcx, 104(%r11) + movq 112(%r10), %rax + movq 112(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 112(%r10) + movq %rcx, 112(%r11) + movq 120(%r10), %rax + movq 120(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 120(%r10) + movq %rcx, 120(%r11) + movq 128(%r10), %rax + movq 128(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 128(%r10) + movq %rcx, 128(%r11) + movq 136(%r10), %rax + movq 136(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 136(%r10) + movq %rcx, 136(%r11) + movq 144(%r10), %rax + movq 144(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 144(%r10) + movq %rcx, 144(%r11) + movq 152(%r10), %rax + movq 152(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 152(%r10) + movq %rcx, 152(%r11) + movq 160(%r10), %rax + movq 160(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 160(%r10) + movq %rcx, 160(%r11) + movq 168(%r10), %rax + movq 168(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 168(%r10) + movq %rcx, 168(%r11) + movq 176(%r10), %rax + movq 176(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 176(%r10) + movq %rcx, 176(%r11) + movq 184(%r10), %rax + movq 184(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 184(%r10) + movq %rcx, 184(%r11) + movq 192(%r10), %rax + movq 192(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 192(%r10) + movq %rcx, 192(%r11) + movq 200(%r10), %rax + movq 200(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 200(%r10) + movq %rcx, 200(%r11) + movq 208(%r10), %rax + movq 208(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 208(%r10) + movq %rcx, 208(%r11) + movq 216(%r10), %rax + movq 216(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 216(%r10) + movq %rcx, 216(%r11) + movq 224(%r10), %rax + movq 224(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 224(%r10) + movq %rcx, 224(%r11) + movq 232(%r10), %rax + movq 232(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 232(%r10) + movq %rcx, 232(%r11) + movq 240(%r10), %rax + movq 240(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 240(%r10) + movq %rcx, 240(%r11) + movq 248(%r10), %rax + movq 248(%r11), %rcx + andq %r14, %rax + andq %r13, %rcx + movq %rax, 248(%r10) + movq %rcx, 248(%r11) + movq (%r10), %rax + addq (%r11), %rax + movq 8(%r10), %rcx + movq %rax, (%r15) + adcq 8(%r11), %rcx + movq 16(%r10), %r8 + movq %rcx, 8(%r15) + adcq 16(%r11), %r8 + movq 24(%r10), %rax + movq %r8, 16(%r15) + adcq 24(%r11), %rax + movq 32(%r10), %rcx + movq %rax, 24(%r15) + adcq 32(%r11), %rcx + movq 40(%r10), %r8 + movq %rcx, 32(%r15) + adcq 40(%r11), %r8 + movq 48(%r10), %rax + movq %r8, 40(%r15) + adcq 48(%r11), %rax + movq 56(%r10), %rcx + movq %rax, 48(%r15) + adcq 56(%r11), %rcx + movq 64(%r10), %r8 + movq %rcx, 56(%r15) + adcq 64(%r11), %r8 + movq 72(%r10), %rax + movq %r8, 64(%r15) + adcq 72(%r11), %rax + movq 80(%r10), %rcx + movq %rax, 72(%r15) + adcq 80(%r11), %rcx + movq 88(%r10), %r8 + movq %rcx, 80(%r15) + adcq 88(%r11), %r8 + movq 96(%r10), %rax + movq %r8, 88(%r15) + adcq 96(%r11), %rax + movq 104(%r10), %rcx + movq %rax, 96(%r15) + adcq 104(%r11), %rcx + movq 112(%r10), %r8 + movq %rcx, 104(%r15) + adcq 112(%r11), %r8 + movq 120(%r10), %rax + movq %r8, 112(%r15) + adcq 120(%r11), %rax + movq 128(%r10), %rcx + movq %rax, 120(%r15) + adcq 128(%r11), %rcx + movq 136(%r10), %r8 + movq %rcx, 128(%r15) + adcq 136(%r11), %r8 + movq 144(%r10), %rax + movq %r8, 136(%r15) + adcq 144(%r11), %rax + movq 152(%r10), %rcx + movq %rax, 144(%r15) + adcq 152(%r11), %rcx + movq 160(%r10), %r8 + movq %rcx, 152(%r15) + adcq 160(%r11), %r8 + movq 168(%r10), %rax + movq %r8, 160(%r15) + adcq 168(%r11), %rax + movq 176(%r10), %rcx + movq %rax, 168(%r15) + adcq 176(%r11), %rcx + movq 184(%r10), %r8 + movq %rcx, 176(%r15) + adcq 184(%r11), %r8 + movq 192(%r10), %rax + movq %r8, 184(%r15) + adcq 192(%r11), %rax + movq 200(%r10), %rcx + movq %rax, 192(%r15) + adcq 200(%r11), %rcx + movq 208(%r10), %r8 + movq %rcx, 200(%r15) + adcq 208(%r11), %r8 + movq 216(%r10), %rax + movq %r8, 208(%r15) + adcq 216(%r11), %rax + movq 224(%r10), %rcx + movq %rax, 216(%r15) + adcq 224(%r11), %rcx + movq 232(%r10), %r8 + movq %rcx, 224(%r15) + adcq 232(%r11), %r8 + movq 240(%r10), %rax + movq %r8, 232(%r15) + adcq 240(%r11), %rax + movq 248(%r10), %rcx + movq %rax, 240(%r15) + adcq 248(%r11), %rcx + movq %rcx, 248(%r15) + adcq $0, %r9 + leaq 512(%rsp), %r11 + movq %rsp, %r10 + movq (%r10), %rax + subq (%r11), %rax + movq 8(%r10), %rcx + movq %rax, (%r10) + sbbq 8(%r11), %rcx + movq 16(%r10), %r8 + movq %rcx, 8(%r10) + sbbq 16(%r11), %r8 + movq 24(%r10), %rax + movq %r8, 16(%r10) + sbbq 24(%r11), %rax + movq 32(%r10), %rcx + movq %rax, 24(%r10) + sbbq 32(%r11), %rcx + movq 40(%r10), %r8 + movq %rcx, 32(%r10) + sbbq 40(%r11), %r8 + movq 48(%r10), %rax + movq %r8, 40(%r10) + sbbq 48(%r11), %rax + movq 56(%r10), %rcx + movq %rax, 48(%r10) + sbbq 56(%r11), %rcx + movq 64(%r10), %r8 + movq %rcx, 56(%r10) + sbbq 64(%r11), %r8 + movq 72(%r10), %rax + movq %r8, 64(%r10) + sbbq 72(%r11), %rax + movq 80(%r10), %rcx + movq %rax, 72(%r10) + sbbq 80(%r11), %rcx + movq 88(%r10), %r8 + movq %rcx, 80(%r10) + sbbq 88(%r11), %r8 + movq 96(%r10), %rax + movq %r8, 88(%r10) + sbbq 96(%r11), %rax + movq 104(%r10), %rcx + movq %rax, 96(%r10) + sbbq 104(%r11), %rcx + movq 112(%r10), %r8 + movq %rcx, 104(%r10) + sbbq 112(%r11), %r8 + movq 120(%r10), %rax + movq %r8, 112(%r10) + sbbq 120(%r11), %rax + movq 128(%r10), %rcx + movq %rax, 120(%r10) + sbbq 128(%r11), %rcx + movq 136(%r10), %r8 + movq %rcx, 128(%r10) + sbbq 136(%r11), %r8 + movq 144(%r10), %rax + movq %r8, 136(%r10) + sbbq 144(%r11), %rax + movq 152(%r10), %rcx + movq %rax, 144(%r10) + sbbq 152(%r11), %rcx + movq 160(%r10), %r8 + movq %rcx, 152(%r10) + sbbq 160(%r11), %r8 + movq 168(%r10), %rax + movq %r8, 160(%r10) + sbbq 168(%r11), %rax + movq 176(%r10), %rcx + movq %rax, 168(%r10) + sbbq 176(%r11), %rcx + movq 184(%r10), %r8 + movq %rcx, 176(%r10) + sbbq 184(%r11), %r8 + movq 192(%r10), %rax + movq %r8, 184(%r10) + sbbq 192(%r11), %rax + movq 200(%r10), %rcx + movq %rax, 192(%r10) + sbbq 200(%r11), %rcx + movq 208(%r10), %r8 + movq %rcx, 200(%r10) + sbbq 208(%r11), %r8 + movq 216(%r10), %rax + movq %r8, 208(%r10) + sbbq 216(%r11), %rax + movq 224(%r10), %rcx + movq %rax, 216(%r10) + sbbq 224(%r11), %rcx + movq 232(%r10), %r8 + movq %rcx, 224(%r10) + sbbq 232(%r11), %r8 + movq 240(%r10), %rax + movq %r8, 232(%r10) + sbbq 240(%r11), %rax + movq 248(%r10), %rcx + movq %rax, 240(%r10) + sbbq 248(%r11), %rcx + movq 256(%r10), %r8 + movq %rcx, 248(%r10) + sbbq 256(%r11), %r8 + movq 264(%r10), %rax + movq %r8, 256(%r10) + sbbq 264(%r11), %rax + movq 272(%r10), %rcx + movq %rax, 264(%r10) + sbbq 272(%r11), %rcx + movq 280(%r10), %r8 + movq %rcx, 272(%r10) + sbbq 280(%r11), %r8 + movq 288(%r10), %rax + movq %r8, 280(%r10) + sbbq 288(%r11), %rax + movq 296(%r10), %rcx + movq %rax, 288(%r10) + sbbq 296(%r11), %rcx + movq 304(%r10), %r8 + movq %rcx, 296(%r10) + sbbq 304(%r11), %r8 + movq 312(%r10), %rax + movq %r8, 304(%r10) + sbbq 312(%r11), %rax + movq 320(%r10), %rcx + movq %rax, 312(%r10) + sbbq 320(%r11), %rcx + movq 328(%r10), %r8 + movq %rcx, 320(%r10) + sbbq 328(%r11), %r8 + movq 336(%r10), %rax + movq %r8, 328(%r10) + sbbq 336(%r11), %rax + movq 344(%r10), %rcx + movq %rax, 336(%r10) + sbbq 344(%r11), %rcx + movq 352(%r10), %r8 + movq %rcx, 344(%r10) + sbbq 352(%r11), %r8 + movq 360(%r10), %rax + movq %r8, 352(%r10) + sbbq 360(%r11), %rax + movq 368(%r10), %rcx + movq %rax, 360(%r10) + sbbq 368(%r11), %rcx + movq 376(%r10), %r8 + movq %rcx, 368(%r10) + sbbq 376(%r11), %r8 + movq 384(%r10), %rax + movq %r8, 376(%r10) + sbbq 384(%r11), %rax + movq 392(%r10), %rcx + movq %rax, 384(%r10) + sbbq 392(%r11), %rcx + movq 400(%r10), %r8 + movq %rcx, 392(%r10) + sbbq 400(%r11), %r8 + movq 408(%r10), %rax + movq %r8, 400(%r10) + sbbq 408(%r11), %rax + movq 416(%r10), %rcx + movq %rax, 408(%r10) + sbbq 416(%r11), %rcx + movq 424(%r10), %r8 + movq %rcx, 416(%r10) + sbbq 424(%r11), %r8 + movq 432(%r10), %rax + movq %r8, 424(%r10) + sbbq 432(%r11), %rax + movq 440(%r10), %rcx + movq %rax, 432(%r10) + sbbq 440(%r11), %rcx + movq 448(%r10), %r8 + movq %rcx, 440(%r10) + sbbq 448(%r11), %r8 + movq 456(%r10), %rax + movq %r8, 448(%r10) + sbbq 456(%r11), %rax + movq 464(%r10), %rcx + movq %rax, 456(%r10) + sbbq 464(%r11), %rcx + movq 472(%r10), %r8 + movq %rcx, 464(%r10) + sbbq 472(%r11), %r8 + movq 480(%r10), %rax + movq %r8, 472(%r10) + sbbq 480(%r11), %rax + movq 488(%r10), %rcx + movq %rax, 480(%r10) + sbbq 488(%r11), %rcx + movq 496(%r10), %r8 + movq %rcx, 488(%r10) + sbbq 496(%r11), %r8 + movq 504(%r10), %rax + movq %r8, 496(%r10) + sbbq 504(%r11), %rax + movq %rax, 504(%r10) + sbbq $0, %r9 + movq (%r10), %rax + subq (%rdi), %rax + movq 8(%r10), %rcx + movq %rax, (%r10) + sbbq 8(%rdi), %rcx + movq 16(%r10), %r8 + movq %rcx, 8(%r10) + sbbq 16(%rdi), %r8 + movq 24(%r10), %rax + movq %r8, 16(%r10) + sbbq 24(%rdi), %rax + movq 32(%r10), %rcx + movq %rax, 24(%r10) + sbbq 32(%rdi), %rcx + movq 40(%r10), %r8 + movq %rcx, 32(%r10) + sbbq 40(%rdi), %r8 + movq 48(%r10), %rax + movq %r8, 40(%r10) + sbbq 48(%rdi), %rax + movq 56(%r10), %rcx + movq %rax, 48(%r10) + sbbq 56(%rdi), %rcx + movq 64(%r10), %r8 + movq %rcx, 56(%r10) + sbbq 64(%rdi), %r8 + movq 72(%r10), %rax + movq %r8, 64(%r10) + sbbq 72(%rdi), %rax + movq 80(%r10), %rcx + movq %rax, 72(%r10) + sbbq 80(%rdi), %rcx + movq 88(%r10), %r8 + movq %rcx, 80(%r10) + sbbq 88(%rdi), %r8 + movq 96(%r10), %rax + movq %r8, 88(%r10) + sbbq 96(%rdi), %rax + movq 104(%r10), %rcx + movq %rax, 96(%r10) + sbbq 104(%rdi), %rcx + movq 112(%r10), %r8 + movq %rcx, 104(%r10) + sbbq 112(%rdi), %r8 + movq 120(%r10), %rax + movq %r8, 112(%r10) + sbbq 120(%rdi), %rax + movq 128(%r10), %rcx + movq %rax, 120(%r10) + sbbq 128(%rdi), %rcx + movq 136(%r10), %r8 + movq %rcx, 128(%r10) + sbbq 136(%rdi), %r8 + movq 144(%r10), %rax + movq %r8, 136(%r10) + sbbq 144(%rdi), %rax + movq 152(%r10), %rcx + movq %rax, 144(%r10) + sbbq 152(%rdi), %rcx + movq 160(%r10), %r8 + movq %rcx, 152(%r10) + sbbq 160(%rdi), %r8 + movq 168(%r10), %rax + movq %r8, 160(%r10) + sbbq 168(%rdi), %rax + movq 176(%r10), %rcx + movq %rax, 168(%r10) + sbbq 176(%rdi), %rcx + movq 184(%r10), %r8 + movq %rcx, 176(%r10) + sbbq 184(%rdi), %r8 + movq 192(%r10), %rax + movq %r8, 184(%r10) + sbbq 192(%rdi), %rax + movq 200(%r10), %rcx + movq %rax, 192(%r10) + sbbq 200(%rdi), %rcx + movq 208(%r10), %r8 + movq %rcx, 200(%r10) + sbbq 208(%rdi), %r8 + movq 216(%r10), %rax + movq %r8, 208(%r10) + sbbq 216(%rdi), %rax + movq 224(%r10), %rcx + movq %rax, 216(%r10) + sbbq 224(%rdi), %rcx + movq 232(%r10), %r8 + movq %rcx, 224(%r10) + sbbq 232(%rdi), %r8 + movq 240(%r10), %rax + movq %r8, 232(%r10) + sbbq 240(%rdi), %rax + movq 248(%r10), %rcx + movq %rax, 240(%r10) + sbbq 248(%rdi), %rcx + movq 256(%r10), %r8 + movq %rcx, 248(%r10) + sbbq 256(%rdi), %r8 + movq 264(%r10), %rax + movq %r8, 256(%r10) + sbbq 264(%rdi), %rax + movq 272(%r10), %rcx + movq %rax, 264(%r10) + sbbq 272(%rdi), %rcx + movq 280(%r10), %r8 + movq %rcx, 272(%r10) + sbbq 280(%rdi), %r8 + movq 288(%r10), %rax + movq %r8, 280(%r10) + sbbq 288(%rdi), %rax + movq 296(%r10), %rcx + movq %rax, 288(%r10) + sbbq 296(%rdi), %rcx + movq 304(%r10), %r8 + movq %rcx, 296(%r10) + sbbq 304(%rdi), %r8 + movq 312(%r10), %rax + movq %r8, 304(%r10) + sbbq 312(%rdi), %rax + movq 320(%r10), %rcx + movq %rax, 312(%r10) + sbbq 320(%rdi), %rcx + movq 328(%r10), %r8 + movq %rcx, 320(%r10) + sbbq 328(%rdi), %r8 + movq 336(%r10), %rax + movq %r8, 328(%r10) + sbbq 336(%rdi), %rax + movq 344(%r10), %rcx + movq %rax, 336(%r10) + sbbq 344(%rdi), %rcx + movq 352(%r10), %r8 + movq %rcx, 344(%r10) + sbbq 352(%rdi), %r8 + movq 360(%r10), %rax + movq %r8, 352(%r10) + sbbq 360(%rdi), %rax + movq 368(%r10), %rcx + movq %rax, 360(%r10) + sbbq 368(%rdi), %rcx + movq 376(%r10), %r8 + movq %rcx, 368(%r10) + sbbq 376(%rdi), %r8 + movq 384(%r10), %rax + movq %r8, 376(%r10) + sbbq 384(%rdi), %rax + movq 392(%r10), %rcx + movq %rax, 384(%r10) + sbbq 392(%rdi), %rcx + movq 400(%r10), %r8 + movq %rcx, 392(%r10) + sbbq 400(%rdi), %r8 + movq 408(%r10), %rax + movq %r8, 400(%r10) + sbbq 408(%rdi), %rax + movq 416(%r10), %rcx + movq %rax, 408(%r10) + sbbq 416(%rdi), %rcx + movq 424(%r10), %r8 + movq %rcx, 416(%r10) + sbbq 424(%rdi), %r8 + movq 432(%r10), %rax + movq %r8, 424(%r10) + sbbq 432(%rdi), %rax + movq 440(%r10), %rcx + movq %rax, 432(%r10) + sbbq 440(%rdi), %rcx + movq 448(%r10), %r8 + movq %rcx, 440(%r10) + sbbq 448(%rdi), %r8 + movq 456(%r10), %rax + movq %r8, 448(%r10) + sbbq 456(%rdi), %rax + movq 464(%r10), %rcx + movq %rax, 456(%r10) + sbbq 464(%rdi), %rcx + movq 472(%r10), %r8 + movq %rcx, 464(%r10) + sbbq 472(%rdi), %r8 + movq 480(%r10), %rax + movq %r8, 472(%r10) + sbbq 480(%rdi), %rax + movq 488(%r10), %rcx + movq %rax, 480(%r10) + sbbq 488(%rdi), %rcx + movq 496(%r10), %r8 + movq %rcx, 488(%r10) + sbbq 496(%rdi), %r8 + movq 504(%r10), %rax + movq %r8, 496(%r10) + sbbq 504(%rdi), %rax + movq %rax, 504(%r10) + sbbq $0, %r9 + subq $256, %r15 + # Add + movq (%r15), %rax + addq (%r10), %rax + movq 8(%r15), %rcx + movq %rax, (%r15) + adcq 8(%r10), %rcx + movq 16(%r15), %r8 + movq %rcx, 8(%r15) + adcq 16(%r10), %r8 + movq 24(%r15), %rax + movq %r8, 16(%r15) + adcq 24(%r10), %rax + movq 32(%r15), %rcx + movq %rax, 24(%r15) + adcq 32(%r10), %rcx + movq 40(%r15), %r8 + movq %rcx, 32(%r15) + adcq 40(%r10), %r8 + movq 48(%r15), %rax + movq %r8, 40(%r15) + adcq 48(%r10), %rax + movq 56(%r15), %rcx + movq %rax, 48(%r15) + adcq 56(%r10), %rcx + movq 64(%r15), %r8 + movq %rcx, 56(%r15) + adcq 64(%r10), %r8 + movq 72(%r15), %rax + movq %r8, 64(%r15) + adcq 72(%r10), %rax + movq 80(%r15), %rcx + movq %rax, 72(%r15) + adcq 80(%r10), %rcx + movq 88(%r15), %r8 + movq %rcx, 80(%r15) + adcq 88(%r10), %r8 + movq 96(%r15), %rax + movq %r8, 88(%r15) + adcq 96(%r10), %rax + movq 104(%r15), %rcx + movq %rax, 96(%r15) + adcq 104(%r10), %rcx + movq 112(%r15), %r8 + movq %rcx, 104(%r15) + adcq 112(%r10), %r8 + movq 120(%r15), %rax + movq %r8, 112(%r15) + adcq 120(%r10), %rax + movq 128(%r15), %rcx + movq %rax, 120(%r15) + adcq 128(%r10), %rcx + movq 136(%r15), %r8 + movq %rcx, 128(%r15) + adcq 136(%r10), %r8 + movq 144(%r15), %rax + movq %r8, 136(%r15) + adcq 144(%r10), %rax + movq 152(%r15), %rcx + movq %rax, 144(%r15) + adcq 152(%r10), %rcx + movq 160(%r15), %r8 + movq %rcx, 152(%r15) + adcq 160(%r10), %r8 + movq 168(%r15), %rax + movq %r8, 160(%r15) + adcq 168(%r10), %rax + movq 176(%r15), %rcx + movq %rax, 168(%r15) + adcq 176(%r10), %rcx + movq 184(%r15), %r8 + movq %rcx, 176(%r15) + adcq 184(%r10), %r8 + movq 192(%r15), %rax + movq %r8, 184(%r15) + adcq 192(%r10), %rax + movq 200(%r15), %rcx + movq %rax, 192(%r15) + adcq 200(%r10), %rcx + movq 208(%r15), %r8 + movq %rcx, 200(%r15) + adcq 208(%r10), %r8 + movq 216(%r15), %rax + movq %r8, 208(%r15) + adcq 216(%r10), %rax + movq 224(%r15), %rcx + movq %rax, 216(%r15) + adcq 224(%r10), %rcx + movq 232(%r15), %r8 + movq %rcx, 224(%r15) + adcq 232(%r10), %r8 + movq 240(%r15), %rax + movq %r8, 232(%r15) + adcq 240(%r10), %rax + movq 248(%r15), %rcx + movq %rax, 240(%r15) + adcq 248(%r10), %rcx + movq 256(%r15), %r8 + movq %rcx, 248(%r15) + adcq 256(%r10), %r8 + movq 264(%r15), %rax + movq %r8, 256(%r15) + adcq 264(%r10), %rax + movq 272(%r15), %rcx + movq %rax, 264(%r15) + adcq 272(%r10), %rcx + movq 280(%r15), %r8 + movq %rcx, 272(%r15) + adcq 280(%r10), %r8 + movq 288(%r15), %rax + movq %r8, 280(%r15) + adcq 288(%r10), %rax + movq 296(%r15), %rcx + movq %rax, 288(%r15) + adcq 296(%r10), %rcx + movq 304(%r15), %r8 + movq %rcx, 296(%r15) + adcq 304(%r10), %r8 + movq 312(%r15), %rax + movq %r8, 304(%r15) + adcq 312(%r10), %rax + movq 320(%r15), %rcx + movq %rax, 312(%r15) + adcq 320(%r10), %rcx + movq 328(%r15), %r8 + movq %rcx, 320(%r15) + adcq 328(%r10), %r8 + movq 336(%r15), %rax + movq %r8, 328(%r15) + adcq 336(%r10), %rax + movq 344(%r15), %rcx + movq %rax, 336(%r15) + adcq 344(%r10), %rcx + movq 352(%r15), %r8 + movq %rcx, 344(%r15) + adcq 352(%r10), %r8 + movq 360(%r15), %rax + movq %r8, 352(%r15) + adcq 360(%r10), %rax + movq 368(%r15), %rcx + movq %rax, 360(%r15) + adcq 368(%r10), %rcx + movq 376(%r15), %r8 + movq %rcx, 368(%r15) + adcq 376(%r10), %r8 + movq 384(%r15), %rax + movq %r8, 376(%r15) + adcq 384(%r10), %rax + movq 392(%r15), %rcx + movq %rax, 384(%r15) + adcq 392(%r10), %rcx + movq 400(%r15), %r8 + movq %rcx, 392(%r15) + adcq 400(%r10), %r8 + movq 408(%r15), %rax + movq %r8, 400(%r15) + adcq 408(%r10), %rax + movq 416(%r15), %rcx + movq %rax, 408(%r15) + adcq 416(%r10), %rcx + movq 424(%r15), %r8 + movq %rcx, 416(%r15) + adcq 424(%r10), %r8 + movq 432(%r15), %rax + movq %r8, 424(%r15) + adcq 432(%r10), %rax + movq 440(%r15), %rcx + movq %rax, 432(%r15) + adcq 440(%r10), %rcx + movq 448(%r15), %r8 + movq %rcx, 440(%r15) + adcq 448(%r10), %r8 + movq 456(%r15), %rax + movq %r8, 448(%r15) + adcq 456(%r10), %rax + movq 464(%r15), %rcx + movq %rax, 456(%r15) + adcq 464(%r10), %rcx + movq 472(%r15), %r8 + movq %rcx, 464(%r15) + adcq 472(%r10), %r8 + movq 480(%r15), %rax + movq %r8, 472(%r15) + adcq 480(%r10), %rax + movq 488(%r15), %rcx + movq %rax, 480(%r15) + adcq 488(%r10), %rcx + movq 496(%r15), %r8 + movq %rcx, 488(%r15) + adcq 496(%r10), %r8 + movq 504(%r15), %rax + movq %r8, 496(%r15) + adcq 504(%r10), %rax + movq %rax, 504(%r15) + adcq $0, %r9 + movq %r9, 768(%rdi) + addq $256, %r15 + # Add + movq (%r15), %rax + xorq %r9, %r9 + addq (%r11), %rax + movq 8(%r15), %rcx + movq %rax, (%r15) + adcq 8(%r11), %rcx + movq 16(%r15), %r8 + movq %rcx, 8(%r15) + adcq 16(%r11), %r8 + movq 24(%r15), %rax + movq %r8, 16(%r15) + adcq 24(%r11), %rax + movq 32(%r15), %rcx + movq %rax, 24(%r15) + adcq 32(%r11), %rcx + movq 40(%r15), %r8 + movq %rcx, 32(%r15) + adcq 40(%r11), %r8 + movq 48(%r15), %rax + movq %r8, 40(%r15) + adcq 48(%r11), %rax + movq 56(%r15), %rcx + movq %rax, 48(%r15) + adcq 56(%r11), %rcx + movq 64(%r15), %r8 + movq %rcx, 56(%r15) + adcq 64(%r11), %r8 + movq 72(%r15), %rax + movq %r8, 64(%r15) + adcq 72(%r11), %rax + movq 80(%r15), %rcx + movq %rax, 72(%r15) + adcq 80(%r11), %rcx + movq 88(%r15), %r8 + movq %rcx, 80(%r15) + adcq 88(%r11), %r8 + movq 96(%r15), %rax + movq %r8, 88(%r15) + adcq 96(%r11), %rax + movq 104(%r15), %rcx + movq %rax, 96(%r15) + adcq 104(%r11), %rcx + movq 112(%r15), %r8 + movq %rcx, 104(%r15) + adcq 112(%r11), %r8 + movq 120(%r15), %rax + movq %r8, 112(%r15) + adcq 120(%r11), %rax + movq 128(%r15), %rcx + movq %rax, 120(%r15) + adcq 128(%r11), %rcx + movq 136(%r15), %r8 + movq %rcx, 128(%r15) + adcq 136(%r11), %r8 + movq 144(%r15), %rax + movq %r8, 136(%r15) + adcq 144(%r11), %rax + movq 152(%r15), %rcx + movq %rax, 144(%r15) + adcq 152(%r11), %rcx + movq 160(%r15), %r8 + movq %rcx, 152(%r15) + adcq 160(%r11), %r8 + movq 168(%r15), %rax + movq %r8, 160(%r15) + adcq 168(%r11), %rax + movq 176(%r15), %rcx + movq %rax, 168(%r15) + adcq 176(%r11), %rcx + movq 184(%r15), %r8 + movq %rcx, 176(%r15) + adcq 184(%r11), %r8 + movq 192(%r15), %rax + movq %r8, 184(%r15) + adcq 192(%r11), %rax + movq 200(%r15), %rcx + movq %rax, 192(%r15) + adcq 200(%r11), %rcx + movq 208(%r15), %r8 + movq %rcx, 200(%r15) + adcq 208(%r11), %r8 + movq 216(%r15), %rax + movq %r8, 208(%r15) + adcq 216(%r11), %rax + movq 224(%r15), %rcx + movq %rax, 216(%r15) + adcq 224(%r11), %rcx + movq 232(%r15), %r8 + movq %rcx, 224(%r15) + adcq 232(%r11), %r8 + movq 240(%r15), %rax + movq %r8, 232(%r15) + adcq 240(%r11), %rax + movq 248(%r15), %rcx + movq %rax, 240(%r15) + adcq 248(%r11), %rcx + movq 256(%r15), %r8 + movq %rcx, 248(%r15) + adcq 256(%r11), %r8 + movq %r8, 256(%r15) + adcq $0, %r9 + # Add to zero + movq 264(%r11), %rax + adcq $0, %rax + movq 272(%r11), %rcx + movq %rax, 264(%r15) + adcq $0, %rcx + movq 280(%r11), %r8 + movq %rcx, 272(%r15) + adcq $0, %r8 + movq 288(%r11), %rax + movq %r8, 280(%r15) + adcq $0, %rax + movq 296(%r11), %rcx + movq %rax, 288(%r15) + adcq $0, %rcx + movq 304(%r11), %r8 + movq %rcx, 296(%r15) + adcq $0, %r8 + movq 312(%r11), %rax + movq %r8, 304(%r15) + adcq $0, %rax + movq 320(%r11), %rcx + movq %rax, 312(%r15) + adcq $0, %rcx + movq 328(%r11), %r8 + movq %rcx, 320(%r15) + adcq $0, %r8 + movq 336(%r11), %rax + movq %r8, 328(%r15) + adcq $0, %rax + movq 344(%r11), %rcx + movq %rax, 336(%r15) + adcq $0, %rcx + movq 352(%r11), %r8 + movq %rcx, 344(%r15) + adcq $0, %r8 + movq 360(%r11), %rax + movq %r8, 352(%r15) + adcq $0, %rax + movq 368(%r11), %rcx + movq %rax, 360(%r15) + adcq $0, %rcx + movq 376(%r11), %r8 + movq %rcx, 368(%r15) + adcq $0, %r8 + movq 384(%r11), %rax + movq %r8, 376(%r15) + adcq $0, %rax + movq 392(%r11), %rcx + movq %rax, 384(%r15) + adcq $0, %rcx + movq 400(%r11), %r8 + movq %rcx, 392(%r15) + adcq $0, %r8 + movq 408(%r11), %rax + movq %r8, 400(%r15) + adcq $0, %rax + movq 416(%r11), %rcx + movq %rax, 408(%r15) + adcq $0, %rcx + movq 424(%r11), %r8 + movq %rcx, 416(%r15) + adcq $0, %r8 + movq 432(%r11), %rax + movq %r8, 424(%r15) + adcq $0, %rax + movq 440(%r11), %rcx + movq %rax, 432(%r15) + adcq $0, %rcx + movq 448(%r11), %r8 + movq %rcx, 440(%r15) + adcq $0, %r8 + movq 456(%r11), %rax + movq %r8, 448(%r15) + adcq $0, %rax + movq 464(%r11), %rcx + movq %rax, 456(%r15) + adcq $0, %rcx + movq 472(%r11), %r8 + movq %rcx, 464(%r15) + adcq $0, %r8 + movq 480(%r11), %rax + movq %r8, 472(%r15) + adcq $0, %rax + movq 488(%r11), %rcx + movq %rax, 480(%r15) + adcq $0, %rcx + movq 496(%r11), %r8 + movq %rcx, 488(%r15) + adcq $0, %r8 + movq 504(%r11), %rax + movq %r8, 496(%r15) + adcq $0, %rax + movq %rax, 504(%r15) + addq $1576, %rsp + pop %r15 + pop %r14 + pop %r13 + pop %r12 + repz retq +#ifndef __APPLE__ +.size sp_4096_mul_64,.-sp_4096_mul_64 +#endif /* __APPLE__ */ /* Add a to a into r. (r = a + a) * * r A single precision integer. @@ -26654,6 +28704,3435 @@ _sp_2048_dbl_32: #ifndef __APPLE__ .size sp_2048_dbl_32,.-sp_2048_dbl_32 #endif /* __APPLE__ */ +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +#ifndef __APPLE__ +.globl sp_4096_sqr_64 +.type sp_4096_sqr_64,@function +.align 16 +sp_4096_sqr_64: +#else +.globl _sp_4096_sqr_64 +.p2align 4 +_sp_4096_sqr_64: +#endif /* __APPLE__ */ + subq $1304, %rsp + movq %rdi, 1280(%rsp) + movq %rsi, 1288(%rsp) + leaq 1024(%rsp), %r8 + leaq 256(%rsi), %r9 + # Add + movq (%rsi), %rdx + xorq %rcx, %rcx + addq (%r9), %rdx + movq 8(%rsi), %rax + movq %rdx, (%r8) + adcq 8(%r9), %rax + movq 16(%rsi), %rdx + movq %rax, 8(%r8) + adcq 16(%r9), %rdx + movq 24(%rsi), %rax + movq %rdx, 16(%r8) + adcq 24(%r9), %rax + movq 32(%rsi), %rdx + movq %rax, 24(%r8) + adcq 32(%r9), %rdx + movq 40(%rsi), %rax + movq %rdx, 32(%r8) + adcq 40(%r9), %rax + movq 48(%rsi), %rdx + movq %rax, 40(%r8) + adcq 48(%r9), %rdx + movq 56(%rsi), %rax + movq %rdx, 48(%r8) + adcq 56(%r9), %rax + movq 64(%rsi), %rdx + movq %rax, 56(%r8) + adcq 64(%r9), %rdx + movq 72(%rsi), %rax + movq %rdx, 64(%r8) + adcq 72(%r9), %rax + movq 80(%rsi), %rdx + movq %rax, 72(%r8) + adcq 80(%r9), %rdx + movq 88(%rsi), %rax + movq %rdx, 80(%r8) + adcq 88(%r9), %rax + movq 96(%rsi), %rdx + movq %rax, 88(%r8) + adcq 96(%r9), %rdx + movq 104(%rsi), %rax + movq %rdx, 96(%r8) + adcq 104(%r9), %rax + movq 112(%rsi), %rdx + movq %rax, 104(%r8) + adcq 112(%r9), %rdx + movq 120(%rsi), %rax + movq %rdx, 112(%r8) + adcq 120(%r9), %rax + movq 128(%rsi), %rdx + movq %rax, 120(%r8) + adcq 128(%r9), %rdx + movq 136(%rsi), %rax + movq %rdx, 128(%r8) + adcq 136(%r9), %rax + movq 144(%rsi), %rdx + movq %rax, 136(%r8) + adcq 144(%r9), %rdx + movq 152(%rsi), %rax + movq %rdx, 144(%r8) + adcq 152(%r9), %rax + movq 160(%rsi), %rdx + movq %rax, 152(%r8) + adcq 160(%r9), %rdx + movq 168(%rsi), %rax + movq %rdx, 160(%r8) + adcq 168(%r9), %rax + movq 176(%rsi), %rdx + movq %rax, 168(%r8) + adcq 176(%r9), %rdx + movq 184(%rsi), %rax + movq %rdx, 176(%r8) + adcq 184(%r9), %rax + movq 192(%rsi), %rdx + movq %rax, 184(%r8) + adcq 192(%r9), %rdx + movq 200(%rsi), %rax + movq %rdx, 192(%r8) + adcq 200(%r9), %rax + movq 208(%rsi), %rdx + movq %rax, 200(%r8) + adcq 208(%r9), %rdx + movq 216(%rsi), %rax + movq %rdx, 208(%r8) + adcq 216(%r9), %rax + movq 224(%rsi), %rdx + movq %rax, 216(%r8) + adcq 224(%r9), %rdx + movq 232(%rsi), %rax + movq %rdx, 224(%r8) + adcq 232(%r9), %rax + movq 240(%rsi), %rdx + movq %rax, 232(%r8) + adcq 240(%r9), %rdx + movq 248(%rsi), %rax + movq %rdx, 240(%r8) + adcq 248(%r9), %rax + movq %rax, 248(%r8) + adcq $0, %rcx + movq %rcx, 1296(%rsp) + movq %r8, %rsi + movq %rsp, %rdi +#ifndef __APPLE__ + callq sp_2048_sqr_32@plt +#else + callq _sp_2048_sqr_32 +#endif /* __APPLE__ */ + movq 1288(%rsp), %rsi + leaq 512(%rsp), %rdi + addq $256, %rsi +#ifndef __APPLE__ + callq sp_2048_sqr_32@plt +#else + callq _sp_2048_sqr_32 +#endif /* __APPLE__ */ + movq 1288(%rsp), %rsi + movq 1280(%rsp), %rdi +#ifndef __APPLE__ + callq sp_2048_sqr_32@plt +#else + callq _sp_2048_sqr_32 +#endif /* __APPLE__ */ + movq 1296(%rsp), %r10 + leaq 1024(%rsp), %r8 + movq %r10, %rcx + negq %r10 + movq (%r8), %rdx + movq 8(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 512(%rdi) + movq %rax, 520(%rdi) + movq 16(%r8), %rdx + movq 24(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 528(%rdi) + movq %rax, 536(%rdi) + movq 32(%r8), %rdx + movq 40(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 544(%rdi) + movq %rax, 552(%rdi) + movq 48(%r8), %rdx + movq 56(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 560(%rdi) + movq %rax, 568(%rdi) + movq 64(%r8), %rdx + movq 72(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 576(%rdi) + movq %rax, 584(%rdi) + movq 80(%r8), %rdx + movq 88(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 592(%rdi) + movq %rax, 600(%rdi) + movq 96(%r8), %rdx + movq 104(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 608(%rdi) + movq %rax, 616(%rdi) + movq 112(%r8), %rdx + movq 120(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 624(%rdi) + movq %rax, 632(%rdi) + movq 128(%r8), %rdx + movq 136(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 640(%rdi) + movq %rax, 648(%rdi) + movq 144(%r8), %rdx + movq 152(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 656(%rdi) + movq %rax, 664(%rdi) + movq 160(%r8), %rdx + movq 168(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 672(%rdi) + movq %rax, 680(%rdi) + movq 176(%r8), %rdx + movq 184(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 688(%rdi) + movq %rax, 696(%rdi) + movq 192(%r8), %rdx + movq 200(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 704(%rdi) + movq %rax, 712(%rdi) + movq 208(%r8), %rdx + movq 216(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 720(%rdi) + movq %rax, 728(%rdi) + movq 224(%r8), %rdx + movq 232(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 736(%rdi) + movq %rax, 744(%rdi) + movq 240(%r8), %rdx + movq 248(%r8), %rax + andq %r10, %rdx + andq %r10, %rax + movq %rdx, 752(%rdi) + movq %rax, 760(%rdi) + movq 512(%rdi), %rdx + addq %rdx, %rdx + movq 520(%rdi), %rax + movq %rdx, 512(%rdi) + adcq %rax, %rax + movq 528(%rdi), %rdx + movq %rax, 520(%rdi) + adcq %rdx, %rdx + movq 536(%rdi), %rax + movq %rdx, 528(%rdi) + adcq %rax, %rax + movq 544(%rdi), %rdx + movq %rax, 536(%rdi) + adcq %rdx, %rdx + movq 552(%rdi), %rax + movq %rdx, 544(%rdi) + adcq %rax, %rax + movq 560(%rdi), %rdx + movq %rax, 552(%rdi) + adcq %rdx, %rdx + movq 568(%rdi), %rax + movq %rdx, 560(%rdi) + adcq %rax, %rax + movq 576(%rdi), %rdx + movq %rax, 568(%rdi) + adcq %rdx, %rdx + movq 584(%rdi), %rax + movq %rdx, 576(%rdi) + adcq %rax, %rax + movq 592(%rdi), %rdx + movq %rax, 584(%rdi) + adcq %rdx, %rdx + movq 600(%rdi), %rax + movq %rdx, 592(%rdi) + adcq %rax, %rax + movq 608(%rdi), %rdx + movq %rax, 600(%rdi) + adcq %rdx, %rdx + movq 616(%rdi), %rax + movq %rdx, 608(%rdi) + adcq %rax, %rax + movq 624(%rdi), %rdx + movq %rax, 616(%rdi) + adcq %rdx, %rdx + movq 632(%rdi), %rax + movq %rdx, 624(%rdi) + adcq %rax, %rax + movq 640(%rdi), %rdx + movq %rax, 632(%rdi) + adcq %rdx, %rdx + movq 648(%rdi), %rax + movq %rdx, 640(%rdi) + adcq %rax, %rax + movq 656(%rdi), %rdx + movq %rax, 648(%rdi) + adcq %rdx, %rdx + movq 664(%rdi), %rax + movq %rdx, 656(%rdi) + adcq %rax, %rax + movq 672(%rdi), %rdx + movq %rax, 664(%rdi) + adcq %rdx, %rdx + movq 680(%rdi), %rax + movq %rdx, 672(%rdi) + adcq %rax, %rax + movq 688(%rdi), %rdx + movq %rax, 680(%rdi) + adcq %rdx, %rdx + movq 696(%rdi), %rax + movq %rdx, 688(%rdi) + adcq %rax, %rax + movq 704(%rdi), %rdx + movq %rax, 696(%rdi) + adcq %rdx, %rdx + movq 712(%rdi), %rax + movq %rdx, 704(%rdi) + adcq %rax, %rax + movq 720(%rdi), %rdx + movq %rax, 712(%rdi) + adcq %rdx, %rdx + movq 728(%rdi), %rax + movq %rdx, 720(%rdi) + adcq %rax, %rax + movq 736(%rdi), %rdx + movq %rax, 728(%rdi) + adcq %rdx, %rdx + movq 744(%rdi), %rax + movq %rdx, 736(%rdi) + adcq %rax, %rax + movq 752(%rdi), %rdx + movq %rax, 744(%rdi) + adcq %rdx, %rdx + movq 760(%rdi), %rax + movq %rdx, 752(%rdi) + adcq %rax, %rax + movq %rax, 760(%rdi) + adcq $0, %rcx + leaq 512(%rsp), %rsi + movq %rsp, %r8 + movq (%r8), %rdx + subq (%rsi), %rdx + movq 8(%r8), %rax + movq %rdx, (%r8) + sbbq 8(%rsi), %rax + movq 16(%r8), %rdx + movq %rax, 8(%r8) + sbbq 16(%rsi), %rdx + movq 24(%r8), %rax + movq %rdx, 16(%r8) + sbbq 24(%rsi), %rax + movq 32(%r8), %rdx + movq %rax, 24(%r8) + sbbq 32(%rsi), %rdx + movq 40(%r8), %rax + movq %rdx, 32(%r8) + sbbq 40(%rsi), %rax + movq 48(%r8), %rdx + movq %rax, 40(%r8) + sbbq 48(%rsi), %rdx + movq 56(%r8), %rax + movq %rdx, 48(%r8) + sbbq 56(%rsi), %rax + movq 64(%r8), %rdx + movq %rax, 56(%r8) + sbbq 64(%rsi), %rdx + movq 72(%r8), %rax + movq %rdx, 64(%r8) + sbbq 72(%rsi), %rax + movq 80(%r8), %rdx + movq %rax, 72(%r8) + sbbq 80(%rsi), %rdx + movq 88(%r8), %rax + movq %rdx, 80(%r8) + sbbq 88(%rsi), %rax + movq 96(%r8), %rdx + movq %rax, 88(%r8) + sbbq 96(%rsi), %rdx + movq 104(%r8), %rax + movq %rdx, 96(%r8) + sbbq 104(%rsi), %rax + movq 112(%r8), %rdx + movq %rax, 104(%r8) + sbbq 112(%rsi), %rdx + movq 120(%r8), %rax + movq %rdx, 112(%r8) + sbbq 120(%rsi), %rax + movq 128(%r8), %rdx + movq %rax, 120(%r8) + sbbq 128(%rsi), %rdx + movq 136(%r8), %rax + movq %rdx, 128(%r8) + sbbq 136(%rsi), %rax + movq 144(%r8), %rdx + movq %rax, 136(%r8) + sbbq 144(%rsi), %rdx + movq 152(%r8), %rax + movq %rdx, 144(%r8) + sbbq 152(%rsi), %rax + movq 160(%r8), %rdx + movq %rax, 152(%r8) + sbbq 160(%rsi), %rdx + movq 168(%r8), %rax + movq %rdx, 160(%r8) + sbbq 168(%rsi), %rax + movq 176(%r8), %rdx + movq %rax, 168(%r8) + sbbq 176(%rsi), %rdx + movq 184(%r8), %rax + movq %rdx, 176(%r8) + sbbq 184(%rsi), %rax + movq 192(%r8), %rdx + movq %rax, 184(%r8) + sbbq 192(%rsi), %rdx + movq 200(%r8), %rax + movq %rdx, 192(%r8) + sbbq 200(%rsi), %rax + movq 208(%r8), %rdx + movq %rax, 200(%r8) + sbbq 208(%rsi), %rdx + movq 216(%r8), %rax + movq %rdx, 208(%r8) + sbbq 216(%rsi), %rax + movq 224(%r8), %rdx + movq %rax, 216(%r8) + sbbq 224(%rsi), %rdx + movq 232(%r8), %rax + movq %rdx, 224(%r8) + sbbq 232(%rsi), %rax + movq 240(%r8), %rdx + movq %rax, 232(%r8) + sbbq 240(%rsi), %rdx + movq 248(%r8), %rax + movq %rdx, 240(%r8) + sbbq 248(%rsi), %rax + movq 256(%r8), %rdx + movq %rax, 248(%r8) + sbbq 256(%rsi), %rdx + movq 264(%r8), %rax + movq %rdx, 256(%r8) + sbbq 264(%rsi), %rax + movq 272(%r8), %rdx + movq %rax, 264(%r8) + sbbq 272(%rsi), %rdx + movq 280(%r8), %rax + movq %rdx, 272(%r8) + sbbq 280(%rsi), %rax + movq 288(%r8), %rdx + movq %rax, 280(%r8) + sbbq 288(%rsi), %rdx + movq 296(%r8), %rax + movq %rdx, 288(%r8) + sbbq 296(%rsi), %rax + movq 304(%r8), %rdx + movq %rax, 296(%r8) + sbbq 304(%rsi), %rdx + movq 312(%r8), %rax + movq %rdx, 304(%r8) + sbbq 312(%rsi), %rax + movq 320(%r8), %rdx + movq %rax, 312(%r8) + sbbq 320(%rsi), %rdx + movq 328(%r8), %rax + movq %rdx, 320(%r8) + sbbq 328(%rsi), %rax + movq 336(%r8), %rdx + movq %rax, 328(%r8) + sbbq 336(%rsi), %rdx + movq 344(%r8), %rax + movq %rdx, 336(%r8) + sbbq 344(%rsi), %rax + movq 352(%r8), %rdx + movq %rax, 344(%r8) + sbbq 352(%rsi), %rdx + movq 360(%r8), %rax + movq %rdx, 352(%r8) + sbbq 360(%rsi), %rax + movq 368(%r8), %rdx + movq %rax, 360(%r8) + sbbq 368(%rsi), %rdx + movq 376(%r8), %rax + movq %rdx, 368(%r8) + sbbq 376(%rsi), %rax + movq 384(%r8), %rdx + movq %rax, 376(%r8) + sbbq 384(%rsi), %rdx + movq 392(%r8), %rax + movq %rdx, 384(%r8) + sbbq 392(%rsi), %rax + movq 400(%r8), %rdx + movq %rax, 392(%r8) + sbbq 400(%rsi), %rdx + movq 408(%r8), %rax + movq %rdx, 400(%r8) + sbbq 408(%rsi), %rax + movq 416(%r8), %rdx + movq %rax, 408(%r8) + sbbq 416(%rsi), %rdx + movq 424(%r8), %rax + movq %rdx, 416(%r8) + sbbq 424(%rsi), %rax + movq 432(%r8), %rdx + movq %rax, 424(%r8) + sbbq 432(%rsi), %rdx + movq 440(%r8), %rax + movq %rdx, 432(%r8) + sbbq 440(%rsi), %rax + movq 448(%r8), %rdx + movq %rax, 440(%r8) + sbbq 448(%rsi), %rdx + movq 456(%r8), %rax + movq %rdx, 448(%r8) + sbbq 456(%rsi), %rax + movq 464(%r8), %rdx + movq %rax, 456(%r8) + sbbq 464(%rsi), %rdx + movq 472(%r8), %rax + movq %rdx, 464(%r8) + sbbq 472(%rsi), %rax + movq 480(%r8), %rdx + movq %rax, 472(%r8) + sbbq 480(%rsi), %rdx + movq 488(%r8), %rax + movq %rdx, 480(%r8) + sbbq 488(%rsi), %rax + movq 496(%r8), %rdx + movq %rax, 488(%r8) + sbbq 496(%rsi), %rdx + movq 504(%r8), %rax + movq %rdx, 496(%r8) + sbbq 504(%rsi), %rax + movq %rax, 504(%r8) + sbbq $0, %rcx + movq (%r8), %rdx + subq (%rdi), %rdx + movq 8(%r8), %rax + movq %rdx, (%r8) + sbbq 8(%rdi), %rax + movq 16(%r8), %rdx + movq %rax, 8(%r8) + sbbq 16(%rdi), %rdx + movq 24(%r8), %rax + movq %rdx, 16(%r8) + sbbq 24(%rdi), %rax + movq 32(%r8), %rdx + movq %rax, 24(%r8) + sbbq 32(%rdi), %rdx + movq 40(%r8), %rax + movq %rdx, 32(%r8) + sbbq 40(%rdi), %rax + movq 48(%r8), %rdx + movq %rax, 40(%r8) + sbbq 48(%rdi), %rdx + movq 56(%r8), %rax + movq %rdx, 48(%r8) + sbbq 56(%rdi), %rax + movq 64(%r8), %rdx + movq %rax, 56(%r8) + sbbq 64(%rdi), %rdx + movq 72(%r8), %rax + movq %rdx, 64(%r8) + sbbq 72(%rdi), %rax + movq 80(%r8), %rdx + movq %rax, 72(%r8) + sbbq 80(%rdi), %rdx + movq 88(%r8), %rax + movq %rdx, 80(%r8) + sbbq 88(%rdi), %rax + movq 96(%r8), %rdx + movq %rax, 88(%r8) + sbbq 96(%rdi), %rdx + movq 104(%r8), %rax + movq %rdx, 96(%r8) + sbbq 104(%rdi), %rax + movq 112(%r8), %rdx + movq %rax, 104(%r8) + sbbq 112(%rdi), %rdx + movq 120(%r8), %rax + movq %rdx, 112(%r8) + sbbq 120(%rdi), %rax + movq 128(%r8), %rdx + movq %rax, 120(%r8) + sbbq 128(%rdi), %rdx + movq 136(%r8), %rax + movq %rdx, 128(%r8) + sbbq 136(%rdi), %rax + movq 144(%r8), %rdx + movq %rax, 136(%r8) + sbbq 144(%rdi), %rdx + movq 152(%r8), %rax + movq %rdx, 144(%r8) + sbbq 152(%rdi), %rax + movq 160(%r8), %rdx + movq %rax, 152(%r8) + sbbq 160(%rdi), %rdx + movq 168(%r8), %rax + movq %rdx, 160(%r8) + sbbq 168(%rdi), %rax + movq 176(%r8), %rdx + movq %rax, 168(%r8) + sbbq 176(%rdi), %rdx + movq 184(%r8), %rax + movq %rdx, 176(%r8) + sbbq 184(%rdi), %rax + movq 192(%r8), %rdx + movq %rax, 184(%r8) + sbbq 192(%rdi), %rdx + movq 200(%r8), %rax + movq %rdx, 192(%r8) + sbbq 200(%rdi), %rax + movq 208(%r8), %rdx + movq %rax, 200(%r8) + sbbq 208(%rdi), %rdx + movq 216(%r8), %rax + movq %rdx, 208(%r8) + sbbq 216(%rdi), %rax + movq 224(%r8), %rdx + movq %rax, 216(%r8) + sbbq 224(%rdi), %rdx + movq 232(%r8), %rax + movq %rdx, 224(%r8) + sbbq 232(%rdi), %rax + movq 240(%r8), %rdx + movq %rax, 232(%r8) + sbbq 240(%rdi), %rdx + movq 248(%r8), %rax + movq %rdx, 240(%r8) + sbbq 248(%rdi), %rax + movq 256(%r8), %rdx + movq %rax, 248(%r8) + sbbq 256(%rdi), %rdx + movq 264(%r8), %rax + movq %rdx, 256(%r8) + sbbq 264(%rdi), %rax + movq 272(%r8), %rdx + movq %rax, 264(%r8) + sbbq 272(%rdi), %rdx + movq 280(%r8), %rax + movq %rdx, 272(%r8) + sbbq 280(%rdi), %rax + movq 288(%r8), %rdx + movq %rax, 280(%r8) + sbbq 288(%rdi), %rdx + movq 296(%r8), %rax + movq %rdx, 288(%r8) + sbbq 296(%rdi), %rax + movq 304(%r8), %rdx + movq %rax, 296(%r8) + sbbq 304(%rdi), %rdx + movq 312(%r8), %rax + movq %rdx, 304(%r8) + sbbq 312(%rdi), %rax + movq 320(%r8), %rdx + movq %rax, 312(%r8) + sbbq 320(%rdi), %rdx + movq 328(%r8), %rax + movq %rdx, 320(%r8) + sbbq 328(%rdi), %rax + movq 336(%r8), %rdx + movq %rax, 328(%r8) + sbbq 336(%rdi), %rdx + movq 344(%r8), %rax + movq %rdx, 336(%r8) + sbbq 344(%rdi), %rax + movq 352(%r8), %rdx + movq %rax, 344(%r8) + sbbq 352(%rdi), %rdx + movq 360(%r8), %rax + movq %rdx, 352(%r8) + sbbq 360(%rdi), %rax + movq 368(%r8), %rdx + movq %rax, 360(%r8) + sbbq 368(%rdi), %rdx + movq 376(%r8), %rax + movq %rdx, 368(%r8) + sbbq 376(%rdi), %rax + movq 384(%r8), %rdx + movq %rax, 376(%r8) + sbbq 384(%rdi), %rdx + movq 392(%r8), %rax + movq %rdx, 384(%r8) + sbbq 392(%rdi), %rax + movq 400(%r8), %rdx + movq %rax, 392(%r8) + sbbq 400(%rdi), %rdx + movq 408(%r8), %rax + movq %rdx, 400(%r8) + sbbq 408(%rdi), %rax + movq 416(%r8), %rdx + movq %rax, 408(%r8) + sbbq 416(%rdi), %rdx + movq 424(%r8), %rax + movq %rdx, 416(%r8) + sbbq 424(%rdi), %rax + movq 432(%r8), %rdx + movq %rax, 424(%r8) + sbbq 432(%rdi), %rdx + movq 440(%r8), %rax + movq %rdx, 432(%r8) + sbbq 440(%rdi), %rax + movq 448(%r8), %rdx + movq %rax, 440(%r8) + sbbq 448(%rdi), %rdx + movq 456(%r8), %rax + movq %rdx, 448(%r8) + sbbq 456(%rdi), %rax + movq 464(%r8), %rdx + movq %rax, 456(%r8) + sbbq 464(%rdi), %rdx + movq 472(%r8), %rax + movq %rdx, 464(%r8) + sbbq 472(%rdi), %rax + movq 480(%r8), %rdx + movq %rax, 472(%r8) + sbbq 480(%rdi), %rdx + movq 488(%r8), %rax + movq %rdx, 480(%r8) + sbbq 488(%rdi), %rax + movq 496(%r8), %rdx + movq %rax, 488(%r8) + sbbq 496(%rdi), %rdx + movq 504(%r8), %rax + movq %rdx, 496(%r8) + sbbq 504(%rdi), %rax + movq %rax, 504(%r8) + sbbq $0, %rcx + # Add in place + movq 256(%rdi), %rdx + addq (%r8), %rdx + movq 264(%rdi), %rax + movq %rdx, 256(%rdi) + adcq 8(%r8), %rax + movq 272(%rdi), %rdx + movq %rax, 264(%rdi) + adcq 16(%r8), %rdx + movq 280(%rdi), %rax + movq %rdx, 272(%rdi) + adcq 24(%r8), %rax + movq 288(%rdi), %rdx + movq %rax, 280(%rdi) + adcq 32(%r8), %rdx + movq 296(%rdi), %rax + movq %rdx, 288(%rdi) + adcq 40(%r8), %rax + movq 304(%rdi), %rdx + movq %rax, 296(%rdi) + adcq 48(%r8), %rdx + movq 312(%rdi), %rax + movq %rdx, 304(%rdi) + adcq 56(%r8), %rax + movq 320(%rdi), %rdx + movq %rax, 312(%rdi) + adcq 64(%r8), %rdx + movq 328(%rdi), %rax + movq %rdx, 320(%rdi) + adcq 72(%r8), %rax + movq 336(%rdi), %rdx + movq %rax, 328(%rdi) + adcq 80(%r8), %rdx + movq 344(%rdi), %rax + movq %rdx, 336(%rdi) + adcq 88(%r8), %rax + movq 352(%rdi), %rdx + movq %rax, 344(%rdi) + adcq 96(%r8), %rdx + movq 360(%rdi), %rax + movq %rdx, 352(%rdi) + adcq 104(%r8), %rax + movq 368(%rdi), %rdx + movq %rax, 360(%rdi) + adcq 112(%r8), %rdx + movq 376(%rdi), %rax + movq %rdx, 368(%rdi) + adcq 120(%r8), %rax + movq 384(%rdi), %rdx + movq %rax, 376(%rdi) + adcq 128(%r8), %rdx + movq 392(%rdi), %rax + movq %rdx, 384(%rdi) + adcq 136(%r8), %rax + movq 400(%rdi), %rdx + movq %rax, 392(%rdi) + adcq 144(%r8), %rdx + movq 408(%rdi), %rax + movq %rdx, 400(%rdi) + adcq 152(%r8), %rax + movq 416(%rdi), %rdx + movq %rax, 408(%rdi) + adcq 160(%r8), %rdx + movq 424(%rdi), %rax + movq %rdx, 416(%rdi) + adcq 168(%r8), %rax + movq 432(%rdi), %rdx + movq %rax, 424(%rdi) + adcq 176(%r8), %rdx + movq 440(%rdi), %rax + movq %rdx, 432(%rdi) + adcq 184(%r8), %rax + movq 448(%rdi), %rdx + movq %rax, 440(%rdi) + adcq 192(%r8), %rdx + movq 456(%rdi), %rax + movq %rdx, 448(%rdi) + adcq 200(%r8), %rax + movq 464(%rdi), %rdx + movq %rax, 456(%rdi) + adcq 208(%r8), %rdx + movq 472(%rdi), %rax + movq %rdx, 464(%rdi) + adcq 216(%r8), %rax + movq 480(%rdi), %rdx + movq %rax, 472(%rdi) + adcq 224(%r8), %rdx + movq 488(%rdi), %rax + movq %rdx, 480(%rdi) + adcq 232(%r8), %rax + movq 496(%rdi), %rdx + movq %rax, 488(%rdi) + adcq 240(%r8), %rdx + movq 504(%rdi), %rax + movq %rdx, 496(%rdi) + adcq 248(%r8), %rax + movq 512(%rdi), %rdx + movq %rax, 504(%rdi) + adcq 256(%r8), %rdx + movq 520(%rdi), %rax + movq %rdx, 512(%rdi) + adcq 264(%r8), %rax + movq 528(%rdi), %rdx + movq %rax, 520(%rdi) + adcq 272(%r8), %rdx + movq 536(%rdi), %rax + movq %rdx, 528(%rdi) + adcq 280(%r8), %rax + movq 544(%rdi), %rdx + movq %rax, 536(%rdi) + adcq 288(%r8), %rdx + movq 552(%rdi), %rax + movq %rdx, 544(%rdi) + adcq 296(%r8), %rax + movq 560(%rdi), %rdx + movq %rax, 552(%rdi) + adcq 304(%r8), %rdx + movq 568(%rdi), %rax + movq %rdx, 560(%rdi) + adcq 312(%r8), %rax + movq 576(%rdi), %rdx + movq %rax, 568(%rdi) + adcq 320(%r8), %rdx + movq 584(%rdi), %rax + movq %rdx, 576(%rdi) + adcq 328(%r8), %rax + movq 592(%rdi), %rdx + movq %rax, 584(%rdi) + adcq 336(%r8), %rdx + movq 600(%rdi), %rax + movq %rdx, 592(%rdi) + adcq 344(%r8), %rax + movq 608(%rdi), %rdx + movq %rax, 600(%rdi) + adcq 352(%r8), %rdx + movq 616(%rdi), %rax + movq %rdx, 608(%rdi) + adcq 360(%r8), %rax + movq 624(%rdi), %rdx + movq %rax, 616(%rdi) + adcq 368(%r8), %rdx + movq 632(%rdi), %rax + movq %rdx, 624(%rdi) + adcq 376(%r8), %rax + movq 640(%rdi), %rdx + movq %rax, 632(%rdi) + adcq 384(%r8), %rdx + movq 648(%rdi), %rax + movq %rdx, 640(%rdi) + adcq 392(%r8), %rax + movq 656(%rdi), %rdx + movq %rax, 648(%rdi) + adcq 400(%r8), %rdx + movq 664(%rdi), %rax + movq %rdx, 656(%rdi) + adcq 408(%r8), %rax + movq 672(%rdi), %rdx + movq %rax, 664(%rdi) + adcq 416(%r8), %rdx + movq 680(%rdi), %rax + movq %rdx, 672(%rdi) + adcq 424(%r8), %rax + movq 688(%rdi), %rdx + movq %rax, 680(%rdi) + adcq 432(%r8), %rdx + movq 696(%rdi), %rax + movq %rdx, 688(%rdi) + adcq 440(%r8), %rax + movq 704(%rdi), %rdx + movq %rax, 696(%rdi) + adcq 448(%r8), %rdx + movq 712(%rdi), %rax + movq %rdx, 704(%rdi) + adcq 456(%r8), %rax + movq 720(%rdi), %rdx + movq %rax, 712(%rdi) + adcq 464(%r8), %rdx + movq 728(%rdi), %rax + movq %rdx, 720(%rdi) + adcq 472(%r8), %rax + movq 736(%rdi), %rdx + movq %rax, 728(%rdi) + adcq 480(%r8), %rdx + movq 744(%rdi), %rax + movq %rdx, 736(%rdi) + adcq 488(%r8), %rax + movq 752(%rdi), %rdx + movq %rax, 744(%rdi) + adcq 496(%r8), %rdx + movq 760(%rdi), %rax + movq %rdx, 752(%rdi) + adcq 504(%r8), %rax + movq %rax, 760(%rdi) + adcq $0, %rcx + movq %rcx, 768(%rdi) + # Add in place + movq 512(%rdi), %rdx + xorq %rcx, %rcx + addq (%rsi), %rdx + movq 520(%rdi), %rax + movq %rdx, 512(%rdi) + adcq 8(%rsi), %rax + movq 528(%rdi), %rdx + movq %rax, 520(%rdi) + adcq 16(%rsi), %rdx + movq 536(%rdi), %rax + movq %rdx, 528(%rdi) + adcq 24(%rsi), %rax + movq 544(%rdi), %rdx + movq %rax, 536(%rdi) + adcq 32(%rsi), %rdx + movq 552(%rdi), %rax + movq %rdx, 544(%rdi) + adcq 40(%rsi), %rax + movq 560(%rdi), %rdx + movq %rax, 552(%rdi) + adcq 48(%rsi), %rdx + movq 568(%rdi), %rax + movq %rdx, 560(%rdi) + adcq 56(%rsi), %rax + movq 576(%rdi), %rdx + movq %rax, 568(%rdi) + adcq 64(%rsi), %rdx + movq 584(%rdi), %rax + movq %rdx, 576(%rdi) + adcq 72(%rsi), %rax + movq 592(%rdi), %rdx + movq %rax, 584(%rdi) + adcq 80(%rsi), %rdx + movq 600(%rdi), %rax + movq %rdx, 592(%rdi) + adcq 88(%rsi), %rax + movq 608(%rdi), %rdx + movq %rax, 600(%rdi) + adcq 96(%rsi), %rdx + movq 616(%rdi), %rax + movq %rdx, 608(%rdi) + adcq 104(%rsi), %rax + movq 624(%rdi), %rdx + movq %rax, 616(%rdi) + adcq 112(%rsi), %rdx + movq 632(%rdi), %rax + movq %rdx, 624(%rdi) + adcq 120(%rsi), %rax + movq 640(%rdi), %rdx + movq %rax, 632(%rdi) + adcq 128(%rsi), %rdx + movq 648(%rdi), %rax + movq %rdx, 640(%rdi) + adcq 136(%rsi), %rax + movq 656(%rdi), %rdx + movq %rax, 648(%rdi) + adcq 144(%rsi), %rdx + movq 664(%rdi), %rax + movq %rdx, 656(%rdi) + adcq 152(%rsi), %rax + movq 672(%rdi), %rdx + movq %rax, 664(%rdi) + adcq 160(%rsi), %rdx + movq 680(%rdi), %rax + movq %rdx, 672(%rdi) + adcq 168(%rsi), %rax + movq 688(%rdi), %rdx + movq %rax, 680(%rdi) + adcq 176(%rsi), %rdx + movq 696(%rdi), %rax + movq %rdx, 688(%rdi) + adcq 184(%rsi), %rax + movq 704(%rdi), %rdx + movq %rax, 696(%rdi) + adcq 192(%rsi), %rdx + movq 712(%rdi), %rax + movq %rdx, 704(%rdi) + adcq 200(%rsi), %rax + movq 720(%rdi), %rdx + movq %rax, 712(%rdi) + adcq 208(%rsi), %rdx + movq 728(%rdi), %rax + movq %rdx, 720(%rdi) + adcq 216(%rsi), %rax + movq 736(%rdi), %rdx + movq %rax, 728(%rdi) + adcq 224(%rsi), %rdx + movq 744(%rdi), %rax + movq %rdx, 736(%rdi) + adcq 232(%rsi), %rax + movq 752(%rdi), %rdx + movq %rax, 744(%rdi) + adcq 240(%rsi), %rdx + movq 760(%rdi), %rax + movq %rdx, 752(%rdi) + adcq 248(%rsi), %rax + movq 768(%rdi), %rdx + movq %rax, 760(%rdi) + adcq 256(%rsi), %rdx + movq %rdx, 768(%rdi) + adcq $0, %rcx + # Add to zero + movq 264(%rsi), %rdx + adcq $0, %rdx + movq 272(%rsi), %rax + movq %rdx, 776(%rdi) + adcq $0, %rax + movq 280(%rsi), %rdx + movq %rax, 784(%rdi) + adcq $0, %rdx + movq 288(%rsi), %rax + movq %rdx, 792(%rdi) + adcq $0, %rax + movq 296(%rsi), %rdx + movq %rax, 800(%rdi) + adcq $0, %rdx + movq 304(%rsi), %rax + movq %rdx, 808(%rdi) + adcq $0, %rax + movq 312(%rsi), %rdx + movq %rax, 816(%rdi) + adcq $0, %rdx + movq 320(%rsi), %rax + movq %rdx, 824(%rdi) + adcq $0, %rax + movq 328(%rsi), %rdx + movq %rax, 832(%rdi) + adcq $0, %rdx + movq 336(%rsi), %rax + movq %rdx, 840(%rdi) + adcq $0, %rax + movq 344(%rsi), %rdx + movq %rax, 848(%rdi) + adcq $0, %rdx + movq 352(%rsi), %rax + movq %rdx, 856(%rdi) + adcq $0, %rax + movq 360(%rsi), %rdx + movq %rax, 864(%rdi) + adcq $0, %rdx + movq 368(%rsi), %rax + movq %rdx, 872(%rdi) + adcq $0, %rax + movq 376(%rsi), %rdx + movq %rax, 880(%rdi) + adcq $0, %rdx + movq 384(%rsi), %rax + movq %rdx, 888(%rdi) + adcq $0, %rax + movq 392(%rsi), %rdx + movq %rax, 896(%rdi) + adcq $0, %rdx + movq 400(%rsi), %rax + movq %rdx, 904(%rdi) + adcq $0, %rax + movq 408(%rsi), %rdx + movq %rax, 912(%rdi) + adcq $0, %rdx + movq 416(%rsi), %rax + movq %rdx, 920(%rdi) + adcq $0, %rax + movq 424(%rsi), %rdx + movq %rax, 928(%rdi) + adcq $0, %rdx + movq 432(%rsi), %rax + movq %rdx, 936(%rdi) + adcq $0, %rax + movq 440(%rsi), %rdx + movq %rax, 944(%rdi) + adcq $0, %rdx + movq 448(%rsi), %rax + movq %rdx, 952(%rdi) + adcq $0, %rax + movq 456(%rsi), %rdx + movq %rax, 960(%rdi) + adcq $0, %rdx + movq 464(%rsi), %rax + movq %rdx, 968(%rdi) + adcq $0, %rax + movq 472(%rsi), %rdx + movq %rax, 976(%rdi) + adcq $0, %rdx + movq 480(%rsi), %rax + movq %rdx, 984(%rdi) + adcq $0, %rax + movq 488(%rsi), %rdx + movq %rax, 992(%rdi) + adcq $0, %rdx + movq 496(%rsi), %rax + movq %rdx, 1000(%rdi) + adcq $0, %rax + movq 504(%rsi), %rdx + movq %rax, 1008(%rdi) + adcq $0, %rdx + movq %rdx, 1016(%rdi) + addq $1304, %rsp + repz retq +#ifndef __APPLE__ +.size sp_4096_sqr_64,.-sp_4096_sqr_64 +#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__ +.globl sp_4096_mul_avx2_64 +.type sp_4096_mul_avx2_64,@function +.align 16 +sp_4096_mul_avx2_64: +#else +.globl _sp_4096_mul_avx2_64 +.p2align 4 +_sp_4096_mul_avx2_64: +#endif /* __APPLE__ */ + push %r12 + push %r13 + push %r14 + push %r15 + subq $1576, %rsp + movq %rdi, 1536(%rsp) + movq %rsi, 1544(%rsp) + movq %rdx, 1552(%rsp) + leaq 1024(%rsp), %r10 + leaq 256(%rsi), %r12 + # Add + movq (%rsi), %rax + xorq %r13, %r13 + addq (%r12), %rax + movq 8(%rsi), %rcx + movq %rax, (%r10) + adcq 8(%r12), %rcx + movq 16(%rsi), %r8 + movq %rcx, 8(%r10) + adcq 16(%r12), %r8 + movq 24(%rsi), %rax + movq %r8, 16(%r10) + adcq 24(%r12), %rax + movq 32(%rsi), %rcx + movq %rax, 24(%r10) + adcq 32(%r12), %rcx + movq 40(%rsi), %r8 + movq %rcx, 32(%r10) + adcq 40(%r12), %r8 + movq 48(%rsi), %rax + movq %r8, 40(%r10) + adcq 48(%r12), %rax + movq 56(%rsi), %rcx + movq %rax, 48(%r10) + adcq 56(%r12), %rcx + movq 64(%rsi), %r8 + movq %rcx, 56(%r10) + adcq 64(%r12), %r8 + movq 72(%rsi), %rax + movq %r8, 64(%r10) + adcq 72(%r12), %rax + movq 80(%rsi), %rcx + movq %rax, 72(%r10) + adcq 80(%r12), %rcx + movq 88(%rsi), %r8 + movq %rcx, 80(%r10) + adcq 88(%r12), %r8 + movq 96(%rsi), %rax + movq %r8, 88(%r10) + adcq 96(%r12), %rax + movq 104(%rsi), %rcx + movq %rax, 96(%r10) + adcq 104(%r12), %rcx + movq 112(%rsi), %r8 + movq %rcx, 104(%r10) + adcq 112(%r12), %r8 + movq 120(%rsi), %rax + movq %r8, 112(%r10) + adcq 120(%r12), %rax + movq 128(%rsi), %rcx + movq %rax, 120(%r10) + adcq 128(%r12), %rcx + movq 136(%rsi), %r8 + movq %rcx, 128(%r10) + adcq 136(%r12), %r8 + movq 144(%rsi), %rax + movq %r8, 136(%r10) + adcq 144(%r12), %rax + movq 152(%rsi), %rcx + movq %rax, 144(%r10) + adcq 152(%r12), %rcx + movq 160(%rsi), %r8 + movq %rcx, 152(%r10) + adcq 160(%r12), %r8 + movq 168(%rsi), %rax + movq %r8, 160(%r10) + adcq 168(%r12), %rax + movq 176(%rsi), %rcx + movq %rax, 168(%r10) + adcq 176(%r12), %rcx + movq 184(%rsi), %r8 + movq %rcx, 176(%r10) + adcq 184(%r12), %r8 + movq 192(%rsi), %rax + movq %r8, 184(%r10) + adcq 192(%r12), %rax + movq 200(%rsi), %rcx + movq %rax, 192(%r10) + adcq 200(%r12), %rcx + movq 208(%rsi), %r8 + movq %rcx, 200(%r10) + adcq 208(%r12), %r8 + movq 216(%rsi), %rax + movq %r8, 208(%r10) + adcq 216(%r12), %rax + movq 224(%rsi), %rcx + movq %rax, 216(%r10) + adcq 224(%r12), %rcx + movq 232(%rsi), %r8 + movq %rcx, 224(%r10) + adcq 232(%r12), %r8 + movq 240(%rsi), %rax + movq %r8, 232(%r10) + adcq 240(%r12), %rax + movq 248(%rsi), %rcx + movq %rax, 240(%r10) + adcq 248(%r12), %rcx + movq %rcx, 248(%r10) + adcq $0, %r13 + movq %r13, 1560(%rsp) + leaq 1280(%rsp), %r11 + leaq 256(%rdx), %r12 + # Add + movq (%rdx), %rax + xorq %r14, %r14 + addq (%r12), %rax + movq 8(%rdx), %rcx + movq %rax, (%r11) + adcq 8(%r12), %rcx + movq 16(%rdx), %r8 + movq %rcx, 8(%r11) + adcq 16(%r12), %r8 + movq 24(%rdx), %rax + movq %r8, 16(%r11) + adcq 24(%r12), %rax + movq 32(%rdx), %rcx + movq %rax, 24(%r11) + adcq 32(%r12), %rcx + movq 40(%rdx), %r8 + movq %rcx, 32(%r11) + adcq 40(%r12), %r8 + movq 48(%rdx), %rax + movq %r8, 40(%r11) + adcq 48(%r12), %rax + movq 56(%rdx), %rcx + movq %rax, 48(%r11) + adcq 56(%r12), %rcx + movq 64(%rdx), %r8 + movq %rcx, 56(%r11) + adcq 64(%r12), %r8 + movq 72(%rdx), %rax + movq %r8, 64(%r11) + adcq 72(%r12), %rax + movq 80(%rdx), %rcx + movq %rax, 72(%r11) + adcq 80(%r12), %rcx + movq 88(%rdx), %r8 + movq %rcx, 80(%r11) + adcq 88(%r12), %r8 + movq 96(%rdx), %rax + movq %r8, 88(%r11) + adcq 96(%r12), %rax + movq 104(%rdx), %rcx + movq %rax, 96(%r11) + adcq 104(%r12), %rcx + movq 112(%rdx), %r8 + movq %rcx, 104(%r11) + adcq 112(%r12), %r8 + movq 120(%rdx), %rax + movq %r8, 112(%r11) + adcq 120(%r12), %rax + movq 128(%rdx), %rcx + movq %rax, 120(%r11) + adcq 128(%r12), %rcx + movq 136(%rdx), %r8 + movq %rcx, 128(%r11) + adcq 136(%r12), %r8 + movq 144(%rdx), %rax + movq %r8, 136(%r11) + adcq 144(%r12), %rax + movq 152(%rdx), %rcx + movq %rax, 144(%r11) + adcq 152(%r12), %rcx + movq 160(%rdx), %r8 + movq %rcx, 152(%r11) + adcq 160(%r12), %r8 + movq 168(%rdx), %rax + movq %r8, 160(%r11) + adcq 168(%r12), %rax + movq 176(%rdx), %rcx + movq %rax, 168(%r11) + adcq 176(%r12), %rcx + movq 184(%rdx), %r8 + movq %rcx, 176(%r11) + adcq 184(%r12), %r8 + movq 192(%rdx), %rax + movq %r8, 184(%r11) + adcq 192(%r12), %rax + movq 200(%rdx), %rcx + movq %rax, 192(%r11) + adcq 200(%r12), %rcx + movq 208(%rdx), %r8 + movq %rcx, 200(%r11) + adcq 208(%r12), %r8 + movq 216(%rdx), %rax + movq %r8, 208(%r11) + adcq 216(%r12), %rax + movq 224(%rdx), %rcx + movq %rax, 216(%r11) + adcq 224(%r12), %rcx + movq 232(%rdx), %r8 + movq %rcx, 224(%r11) + adcq 232(%r12), %r8 + movq 240(%rdx), %rax + movq %r8, 232(%r11) + adcq 240(%r12), %rax + movq 248(%rdx), %rcx + movq %rax, 240(%r11) + adcq 248(%r12), %rcx + movq %rcx, 248(%r11) + adcq $0, %r14 + movq %r14, 1568(%rsp) + movq %r11, %rdx + movq %r10, %rsi + movq %rsp, %rdi +#ifndef __APPLE__ + callq sp_2048_mul_avx2_32@plt +#else + callq _sp_2048_mul_avx2_32 +#endif /* __APPLE__ */ + movq 1552(%rsp), %rdx + movq 1544(%rsp), %rsi + leaq 512(%rsp), %rdi + addq $256, %rdx + addq $256, %rsi +#ifndef __APPLE__ + callq sp_2048_mul_avx2_32@plt +#else + callq _sp_2048_mul_avx2_32 +#endif /* __APPLE__ */ + movq 1552(%rsp), %rdx + movq 1544(%rsp), %rsi + movq 1536(%rsp), %rdi +#ifndef __APPLE__ + callq sp_2048_mul_avx2_32@plt +#else + callq _sp_2048_mul_avx2_32 +#endif /* __APPLE__ */ + movq 1560(%rsp), %r13 + movq 1568(%rsp), %r14 + movq 1536(%rsp), %r15 + movq %r13, %r9 + leaq 1024(%rsp), %r10 + leaq 1280(%rsp), %r11 + andq %r14, %r9 + negq %r13 + negq %r14 + addq $512, %r15 + movq (%r10), %rax + movq (%r11), %rcx + pextq %r14, %rax, %rax + pextq %r13, %rcx, %rcx + addq %rcx, %rax + movq 8(%r10), %rcx + movq 8(%r11), %r8 + pextq %r14, %rcx, %rcx + pextq %r13, %r8, %r8 + movq %rax, (%r15) + adcq %r8, %rcx + movq 16(%r10), %r8 + movq 16(%r11), %rax + pextq %r14, %r8, %r8 + pextq %r13, %rax, %rax + movq %rcx, 8(%r15) + adcq %rax, %r8 + movq 24(%r10), %rax + movq 24(%r11), %rcx + pextq %r14, %rax, %rax + pextq %r13, %rcx, %rcx + movq %r8, 16(%r15) + adcq %rcx, %rax + movq 32(%r10), %rcx + movq 32(%r11), %r8 + pextq %r14, %rcx, %rcx + pextq %r13, %r8, %r8 + movq %rax, 24(%r15) + adcq %r8, %rcx + movq 40(%r10), %r8 + movq 40(%r11), %rax + pextq %r14, %r8, %r8 + pextq %r13, %rax, %rax + movq %rcx, 32(%r15) + adcq %rax, %r8 + movq 48(%r10), %rax + movq 48(%r11), %rcx + pextq %r14, %rax, %rax + pextq %r13, %rcx, %rcx + movq %r8, 40(%r15) + adcq %rcx, %rax + movq 56(%r10), %rcx + movq 56(%r11), %r8 + pextq %r14, %rcx, %rcx + pextq %r13, %r8, %r8 + movq %rax, 48(%r15) + adcq %r8, %rcx + movq 64(%r10), %r8 + movq 64(%r11), %rax + pextq %r14, %r8, %r8 + pextq %r13, %rax, %rax + movq %rcx, 56(%r15) + adcq %rax, %r8 + movq 72(%r10), %rax + movq 72(%r11), %rcx + pextq %r14, %rax, %rax + pextq %r13, %rcx, %rcx + movq %r8, 64(%r15) + adcq %rcx, %rax + movq 80(%r10), %rcx + movq 80(%r11), %r8 + pextq %r14, %rcx, %rcx + pextq %r13, %r8, %r8 + movq %rax, 72(%r15) + adcq %r8, %rcx + movq 88(%r10), %r8 + movq 88(%r11), %rax + pextq %r14, %r8, %r8 + pextq %r13, %rax, %rax + movq %rcx, 80(%r15) + adcq %rax, %r8 + movq 96(%r10), %rax + movq 96(%r11), %rcx + pextq %r14, %rax, %rax + pextq %r13, %rcx, %rcx + movq %r8, 88(%r15) + adcq %rcx, %rax + movq 104(%r10), %rcx + movq 104(%r11), %r8 + pextq %r14, %rcx, %rcx + pextq %r13, %r8, %r8 + movq %rax, 96(%r15) + adcq %r8, %rcx + movq 112(%r10), %r8 + movq 112(%r11), %rax + pextq %r14, %r8, %r8 + pextq %r13, %rax, %rax + movq %rcx, 104(%r15) + adcq %rax, %r8 + movq 120(%r10), %rax + movq 120(%r11), %rcx + pextq %r14, %rax, %rax + pextq %r13, %rcx, %rcx + movq %r8, 112(%r15) + adcq %rcx, %rax + movq 128(%r10), %rcx + movq 128(%r11), %r8 + pextq %r14, %rcx, %rcx + pextq %r13, %r8, %r8 + movq %rax, 120(%r15) + adcq %r8, %rcx + movq 136(%r10), %r8 + movq 136(%r11), %rax + pextq %r14, %r8, %r8 + pextq %r13, %rax, %rax + movq %rcx, 128(%r15) + adcq %rax, %r8 + movq 144(%r10), %rax + movq 144(%r11), %rcx + pextq %r14, %rax, %rax + pextq %r13, %rcx, %rcx + movq %r8, 136(%r15) + adcq %rcx, %rax + movq 152(%r10), %rcx + movq 152(%r11), %r8 + pextq %r14, %rcx, %rcx + pextq %r13, %r8, %r8 + movq %rax, 144(%r15) + adcq %r8, %rcx + movq 160(%r10), %r8 + movq 160(%r11), %rax + pextq %r14, %r8, %r8 + pextq %r13, %rax, %rax + movq %rcx, 152(%r15) + adcq %rax, %r8 + movq 168(%r10), %rax + movq 168(%r11), %rcx + pextq %r14, %rax, %rax + pextq %r13, %rcx, %rcx + movq %r8, 160(%r15) + adcq %rcx, %rax + movq 176(%r10), %rcx + movq 176(%r11), %r8 + pextq %r14, %rcx, %rcx + pextq %r13, %r8, %r8 + movq %rax, 168(%r15) + adcq %r8, %rcx + movq 184(%r10), %r8 + movq 184(%r11), %rax + pextq %r14, %r8, %r8 + pextq %r13, %rax, %rax + movq %rcx, 176(%r15) + adcq %rax, %r8 + movq 192(%r10), %rax + movq 192(%r11), %rcx + pextq %r14, %rax, %rax + pextq %r13, %rcx, %rcx + movq %r8, 184(%r15) + adcq %rcx, %rax + movq 200(%r10), %rcx + movq 200(%r11), %r8 + pextq %r14, %rcx, %rcx + pextq %r13, %r8, %r8 + movq %rax, 192(%r15) + adcq %r8, %rcx + movq 208(%r10), %r8 + movq 208(%r11), %rax + pextq %r14, %r8, %r8 + pextq %r13, %rax, %rax + movq %rcx, 200(%r15) + adcq %rax, %r8 + movq 216(%r10), %rax + movq 216(%r11), %rcx + pextq %r14, %rax, %rax + pextq %r13, %rcx, %rcx + movq %r8, 208(%r15) + adcq %rcx, %rax + movq 224(%r10), %rcx + movq 224(%r11), %r8 + pextq %r14, %rcx, %rcx + pextq %r13, %r8, %r8 + movq %rax, 216(%r15) + adcq %r8, %rcx + movq 232(%r10), %r8 + movq 232(%r11), %rax + pextq %r14, %r8, %r8 + pextq %r13, %rax, %rax + movq %rcx, 224(%r15) + adcq %rax, %r8 + movq 240(%r10), %rax + movq 240(%r11), %rcx + pextq %r14, %rax, %rax + pextq %r13, %rcx, %rcx + movq %r8, 232(%r15) + adcq %rcx, %rax + movq 248(%r10), %rcx + movq 248(%r11), %r8 + pextq %r14, %rcx, %rcx + pextq %r13, %r8, %r8 + movq %rax, 240(%r15) + adcq %r8, %rcx + movq %rcx, 248(%r15) + adcq $0, %r9 + leaq 512(%rsp), %r11 + movq %rsp, %r10 + movq (%r10), %rax + subq (%r11), %rax + movq 8(%r10), %rcx + movq %rax, (%r10) + sbbq 8(%r11), %rcx + movq 16(%r10), %r8 + movq %rcx, 8(%r10) + sbbq 16(%r11), %r8 + movq 24(%r10), %rax + movq %r8, 16(%r10) + sbbq 24(%r11), %rax + movq 32(%r10), %rcx + movq %rax, 24(%r10) + sbbq 32(%r11), %rcx + movq 40(%r10), %r8 + movq %rcx, 32(%r10) + sbbq 40(%r11), %r8 + movq 48(%r10), %rax + movq %r8, 40(%r10) + sbbq 48(%r11), %rax + movq 56(%r10), %rcx + movq %rax, 48(%r10) + sbbq 56(%r11), %rcx + movq 64(%r10), %r8 + movq %rcx, 56(%r10) + sbbq 64(%r11), %r8 + movq 72(%r10), %rax + movq %r8, 64(%r10) + sbbq 72(%r11), %rax + movq 80(%r10), %rcx + movq %rax, 72(%r10) + sbbq 80(%r11), %rcx + movq 88(%r10), %r8 + movq %rcx, 80(%r10) + sbbq 88(%r11), %r8 + movq 96(%r10), %rax + movq %r8, 88(%r10) + sbbq 96(%r11), %rax + movq 104(%r10), %rcx + movq %rax, 96(%r10) + sbbq 104(%r11), %rcx + movq 112(%r10), %r8 + movq %rcx, 104(%r10) + sbbq 112(%r11), %r8 + movq 120(%r10), %rax + movq %r8, 112(%r10) + sbbq 120(%r11), %rax + movq 128(%r10), %rcx + movq %rax, 120(%r10) + sbbq 128(%r11), %rcx + movq 136(%r10), %r8 + movq %rcx, 128(%r10) + sbbq 136(%r11), %r8 + movq 144(%r10), %rax + movq %r8, 136(%r10) + sbbq 144(%r11), %rax + movq 152(%r10), %rcx + movq %rax, 144(%r10) + sbbq 152(%r11), %rcx + movq 160(%r10), %r8 + movq %rcx, 152(%r10) + sbbq 160(%r11), %r8 + movq 168(%r10), %rax + movq %r8, 160(%r10) + sbbq 168(%r11), %rax + movq 176(%r10), %rcx + movq %rax, 168(%r10) + sbbq 176(%r11), %rcx + movq 184(%r10), %r8 + movq %rcx, 176(%r10) + sbbq 184(%r11), %r8 + movq 192(%r10), %rax + movq %r8, 184(%r10) + sbbq 192(%r11), %rax + movq 200(%r10), %rcx + movq %rax, 192(%r10) + sbbq 200(%r11), %rcx + movq 208(%r10), %r8 + movq %rcx, 200(%r10) + sbbq 208(%r11), %r8 + movq 216(%r10), %rax + movq %r8, 208(%r10) + sbbq 216(%r11), %rax + movq 224(%r10), %rcx + movq %rax, 216(%r10) + sbbq 224(%r11), %rcx + movq 232(%r10), %r8 + movq %rcx, 224(%r10) + sbbq 232(%r11), %r8 + movq 240(%r10), %rax + movq %r8, 232(%r10) + sbbq 240(%r11), %rax + movq 248(%r10), %rcx + movq %rax, 240(%r10) + sbbq 248(%r11), %rcx + movq 256(%r10), %r8 + movq %rcx, 248(%r10) + sbbq 256(%r11), %r8 + movq 264(%r10), %rax + movq %r8, 256(%r10) + sbbq 264(%r11), %rax + movq 272(%r10), %rcx + movq %rax, 264(%r10) + sbbq 272(%r11), %rcx + movq 280(%r10), %r8 + movq %rcx, 272(%r10) + sbbq 280(%r11), %r8 + movq 288(%r10), %rax + movq %r8, 280(%r10) + sbbq 288(%r11), %rax + movq 296(%r10), %rcx + movq %rax, 288(%r10) + sbbq 296(%r11), %rcx + movq 304(%r10), %r8 + movq %rcx, 296(%r10) + sbbq 304(%r11), %r8 + movq 312(%r10), %rax + movq %r8, 304(%r10) + sbbq 312(%r11), %rax + movq 320(%r10), %rcx + movq %rax, 312(%r10) + sbbq 320(%r11), %rcx + movq 328(%r10), %r8 + movq %rcx, 320(%r10) + sbbq 328(%r11), %r8 + movq 336(%r10), %rax + movq %r8, 328(%r10) + sbbq 336(%r11), %rax + movq 344(%r10), %rcx + movq %rax, 336(%r10) + sbbq 344(%r11), %rcx + movq 352(%r10), %r8 + movq %rcx, 344(%r10) + sbbq 352(%r11), %r8 + movq 360(%r10), %rax + movq %r8, 352(%r10) + sbbq 360(%r11), %rax + movq 368(%r10), %rcx + movq %rax, 360(%r10) + sbbq 368(%r11), %rcx + movq 376(%r10), %r8 + movq %rcx, 368(%r10) + sbbq 376(%r11), %r8 + movq 384(%r10), %rax + movq %r8, 376(%r10) + sbbq 384(%r11), %rax + movq 392(%r10), %rcx + movq %rax, 384(%r10) + sbbq 392(%r11), %rcx + movq 400(%r10), %r8 + movq %rcx, 392(%r10) + sbbq 400(%r11), %r8 + movq 408(%r10), %rax + movq %r8, 400(%r10) + sbbq 408(%r11), %rax + movq 416(%r10), %rcx + movq %rax, 408(%r10) + sbbq 416(%r11), %rcx + movq 424(%r10), %r8 + movq %rcx, 416(%r10) + sbbq 424(%r11), %r8 + movq 432(%r10), %rax + movq %r8, 424(%r10) + sbbq 432(%r11), %rax + movq 440(%r10), %rcx + movq %rax, 432(%r10) + sbbq 440(%r11), %rcx + movq 448(%r10), %r8 + movq %rcx, 440(%r10) + sbbq 448(%r11), %r8 + movq 456(%r10), %rax + movq %r8, 448(%r10) + sbbq 456(%r11), %rax + movq 464(%r10), %rcx + movq %rax, 456(%r10) + sbbq 464(%r11), %rcx + movq 472(%r10), %r8 + movq %rcx, 464(%r10) + sbbq 472(%r11), %r8 + movq 480(%r10), %rax + movq %r8, 472(%r10) + sbbq 480(%r11), %rax + movq 488(%r10), %rcx + movq %rax, 480(%r10) + sbbq 488(%r11), %rcx + movq 496(%r10), %r8 + movq %rcx, 488(%r10) + sbbq 496(%r11), %r8 + movq 504(%r10), %rax + movq %r8, 496(%r10) + sbbq 504(%r11), %rax + movq %rax, 504(%r10) + sbbq $0, %r9 + movq (%r10), %rax + subq (%rdi), %rax + movq 8(%r10), %rcx + movq %rax, (%r10) + sbbq 8(%rdi), %rcx + movq 16(%r10), %r8 + movq %rcx, 8(%r10) + sbbq 16(%rdi), %r8 + movq 24(%r10), %rax + movq %r8, 16(%r10) + sbbq 24(%rdi), %rax + movq 32(%r10), %rcx + movq %rax, 24(%r10) + sbbq 32(%rdi), %rcx + movq 40(%r10), %r8 + movq %rcx, 32(%r10) + sbbq 40(%rdi), %r8 + movq 48(%r10), %rax + movq %r8, 40(%r10) + sbbq 48(%rdi), %rax + movq 56(%r10), %rcx + movq %rax, 48(%r10) + sbbq 56(%rdi), %rcx + movq 64(%r10), %r8 + movq %rcx, 56(%r10) + sbbq 64(%rdi), %r8 + movq 72(%r10), %rax + movq %r8, 64(%r10) + sbbq 72(%rdi), %rax + movq 80(%r10), %rcx + movq %rax, 72(%r10) + sbbq 80(%rdi), %rcx + movq 88(%r10), %r8 + movq %rcx, 80(%r10) + sbbq 88(%rdi), %r8 + movq 96(%r10), %rax + movq %r8, 88(%r10) + sbbq 96(%rdi), %rax + movq 104(%r10), %rcx + movq %rax, 96(%r10) + sbbq 104(%rdi), %rcx + movq 112(%r10), %r8 + movq %rcx, 104(%r10) + sbbq 112(%rdi), %r8 + movq 120(%r10), %rax + movq %r8, 112(%r10) + sbbq 120(%rdi), %rax + movq 128(%r10), %rcx + movq %rax, 120(%r10) + sbbq 128(%rdi), %rcx + movq 136(%r10), %r8 + movq %rcx, 128(%r10) + sbbq 136(%rdi), %r8 + movq 144(%r10), %rax + movq %r8, 136(%r10) + sbbq 144(%rdi), %rax + movq 152(%r10), %rcx + movq %rax, 144(%r10) + sbbq 152(%rdi), %rcx + movq 160(%r10), %r8 + movq %rcx, 152(%r10) + sbbq 160(%rdi), %r8 + movq 168(%r10), %rax + movq %r8, 160(%r10) + sbbq 168(%rdi), %rax + movq 176(%r10), %rcx + movq %rax, 168(%r10) + sbbq 176(%rdi), %rcx + movq 184(%r10), %r8 + movq %rcx, 176(%r10) + sbbq 184(%rdi), %r8 + movq 192(%r10), %rax + movq %r8, 184(%r10) + sbbq 192(%rdi), %rax + movq 200(%r10), %rcx + movq %rax, 192(%r10) + sbbq 200(%rdi), %rcx + movq 208(%r10), %r8 + movq %rcx, 200(%r10) + sbbq 208(%rdi), %r8 + movq 216(%r10), %rax + movq %r8, 208(%r10) + sbbq 216(%rdi), %rax + movq 224(%r10), %rcx + movq %rax, 216(%r10) + sbbq 224(%rdi), %rcx + movq 232(%r10), %r8 + movq %rcx, 224(%r10) + sbbq 232(%rdi), %r8 + movq 240(%r10), %rax + movq %r8, 232(%r10) + sbbq 240(%rdi), %rax + movq 248(%r10), %rcx + movq %rax, 240(%r10) + sbbq 248(%rdi), %rcx + movq 256(%r10), %r8 + movq %rcx, 248(%r10) + sbbq 256(%rdi), %r8 + movq 264(%r10), %rax + movq %r8, 256(%r10) + sbbq 264(%rdi), %rax + movq 272(%r10), %rcx + movq %rax, 264(%r10) + sbbq 272(%rdi), %rcx + movq 280(%r10), %r8 + movq %rcx, 272(%r10) + sbbq 280(%rdi), %r8 + movq 288(%r10), %rax + movq %r8, 280(%r10) + sbbq 288(%rdi), %rax + movq 296(%r10), %rcx + movq %rax, 288(%r10) + sbbq 296(%rdi), %rcx + movq 304(%r10), %r8 + movq %rcx, 296(%r10) + sbbq 304(%rdi), %r8 + movq 312(%r10), %rax + movq %r8, 304(%r10) + sbbq 312(%rdi), %rax + movq 320(%r10), %rcx + movq %rax, 312(%r10) + sbbq 320(%rdi), %rcx + movq 328(%r10), %r8 + movq %rcx, 320(%r10) + sbbq 328(%rdi), %r8 + movq 336(%r10), %rax + movq %r8, 328(%r10) + sbbq 336(%rdi), %rax + movq 344(%r10), %rcx + movq %rax, 336(%r10) + sbbq 344(%rdi), %rcx + movq 352(%r10), %r8 + movq %rcx, 344(%r10) + sbbq 352(%rdi), %r8 + movq 360(%r10), %rax + movq %r8, 352(%r10) + sbbq 360(%rdi), %rax + movq 368(%r10), %rcx + movq %rax, 360(%r10) + sbbq 368(%rdi), %rcx + movq 376(%r10), %r8 + movq %rcx, 368(%r10) + sbbq 376(%rdi), %r8 + movq 384(%r10), %rax + movq %r8, 376(%r10) + sbbq 384(%rdi), %rax + movq 392(%r10), %rcx + movq %rax, 384(%r10) + sbbq 392(%rdi), %rcx + movq 400(%r10), %r8 + movq %rcx, 392(%r10) + sbbq 400(%rdi), %r8 + movq 408(%r10), %rax + movq %r8, 400(%r10) + sbbq 408(%rdi), %rax + movq 416(%r10), %rcx + movq %rax, 408(%r10) + sbbq 416(%rdi), %rcx + movq 424(%r10), %r8 + movq %rcx, 416(%r10) + sbbq 424(%rdi), %r8 + movq 432(%r10), %rax + movq %r8, 424(%r10) + sbbq 432(%rdi), %rax + movq 440(%r10), %rcx + movq %rax, 432(%r10) + sbbq 440(%rdi), %rcx + movq 448(%r10), %r8 + movq %rcx, 440(%r10) + sbbq 448(%rdi), %r8 + movq 456(%r10), %rax + movq %r8, 448(%r10) + sbbq 456(%rdi), %rax + movq 464(%r10), %rcx + movq %rax, 456(%r10) + sbbq 464(%rdi), %rcx + movq 472(%r10), %r8 + movq %rcx, 464(%r10) + sbbq 472(%rdi), %r8 + movq 480(%r10), %rax + movq %r8, 472(%r10) + sbbq 480(%rdi), %rax + movq 488(%r10), %rcx + movq %rax, 480(%r10) + sbbq 488(%rdi), %rcx + movq 496(%r10), %r8 + movq %rcx, 488(%r10) + sbbq 496(%rdi), %r8 + movq 504(%r10), %rax + movq %r8, 496(%r10) + sbbq 504(%rdi), %rax + movq %rax, 504(%r10) + sbbq $0, %r9 + subq $256, %r15 + # Add + movq (%r15), %rax + addq (%r10), %rax + movq 8(%r15), %rcx + movq %rax, (%r15) + adcq 8(%r10), %rcx + movq 16(%r15), %r8 + movq %rcx, 8(%r15) + adcq 16(%r10), %r8 + movq 24(%r15), %rax + movq %r8, 16(%r15) + adcq 24(%r10), %rax + movq 32(%r15), %rcx + movq %rax, 24(%r15) + adcq 32(%r10), %rcx + movq 40(%r15), %r8 + movq %rcx, 32(%r15) + adcq 40(%r10), %r8 + movq 48(%r15), %rax + movq %r8, 40(%r15) + adcq 48(%r10), %rax + movq 56(%r15), %rcx + movq %rax, 48(%r15) + adcq 56(%r10), %rcx + movq 64(%r15), %r8 + movq %rcx, 56(%r15) + adcq 64(%r10), %r8 + movq 72(%r15), %rax + movq %r8, 64(%r15) + adcq 72(%r10), %rax + movq 80(%r15), %rcx + movq %rax, 72(%r15) + adcq 80(%r10), %rcx + movq 88(%r15), %r8 + movq %rcx, 80(%r15) + adcq 88(%r10), %r8 + movq 96(%r15), %rax + movq %r8, 88(%r15) + adcq 96(%r10), %rax + movq 104(%r15), %rcx + movq %rax, 96(%r15) + adcq 104(%r10), %rcx + movq 112(%r15), %r8 + movq %rcx, 104(%r15) + adcq 112(%r10), %r8 + movq 120(%r15), %rax + movq %r8, 112(%r15) + adcq 120(%r10), %rax + movq 128(%r15), %rcx + movq %rax, 120(%r15) + adcq 128(%r10), %rcx + movq 136(%r15), %r8 + movq %rcx, 128(%r15) + adcq 136(%r10), %r8 + movq 144(%r15), %rax + movq %r8, 136(%r15) + adcq 144(%r10), %rax + movq 152(%r15), %rcx + movq %rax, 144(%r15) + adcq 152(%r10), %rcx + movq 160(%r15), %r8 + movq %rcx, 152(%r15) + adcq 160(%r10), %r8 + movq 168(%r15), %rax + movq %r8, 160(%r15) + adcq 168(%r10), %rax + movq 176(%r15), %rcx + movq %rax, 168(%r15) + adcq 176(%r10), %rcx + movq 184(%r15), %r8 + movq %rcx, 176(%r15) + adcq 184(%r10), %r8 + movq 192(%r15), %rax + movq %r8, 184(%r15) + adcq 192(%r10), %rax + movq 200(%r15), %rcx + movq %rax, 192(%r15) + adcq 200(%r10), %rcx + movq 208(%r15), %r8 + movq %rcx, 200(%r15) + adcq 208(%r10), %r8 + movq 216(%r15), %rax + movq %r8, 208(%r15) + adcq 216(%r10), %rax + movq 224(%r15), %rcx + movq %rax, 216(%r15) + adcq 224(%r10), %rcx + movq 232(%r15), %r8 + movq %rcx, 224(%r15) + adcq 232(%r10), %r8 + movq 240(%r15), %rax + movq %r8, 232(%r15) + adcq 240(%r10), %rax + movq 248(%r15), %rcx + movq %rax, 240(%r15) + adcq 248(%r10), %rcx + movq 256(%r15), %r8 + movq %rcx, 248(%r15) + adcq 256(%r10), %r8 + movq 264(%r15), %rax + movq %r8, 256(%r15) + adcq 264(%r10), %rax + movq 272(%r15), %rcx + movq %rax, 264(%r15) + adcq 272(%r10), %rcx + movq 280(%r15), %r8 + movq %rcx, 272(%r15) + adcq 280(%r10), %r8 + movq 288(%r15), %rax + movq %r8, 280(%r15) + adcq 288(%r10), %rax + movq 296(%r15), %rcx + movq %rax, 288(%r15) + adcq 296(%r10), %rcx + movq 304(%r15), %r8 + movq %rcx, 296(%r15) + adcq 304(%r10), %r8 + movq 312(%r15), %rax + movq %r8, 304(%r15) + adcq 312(%r10), %rax + movq 320(%r15), %rcx + movq %rax, 312(%r15) + adcq 320(%r10), %rcx + movq 328(%r15), %r8 + movq %rcx, 320(%r15) + adcq 328(%r10), %r8 + movq 336(%r15), %rax + movq %r8, 328(%r15) + adcq 336(%r10), %rax + movq 344(%r15), %rcx + movq %rax, 336(%r15) + adcq 344(%r10), %rcx + movq 352(%r15), %r8 + movq %rcx, 344(%r15) + adcq 352(%r10), %r8 + movq 360(%r15), %rax + movq %r8, 352(%r15) + adcq 360(%r10), %rax + movq 368(%r15), %rcx + movq %rax, 360(%r15) + adcq 368(%r10), %rcx + movq 376(%r15), %r8 + movq %rcx, 368(%r15) + adcq 376(%r10), %r8 + movq 384(%r15), %rax + movq %r8, 376(%r15) + adcq 384(%r10), %rax + movq 392(%r15), %rcx + movq %rax, 384(%r15) + adcq 392(%r10), %rcx + movq 400(%r15), %r8 + movq %rcx, 392(%r15) + adcq 400(%r10), %r8 + movq 408(%r15), %rax + movq %r8, 400(%r15) + adcq 408(%r10), %rax + movq 416(%r15), %rcx + movq %rax, 408(%r15) + adcq 416(%r10), %rcx + movq 424(%r15), %r8 + movq %rcx, 416(%r15) + adcq 424(%r10), %r8 + movq 432(%r15), %rax + movq %r8, 424(%r15) + adcq 432(%r10), %rax + movq 440(%r15), %rcx + movq %rax, 432(%r15) + adcq 440(%r10), %rcx + movq 448(%r15), %r8 + movq %rcx, 440(%r15) + adcq 448(%r10), %r8 + movq 456(%r15), %rax + movq %r8, 448(%r15) + adcq 456(%r10), %rax + movq 464(%r15), %rcx + movq %rax, 456(%r15) + adcq 464(%r10), %rcx + movq 472(%r15), %r8 + movq %rcx, 464(%r15) + adcq 472(%r10), %r8 + movq 480(%r15), %rax + movq %r8, 472(%r15) + adcq 480(%r10), %rax + movq 488(%r15), %rcx + movq %rax, 480(%r15) + adcq 488(%r10), %rcx + movq 496(%r15), %r8 + movq %rcx, 488(%r15) + adcq 496(%r10), %r8 + movq 504(%r15), %rax + movq %r8, 496(%r15) + adcq 504(%r10), %rax + movq %rax, 504(%r15) + adcq $0, %r9 + movq %r9, 768(%rdi) + addq $256, %r15 + # Add + movq (%r15), %rax + xorq %r9, %r9 + addq (%r11), %rax + movq 8(%r15), %rcx + movq %rax, (%r15) + adcq 8(%r11), %rcx + movq 16(%r15), %r8 + movq %rcx, 8(%r15) + adcq 16(%r11), %r8 + movq 24(%r15), %rax + movq %r8, 16(%r15) + adcq 24(%r11), %rax + movq 32(%r15), %rcx + movq %rax, 24(%r15) + adcq 32(%r11), %rcx + movq 40(%r15), %r8 + movq %rcx, 32(%r15) + adcq 40(%r11), %r8 + movq 48(%r15), %rax + movq %r8, 40(%r15) + adcq 48(%r11), %rax + movq 56(%r15), %rcx + movq %rax, 48(%r15) + adcq 56(%r11), %rcx + movq 64(%r15), %r8 + movq %rcx, 56(%r15) + adcq 64(%r11), %r8 + movq 72(%r15), %rax + movq %r8, 64(%r15) + adcq 72(%r11), %rax + movq 80(%r15), %rcx + movq %rax, 72(%r15) + adcq 80(%r11), %rcx + movq 88(%r15), %r8 + movq %rcx, 80(%r15) + adcq 88(%r11), %r8 + movq 96(%r15), %rax + movq %r8, 88(%r15) + adcq 96(%r11), %rax + movq 104(%r15), %rcx + movq %rax, 96(%r15) + adcq 104(%r11), %rcx + movq 112(%r15), %r8 + movq %rcx, 104(%r15) + adcq 112(%r11), %r8 + movq 120(%r15), %rax + movq %r8, 112(%r15) + adcq 120(%r11), %rax + movq 128(%r15), %rcx + movq %rax, 120(%r15) + adcq 128(%r11), %rcx + movq 136(%r15), %r8 + movq %rcx, 128(%r15) + adcq 136(%r11), %r8 + movq 144(%r15), %rax + movq %r8, 136(%r15) + adcq 144(%r11), %rax + movq 152(%r15), %rcx + movq %rax, 144(%r15) + adcq 152(%r11), %rcx + movq 160(%r15), %r8 + movq %rcx, 152(%r15) + adcq 160(%r11), %r8 + movq 168(%r15), %rax + movq %r8, 160(%r15) + adcq 168(%r11), %rax + movq 176(%r15), %rcx + movq %rax, 168(%r15) + adcq 176(%r11), %rcx + movq 184(%r15), %r8 + movq %rcx, 176(%r15) + adcq 184(%r11), %r8 + movq 192(%r15), %rax + movq %r8, 184(%r15) + adcq 192(%r11), %rax + movq 200(%r15), %rcx + movq %rax, 192(%r15) + adcq 200(%r11), %rcx + movq 208(%r15), %r8 + movq %rcx, 200(%r15) + adcq 208(%r11), %r8 + movq 216(%r15), %rax + movq %r8, 208(%r15) + adcq 216(%r11), %rax + movq 224(%r15), %rcx + movq %rax, 216(%r15) + adcq 224(%r11), %rcx + movq 232(%r15), %r8 + movq %rcx, 224(%r15) + adcq 232(%r11), %r8 + movq 240(%r15), %rax + movq %r8, 232(%r15) + adcq 240(%r11), %rax + movq 248(%r15), %rcx + movq %rax, 240(%r15) + adcq 248(%r11), %rcx + movq 256(%r15), %r8 + movq %rcx, 248(%r15) + adcq 256(%r11), %r8 + movq %r8, 256(%r15) + adcq $0, %r9 + # Add to zero + movq 264(%r11), %rax + adcq $0, %rax + movq 272(%r11), %rcx + movq %rax, 264(%r15) + adcq $0, %rcx + movq 280(%r11), %r8 + movq %rcx, 272(%r15) + adcq $0, %r8 + movq 288(%r11), %rax + movq %r8, 280(%r15) + adcq $0, %rax + movq 296(%r11), %rcx + movq %rax, 288(%r15) + adcq $0, %rcx + movq 304(%r11), %r8 + movq %rcx, 296(%r15) + adcq $0, %r8 + movq 312(%r11), %rax + movq %r8, 304(%r15) + adcq $0, %rax + movq 320(%r11), %rcx + movq %rax, 312(%r15) + adcq $0, %rcx + movq 328(%r11), %r8 + movq %rcx, 320(%r15) + adcq $0, %r8 + movq 336(%r11), %rax + movq %r8, 328(%r15) + adcq $0, %rax + movq 344(%r11), %rcx + movq %rax, 336(%r15) + adcq $0, %rcx + movq 352(%r11), %r8 + movq %rcx, 344(%r15) + adcq $0, %r8 + movq 360(%r11), %rax + movq %r8, 352(%r15) + adcq $0, %rax + movq 368(%r11), %rcx + movq %rax, 360(%r15) + adcq $0, %rcx + movq 376(%r11), %r8 + movq %rcx, 368(%r15) + adcq $0, %r8 + movq 384(%r11), %rax + movq %r8, 376(%r15) + adcq $0, %rax + movq 392(%r11), %rcx + movq %rax, 384(%r15) + adcq $0, %rcx + movq 400(%r11), %r8 + movq %rcx, 392(%r15) + adcq $0, %r8 + movq 408(%r11), %rax + movq %r8, 400(%r15) + adcq $0, %rax + movq 416(%r11), %rcx + movq %rax, 408(%r15) + adcq $0, %rcx + movq 424(%r11), %r8 + movq %rcx, 416(%r15) + adcq $0, %r8 + movq 432(%r11), %rax + movq %r8, 424(%r15) + adcq $0, %rax + movq 440(%r11), %rcx + movq %rax, 432(%r15) + adcq $0, %rcx + movq 448(%r11), %r8 + movq %rcx, 440(%r15) + adcq $0, %r8 + movq 456(%r11), %rax + movq %r8, 448(%r15) + adcq $0, %rax + movq 464(%r11), %rcx + movq %rax, 456(%r15) + adcq $0, %rcx + movq 472(%r11), %r8 + movq %rcx, 464(%r15) + adcq $0, %r8 + movq 480(%r11), %rax + movq %r8, 472(%r15) + adcq $0, %rax + movq 488(%r11), %rcx + movq %rax, 480(%r15) + adcq $0, %rcx + movq 496(%r11), %r8 + movq %rcx, 488(%r15) + adcq $0, %r8 + movq 504(%r11), %rax + movq %r8, 496(%r15) + adcq $0, %rax + movq %rax, 504(%r15) + addq $1576, %rsp + pop %r15 + pop %r14 + pop %r13 + pop %r12 + repz retq +#ifndef __APPLE__ +.size sp_4096_mul_avx2_64,.-sp_4096_mul_avx2_64 +#endif /* __APPLE__ */ +/* Square a and put result in r. (r = a * a) + * + * r A single precision integer. + * a A single precision integer. + */ +#ifndef __APPLE__ +.globl sp_4096_sqr_avx2_64 +.type sp_4096_sqr_avx2_64,@function +.align 16 +sp_4096_sqr_avx2_64: +#else +.globl _sp_4096_sqr_avx2_64 +.p2align 4 +_sp_4096_sqr_avx2_64: +#endif /* __APPLE__ */ + subq $1304, %rsp + movq %rdi, 1280(%rsp) + movq %rsi, 1288(%rsp) + leaq 1024(%rsp), %r8 + leaq 256(%rsi), %r9 + # Add + movq (%rsi), %rdx + xorq %rcx, %rcx + addq (%r9), %rdx + movq 8(%rsi), %rax + movq %rdx, (%r8) + adcq 8(%r9), %rax + movq 16(%rsi), %rdx + movq %rax, 8(%r8) + adcq 16(%r9), %rdx + movq 24(%rsi), %rax + movq %rdx, 16(%r8) + adcq 24(%r9), %rax + movq 32(%rsi), %rdx + movq %rax, 24(%r8) + adcq 32(%r9), %rdx + movq 40(%rsi), %rax + movq %rdx, 32(%r8) + adcq 40(%r9), %rax + movq 48(%rsi), %rdx + movq %rax, 40(%r8) + adcq 48(%r9), %rdx + movq 56(%rsi), %rax + movq %rdx, 48(%r8) + adcq 56(%r9), %rax + movq 64(%rsi), %rdx + movq %rax, 56(%r8) + adcq 64(%r9), %rdx + movq 72(%rsi), %rax + movq %rdx, 64(%r8) + adcq 72(%r9), %rax + movq 80(%rsi), %rdx + movq %rax, 72(%r8) + adcq 80(%r9), %rdx + movq 88(%rsi), %rax + movq %rdx, 80(%r8) + adcq 88(%r9), %rax + movq 96(%rsi), %rdx + movq %rax, 88(%r8) + adcq 96(%r9), %rdx + movq 104(%rsi), %rax + movq %rdx, 96(%r8) + adcq 104(%r9), %rax + movq 112(%rsi), %rdx + movq %rax, 104(%r8) + adcq 112(%r9), %rdx + movq 120(%rsi), %rax + movq %rdx, 112(%r8) + adcq 120(%r9), %rax + movq 128(%rsi), %rdx + movq %rax, 120(%r8) + adcq 128(%r9), %rdx + movq 136(%rsi), %rax + movq %rdx, 128(%r8) + adcq 136(%r9), %rax + movq 144(%rsi), %rdx + movq %rax, 136(%r8) + adcq 144(%r9), %rdx + movq 152(%rsi), %rax + movq %rdx, 144(%r8) + adcq 152(%r9), %rax + movq 160(%rsi), %rdx + movq %rax, 152(%r8) + adcq 160(%r9), %rdx + movq 168(%rsi), %rax + movq %rdx, 160(%r8) + adcq 168(%r9), %rax + movq 176(%rsi), %rdx + movq %rax, 168(%r8) + adcq 176(%r9), %rdx + movq 184(%rsi), %rax + movq %rdx, 176(%r8) + adcq 184(%r9), %rax + movq 192(%rsi), %rdx + movq %rax, 184(%r8) + adcq 192(%r9), %rdx + movq 200(%rsi), %rax + movq %rdx, 192(%r8) + adcq 200(%r9), %rax + movq 208(%rsi), %rdx + movq %rax, 200(%r8) + adcq 208(%r9), %rdx + movq 216(%rsi), %rax + movq %rdx, 208(%r8) + adcq 216(%r9), %rax + movq 224(%rsi), %rdx + movq %rax, 216(%r8) + adcq 224(%r9), %rdx + movq 232(%rsi), %rax + movq %rdx, 224(%r8) + adcq 232(%r9), %rax + movq 240(%rsi), %rdx + movq %rax, 232(%r8) + adcq 240(%r9), %rdx + movq 248(%rsi), %rax + movq %rdx, 240(%r8) + adcq 248(%r9), %rax + movq %rax, 248(%r8) + adcq $0, %rcx + movq %rcx, 1296(%rsp) + movq %r8, %rsi + movq %rsp, %rdi +#ifndef __APPLE__ + callq sp_2048_sqr_avx2_32@plt +#else + callq _sp_2048_sqr_avx2_32 +#endif /* __APPLE__ */ + movq 1288(%rsp), %rsi + leaq 512(%rsp), %rdi + addq $256, %rsi +#ifndef __APPLE__ + callq sp_2048_sqr_avx2_32@plt +#else + callq _sp_2048_sqr_avx2_32 +#endif /* __APPLE__ */ + movq 1288(%rsp), %rsi + movq 1280(%rsp), %rdi +#ifndef __APPLE__ + callq sp_2048_sqr_avx2_32@plt +#else + callq _sp_2048_sqr_avx2_32 +#endif /* __APPLE__ */ + movq 1296(%rsp), %r10 + leaq 1024(%rsp), %r8 + movq %r10, %rcx + negq %r10 + movq (%r8), %rdx + pextq %r10, %rdx, %rdx + addq %rdx, %rdx + movq 8(%r8), %rax + movq %rdx, 512(%rdi) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 16(%r8), %rdx + movq %rax, 520(%rdi) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 24(%r8), %rax + movq %rdx, 528(%rdi) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 32(%r8), %rdx + movq %rax, 536(%rdi) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 40(%r8), %rax + movq %rdx, 544(%rdi) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 48(%r8), %rdx + movq %rax, 552(%rdi) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 56(%r8), %rax + movq %rdx, 560(%rdi) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 64(%r8), %rdx + movq %rax, 568(%rdi) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 72(%r8), %rax + movq %rdx, 576(%rdi) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 80(%r8), %rdx + movq %rax, 584(%rdi) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 88(%r8), %rax + movq %rdx, 592(%rdi) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 96(%r8), %rdx + movq %rax, 600(%rdi) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 104(%r8), %rax + movq %rdx, 608(%rdi) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 112(%r8), %rdx + movq %rax, 616(%rdi) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 120(%r8), %rax + movq %rdx, 624(%rdi) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 128(%r8), %rdx + movq %rax, 632(%rdi) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 136(%r8), %rax + movq %rdx, 640(%rdi) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 144(%r8), %rdx + movq %rax, 648(%rdi) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 152(%r8), %rax + movq %rdx, 656(%rdi) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 160(%r8), %rdx + movq %rax, 664(%rdi) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 168(%r8), %rax + movq %rdx, 672(%rdi) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 176(%r8), %rdx + movq %rax, 680(%rdi) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 184(%r8), %rax + movq %rdx, 688(%rdi) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 192(%r8), %rdx + movq %rax, 696(%rdi) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 200(%r8), %rax + movq %rdx, 704(%rdi) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 208(%r8), %rdx + movq %rax, 712(%rdi) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 216(%r8), %rax + movq %rdx, 720(%rdi) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 224(%r8), %rdx + movq %rax, 728(%rdi) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 232(%r8), %rax + movq %rdx, 736(%rdi) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq 240(%r8), %rdx + movq %rax, 744(%rdi) + pextq %r10, %rdx, %rdx + adcq %rdx, %rdx + movq 248(%r8), %rax + movq %rdx, 752(%rdi) + pextq %r10, %rax, %rax + adcq %rax, %rax + movq %rax, 760(%rdi) + adcq $0, %rcx + leaq 512(%rsp), %rsi + movq %rsp, %r8 + movq (%r8), %rdx + subq (%rsi), %rdx + movq 8(%r8), %rax + movq %rdx, (%r8) + sbbq 8(%rsi), %rax + movq 16(%r8), %rdx + movq %rax, 8(%r8) + sbbq 16(%rsi), %rdx + movq 24(%r8), %rax + movq %rdx, 16(%r8) + sbbq 24(%rsi), %rax + movq 32(%r8), %rdx + movq %rax, 24(%r8) + sbbq 32(%rsi), %rdx + movq 40(%r8), %rax + movq %rdx, 32(%r8) + sbbq 40(%rsi), %rax + movq 48(%r8), %rdx + movq %rax, 40(%r8) + sbbq 48(%rsi), %rdx + movq 56(%r8), %rax + movq %rdx, 48(%r8) + sbbq 56(%rsi), %rax + movq 64(%r8), %rdx + movq %rax, 56(%r8) + sbbq 64(%rsi), %rdx + movq 72(%r8), %rax + movq %rdx, 64(%r8) + sbbq 72(%rsi), %rax + movq 80(%r8), %rdx + movq %rax, 72(%r8) + sbbq 80(%rsi), %rdx + movq 88(%r8), %rax + movq %rdx, 80(%r8) + sbbq 88(%rsi), %rax + movq 96(%r8), %rdx + movq %rax, 88(%r8) + sbbq 96(%rsi), %rdx + movq 104(%r8), %rax + movq %rdx, 96(%r8) + sbbq 104(%rsi), %rax + movq 112(%r8), %rdx + movq %rax, 104(%r8) + sbbq 112(%rsi), %rdx + movq 120(%r8), %rax + movq %rdx, 112(%r8) + sbbq 120(%rsi), %rax + movq 128(%r8), %rdx + movq %rax, 120(%r8) + sbbq 128(%rsi), %rdx + movq 136(%r8), %rax + movq %rdx, 128(%r8) + sbbq 136(%rsi), %rax + movq 144(%r8), %rdx + movq %rax, 136(%r8) + sbbq 144(%rsi), %rdx + movq 152(%r8), %rax + movq %rdx, 144(%r8) + sbbq 152(%rsi), %rax + movq 160(%r8), %rdx + movq %rax, 152(%r8) + sbbq 160(%rsi), %rdx + movq 168(%r8), %rax + movq %rdx, 160(%r8) + sbbq 168(%rsi), %rax + movq 176(%r8), %rdx + movq %rax, 168(%r8) + sbbq 176(%rsi), %rdx + movq 184(%r8), %rax + movq %rdx, 176(%r8) + sbbq 184(%rsi), %rax + movq 192(%r8), %rdx + movq %rax, 184(%r8) + sbbq 192(%rsi), %rdx + movq 200(%r8), %rax + movq %rdx, 192(%r8) + sbbq 200(%rsi), %rax + movq 208(%r8), %rdx + movq %rax, 200(%r8) + sbbq 208(%rsi), %rdx + movq 216(%r8), %rax + movq %rdx, 208(%r8) + sbbq 216(%rsi), %rax + movq 224(%r8), %rdx + movq %rax, 216(%r8) + sbbq 224(%rsi), %rdx + movq 232(%r8), %rax + movq %rdx, 224(%r8) + sbbq 232(%rsi), %rax + movq 240(%r8), %rdx + movq %rax, 232(%r8) + sbbq 240(%rsi), %rdx + movq 248(%r8), %rax + movq %rdx, 240(%r8) + sbbq 248(%rsi), %rax + movq 256(%r8), %rdx + movq %rax, 248(%r8) + sbbq 256(%rsi), %rdx + movq 264(%r8), %rax + movq %rdx, 256(%r8) + sbbq 264(%rsi), %rax + movq 272(%r8), %rdx + movq %rax, 264(%r8) + sbbq 272(%rsi), %rdx + movq 280(%r8), %rax + movq %rdx, 272(%r8) + sbbq 280(%rsi), %rax + movq 288(%r8), %rdx + movq %rax, 280(%r8) + sbbq 288(%rsi), %rdx + movq 296(%r8), %rax + movq %rdx, 288(%r8) + sbbq 296(%rsi), %rax + movq 304(%r8), %rdx + movq %rax, 296(%r8) + sbbq 304(%rsi), %rdx + movq 312(%r8), %rax + movq %rdx, 304(%r8) + sbbq 312(%rsi), %rax + movq 320(%r8), %rdx + movq %rax, 312(%r8) + sbbq 320(%rsi), %rdx + movq 328(%r8), %rax + movq %rdx, 320(%r8) + sbbq 328(%rsi), %rax + movq 336(%r8), %rdx + movq %rax, 328(%r8) + sbbq 336(%rsi), %rdx + movq 344(%r8), %rax + movq %rdx, 336(%r8) + sbbq 344(%rsi), %rax + movq 352(%r8), %rdx + movq %rax, 344(%r8) + sbbq 352(%rsi), %rdx + movq 360(%r8), %rax + movq %rdx, 352(%r8) + sbbq 360(%rsi), %rax + movq 368(%r8), %rdx + movq %rax, 360(%r8) + sbbq 368(%rsi), %rdx + movq 376(%r8), %rax + movq %rdx, 368(%r8) + sbbq 376(%rsi), %rax + movq 384(%r8), %rdx + movq %rax, 376(%r8) + sbbq 384(%rsi), %rdx + movq 392(%r8), %rax + movq %rdx, 384(%r8) + sbbq 392(%rsi), %rax + movq 400(%r8), %rdx + movq %rax, 392(%r8) + sbbq 400(%rsi), %rdx + movq 408(%r8), %rax + movq %rdx, 400(%r8) + sbbq 408(%rsi), %rax + movq 416(%r8), %rdx + movq %rax, 408(%r8) + sbbq 416(%rsi), %rdx + movq 424(%r8), %rax + movq %rdx, 416(%r8) + sbbq 424(%rsi), %rax + movq 432(%r8), %rdx + movq %rax, 424(%r8) + sbbq 432(%rsi), %rdx + movq 440(%r8), %rax + movq %rdx, 432(%r8) + sbbq 440(%rsi), %rax + movq 448(%r8), %rdx + movq %rax, 440(%r8) + sbbq 448(%rsi), %rdx + movq 456(%r8), %rax + movq %rdx, 448(%r8) + sbbq 456(%rsi), %rax + movq 464(%r8), %rdx + movq %rax, 456(%r8) + sbbq 464(%rsi), %rdx + movq 472(%r8), %rax + movq %rdx, 464(%r8) + sbbq 472(%rsi), %rax + movq 480(%r8), %rdx + movq %rax, 472(%r8) + sbbq 480(%rsi), %rdx + movq 488(%r8), %rax + movq %rdx, 480(%r8) + sbbq 488(%rsi), %rax + movq 496(%r8), %rdx + movq %rax, 488(%r8) + sbbq 496(%rsi), %rdx + movq 504(%r8), %rax + movq %rdx, 496(%r8) + sbbq 504(%rsi), %rax + movq %rax, 504(%r8) + sbbq $0, %rcx + movq (%r8), %rdx + subq (%rdi), %rdx + movq 8(%r8), %rax + movq %rdx, (%r8) + sbbq 8(%rdi), %rax + movq 16(%r8), %rdx + movq %rax, 8(%r8) + sbbq 16(%rdi), %rdx + movq 24(%r8), %rax + movq %rdx, 16(%r8) + sbbq 24(%rdi), %rax + movq 32(%r8), %rdx + movq %rax, 24(%r8) + sbbq 32(%rdi), %rdx + movq 40(%r8), %rax + movq %rdx, 32(%r8) + sbbq 40(%rdi), %rax + movq 48(%r8), %rdx + movq %rax, 40(%r8) + sbbq 48(%rdi), %rdx + movq 56(%r8), %rax + movq %rdx, 48(%r8) + sbbq 56(%rdi), %rax + movq 64(%r8), %rdx + movq %rax, 56(%r8) + sbbq 64(%rdi), %rdx + movq 72(%r8), %rax + movq %rdx, 64(%r8) + sbbq 72(%rdi), %rax + movq 80(%r8), %rdx + movq %rax, 72(%r8) + sbbq 80(%rdi), %rdx + movq 88(%r8), %rax + movq %rdx, 80(%r8) + sbbq 88(%rdi), %rax + movq 96(%r8), %rdx + movq %rax, 88(%r8) + sbbq 96(%rdi), %rdx + movq 104(%r8), %rax + movq %rdx, 96(%r8) + sbbq 104(%rdi), %rax + movq 112(%r8), %rdx + movq %rax, 104(%r8) + sbbq 112(%rdi), %rdx + movq 120(%r8), %rax + movq %rdx, 112(%r8) + sbbq 120(%rdi), %rax + movq 128(%r8), %rdx + movq %rax, 120(%r8) + sbbq 128(%rdi), %rdx + movq 136(%r8), %rax + movq %rdx, 128(%r8) + sbbq 136(%rdi), %rax + movq 144(%r8), %rdx + movq %rax, 136(%r8) + sbbq 144(%rdi), %rdx + movq 152(%r8), %rax + movq %rdx, 144(%r8) + sbbq 152(%rdi), %rax + movq 160(%r8), %rdx + movq %rax, 152(%r8) + sbbq 160(%rdi), %rdx + movq 168(%r8), %rax + movq %rdx, 160(%r8) + sbbq 168(%rdi), %rax + movq 176(%r8), %rdx + movq %rax, 168(%r8) + sbbq 176(%rdi), %rdx + movq 184(%r8), %rax + movq %rdx, 176(%r8) + sbbq 184(%rdi), %rax + movq 192(%r8), %rdx + movq %rax, 184(%r8) + sbbq 192(%rdi), %rdx + movq 200(%r8), %rax + movq %rdx, 192(%r8) + sbbq 200(%rdi), %rax + movq 208(%r8), %rdx + movq %rax, 200(%r8) + sbbq 208(%rdi), %rdx + movq 216(%r8), %rax + movq %rdx, 208(%r8) + sbbq 216(%rdi), %rax + movq 224(%r8), %rdx + movq %rax, 216(%r8) + sbbq 224(%rdi), %rdx + movq 232(%r8), %rax + movq %rdx, 224(%r8) + sbbq 232(%rdi), %rax + movq 240(%r8), %rdx + movq %rax, 232(%r8) + sbbq 240(%rdi), %rdx + movq 248(%r8), %rax + movq %rdx, 240(%r8) + sbbq 248(%rdi), %rax + movq 256(%r8), %rdx + movq %rax, 248(%r8) + sbbq 256(%rdi), %rdx + movq 264(%r8), %rax + movq %rdx, 256(%r8) + sbbq 264(%rdi), %rax + movq 272(%r8), %rdx + movq %rax, 264(%r8) + sbbq 272(%rdi), %rdx + movq 280(%r8), %rax + movq %rdx, 272(%r8) + sbbq 280(%rdi), %rax + movq 288(%r8), %rdx + movq %rax, 280(%r8) + sbbq 288(%rdi), %rdx + movq 296(%r8), %rax + movq %rdx, 288(%r8) + sbbq 296(%rdi), %rax + movq 304(%r8), %rdx + movq %rax, 296(%r8) + sbbq 304(%rdi), %rdx + movq 312(%r8), %rax + movq %rdx, 304(%r8) + sbbq 312(%rdi), %rax + movq 320(%r8), %rdx + movq %rax, 312(%r8) + sbbq 320(%rdi), %rdx + movq 328(%r8), %rax + movq %rdx, 320(%r8) + sbbq 328(%rdi), %rax + movq 336(%r8), %rdx + movq %rax, 328(%r8) + sbbq 336(%rdi), %rdx + movq 344(%r8), %rax + movq %rdx, 336(%r8) + sbbq 344(%rdi), %rax + movq 352(%r8), %rdx + movq %rax, 344(%r8) + sbbq 352(%rdi), %rdx + movq 360(%r8), %rax + movq %rdx, 352(%r8) + sbbq 360(%rdi), %rax + movq 368(%r8), %rdx + movq %rax, 360(%r8) + sbbq 368(%rdi), %rdx + movq 376(%r8), %rax + movq %rdx, 368(%r8) + sbbq 376(%rdi), %rax + movq 384(%r8), %rdx + movq %rax, 376(%r8) + sbbq 384(%rdi), %rdx + movq 392(%r8), %rax + movq %rdx, 384(%r8) + sbbq 392(%rdi), %rax + movq 400(%r8), %rdx + movq %rax, 392(%r8) + sbbq 400(%rdi), %rdx + movq 408(%r8), %rax + movq %rdx, 400(%r8) + sbbq 408(%rdi), %rax + movq 416(%r8), %rdx + movq %rax, 408(%r8) + sbbq 416(%rdi), %rdx + movq 424(%r8), %rax + movq %rdx, 416(%r8) + sbbq 424(%rdi), %rax + movq 432(%r8), %rdx + movq %rax, 424(%r8) + sbbq 432(%rdi), %rdx + movq 440(%r8), %rax + movq %rdx, 432(%r8) + sbbq 440(%rdi), %rax + movq 448(%r8), %rdx + movq %rax, 440(%r8) + sbbq 448(%rdi), %rdx + movq 456(%r8), %rax + movq %rdx, 448(%r8) + sbbq 456(%rdi), %rax + movq 464(%r8), %rdx + movq %rax, 456(%r8) + sbbq 464(%rdi), %rdx + movq 472(%r8), %rax + movq %rdx, 464(%r8) + sbbq 472(%rdi), %rax + movq 480(%r8), %rdx + movq %rax, 472(%r8) + sbbq 480(%rdi), %rdx + movq 488(%r8), %rax + movq %rdx, 480(%r8) + sbbq 488(%rdi), %rax + movq 496(%r8), %rdx + movq %rax, 488(%r8) + sbbq 496(%rdi), %rdx + movq 504(%r8), %rax + movq %rdx, 496(%r8) + sbbq 504(%rdi), %rax + movq %rax, 504(%r8) + sbbq $0, %rcx + # Add in place + movq 256(%rdi), %rdx + addq (%r8), %rdx + movq 264(%rdi), %rax + movq %rdx, 256(%rdi) + adcq 8(%r8), %rax + movq 272(%rdi), %rdx + movq %rax, 264(%rdi) + adcq 16(%r8), %rdx + movq 280(%rdi), %rax + movq %rdx, 272(%rdi) + adcq 24(%r8), %rax + movq 288(%rdi), %rdx + movq %rax, 280(%rdi) + adcq 32(%r8), %rdx + movq 296(%rdi), %rax + movq %rdx, 288(%rdi) + adcq 40(%r8), %rax + movq 304(%rdi), %rdx + movq %rax, 296(%rdi) + adcq 48(%r8), %rdx + movq 312(%rdi), %rax + movq %rdx, 304(%rdi) + adcq 56(%r8), %rax + movq 320(%rdi), %rdx + movq %rax, 312(%rdi) + adcq 64(%r8), %rdx + movq 328(%rdi), %rax + movq %rdx, 320(%rdi) + adcq 72(%r8), %rax + movq 336(%rdi), %rdx + movq %rax, 328(%rdi) + adcq 80(%r8), %rdx + movq 344(%rdi), %rax + movq %rdx, 336(%rdi) + adcq 88(%r8), %rax + movq 352(%rdi), %rdx + movq %rax, 344(%rdi) + adcq 96(%r8), %rdx + movq 360(%rdi), %rax + movq %rdx, 352(%rdi) + adcq 104(%r8), %rax + movq 368(%rdi), %rdx + movq %rax, 360(%rdi) + adcq 112(%r8), %rdx + movq 376(%rdi), %rax + movq %rdx, 368(%rdi) + adcq 120(%r8), %rax + movq 384(%rdi), %rdx + movq %rax, 376(%rdi) + adcq 128(%r8), %rdx + movq 392(%rdi), %rax + movq %rdx, 384(%rdi) + adcq 136(%r8), %rax + movq 400(%rdi), %rdx + movq %rax, 392(%rdi) + adcq 144(%r8), %rdx + movq 408(%rdi), %rax + movq %rdx, 400(%rdi) + adcq 152(%r8), %rax + movq 416(%rdi), %rdx + movq %rax, 408(%rdi) + adcq 160(%r8), %rdx + movq 424(%rdi), %rax + movq %rdx, 416(%rdi) + adcq 168(%r8), %rax + movq 432(%rdi), %rdx + movq %rax, 424(%rdi) + adcq 176(%r8), %rdx + movq 440(%rdi), %rax + movq %rdx, 432(%rdi) + adcq 184(%r8), %rax + movq 448(%rdi), %rdx + movq %rax, 440(%rdi) + adcq 192(%r8), %rdx + movq 456(%rdi), %rax + movq %rdx, 448(%rdi) + adcq 200(%r8), %rax + movq 464(%rdi), %rdx + movq %rax, 456(%rdi) + adcq 208(%r8), %rdx + movq 472(%rdi), %rax + movq %rdx, 464(%rdi) + adcq 216(%r8), %rax + movq 480(%rdi), %rdx + movq %rax, 472(%rdi) + adcq 224(%r8), %rdx + movq 488(%rdi), %rax + movq %rdx, 480(%rdi) + adcq 232(%r8), %rax + movq 496(%rdi), %rdx + movq %rax, 488(%rdi) + adcq 240(%r8), %rdx + movq 504(%rdi), %rax + movq %rdx, 496(%rdi) + adcq 248(%r8), %rax + movq 512(%rdi), %rdx + movq %rax, 504(%rdi) + adcq 256(%r8), %rdx + movq 520(%rdi), %rax + movq %rdx, 512(%rdi) + adcq 264(%r8), %rax + movq 528(%rdi), %rdx + movq %rax, 520(%rdi) + adcq 272(%r8), %rdx + movq 536(%rdi), %rax + movq %rdx, 528(%rdi) + adcq 280(%r8), %rax + movq 544(%rdi), %rdx + movq %rax, 536(%rdi) + adcq 288(%r8), %rdx + movq 552(%rdi), %rax + movq %rdx, 544(%rdi) + adcq 296(%r8), %rax + movq 560(%rdi), %rdx + movq %rax, 552(%rdi) + adcq 304(%r8), %rdx + movq 568(%rdi), %rax + movq %rdx, 560(%rdi) + adcq 312(%r8), %rax + movq 576(%rdi), %rdx + movq %rax, 568(%rdi) + adcq 320(%r8), %rdx + movq 584(%rdi), %rax + movq %rdx, 576(%rdi) + adcq 328(%r8), %rax + movq 592(%rdi), %rdx + movq %rax, 584(%rdi) + adcq 336(%r8), %rdx + movq 600(%rdi), %rax + movq %rdx, 592(%rdi) + adcq 344(%r8), %rax + movq 608(%rdi), %rdx + movq %rax, 600(%rdi) + adcq 352(%r8), %rdx + movq 616(%rdi), %rax + movq %rdx, 608(%rdi) + adcq 360(%r8), %rax + movq 624(%rdi), %rdx + movq %rax, 616(%rdi) + adcq 368(%r8), %rdx + movq 632(%rdi), %rax + movq %rdx, 624(%rdi) + adcq 376(%r8), %rax + movq 640(%rdi), %rdx + movq %rax, 632(%rdi) + adcq 384(%r8), %rdx + movq 648(%rdi), %rax + movq %rdx, 640(%rdi) + adcq 392(%r8), %rax + movq 656(%rdi), %rdx + movq %rax, 648(%rdi) + adcq 400(%r8), %rdx + movq 664(%rdi), %rax + movq %rdx, 656(%rdi) + adcq 408(%r8), %rax + movq 672(%rdi), %rdx + movq %rax, 664(%rdi) + adcq 416(%r8), %rdx + movq 680(%rdi), %rax + movq %rdx, 672(%rdi) + adcq 424(%r8), %rax + movq 688(%rdi), %rdx + movq %rax, 680(%rdi) + adcq 432(%r8), %rdx + movq 696(%rdi), %rax + movq %rdx, 688(%rdi) + adcq 440(%r8), %rax + movq 704(%rdi), %rdx + movq %rax, 696(%rdi) + adcq 448(%r8), %rdx + movq 712(%rdi), %rax + movq %rdx, 704(%rdi) + adcq 456(%r8), %rax + movq 720(%rdi), %rdx + movq %rax, 712(%rdi) + adcq 464(%r8), %rdx + movq 728(%rdi), %rax + movq %rdx, 720(%rdi) + adcq 472(%r8), %rax + movq 736(%rdi), %rdx + movq %rax, 728(%rdi) + adcq 480(%r8), %rdx + movq 744(%rdi), %rax + movq %rdx, 736(%rdi) + adcq 488(%r8), %rax + movq 752(%rdi), %rdx + movq %rax, 744(%rdi) + adcq 496(%r8), %rdx + movq 760(%rdi), %rax + movq %rdx, 752(%rdi) + adcq 504(%r8), %rax + movq %rax, 760(%rdi) + adcq $0, %rcx + movq %rcx, 768(%rdi) + # Add in place + movq 512(%rdi), %rdx + xorq %rcx, %rcx + addq (%rsi), %rdx + movq 520(%rdi), %rax + movq %rdx, 512(%rdi) + adcq 8(%rsi), %rax + movq 528(%rdi), %rdx + movq %rax, 520(%rdi) + adcq 16(%rsi), %rdx + movq 536(%rdi), %rax + movq %rdx, 528(%rdi) + adcq 24(%rsi), %rax + movq 544(%rdi), %rdx + movq %rax, 536(%rdi) + adcq 32(%rsi), %rdx + movq 552(%rdi), %rax + movq %rdx, 544(%rdi) + adcq 40(%rsi), %rax + movq 560(%rdi), %rdx + movq %rax, 552(%rdi) + adcq 48(%rsi), %rdx + movq 568(%rdi), %rax + movq %rdx, 560(%rdi) + adcq 56(%rsi), %rax + movq 576(%rdi), %rdx + movq %rax, 568(%rdi) + adcq 64(%rsi), %rdx + movq 584(%rdi), %rax + movq %rdx, 576(%rdi) + adcq 72(%rsi), %rax + movq 592(%rdi), %rdx + movq %rax, 584(%rdi) + adcq 80(%rsi), %rdx + movq 600(%rdi), %rax + movq %rdx, 592(%rdi) + adcq 88(%rsi), %rax + movq 608(%rdi), %rdx + movq %rax, 600(%rdi) + adcq 96(%rsi), %rdx + movq 616(%rdi), %rax + movq %rdx, 608(%rdi) + adcq 104(%rsi), %rax + movq 624(%rdi), %rdx + movq %rax, 616(%rdi) + adcq 112(%rsi), %rdx + movq 632(%rdi), %rax + movq %rdx, 624(%rdi) + adcq 120(%rsi), %rax + movq 640(%rdi), %rdx + movq %rax, 632(%rdi) + adcq 128(%rsi), %rdx + movq 648(%rdi), %rax + movq %rdx, 640(%rdi) + adcq 136(%rsi), %rax + movq 656(%rdi), %rdx + movq %rax, 648(%rdi) + adcq 144(%rsi), %rdx + movq 664(%rdi), %rax + movq %rdx, 656(%rdi) + adcq 152(%rsi), %rax + movq 672(%rdi), %rdx + movq %rax, 664(%rdi) + adcq 160(%rsi), %rdx + movq 680(%rdi), %rax + movq %rdx, 672(%rdi) + adcq 168(%rsi), %rax + movq 688(%rdi), %rdx + movq %rax, 680(%rdi) + adcq 176(%rsi), %rdx + movq 696(%rdi), %rax + movq %rdx, 688(%rdi) + adcq 184(%rsi), %rax + movq 704(%rdi), %rdx + movq %rax, 696(%rdi) + adcq 192(%rsi), %rdx + movq 712(%rdi), %rax + movq %rdx, 704(%rdi) + adcq 200(%rsi), %rax + movq 720(%rdi), %rdx + movq %rax, 712(%rdi) + adcq 208(%rsi), %rdx + movq 728(%rdi), %rax + movq %rdx, 720(%rdi) + adcq 216(%rsi), %rax + movq 736(%rdi), %rdx + movq %rax, 728(%rdi) + adcq 224(%rsi), %rdx + movq 744(%rdi), %rax + movq %rdx, 736(%rdi) + adcq 232(%rsi), %rax + movq 752(%rdi), %rdx + movq %rax, 744(%rdi) + adcq 240(%rsi), %rdx + movq 760(%rdi), %rax + movq %rdx, 752(%rdi) + adcq 248(%rsi), %rax + movq 768(%rdi), %rdx + movq %rax, 760(%rdi) + adcq 256(%rsi), %rdx + movq %rdx, 768(%rdi) + adcq $0, %rcx + # Add to zero + movq 264(%rsi), %rdx + adcq $0, %rdx + movq 272(%rsi), %rax + movq %rdx, 776(%rdi) + adcq $0, %rax + movq 280(%rsi), %rdx + movq %rax, 784(%rdi) + adcq $0, %rdx + movq 288(%rsi), %rax + movq %rdx, 792(%rdi) + adcq $0, %rax + movq 296(%rsi), %rdx + movq %rax, 800(%rdi) + adcq $0, %rdx + movq 304(%rsi), %rax + movq %rdx, 808(%rdi) + adcq $0, %rax + movq 312(%rsi), %rdx + movq %rax, 816(%rdi) + adcq $0, %rdx + movq 320(%rsi), %rax + movq %rdx, 824(%rdi) + adcq $0, %rax + movq 328(%rsi), %rdx + movq %rax, 832(%rdi) + adcq $0, %rdx + movq 336(%rsi), %rax + movq %rdx, 840(%rdi) + adcq $0, %rax + movq 344(%rsi), %rdx + movq %rax, 848(%rdi) + adcq $0, %rdx + movq 352(%rsi), %rax + movq %rdx, 856(%rdi) + adcq $0, %rax + movq 360(%rsi), %rdx + movq %rax, 864(%rdi) + adcq $0, %rdx + movq 368(%rsi), %rax + movq %rdx, 872(%rdi) + adcq $0, %rax + movq 376(%rsi), %rdx + movq %rax, 880(%rdi) + adcq $0, %rdx + movq 384(%rsi), %rax + movq %rdx, 888(%rdi) + adcq $0, %rax + movq 392(%rsi), %rdx + movq %rax, 896(%rdi) + adcq $0, %rdx + movq 400(%rsi), %rax + movq %rdx, 904(%rdi) + adcq $0, %rax + movq 408(%rsi), %rdx + movq %rax, 912(%rdi) + adcq $0, %rdx + movq 416(%rsi), %rax + movq %rdx, 920(%rdi) + adcq $0, %rax + movq 424(%rsi), %rdx + movq %rax, 928(%rdi) + adcq $0, %rdx + movq 432(%rsi), %rax + movq %rdx, 936(%rdi) + adcq $0, %rax + movq 440(%rsi), %rdx + movq %rax, 944(%rdi) + adcq $0, %rdx + movq 448(%rsi), %rax + movq %rdx, 952(%rdi) + adcq $0, %rax + movq 456(%rsi), %rdx + movq %rax, 960(%rdi) + adcq $0, %rdx + movq 464(%rsi), %rax + movq %rdx, 968(%rdi) + adcq $0, %rax + movq 472(%rsi), %rdx + movq %rax, 976(%rdi) + adcq $0, %rdx + movq 480(%rsi), %rax + movq %rdx, 984(%rdi) + adcq $0, %rax + movq 488(%rsi), %rdx + movq %rax, 992(%rdi) + adcq $0, %rdx + movq 496(%rsi), %rax + movq %rdx, 1000(%rdi) + adcq $0, %rax + movq 504(%rsi), %rdx + movq %rax, 1008(%rdi) + adcq $0, %rdx + movq %rdx, 1016(%rdi) + addq $1304, %rsp + repz retq +#ifndef __APPLE__ +.size sp_4096_sqr_avx2_64,.-sp_4096_sqr_avx2_64 +#endif /* __APPLE__ */ /* Mul a by digit b into r. (r = a * b) * * r A single precision integer. @@ -28368,326 +33847,326 @@ sp_4096_cond_sub_avx2_64: _sp_4096_cond_sub_avx2_64: #endif /* __APPLE__ */ movq $0, %rax - movq (%rsi), %r8 movq (%rdx), %r10 + movq (%rsi), %r8 pextq %rcx, %r10, %r10 subq %r10, %r8 - movq 8(%rsi), %r9 movq 8(%rdx), %r10 + movq 8(%rsi), %r9 pextq %rcx, %r10, %r10 movq %r8, (%rdi) sbbq %r10, %r9 - movq 16(%rsi), %r8 - movq 16(%rdx), %r10 - pextq %rcx, %r10, %r10 + movq 16(%rdx), %r8 + movq 16(%rsi), %r10 + pextq %rcx, %r8, %r8 movq %r9, 8(%rdi) - sbbq %r10, %r8 - movq 24(%rsi), %r9 - movq 24(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 16(%rdi) - sbbq %r10, %r9 - movq 32(%rsi), %r8 + 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 %r9, 24(%rdi) - sbbq %r10, %r8 - movq 40(%rsi), %r9 - movq 40(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 32(%rdi) + 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 - movq 48(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r9, 40(%rdi) - sbbq %r10, %r8 - movq 56(%rsi), %r9 + 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(%rsi), %r8 - movq 64(%rdx), %r10 - pextq %rcx, %r10, %r10 + movq 64(%rdx), %r8 + movq 64(%rsi), %r10 + pextq %rcx, %r8, %r8 movq %r9, 56(%rdi) - sbbq %r10, %r8 - movq 72(%rsi), %r9 - movq 72(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 64(%rdi) - sbbq %r10, %r9 - movq 80(%rsi), %r8 + 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 %r9, 72(%rdi) - sbbq %r10, %r8 - movq 88(%rsi), %r9 - movq 88(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 80(%rdi) + 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 - movq 96(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r9, 88(%rdi) - sbbq %r10, %r8 - movq 104(%rsi), %r9 + 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(%rsi), %r8 - movq 112(%rdx), %r10 - pextq %rcx, %r10, %r10 + movq 112(%rdx), %r8 + movq 112(%rsi), %r10 + pextq %rcx, %r8, %r8 movq %r9, 104(%rdi) - sbbq %r10, %r8 - movq 120(%rsi), %r9 - movq 120(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 112(%rdi) - sbbq %r10, %r9 - movq 128(%rsi), %r8 + sbbq %r8, %r10 + movq 120(%rdx), %r9 + movq 120(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 112(%rdi) + sbbq %r9, %r8 movq 128(%rdx), %r10 + movq 128(%rsi), %r9 pextq %rcx, %r10, %r10 - movq %r9, 120(%rdi) - sbbq %r10, %r8 - movq 136(%rsi), %r9 - movq 136(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 128(%rdi) + movq %r8, 120(%rdi) sbbq %r10, %r9 + movq 136(%rdx), %r8 + movq 136(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 128(%rdi) + sbbq %r8, %r10 + movq 144(%rdx), %r9 movq 144(%rsi), %r8 - movq 144(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r9, 136(%rdi) - sbbq %r10, %r8 - movq 152(%rsi), %r9 + pextq %rcx, %r9, %r9 + movq %r10, 136(%rdi) + sbbq %r9, %r8 movq 152(%rdx), %r10 + movq 152(%rsi), %r9 pextq %rcx, %r10, %r10 movq %r8, 144(%rdi) sbbq %r10, %r9 - movq 160(%rsi), %r8 - movq 160(%rdx), %r10 - pextq %rcx, %r10, %r10 + movq 160(%rdx), %r8 + movq 160(%rsi), %r10 + pextq %rcx, %r8, %r8 movq %r9, 152(%rdi) - sbbq %r10, %r8 - movq 168(%rsi), %r9 - movq 168(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 160(%rdi) - sbbq %r10, %r9 - movq 176(%rsi), %r8 + sbbq %r8, %r10 + movq 168(%rdx), %r9 + movq 168(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 160(%rdi) + sbbq %r9, %r8 movq 176(%rdx), %r10 + movq 176(%rsi), %r9 pextq %rcx, %r10, %r10 - movq %r9, 168(%rdi) - sbbq %r10, %r8 - movq 184(%rsi), %r9 - movq 184(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 176(%rdi) + movq %r8, 168(%rdi) sbbq %r10, %r9 + movq 184(%rdx), %r8 + movq 184(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 176(%rdi) + sbbq %r8, %r10 + movq 192(%rdx), %r9 movq 192(%rsi), %r8 - movq 192(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r9, 184(%rdi) - sbbq %r10, %r8 - movq 200(%rsi), %r9 + pextq %rcx, %r9, %r9 + movq %r10, 184(%rdi) + sbbq %r9, %r8 movq 200(%rdx), %r10 + movq 200(%rsi), %r9 pextq %rcx, %r10, %r10 movq %r8, 192(%rdi) sbbq %r10, %r9 - movq 208(%rsi), %r8 - movq 208(%rdx), %r10 - pextq %rcx, %r10, %r10 + movq 208(%rdx), %r8 + movq 208(%rsi), %r10 + pextq %rcx, %r8, %r8 movq %r9, 200(%rdi) - sbbq %r10, %r8 - movq 216(%rsi), %r9 - movq 216(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 208(%rdi) - sbbq %r10, %r9 - movq 224(%rsi), %r8 + sbbq %r8, %r10 + movq 216(%rdx), %r9 + movq 216(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 208(%rdi) + sbbq %r9, %r8 movq 224(%rdx), %r10 + movq 224(%rsi), %r9 pextq %rcx, %r10, %r10 - movq %r9, 216(%rdi) - sbbq %r10, %r8 - movq 232(%rsi), %r9 - movq 232(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 224(%rdi) + movq %r8, 216(%rdi) sbbq %r10, %r9 + movq 232(%rdx), %r8 + movq 232(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 224(%rdi) + sbbq %r8, %r10 + movq 240(%rdx), %r9 movq 240(%rsi), %r8 - movq 240(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r9, 232(%rdi) - sbbq %r10, %r8 - movq 248(%rsi), %r9 + pextq %rcx, %r9, %r9 + movq %r10, 232(%rdi) + sbbq %r9, %r8 movq 248(%rdx), %r10 + movq 248(%rsi), %r9 pextq %rcx, %r10, %r10 movq %r8, 240(%rdi) sbbq %r10, %r9 - movq 256(%rsi), %r8 - movq 256(%rdx), %r10 - pextq %rcx, %r10, %r10 + movq 256(%rdx), %r8 + movq 256(%rsi), %r10 + pextq %rcx, %r8, %r8 movq %r9, 248(%rdi) - sbbq %r10, %r8 - movq 264(%rsi), %r9 - movq 264(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 256(%rdi) - sbbq %r10, %r9 - movq 272(%rsi), %r8 + sbbq %r8, %r10 + movq 264(%rdx), %r9 + movq 264(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 256(%rdi) + sbbq %r9, %r8 movq 272(%rdx), %r10 + movq 272(%rsi), %r9 pextq %rcx, %r10, %r10 - movq %r9, 264(%rdi) - sbbq %r10, %r8 - movq 280(%rsi), %r9 - movq 280(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 272(%rdi) + movq %r8, 264(%rdi) sbbq %r10, %r9 + movq 280(%rdx), %r8 + movq 280(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 272(%rdi) + sbbq %r8, %r10 + movq 288(%rdx), %r9 movq 288(%rsi), %r8 - movq 288(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r9, 280(%rdi) - sbbq %r10, %r8 - movq 296(%rsi), %r9 + pextq %rcx, %r9, %r9 + movq %r10, 280(%rdi) + sbbq %r9, %r8 movq 296(%rdx), %r10 + movq 296(%rsi), %r9 pextq %rcx, %r10, %r10 movq %r8, 288(%rdi) sbbq %r10, %r9 - movq 304(%rsi), %r8 - movq 304(%rdx), %r10 - pextq %rcx, %r10, %r10 + movq 304(%rdx), %r8 + movq 304(%rsi), %r10 + pextq %rcx, %r8, %r8 movq %r9, 296(%rdi) - sbbq %r10, %r8 - movq 312(%rsi), %r9 - movq 312(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 304(%rdi) - sbbq %r10, %r9 - movq 320(%rsi), %r8 + sbbq %r8, %r10 + movq 312(%rdx), %r9 + movq 312(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 304(%rdi) + sbbq %r9, %r8 movq 320(%rdx), %r10 + movq 320(%rsi), %r9 pextq %rcx, %r10, %r10 - movq %r9, 312(%rdi) - sbbq %r10, %r8 - movq 328(%rsi), %r9 - movq 328(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 320(%rdi) + movq %r8, 312(%rdi) sbbq %r10, %r9 + movq 328(%rdx), %r8 + movq 328(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 320(%rdi) + sbbq %r8, %r10 + movq 336(%rdx), %r9 movq 336(%rsi), %r8 - movq 336(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r9, 328(%rdi) - sbbq %r10, %r8 - movq 344(%rsi), %r9 + pextq %rcx, %r9, %r9 + movq %r10, 328(%rdi) + sbbq %r9, %r8 movq 344(%rdx), %r10 + movq 344(%rsi), %r9 pextq %rcx, %r10, %r10 movq %r8, 336(%rdi) sbbq %r10, %r9 - movq 352(%rsi), %r8 - movq 352(%rdx), %r10 - pextq %rcx, %r10, %r10 + movq 352(%rdx), %r8 + movq 352(%rsi), %r10 + pextq %rcx, %r8, %r8 movq %r9, 344(%rdi) - sbbq %r10, %r8 - movq 360(%rsi), %r9 - movq 360(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 352(%rdi) - sbbq %r10, %r9 - movq 368(%rsi), %r8 + sbbq %r8, %r10 + movq 360(%rdx), %r9 + movq 360(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 352(%rdi) + sbbq %r9, %r8 movq 368(%rdx), %r10 + movq 368(%rsi), %r9 pextq %rcx, %r10, %r10 - movq %r9, 360(%rdi) - sbbq %r10, %r8 - movq 376(%rsi), %r9 - movq 376(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 368(%rdi) + movq %r8, 360(%rdi) sbbq %r10, %r9 + movq 376(%rdx), %r8 + movq 376(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 368(%rdi) + sbbq %r8, %r10 + movq 384(%rdx), %r9 movq 384(%rsi), %r8 - movq 384(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r9, 376(%rdi) - sbbq %r10, %r8 - movq 392(%rsi), %r9 + pextq %rcx, %r9, %r9 + movq %r10, 376(%rdi) + sbbq %r9, %r8 movq 392(%rdx), %r10 + movq 392(%rsi), %r9 pextq %rcx, %r10, %r10 movq %r8, 384(%rdi) sbbq %r10, %r9 - movq 400(%rsi), %r8 - movq 400(%rdx), %r10 - pextq %rcx, %r10, %r10 + movq 400(%rdx), %r8 + movq 400(%rsi), %r10 + pextq %rcx, %r8, %r8 movq %r9, 392(%rdi) - sbbq %r10, %r8 - movq 408(%rsi), %r9 - movq 408(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 400(%rdi) - sbbq %r10, %r9 - movq 416(%rsi), %r8 + sbbq %r8, %r10 + movq 408(%rdx), %r9 + movq 408(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 400(%rdi) + sbbq %r9, %r8 movq 416(%rdx), %r10 + movq 416(%rsi), %r9 pextq %rcx, %r10, %r10 - movq %r9, 408(%rdi) - sbbq %r10, %r8 - movq 424(%rsi), %r9 - movq 424(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 416(%rdi) + movq %r8, 408(%rdi) sbbq %r10, %r9 + movq 424(%rdx), %r8 + movq 424(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 416(%rdi) + sbbq %r8, %r10 + movq 432(%rdx), %r9 movq 432(%rsi), %r8 - movq 432(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r9, 424(%rdi) - sbbq %r10, %r8 - movq 440(%rsi), %r9 + pextq %rcx, %r9, %r9 + movq %r10, 424(%rdi) + sbbq %r9, %r8 movq 440(%rdx), %r10 + movq 440(%rsi), %r9 pextq %rcx, %r10, %r10 movq %r8, 432(%rdi) sbbq %r10, %r9 - movq 448(%rsi), %r8 - movq 448(%rdx), %r10 - pextq %rcx, %r10, %r10 + movq 448(%rdx), %r8 + movq 448(%rsi), %r10 + pextq %rcx, %r8, %r8 movq %r9, 440(%rdi) - sbbq %r10, %r8 - movq 456(%rsi), %r9 - movq 456(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 448(%rdi) - sbbq %r10, %r9 - movq 464(%rsi), %r8 + sbbq %r8, %r10 + movq 456(%rdx), %r9 + movq 456(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 448(%rdi) + sbbq %r9, %r8 movq 464(%rdx), %r10 + movq 464(%rsi), %r9 pextq %rcx, %r10, %r10 - movq %r9, 456(%rdi) - sbbq %r10, %r8 - movq 472(%rsi), %r9 - movq 472(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 464(%rdi) + movq %r8, 456(%rdi) sbbq %r10, %r9 + movq 472(%rdx), %r8 + movq 472(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 464(%rdi) + sbbq %r8, %r10 + movq 480(%rdx), %r9 movq 480(%rsi), %r8 - movq 480(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r9, 472(%rdi) - sbbq %r10, %r8 - movq 488(%rsi), %r9 + pextq %rcx, %r9, %r9 + movq %r10, 472(%rdi) + sbbq %r9, %r8 movq 488(%rdx), %r10 + movq 488(%rsi), %r9 pextq %rcx, %r10, %r10 movq %r8, 480(%rdi) sbbq %r10, %r9 - movq 496(%rsi), %r8 - movq 496(%rdx), %r10 - pextq %rcx, %r10, %r10 + movq 496(%rdx), %r8 + movq 496(%rsi), %r10 + pextq %rcx, %r8, %r8 movq %r9, 488(%rdi) - sbbq %r10, %r8 - movq 504(%rsi), %r9 - movq 504(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 496(%rdi) - sbbq %r10, %r9 - movq %r9, 504(%rdi) + sbbq %r8, %r10 + movq 504(%rdx), %r9 + movq 504(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 496(%rdi) + sbbq %r9, %r8 + movq %r8, 504(%rdi) sbbq $0, %rax repz retq #ifndef __APPLE__ @@ -28710,390 +34189,392 @@ sp_4096_mul_d_avx2_64: .p2align 4 _sp_4096_mul_d_avx2_64: #endif /* __APPLE__ */ + movq %rdx, %rax # A[0] * B - xorq %r10, %r10 - mulxq (%rsi), %r8, %r9 - movq %r8, (%rdi) + movq %rax, %rdx + xorq %r11, %r11 + mulxq (%rsi), %r9, %r10 + movq %r9, (%rdi) # A[1] * B - mulxq 8(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 8(%rdi) - adoxq %rcx, %r8 + mulxq 8(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 8(%rdi) + adoxq %r8, %r9 # A[2] * B - mulxq 16(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 16(%rdi) - adoxq %rcx, %r9 + mulxq 16(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 16(%rdi) + adoxq %r8, %r10 # A[3] * B - mulxq 24(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 24(%rdi) - adoxq %rcx, %r8 + mulxq 24(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 24(%rdi) + adoxq %r8, %r9 # A[4] * B - mulxq 32(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 32(%rdi) - adoxq %rcx, %r9 + mulxq 32(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 32(%rdi) + adoxq %r8, %r10 # A[5] * B - mulxq 40(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 40(%rdi) - adoxq %rcx, %r8 + mulxq 40(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 40(%rdi) + adoxq %r8, %r9 # A[6] * B - mulxq 48(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 48(%rdi) - adoxq %rcx, %r9 + mulxq 48(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 48(%rdi) + adoxq %r8, %r10 # A[7] * B - mulxq 56(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 56(%rdi) - adoxq %rcx, %r8 + mulxq 56(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 56(%rdi) + adoxq %r8, %r9 # A[8] * B - mulxq 64(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 64(%rdi) - adoxq %rcx, %r9 + mulxq 64(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 64(%rdi) + adoxq %r8, %r10 # A[9] * B - mulxq 72(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 72(%rdi) - adoxq %rcx, %r8 + mulxq 72(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 72(%rdi) + adoxq %r8, %r9 # A[10] * B - mulxq 80(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 80(%rdi) - adoxq %rcx, %r9 + mulxq 80(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 80(%rdi) + adoxq %r8, %r10 # A[11] * B - mulxq 88(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 88(%rdi) - adoxq %rcx, %r8 + mulxq 88(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 88(%rdi) + adoxq %r8, %r9 # A[12] * B - mulxq 96(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 96(%rdi) - adoxq %rcx, %r9 + mulxq 96(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 96(%rdi) + adoxq %r8, %r10 # A[13] * B - mulxq 104(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 104(%rdi) - adoxq %rcx, %r8 + mulxq 104(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 104(%rdi) + adoxq %r8, %r9 # A[14] * B - mulxq 112(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 112(%rdi) - adoxq %rcx, %r9 + mulxq 112(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 112(%rdi) + adoxq %r8, %r10 # A[15] * B - mulxq 120(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 120(%rdi) - adoxq %rcx, %r8 + mulxq 120(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 120(%rdi) + adoxq %r8, %r9 # A[16] * B - mulxq 128(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 128(%rdi) - adoxq %rcx, %r9 + mulxq 128(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 128(%rdi) + adoxq %r8, %r10 # A[17] * B - mulxq 136(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 136(%rdi) - adoxq %rcx, %r8 + mulxq 136(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 136(%rdi) + adoxq %r8, %r9 # A[18] * B - mulxq 144(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 144(%rdi) - adoxq %rcx, %r9 + mulxq 144(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 144(%rdi) + adoxq %r8, %r10 # A[19] * B - mulxq 152(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 152(%rdi) - adoxq %rcx, %r8 + mulxq 152(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 152(%rdi) + adoxq %r8, %r9 # A[20] * B - mulxq 160(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 160(%rdi) - adoxq %rcx, %r9 + mulxq 160(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 160(%rdi) + adoxq %r8, %r10 # A[21] * B - mulxq 168(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 168(%rdi) - adoxq %rcx, %r8 + mulxq 168(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 168(%rdi) + adoxq %r8, %r9 # A[22] * B - mulxq 176(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 176(%rdi) - adoxq %rcx, %r9 + mulxq 176(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 176(%rdi) + adoxq %r8, %r10 # A[23] * B - mulxq 184(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 184(%rdi) - adoxq %rcx, %r8 + mulxq 184(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 184(%rdi) + adoxq %r8, %r9 # A[24] * B - mulxq 192(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 192(%rdi) - adoxq %rcx, %r9 + mulxq 192(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 192(%rdi) + adoxq %r8, %r10 # A[25] * B - mulxq 200(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 200(%rdi) - adoxq %rcx, %r8 + mulxq 200(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 200(%rdi) + adoxq %r8, %r9 # A[26] * B - mulxq 208(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 208(%rdi) - adoxq %rcx, %r9 + mulxq 208(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 208(%rdi) + adoxq %r8, %r10 # A[27] * B - mulxq 216(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 216(%rdi) - adoxq %rcx, %r8 + mulxq 216(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 216(%rdi) + adoxq %r8, %r9 # A[28] * B - mulxq 224(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 224(%rdi) - adoxq %rcx, %r9 + mulxq 224(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 224(%rdi) + adoxq %r8, %r10 # A[29] * B - mulxq 232(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 232(%rdi) - adoxq %rcx, %r8 + mulxq 232(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 232(%rdi) + adoxq %r8, %r9 # A[30] * B - mulxq 240(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 240(%rdi) - adoxq %rcx, %r9 + mulxq 240(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 240(%rdi) + adoxq %r8, %r10 # A[31] * B - mulxq 248(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 248(%rdi) - adoxq %rcx, %r8 + mulxq 248(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 248(%rdi) + adoxq %r8, %r9 # A[32] * B - mulxq 256(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 256(%rdi) - adoxq %rcx, %r9 + mulxq 256(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 256(%rdi) + adoxq %r8, %r10 # A[33] * B - mulxq 264(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 264(%rdi) - adoxq %rcx, %r8 + mulxq 264(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 264(%rdi) + adoxq %r8, %r9 # A[34] * B - mulxq 272(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 272(%rdi) - adoxq %rcx, %r9 + mulxq 272(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 272(%rdi) + adoxq %r8, %r10 # A[35] * B - mulxq 280(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 280(%rdi) - adoxq %rcx, %r8 + mulxq 280(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 280(%rdi) + adoxq %r8, %r9 # A[36] * B - mulxq 288(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 288(%rdi) - adoxq %rcx, %r9 + mulxq 288(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 288(%rdi) + adoxq %r8, %r10 # A[37] * B - mulxq 296(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 296(%rdi) - adoxq %rcx, %r8 + mulxq 296(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 296(%rdi) + adoxq %r8, %r9 # A[38] * B - mulxq 304(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 304(%rdi) - adoxq %rcx, %r9 + mulxq 304(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 304(%rdi) + adoxq %r8, %r10 # A[39] * B - mulxq 312(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 312(%rdi) - adoxq %rcx, %r8 + mulxq 312(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 312(%rdi) + adoxq %r8, %r9 # A[40] * B - mulxq 320(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 320(%rdi) - adoxq %rcx, %r9 + mulxq 320(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 320(%rdi) + adoxq %r8, %r10 # A[41] * B - mulxq 328(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 328(%rdi) - adoxq %rcx, %r8 + mulxq 328(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 328(%rdi) + adoxq %r8, %r9 # A[42] * B - mulxq 336(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 336(%rdi) - adoxq %rcx, %r9 + mulxq 336(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 336(%rdi) + adoxq %r8, %r10 # A[43] * B - mulxq 344(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 344(%rdi) - adoxq %rcx, %r8 + mulxq 344(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 344(%rdi) + adoxq %r8, %r9 # A[44] * B - mulxq 352(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 352(%rdi) - adoxq %rcx, %r9 + mulxq 352(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 352(%rdi) + adoxq %r8, %r10 # A[45] * B - mulxq 360(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 360(%rdi) - adoxq %rcx, %r8 + mulxq 360(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 360(%rdi) + adoxq %r8, %r9 # A[46] * B - mulxq 368(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 368(%rdi) - adoxq %rcx, %r9 + mulxq 368(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 368(%rdi) + adoxq %r8, %r10 # A[47] * B - mulxq 376(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 376(%rdi) - adoxq %rcx, %r8 + mulxq 376(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 376(%rdi) + adoxq %r8, %r9 # A[48] * B - mulxq 384(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 384(%rdi) - adoxq %rcx, %r9 + mulxq 384(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 384(%rdi) + adoxq %r8, %r10 # A[49] * B - mulxq 392(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 392(%rdi) - adoxq %rcx, %r8 + mulxq 392(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 392(%rdi) + adoxq %r8, %r9 # A[50] * B - mulxq 400(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 400(%rdi) - adoxq %rcx, %r9 + mulxq 400(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 400(%rdi) + adoxq %r8, %r10 # A[51] * B - mulxq 408(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 408(%rdi) - adoxq %rcx, %r8 + mulxq 408(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 408(%rdi) + adoxq %r8, %r9 # A[52] * B - mulxq 416(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 416(%rdi) - adoxq %rcx, %r9 + mulxq 416(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 416(%rdi) + adoxq %r8, %r10 # A[53] * B - mulxq 424(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 424(%rdi) - adoxq %rcx, %r8 + mulxq 424(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 424(%rdi) + adoxq %r8, %r9 # A[54] * B - mulxq 432(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 432(%rdi) - adoxq %rcx, %r9 + mulxq 432(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 432(%rdi) + adoxq %r8, %r10 # A[55] * B - mulxq 440(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 440(%rdi) - adoxq %rcx, %r8 + mulxq 440(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 440(%rdi) + adoxq %r8, %r9 # A[56] * B - mulxq 448(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 448(%rdi) - adoxq %rcx, %r9 + mulxq 448(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 448(%rdi) + adoxq %r8, %r10 # A[57] * B - mulxq 456(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 456(%rdi) - adoxq %rcx, %r8 + mulxq 456(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 456(%rdi) + adoxq %r8, %r9 # A[58] * B - mulxq 464(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 464(%rdi) - adoxq %rcx, %r9 + mulxq 464(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 464(%rdi) + adoxq %r8, %r10 # A[59] * B - mulxq 472(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 472(%rdi) - adoxq %rcx, %r8 + mulxq 472(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 472(%rdi) + adoxq %r8, %r9 # A[60] * B - mulxq 480(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 480(%rdi) - adoxq %rcx, %r9 + mulxq 480(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 480(%rdi) + adoxq %r8, %r10 # A[61] * B - mulxq 488(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 488(%rdi) - adoxq %rcx, %r8 + mulxq 488(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 488(%rdi) + adoxq %r8, %r9 # A[62] * B - mulxq 496(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 496(%rdi) - adoxq %rcx, %r9 + mulxq 496(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 496(%rdi) + adoxq %r8, %r10 # A[63] * B - mulxq 504(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - adoxq %rcx, %r8 - adcxq %r10, %r8 - movq %r9, 504(%rdi) - movq %r8, 512(%rdi) + mulxq 504(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + adoxq %r8, %r9 + adcxq %r11, %r9 + movq %r10, 504(%rdi) + movq %r9, 512(%rdi) repz retq #ifndef __APPLE__ .size sp_4096_mul_d_avx2_64,.-sp_4096_mul_d_avx2_64 @@ -29871,419 +35352,735 @@ _sp_4096_mont_reduce_avx2_64: push %r12 push %r13 push %r14 - movq %rdx, %rax + movq %rdx, %r8 xorq %r14, %r14 # i = 64 movq $64, %r9 movq (%rdi), %r13 + addq $256, %rdi xorq %r12, %r12 L_mont_loop_avx2_64: # mu = a[i] * mp movq %r13, %rdx - mulxq %rax, %rdx, %r8 movq %r13, %r10 + imulq %r8, %rdx + xorq %r12, %r12 # a[i+0] += m[0] * mu - mulxq (%rsi), %rcx, %r8 - movq 8(%rdi), %r13 - adcxq %rcx, %r10 - adoxq %r8, %r13 + mulxq (%rsi), %rax, %rcx + movq -248(%rdi), %r13 + adcxq %rax, %r10 + adoxq %rcx, %r13 # a[i+1] += m[1] * mu - mulxq 8(%rsi), %rcx, %r8 - movq 16(%rdi), %r10 - adcxq %rcx, %r13 - adoxq %r8, %r10 + mulxq 8(%rsi), %rax, %rcx + movq -240(%rdi), %r10 + adcxq %rax, %r13 + adoxq %rcx, %r10 # a[i+2] += m[2] * mu - mulxq 16(%rsi), %rcx, %r8 - movq 24(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 16(%rdi) + mulxq 16(%rsi), %rax, %rcx + movq -232(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -240(%rdi) # a[i+3] += m[3] * mu - mulxq 24(%rsi), %rcx, %r8 - movq 32(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 24(%rdi) + mulxq 24(%rsi), %rax, %rcx + movq -224(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -232(%rdi) # a[i+4] += m[4] * mu - mulxq 32(%rsi), %rcx, %r8 - movq 40(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 32(%rdi) + mulxq 32(%rsi), %rax, %rcx + movq -216(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -224(%rdi) # a[i+5] += m[5] * mu - mulxq 40(%rsi), %rcx, %r8 - movq 48(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 40(%rdi) + mulxq 40(%rsi), %rax, %rcx + movq -208(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -216(%rdi) # a[i+6] += m[6] * mu - mulxq 48(%rsi), %rcx, %r8 - movq 56(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 48(%rdi) + mulxq 48(%rsi), %rax, %rcx + movq -200(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -208(%rdi) # a[i+7] += m[7] * mu - mulxq 56(%rsi), %rcx, %r8 - movq 64(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 56(%rdi) + mulxq 56(%rsi), %rax, %rcx + movq -192(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -200(%rdi) # a[i+8] += m[8] * mu - mulxq 64(%rsi), %rcx, %r8 - movq 72(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 64(%rdi) + mulxq 64(%rsi), %rax, %rcx + movq -184(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -192(%rdi) # a[i+9] += m[9] * mu - mulxq 72(%rsi), %rcx, %r8 - movq 80(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 72(%rdi) + mulxq 72(%rsi), %rax, %rcx + movq -176(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -184(%rdi) # a[i+10] += m[10] * mu - mulxq 80(%rsi), %rcx, %r8 - movq 88(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 80(%rdi) + mulxq 80(%rsi), %rax, %rcx + movq -168(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -176(%rdi) # a[i+11] += m[11] * mu - mulxq 88(%rsi), %rcx, %r8 - movq 96(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 88(%rdi) + mulxq 88(%rsi), %rax, %rcx + movq -160(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -168(%rdi) # a[i+12] += m[12] * mu - mulxq 96(%rsi), %rcx, %r8 - movq 104(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 96(%rdi) + mulxq 96(%rsi), %rax, %rcx + movq -152(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -160(%rdi) # a[i+13] += m[13] * mu - mulxq 104(%rsi), %rcx, %r8 - movq 112(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 104(%rdi) + mulxq 104(%rsi), %rax, %rcx + movq -144(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -152(%rdi) # a[i+14] += m[14] * mu - mulxq 112(%rsi), %rcx, %r8 - movq 120(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 112(%rdi) + mulxq 112(%rsi), %rax, %rcx + movq -136(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -144(%rdi) # a[i+15] += m[15] * mu - mulxq 120(%rsi), %rcx, %r8 - movq 128(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 120(%rdi) + mulxq 120(%rsi), %rax, %rcx + movq -128(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -136(%rdi) # a[i+16] += m[16] * mu - mulxq 128(%rsi), %rcx, %r8 - movq 136(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 128(%rdi) + mulxq 128(%rsi), %rax, %rcx + movq -120(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -128(%rdi) # a[i+17] += m[17] * mu - mulxq 136(%rsi), %rcx, %r8 - movq 144(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 136(%rdi) + mulxq 136(%rsi), %rax, %rcx + movq -112(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -120(%rdi) # a[i+18] += m[18] * mu - mulxq 144(%rsi), %rcx, %r8 - movq 152(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 144(%rdi) + mulxq 144(%rsi), %rax, %rcx + movq -104(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -112(%rdi) # a[i+19] += m[19] * mu - mulxq 152(%rsi), %rcx, %r8 - movq 160(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 152(%rdi) + mulxq 152(%rsi), %rax, %rcx + movq -96(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -104(%rdi) # a[i+20] += m[20] * mu - mulxq 160(%rsi), %rcx, %r8 - movq 168(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 160(%rdi) + mulxq 160(%rsi), %rax, %rcx + movq -88(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -96(%rdi) # a[i+21] += m[21] * mu - mulxq 168(%rsi), %rcx, %r8 - movq 176(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 168(%rdi) + mulxq 168(%rsi), %rax, %rcx + movq -80(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -88(%rdi) # a[i+22] += m[22] * mu - mulxq 176(%rsi), %rcx, %r8 - movq 184(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 176(%rdi) + mulxq 176(%rsi), %rax, %rcx + movq -72(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -80(%rdi) # a[i+23] += m[23] * mu - mulxq 184(%rsi), %rcx, %r8 - movq 192(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 184(%rdi) + mulxq 184(%rsi), %rax, %rcx + movq -64(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -72(%rdi) # a[i+24] += m[24] * mu - mulxq 192(%rsi), %rcx, %r8 - movq 200(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 192(%rdi) + mulxq 192(%rsi), %rax, %rcx + movq -56(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -64(%rdi) # a[i+25] += m[25] * mu - mulxq 200(%rsi), %rcx, %r8 - movq 208(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 200(%rdi) + mulxq 200(%rsi), %rax, %rcx + movq -48(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -56(%rdi) # a[i+26] += m[26] * mu - mulxq 208(%rsi), %rcx, %r8 - movq 216(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 208(%rdi) + mulxq 208(%rsi), %rax, %rcx + movq -40(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -48(%rdi) # a[i+27] += m[27] * mu - mulxq 216(%rsi), %rcx, %r8 - movq 224(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 216(%rdi) + mulxq 216(%rsi), %rax, %rcx + movq -32(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -40(%rdi) # a[i+28] += m[28] * mu - mulxq 224(%rsi), %rcx, %r8 - movq 232(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 224(%rdi) + mulxq 224(%rsi), %rax, %rcx + movq -24(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -32(%rdi) # a[i+29] += m[29] * mu - mulxq 232(%rsi), %rcx, %r8 - movq 240(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 232(%rdi) + mulxq 232(%rsi), %rax, %rcx + movq -16(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -24(%rdi) # a[i+30] += m[30] * mu - mulxq 240(%rsi), %rcx, %r8 - movq 248(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 240(%rdi) + mulxq 240(%rsi), %rax, %rcx + movq -8(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, -16(%rdi) # a[i+31] += m[31] * mu - mulxq 248(%rsi), %rcx, %r8 - movq 256(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 248(%rdi) + mulxq 248(%rsi), %rax, %rcx + movq (%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, -8(%rdi) # a[i+32] += m[32] * mu - mulxq 256(%rsi), %rcx, %r8 - movq 264(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 256(%rdi) + mulxq 256(%rsi), %rax, %rcx + movq 8(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, (%rdi) # a[i+33] += m[33] * mu - mulxq 264(%rsi), %rcx, %r8 - movq 272(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 264(%rdi) + mulxq 264(%rsi), %rax, %rcx + movq 16(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 8(%rdi) # a[i+34] += m[34] * mu - mulxq 272(%rsi), %rcx, %r8 - movq 280(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 272(%rdi) + mulxq 272(%rsi), %rax, %rcx + movq 24(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 16(%rdi) # a[i+35] += m[35] * mu - mulxq 280(%rsi), %rcx, %r8 - movq 288(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 280(%rdi) + mulxq 280(%rsi), %rax, %rcx + movq 32(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 24(%rdi) # a[i+36] += m[36] * mu - mulxq 288(%rsi), %rcx, %r8 - movq 296(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 288(%rdi) + mulxq 288(%rsi), %rax, %rcx + movq 40(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 32(%rdi) # a[i+37] += m[37] * mu - mulxq 296(%rsi), %rcx, %r8 - movq 304(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 296(%rdi) + mulxq 296(%rsi), %rax, %rcx + movq 48(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 40(%rdi) # a[i+38] += m[38] * mu - mulxq 304(%rsi), %rcx, %r8 - movq 312(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 304(%rdi) + mulxq 304(%rsi), %rax, %rcx + movq 56(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 48(%rdi) # a[i+39] += m[39] * mu - mulxq 312(%rsi), %rcx, %r8 - movq 320(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 312(%rdi) + mulxq 312(%rsi), %rax, %rcx + movq 64(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 56(%rdi) # a[i+40] += m[40] * mu - mulxq 320(%rsi), %rcx, %r8 - movq 328(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 320(%rdi) + mulxq 320(%rsi), %rax, %rcx + movq 72(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 64(%rdi) # a[i+41] += m[41] * mu - mulxq 328(%rsi), %rcx, %r8 - movq 336(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 328(%rdi) + mulxq 328(%rsi), %rax, %rcx + movq 80(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 72(%rdi) # a[i+42] += m[42] * mu - mulxq 336(%rsi), %rcx, %r8 - movq 344(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 336(%rdi) + mulxq 336(%rsi), %rax, %rcx + movq 88(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 80(%rdi) # a[i+43] += m[43] * mu - mulxq 344(%rsi), %rcx, %r8 - movq 352(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 344(%rdi) + mulxq 344(%rsi), %rax, %rcx + movq 96(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 88(%rdi) # a[i+44] += m[44] * mu - mulxq 352(%rsi), %rcx, %r8 - movq 360(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 352(%rdi) + mulxq 352(%rsi), %rax, %rcx + movq 104(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 96(%rdi) # a[i+45] += m[45] * mu - mulxq 360(%rsi), %rcx, %r8 - movq 368(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 360(%rdi) + mulxq 360(%rsi), %rax, %rcx + movq 112(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 104(%rdi) # a[i+46] += m[46] * mu - mulxq 368(%rsi), %rcx, %r8 - movq 376(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 368(%rdi) + mulxq 368(%rsi), %rax, %rcx + movq 120(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 112(%rdi) # a[i+47] += m[47] * mu - mulxq 376(%rsi), %rcx, %r8 - movq 384(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 376(%rdi) + mulxq 376(%rsi), %rax, %rcx + movq 128(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 120(%rdi) # a[i+48] += m[48] * mu - mulxq 384(%rsi), %rcx, %r8 - movq 392(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 384(%rdi) + mulxq 384(%rsi), %rax, %rcx + movq 136(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 128(%rdi) # a[i+49] += m[49] * mu - mulxq 392(%rsi), %rcx, %r8 - movq 400(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 392(%rdi) + mulxq 392(%rsi), %rax, %rcx + movq 144(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 136(%rdi) # a[i+50] += m[50] * mu - mulxq 400(%rsi), %rcx, %r8 - movq 408(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 400(%rdi) + mulxq 400(%rsi), %rax, %rcx + movq 152(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 144(%rdi) # a[i+51] += m[51] * mu - mulxq 408(%rsi), %rcx, %r8 - movq 416(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 408(%rdi) + mulxq 408(%rsi), %rax, %rcx + movq 160(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 152(%rdi) # a[i+52] += m[52] * mu - mulxq 416(%rsi), %rcx, %r8 - movq 424(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 416(%rdi) + mulxq 416(%rsi), %rax, %rcx + movq 168(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 160(%rdi) # a[i+53] += m[53] * mu - mulxq 424(%rsi), %rcx, %r8 - movq 432(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 424(%rdi) + mulxq 424(%rsi), %rax, %rcx + movq 176(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 168(%rdi) # a[i+54] += m[54] * mu - mulxq 432(%rsi), %rcx, %r8 - movq 440(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 432(%rdi) + mulxq 432(%rsi), %rax, %rcx + movq 184(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 176(%rdi) # a[i+55] += m[55] * mu - mulxq 440(%rsi), %rcx, %r8 - movq 448(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 440(%rdi) + mulxq 440(%rsi), %rax, %rcx + movq 192(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 184(%rdi) # a[i+56] += m[56] * mu - mulxq 448(%rsi), %rcx, %r8 - movq 456(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 448(%rdi) + mulxq 448(%rsi), %rax, %rcx + movq 200(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 192(%rdi) # a[i+57] += m[57] * mu - mulxq 456(%rsi), %rcx, %r8 - movq 464(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 456(%rdi) + mulxq 456(%rsi), %rax, %rcx + movq 208(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 200(%rdi) # a[i+58] += m[58] * mu - mulxq 464(%rsi), %rcx, %r8 - movq 472(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 464(%rdi) + mulxq 464(%rsi), %rax, %rcx + movq 216(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 208(%rdi) # a[i+59] += m[59] * mu - mulxq 472(%rsi), %rcx, %r8 - movq 480(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 472(%rdi) + mulxq 472(%rsi), %rax, %rcx + movq 224(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 216(%rdi) # a[i+60] += m[60] * mu - mulxq 480(%rsi), %rcx, %r8 - movq 488(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 480(%rdi) + mulxq 480(%rsi), %rax, %rcx + movq 232(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 224(%rdi) # a[i+61] += m[61] * mu - mulxq 488(%rsi), %rcx, %r8 - movq 496(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 488(%rdi) + mulxq 488(%rsi), %rax, %rcx + movq 240(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 232(%rdi) # a[i+62] += m[62] * mu - mulxq 496(%rsi), %rcx, %r8 - movq 504(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 496(%rdi) + mulxq 496(%rsi), %rax, %rcx + movq 248(%rdi), %r11 + adcxq %rax, %r10 + adoxq %rcx, %r11 + movq %r10, 240(%rdi) # a[i+63] += m[63] * mu - mulxq 504(%rsi), %rcx, %r8 - movq 512(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 504(%rdi) + mulxq 504(%rsi), %rax, %rcx + movq 256(%rdi), %r10 + adcxq %rax, %r11 + adoxq %rcx, %r10 + movq %r11, 248(%rdi) adcxq %r14, %r10 + movq %r10, 256(%rdi) movq %r12, %r14 - movq %r10, 512(%rdi) adoxq %r12, %r14 adcxq %r12, %r14 - # i -= 1 + # a += 1 addq $8, %rdi - decq %r9 + # i -= 1 + subq $1, %r9 jnz L_mont_loop_avx2_64 - movq %r13, (%rdi) + subq $256, %rdi negq %r14 - movq %r14, %rcx - movq %rsi, %rdx - movq %rdi, %rsi + movq %rdi, %r8 subq $512, %rdi -#ifndef __APPLE__ - callq sp_4096_cond_sub_avx2_64@plt -#else - callq _sp_4096_cond_sub_avx2_64 -#endif /* __APPLE__ */ + movq (%rsi), %rcx + movq %r13, %rdx + pextq %r14, %rcx, %rcx + subq %rcx, %rdx + movq 8(%rsi), %rcx + movq 8(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, (%rdi) + sbbq %rcx, %rax + movq 16(%rsi), %rdx + movq 16(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 8(%rdi) + sbbq %rdx, %rcx + movq 24(%rsi), %rax + movq 24(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 16(%rdi) + sbbq %rax, %rdx + movq 32(%rsi), %rcx + movq 32(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 24(%rdi) + sbbq %rcx, %rax + movq 40(%rsi), %rdx + movq 40(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 32(%rdi) + sbbq %rdx, %rcx + movq 48(%rsi), %rax + movq 48(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 40(%rdi) + sbbq %rax, %rdx + movq 56(%rsi), %rcx + movq 56(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 48(%rdi) + sbbq %rcx, %rax + movq 64(%rsi), %rdx + movq 64(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 56(%rdi) + sbbq %rdx, %rcx + movq 72(%rsi), %rax + movq 72(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 64(%rdi) + sbbq %rax, %rdx + movq 80(%rsi), %rcx + movq 80(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 72(%rdi) + sbbq %rcx, %rax + movq 88(%rsi), %rdx + movq 88(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 80(%rdi) + sbbq %rdx, %rcx + movq 96(%rsi), %rax + movq 96(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 88(%rdi) + sbbq %rax, %rdx + movq 104(%rsi), %rcx + movq 104(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 96(%rdi) + sbbq %rcx, %rax + movq 112(%rsi), %rdx + movq 112(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 104(%rdi) + sbbq %rdx, %rcx + movq 120(%rsi), %rax + movq 120(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 112(%rdi) + sbbq %rax, %rdx + movq 128(%rsi), %rcx + movq 128(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 120(%rdi) + sbbq %rcx, %rax + movq 136(%rsi), %rdx + movq 136(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 128(%rdi) + sbbq %rdx, %rcx + movq 144(%rsi), %rax + movq 144(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 136(%rdi) + sbbq %rax, %rdx + movq 152(%rsi), %rcx + movq 152(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 144(%rdi) + sbbq %rcx, %rax + movq 160(%rsi), %rdx + movq 160(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 152(%rdi) + sbbq %rdx, %rcx + movq 168(%rsi), %rax + movq 168(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 160(%rdi) + sbbq %rax, %rdx + movq 176(%rsi), %rcx + movq 176(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 168(%rdi) + sbbq %rcx, %rax + movq 184(%rsi), %rdx + movq 184(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 176(%rdi) + sbbq %rdx, %rcx + movq 192(%rsi), %rax + movq 192(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 184(%rdi) + sbbq %rax, %rdx + movq 200(%rsi), %rcx + movq 200(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 192(%rdi) + sbbq %rcx, %rax + movq 208(%rsi), %rdx + movq 208(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 200(%rdi) + sbbq %rdx, %rcx + movq 216(%rsi), %rax + movq 216(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 208(%rdi) + sbbq %rax, %rdx + movq 224(%rsi), %rcx + movq 224(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 216(%rdi) + sbbq %rcx, %rax + movq 232(%rsi), %rdx + movq 232(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 224(%rdi) + sbbq %rdx, %rcx + movq 240(%rsi), %rax + movq 240(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 232(%rdi) + sbbq %rax, %rdx + movq 248(%rsi), %rcx + movq 248(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 240(%rdi) + sbbq %rcx, %rax + movq 256(%rsi), %rdx + movq 256(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 248(%rdi) + sbbq %rdx, %rcx + movq 264(%rsi), %rax + movq 264(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 256(%rdi) + sbbq %rax, %rdx + movq 272(%rsi), %rcx + movq 272(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 264(%rdi) + sbbq %rcx, %rax + movq 280(%rsi), %rdx + movq 280(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 272(%rdi) + sbbq %rdx, %rcx + movq 288(%rsi), %rax + movq 288(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 280(%rdi) + sbbq %rax, %rdx + movq 296(%rsi), %rcx + movq 296(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 288(%rdi) + sbbq %rcx, %rax + movq 304(%rsi), %rdx + movq 304(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 296(%rdi) + sbbq %rdx, %rcx + movq 312(%rsi), %rax + movq 312(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 304(%rdi) + sbbq %rax, %rdx + movq 320(%rsi), %rcx + movq 320(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 312(%rdi) + sbbq %rcx, %rax + movq 328(%rsi), %rdx + movq 328(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 320(%rdi) + sbbq %rdx, %rcx + movq 336(%rsi), %rax + movq 336(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 328(%rdi) + sbbq %rax, %rdx + movq 344(%rsi), %rcx + movq 344(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 336(%rdi) + sbbq %rcx, %rax + movq 352(%rsi), %rdx + movq 352(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 344(%rdi) + sbbq %rdx, %rcx + movq 360(%rsi), %rax + movq 360(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 352(%rdi) + sbbq %rax, %rdx + movq 368(%rsi), %rcx + movq 368(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 360(%rdi) + sbbq %rcx, %rax + movq 376(%rsi), %rdx + movq 376(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 368(%rdi) + sbbq %rdx, %rcx + movq 384(%rsi), %rax + movq 384(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 376(%rdi) + sbbq %rax, %rdx + movq 392(%rsi), %rcx + movq 392(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 384(%rdi) + sbbq %rcx, %rax + movq 400(%rsi), %rdx + movq 400(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 392(%rdi) + sbbq %rdx, %rcx + movq 408(%rsi), %rax + movq 408(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 400(%rdi) + sbbq %rax, %rdx + movq 416(%rsi), %rcx + movq 416(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 408(%rdi) + sbbq %rcx, %rax + movq 424(%rsi), %rdx + movq 424(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 416(%rdi) + sbbq %rdx, %rcx + movq 432(%rsi), %rax + movq 432(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 424(%rdi) + sbbq %rax, %rdx + movq 440(%rsi), %rcx + movq 440(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 432(%rdi) + sbbq %rcx, %rax + movq 448(%rsi), %rdx + movq 448(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 440(%rdi) + sbbq %rdx, %rcx + movq 456(%rsi), %rax + movq 456(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 448(%rdi) + sbbq %rax, %rdx + movq 464(%rsi), %rcx + movq 464(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 456(%rdi) + sbbq %rcx, %rax + movq 472(%rsi), %rdx + movq 472(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 464(%rdi) + sbbq %rdx, %rcx + movq 480(%rsi), %rax + movq 480(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 472(%rdi) + sbbq %rax, %rdx + movq 488(%rsi), %rcx + movq 488(%r8), %rax + pextq %r14, %rcx, %rcx + movq %rdx, 480(%rdi) + sbbq %rcx, %rax + movq 496(%rsi), %rdx + movq 496(%r8), %rcx + pextq %r14, %rdx, %rdx + movq %rax, 488(%rdi) + sbbq %rdx, %rcx + movq 504(%rsi), %rax + movq 504(%r8), %rdx + pextq %r14, %rax, %rax + movq %rcx, 496(%rdi) + sbbq %rax, %rdx + movq %rdx, 504(%rdi) pop %r14 pop %r13 pop %r12 @@ -31892,6 +37689,7 @@ sp_256_add_4: .p2align 4 _sp_256_add_4: #endif /* __APPLE__ */ + # Add movq (%rsi), %rcx xorq %rax, %rax addq (%rdx), %rcx @@ -32313,30 +38111,32 @@ sp_256_mul_d_avx2_4: .p2align 4 _sp_256_mul_d_avx2_4: #endif /* __APPLE__ */ + movq %rdx, %rax # A[0] * B - xorq %r10, %r10 - mulxq (%rsi), %r8, %r9 - movq %r8, (%rdi) + movq %rax, %rdx + xorq %r11, %r11 + mulxq (%rsi), %r9, %r10 + movq %r9, (%rdi) # A[1] * B - mulxq 8(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 8(%rdi) - adoxq %rcx, %r8 + mulxq 8(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 8(%rdi) + adoxq %r8, %r9 # A[2] * B - mulxq 16(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 16(%rdi) - adoxq %rcx, %r9 + mulxq 16(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 16(%rdi) + adoxq %r8, %r10 # A[3] * B - mulxq 24(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - adoxq %rcx, %r8 - adcxq %r10, %r8 - movq %r9, 24(%rdi) - movq %r8, 32(%rdi) + mulxq 24(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + adoxq %r8, %r9 + adcxq %r11, %r9 + movq %r10, 24(%rdi) + movq %r9, 32(%rdi) repz retq #ifndef __APPLE__ .size sp_256_mul_d_avx2_4,.-sp_256_mul_d_avx2_4 @@ -33701,6 +39501,7 @@ sp_384_add_6: .p2align 4 _sp_384_add_6: #endif /* __APPLE__ */ + # Add movq (%rsi), %rcx xorq %rax, %rax addq (%rdx), %rcx @@ -34169,60 +39970,6 @@ _sp_384_mul_avx2_6: #ifndef __APPLE__ .size sp_384_mul_avx2_6,.-sp_384_mul_avx2_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__ -.globl sp_384_cond_sub_avx2_6 -.type sp_384_cond_sub_avx2_6,@function -.align 16 -sp_384_cond_sub_avx2_6: -#else -.globl _sp_384_cond_sub_avx2_6 -.p2align 4 -_sp_384_cond_sub_avx2_6: -#endif /* __APPLE__ */ - movq $0, %rax - movq (%rsi), %r8 - movq (%rdx), %r10 - pextq %rcx, %r10, %r10 - subq %r10, %r8 - movq 8(%rsi), %r9 - movq 8(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, (%rdi) - sbbq %r10, %r9 - movq 16(%rsi), %r8 - movq 16(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r9, 8(%rdi) - sbbq %r10, %r8 - movq 24(%rsi), %r9 - movq 24(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 16(%rdi) - sbbq %r10, %r9 - movq 32(%rsi), %r8 - movq 32(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r9, 24(%rdi) - sbbq %r10, %r8 - movq 40(%rsi), %r9 - movq 40(%rdx), %r10 - pextq %rcx, %r10, %r10 - movq %r8, 32(%rdi) - sbbq %r10, %r9 - movq %r9, 40(%rdi) - sbbq $0, %rax - repz retq -#ifndef __APPLE__ -.size sp_384_cond_sub_avx2_6,.-sp_384_cond_sub_avx2_6 -#endif /* __APPLE__ */ #ifdef HAVE_INTEL_AVX2 /* Reduce the number back to 384 bits using Montgomery reduction. * @@ -34242,73 +39989,308 @@ _sp_384_mont_reduce_order_avx2_6: #endif /* __APPLE__ */ push %r12 push %r13 - push %r14 movq %rdx, %rax - xorq %r14, %r14 - # i = 6 - movq $6, %r9 - movq (%rdi), %r13 - xorq %r12, %r12 + xorq %r13, %r13 + movq (%rdi), %r12 + xorq %r11, %r11 L_mont_loop_order_avx2_6: # mu = a[i] * mp - movq %r13, %rdx - mulxq %rax, %rdx, %r8 - movq %r13, %r10 + movq %r12, %rdx + movq %r12, %r9 + imulq %rax, %rdx + xorq %r11, %r11 # a[i+0] += m[0] * mu mulxq (%rsi), %rcx, %r8 - movq 8(%rdi), %r13 - adcxq %rcx, %r10 - adoxq %r8, %r13 + movq 8(%rdi), %r12 + adcxq %rcx, %r9 + adoxq %r8, %r12 # a[i+1] += m[1] * mu mulxq 8(%rsi), %rcx, %r8 - movq 16(%rdi), %r10 - adcxq %rcx, %r13 - adoxq %r8, %r10 + movq 16(%rdi), %r9 + adcxq %rcx, %r12 + adoxq %r8, %r9 # a[i+2] += m[2] * mu mulxq 16(%rsi), %rcx, %r8 - movq 24(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 16(%rdi) + movq 24(%rdi), %r10 + adcxq %rcx, %r9 + adoxq %r8, %r10 + movq %r9, 16(%rdi) # a[i+3] += m[3] * mu mulxq 24(%rsi), %rcx, %r8 - movq 32(%rdi), %r10 - adcxq %rcx, %r11 - adoxq %r8, %r10 - movq %r11, 24(%rdi) + movq 32(%rdi), %r9 + adcxq %rcx, %r10 + adoxq %r8, %r9 + movq %r10, 24(%rdi) # a[i+4] += m[4] * mu mulxq 32(%rsi), %rcx, %r8 - movq 40(%rdi), %r11 - adcxq %rcx, %r10 - adoxq %r8, %r11 - movq %r10, 32(%rdi) + movq 40(%rdi), %r10 + adcxq %rcx, %r9 + adoxq %r8, %r10 + movq %r9, 32(%rdi) # a[i+5] += m[5] * mu mulxq 40(%rsi), %rcx, %r8 - movq 48(%rdi), %r10 - adcxq %rcx, %r11 + movq 48(%rdi), %r9 + adcxq %rcx, %r10 + adoxq %r8, %r9 + movq %r10, 40(%rdi) + adcxq %r13, %r9 + movq %r9, 48(%rdi) + movq %r11, %r13 + adoxq %r11, %r13 + adcxq %r11, %r13 + # mu = a[i] * mp + movq %r12, %rdx + movq %r12, %r9 + imulq %rax, %rdx + xorq %r11, %r11 + # a[i+0] += m[0] * mu + mulxq (%rsi), %rcx, %r8 + movq 16(%rdi), %r12 + adcxq %rcx, %r9 + adoxq %r8, %r12 + # a[i+1] += m[1] * mu + mulxq 8(%rsi), %rcx, %r8 + movq 24(%rdi), %r9 + adcxq %rcx, %r12 + adoxq %r8, %r9 + # a[i+2] += m[2] * mu + mulxq 16(%rsi), %rcx, %r8 + movq 32(%rdi), %r10 + adcxq %rcx, %r9 adoxq %r8, %r10 - movq %r11, 40(%rdi) - adcxq %r14, %r10 - movq %r12, %r14 + movq %r9, 24(%rdi) + # a[i+3] += m[3] * mu + mulxq 24(%rsi), %rcx, %r8 + movq 40(%rdi), %r9 + adcxq %rcx, %r10 + adoxq %r8, %r9 + movq %r10, 32(%rdi) + # a[i+4] += m[4] * mu + mulxq 32(%rsi), %rcx, %r8 + movq 48(%rdi), %r10 + adcxq %rcx, %r9 + adoxq %r8, %r10 + movq %r9, 40(%rdi) + # a[i+5] += m[5] * mu + mulxq 40(%rsi), %rcx, %r8 + movq 56(%rdi), %r9 + adcxq %rcx, %r10 + adoxq %r8, %r9 movq %r10, 48(%rdi) - adoxq %r12, %r14 - adcxq %r12, %r14 - # i -= 1 - addq $8, %rdi - decq %r9 - jnz L_mont_loop_order_avx2_6 - movq %r13, (%rdi) - negq %r14 - movq %r14, %rcx - movq %rsi, %rdx - movq %rdi, %rsi - subq $48, %rdi -#ifndef __APPLE__ - callq sp_384_cond_sub_avx2_6@plt -#else - callq _sp_384_cond_sub_avx2_6 -#endif /* __APPLE__ */ - pop %r14 + adcxq %r13, %r9 + movq %r9, 56(%rdi) + movq %r11, %r13 + adoxq %r11, %r13 + adcxq %r11, %r13 + # mu = a[i] * mp + movq %r12, %rdx + movq %r12, %r9 + imulq %rax, %rdx + xorq %r11, %r11 + # a[i+0] += m[0] * mu + mulxq (%rsi), %rcx, %r8 + movq 24(%rdi), %r12 + adcxq %rcx, %r9 + adoxq %r8, %r12 + # a[i+1] += m[1] * mu + mulxq 8(%rsi), %rcx, %r8 + movq 32(%rdi), %r9 + adcxq %rcx, %r12 + adoxq %r8, %r9 + # a[i+2] += m[2] * mu + mulxq 16(%rsi), %rcx, %r8 + movq 40(%rdi), %r10 + adcxq %rcx, %r9 + adoxq %r8, %r10 + movq %r9, 32(%rdi) + # a[i+3] += m[3] * mu + mulxq 24(%rsi), %rcx, %r8 + movq 48(%rdi), %r9 + adcxq %rcx, %r10 + adoxq %r8, %r9 + movq %r10, 40(%rdi) + # a[i+4] += m[4] * mu + mulxq 32(%rsi), %rcx, %r8 + movq 56(%rdi), %r10 + adcxq %rcx, %r9 + adoxq %r8, %r10 + movq %r9, 48(%rdi) + # a[i+5] += m[5] * mu + mulxq 40(%rsi), %rcx, %r8 + movq 64(%rdi), %r9 + adcxq %rcx, %r10 + adoxq %r8, %r9 + movq %r10, 56(%rdi) + adcxq %r13, %r9 + movq %r9, 64(%rdi) + movq %r11, %r13 + adoxq %r11, %r13 + adcxq %r11, %r13 + # mu = a[i] * mp + movq %r12, %rdx + movq %r12, %r9 + imulq %rax, %rdx + xorq %r11, %r11 + # a[i+0] += m[0] * mu + mulxq (%rsi), %rcx, %r8 + movq 32(%rdi), %r12 + adcxq %rcx, %r9 + adoxq %r8, %r12 + # a[i+1] += m[1] * mu + mulxq 8(%rsi), %rcx, %r8 + movq 40(%rdi), %r9 + adcxq %rcx, %r12 + adoxq %r8, %r9 + # a[i+2] += m[2] * mu + mulxq 16(%rsi), %rcx, %r8 + movq 48(%rdi), %r10 + adcxq %rcx, %r9 + adoxq %r8, %r10 + movq %r9, 40(%rdi) + # a[i+3] += m[3] * mu + mulxq 24(%rsi), %rcx, %r8 + movq 56(%rdi), %r9 + adcxq %rcx, %r10 + adoxq %r8, %r9 + movq %r10, 48(%rdi) + # a[i+4] += m[4] * mu + mulxq 32(%rsi), %rcx, %r8 + movq 64(%rdi), %r10 + adcxq %rcx, %r9 + adoxq %r8, %r10 + movq %r9, 56(%rdi) + # a[i+5] += m[5] * mu + mulxq 40(%rsi), %rcx, %r8 + movq 72(%rdi), %r9 + adcxq %rcx, %r10 + adoxq %r8, %r9 + movq %r10, 64(%rdi) + adcxq %r13, %r9 + movq %r9, 72(%rdi) + movq %r11, %r13 + adoxq %r11, %r13 + adcxq %r11, %r13 + # mu = a[i] * mp + movq %r12, %rdx + movq %r12, %r9 + imulq %rax, %rdx + xorq %r11, %r11 + # a[i+0] += m[0] * mu + mulxq (%rsi), %rcx, %r8 + movq 40(%rdi), %r12 + adcxq %rcx, %r9 + adoxq %r8, %r12 + # a[i+1] += m[1] * mu + mulxq 8(%rsi), %rcx, %r8 + movq 48(%rdi), %r9 + adcxq %rcx, %r12 + adoxq %r8, %r9 + # a[i+2] += m[2] * mu + mulxq 16(%rsi), %rcx, %r8 + movq 56(%rdi), %r10 + adcxq %rcx, %r9 + adoxq %r8, %r10 + movq %r9, 48(%rdi) + # a[i+3] += m[3] * mu + mulxq 24(%rsi), %rcx, %r8 + movq 64(%rdi), %r9 + adcxq %rcx, %r10 + adoxq %r8, %r9 + movq %r10, 56(%rdi) + # a[i+4] += m[4] * mu + mulxq 32(%rsi), %rcx, %r8 + movq 72(%rdi), %r10 + adcxq %rcx, %r9 + adoxq %r8, %r10 + movq %r9, 64(%rdi) + # a[i+5] += m[5] * mu + mulxq 40(%rsi), %rcx, %r8 + movq 80(%rdi), %r9 + adcxq %rcx, %r10 + adoxq %r8, %r9 + movq %r10, 72(%rdi) + adcxq %r13, %r9 + movq %r9, 80(%rdi) + movq %r11, %r13 + adoxq %r11, %r13 + adcxq %r11, %r13 + # mu = a[i] * mp + movq %r12, %rdx + movq %r12, %r9 + imulq %rax, %rdx + xorq %r11, %r11 + # a[i+0] += m[0] * mu + mulxq (%rsi), %rcx, %r8 + movq 48(%rdi), %r12 + adcxq %rcx, %r9 + adoxq %r8, %r12 + # a[i+1] += m[1] * mu + mulxq 8(%rsi), %rcx, %r8 + movq 56(%rdi), %r9 + adcxq %rcx, %r12 + adoxq %r8, %r9 + # a[i+2] += m[2] * mu + mulxq 16(%rsi), %rcx, %r8 + movq 64(%rdi), %r10 + adcxq %rcx, %r9 + adoxq %r8, %r10 + movq %r9, 56(%rdi) + # a[i+3] += m[3] * mu + mulxq 24(%rsi), %rcx, %r8 + movq 72(%rdi), %r9 + adcxq %rcx, %r10 + adoxq %r8, %r9 + movq %r10, 64(%rdi) + # a[i+4] += m[4] * mu + mulxq 32(%rsi), %rcx, %r8 + movq 80(%rdi), %r10 + adcxq %rcx, %r9 + adoxq %r8, %r10 + movq %r9, 72(%rdi) + # a[i+5] += m[5] * mu + mulxq 40(%rsi), %rcx, %r8 + movq 88(%rdi), %r9 + adcxq %rcx, %r10 + adoxq %r8, %r9 + movq %r10, 80(%rdi) + adcxq %r13, %r9 + movq %r9, 88(%rdi) + movq %r11, %r13 + adoxq %r11, %r13 + adcxq %r11, %r13 + negq %r13 + movq %rdi, %rax + addq $48, %rdi + movq (%rsi), %r8 + movq %r12, %rdx + pextq %r13, %r8, %r8 + subq %r8, %rdx + movq 8(%rsi), %r8 + movq 8(%rdi), %rcx + pextq %r13, %r8, %r8 + movq %rdx, (%rax) + sbbq %r8, %rcx + movq 16(%rsi), %rdx + movq 16(%rdi), %r8 + pextq %r13, %rdx, %rdx + movq %rcx, 8(%rax) + sbbq %rdx, %r8 + movq 24(%rsi), %rcx + movq 24(%rdi), %rdx + pextq %r13, %rcx, %rcx + movq %r8, 16(%rax) + sbbq %rcx, %rdx + movq 32(%rsi), %r8 + movq 32(%rdi), %rcx + pextq %r13, %r8, %r8 + movq %rdx, 24(%rax) + sbbq %r8, %rcx + movq 40(%rsi), %rdx + movq 40(%rdi), %r8 + pextq %r13, %rdx, %rdx + movq %rcx, 32(%rax) + sbbq %rdx, %r8 + movq %r8, 40(%rax) pop %r13 pop %r12 repz retq @@ -34629,30 +40611,78 @@ sp_384_sub_in_place_6: .p2align 4 _sp_384_sub_in_place_6: #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 %rcx, 40(%rdi) + movq (%rsi), %rdx + movq 8(%rsi), %rcx + movq 16(%rsi), %r8 + movq 24(%rsi), %r9 + movq 32(%rsi), %r10 + movq 40(%rsi), %r11 + subq %rdx, (%rdi) + sbbq %rcx, 8(%rdi) + sbbq %r8, 16(%rdi) + sbbq %r9, 24(%rdi) + sbbq %r10, 32(%rdi) + sbbq %r11, 40(%rdi) sbbq $0, %rax repz retq #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__ +.globl sp_384_cond_sub_avx2_6 +.type sp_384_cond_sub_avx2_6,@function +.align 16 +sp_384_cond_sub_avx2_6: +#else +.globl _sp_384_cond_sub_avx2_6 +.p2align 4 +_sp_384_cond_sub_avx2_6: +#endif /* __APPLE__ */ + movq $0, %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 $0, %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. @@ -34737,42 +40767,44 @@ sp_384_mul_d_avx2_6: .p2align 4 _sp_384_mul_d_avx2_6: #endif /* __APPLE__ */ + movq %rdx, %rax # A[0] * B - xorq %r10, %r10 - mulxq (%rsi), %r8, %r9 - movq %r8, (%rdi) + movq %rax, %rdx + xorq %r11, %r11 + mulxq (%rsi), %r9, %r10 + movq %r9, (%rdi) # A[1] * B - mulxq 8(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 8(%rdi) - adoxq %rcx, %r8 + mulxq 8(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 8(%rdi) + adoxq %r8, %r9 # A[2] * B - mulxq 16(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 16(%rdi) - adoxq %rcx, %r9 + mulxq 16(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 16(%rdi) + adoxq %r8, %r10 # A[3] * B - mulxq 24(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - movq %r9, 24(%rdi) - adoxq %rcx, %r8 + mulxq 24(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + movq %r10, 24(%rdi) + adoxq %r8, %r9 # A[4] * B - mulxq 32(%rsi), %rax, %rcx - movq %r10, %r9 - adcxq %rax, %r8 - movq %r8, 32(%rdi) - adoxq %rcx, %r9 + mulxq 32(%rsi), %rcx, %r8 + movq %r11, %r10 + adcxq %rcx, %r9 + movq %r9, 32(%rdi) + adoxq %r8, %r10 # A[5] * B - mulxq 40(%rsi), %rax, %rcx - movq %r10, %r8 - adcxq %rax, %r9 - adoxq %rcx, %r8 - adcxq %r10, %r8 - movq %r9, 40(%rdi) - movq %r8, 48(%rdi) + mulxq 40(%rsi), %rcx, %r8 + movq %r11, %r9 + adcxq %rcx, %r10 + adoxq %r8, %r9 + adcxq %r11, %r9 + movq %r10, 40(%rdi) + movq %r9, 48(%rdi) repz retq #ifndef __APPLE__ .size sp_384_mul_d_avx2_6,.-sp_384_mul_d_avx2_6 From 92114fef753bec7516bd3bfec1f31871f328f3f8 Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 24 Feb 2020 19:24:53 -0800 Subject: [PATCH 167/649] Fixes for building NO_ASN_TIME with OPENSSL_EXTRA. Fixes #2820. * `./configure --enable-opensslextra CFLAGS="-DNO_ASN_TIME"` --- src/internal.c | 4 ++-- src/ssl.c | 11 +++++++++-- tests/api.c | 19 ++++++++++--------- wolfssl/wolfcrypt/settings.h | 6 ++++++ 4 files changed, 27 insertions(+), 13 deletions(-) diff --git a/src/internal.c b/src/internal.c index d73a881c7..f457c4841 100644 --- a/src/internal.c +++ b/src/internal.c @@ -7309,8 +7309,7 @@ ProtocolVersion MakeDTLSv1_2(void) #endif /* WOLFSSL_DTLS */ - - +#ifndef NO_ASN_TIME #if defined(USER_TICKS) #if 0 word32 LowResTimer(void) @@ -7525,6 +7524,7 @@ ProtocolVersion MakeDTLSv1_2(void) return (word32)XTIME(0); } #endif +#endif /* !NO_ASN_TIME */ #if !defined(WOLFSSL_NO_CLIENT_AUTH) && \ ((defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \ (defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH))) diff --git a/src/ssl.c b/src/ssl.c index 96b99596c..41bec979f 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -23539,6 +23539,7 @@ int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b) } } + #ifndef NO_ASN_TIME /* print validity */ { char tmp[80]; @@ -23547,6 +23548,7 @@ int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b) (int)XSTRLEN(" Validity\n")) <= 0) { return WOLFSSL_FAILURE; } + if (wolfSSL_BIO_write(bio, " Not Before: ", (int)XSTRLEN(" Not Before: ")) <= 0) { return WOLFSSL_FAILURE; @@ -23591,6 +23593,7 @@ int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b) return WOLFSSL_FAILURE; } } + #endif /* print subject */ { @@ -26450,6 +26453,7 @@ void wolfSSL_X509_OBJECT_free_contents(WOLFSSL_X509_OBJECT* obj) } #endif +#ifndef NO_ASN_TIME int wolfSSL_X509_cmp_current_time(const WOLFSSL_ASN1_TIME* asnTime) { return wolfSSL_X509_cmp_time(asnTime, NULL); @@ -26534,6 +26538,7 @@ int wolfSSL_X509_cmp_time(const WOLFSSL_ASN1_TIME* asnTime, time_t* cmpTime) return ret; } +#endif /* !NO_ASN_TIME */ #if defined(OPENSSL_EXTRA) && !defined(NO_ASN_TIME) && !defined(USER_TIME) && \ !defined(TIME_OVERRIDES) @@ -26754,6 +26759,7 @@ WOLFSSL_ASN1_INTEGER* wolfSSL_X509_get_serialNumber(WOLFSSL_X509* x509) #if defined(WOLFSSL_MYSQL_COMPATIBLE) || defined(WOLFSSL_NGINX) || \ defined(WOLFSSL_HAPROXY) || defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) +#ifndef NO_ASN_TIME int wolfSSL_ASN1_TIME_print(WOLFSSL_BIO* bio, const WOLFSSL_ASN1_TIME* asnTime) { char buf[MAX_TIME_STRING_SZ]; @@ -26781,7 +26787,6 @@ int wolfSSL_ASN1_TIME_print(WOLFSSL_BIO* bio, const WOLFSSL_ASN1_TIME* asnTime) return ret; } - char* wolfSSL_ASN1_TIME_to_string(WOLFSSL_ASN1_TIME* t, char* buf, int len) { WOLFSSL_ENTER("wolfSSL_ASN1_TIME_to_string"); @@ -26802,6 +26807,7 @@ char* wolfSSL_ASN1_TIME_to_string(WOLFSSL_ASN1_TIME* t, char* buf, int len) return buf; } +#endif /* !NO_ASN_TIME */ #endif /* WOLFSSL_MYSQL_COMPATIBLE || WOLFSSL_NGINX || WOLFSSL_HAPROXY || OPENSSL_EXTRA*/ @@ -29454,6 +29460,7 @@ int wolfSSL_BIO_dump(WOLFSSL_BIO *bio, const char *buf, int length) return ret; } +#ifndef NO_ASN_TIME int wolfSSL_ASN1_UTCTIME_print(WOLFSSL_BIO* bio, const WOLFSSL_ASN1_UTCTIME* a) { WOLFSSL_ENTER("ASN1_UTCTIME_print"); @@ -29468,7 +29475,6 @@ int wolfSSL_ASN1_UTCTIME_print(WOLFSSL_BIO* bio, const WOLFSSL_ASN1_UTCTIME* a) return wolfSSL_ASN1_TIME_print(bio, a); } - /* Checks the ASN1 syntax of "a" * returns WOLFSSL_SUCCESS (1) if correct otherwise WOLFSSL_FAILURE (0) */ int wolfSSL_ASN1_TIME_check(const WOLFSSL_ASN1_TIME* a) @@ -29484,6 +29490,7 @@ int wolfSSL_ASN1_TIME_check(const WOLFSSL_ASN1_TIME* a) } return WOLFSSL_SUCCESS; } +#endif /* !NO_ASN_TIME */ #ifndef NO_WOLFSSL_STUB int wolfSSL_ASN1_TIME_diff(int *pday, int *psec, diff --git a/tests/api.c b/tests/api.c index 8bbfbeb6c..23f51d060 100644 --- a/tests/api.c +++ b/tests/api.c @@ -20388,7 +20388,7 @@ static void test_wolfSSL_ASN1_TIME_print(void) static void test_wolfSSL_ASN1_UTCTIME_print(void) { - #if defined(OPENSSL_EXTRA) +#if defined(OPENSSL_EXTRA) && !defined(NO_ASN_TIME) BIO* bio; ASN1_UTCTIME* utc = NULL; unsigned char buf[25]; @@ -20429,7 +20429,7 @@ static void test_wolfSSL_ASN1_UTCTIME_print(void) BIO_free(bio); printf(resultFmt, passed); - #endif /* OPENSSL_EXTRA */ +#endif /* OPENSSL_EXTRA && !NO_ASN_TIME */ } @@ -23365,7 +23365,7 @@ static void test_wolfSSL_DES_ecb_encrypt(void) static void test_wolfSSL_ASN1_TIME_adj(void) { -#if defined(OPENSSL_EXTRA) && !defined(NO_ASN1_TIME) \ +#if defined(OPENSSL_EXTRA) && !defined(NO_ASN_TIME) \ && !defined(USER_TIME) && !defined(TIME_OVERRIDES) const int year = 365*24*60*60; @@ -23455,7 +23455,7 @@ static void test_wolfSSL_ASN1_TIME_adj(void) static void test_wolfSSL_X509_cmp_time(void) { -#if defined(OPENSSL_EXTRA) && !defined(NO_ASN1_TIME) \ +#if defined(OPENSSL_EXTRA) && !defined(NO_ASN_TIME) \ && !defined(USER_TIME) && !defined(TIME_OVERRIDES) WOLFSSL_ASN1_TIME asn_time; time_t t; @@ -23477,9 +23477,10 @@ static void test_wolfSSL_X509_cmp_time(void) static void test_wolfSSL_X509_time_adj(void) { -#if defined(OPENSSL_EXTRA) && !defined(NO_ASN1_TIME) && \ +#if defined(OPENSSL_EXTRA) && !defined(NO_ASN_TIME) && \ !defined(USER_TIME) && !defined(TIME_OVERRIDES) && \ - defined(USE_CERT_BUFFERS_2048) && !defined(NO_RSA) + defined(USE_CERT_BUFFERS_2048) && !defined(NO_RSA) && \ + !defined(NO_ASN_TIME) X509* x509; time_t t, not_before, not_after; @@ -24647,7 +24648,7 @@ static void test_wolfSSL_X509_set_name(void) static void test_wolfSSL_X509_set_notAfter(void) { #if (defined(OPENSSL_ALL) || defined(WOLFSSL_APACHE_HTTPD)) \ - && !defined(NO_ASN1_TIME) && !defined(USER_TIME) && \ + && !defined(NO_ASN_TIME) && !defined(USER_TIME) && \ !defined(TIME_OVERRIDES) && !defined(NO_CERTS) && \ defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ) &&\ !defined(TIME_T_NOT_64BIT) && !defined(NO_64BIT) @@ -24702,7 +24703,7 @@ static void test_wolfSSL_X509_set_notAfter(void) static void test_wolfSSL_X509_set_notBefore(void) { #if (defined(OPENSSL_ALL) || defined(WOLFSSL_APACHE_HTTPD)) \ - && !defined(NO_ASN1_TIME) && !defined(USER_TIME) && \ + && !defined(NO_ASN_TIME) && !defined(USER_TIME) && \ !defined(TIME_OVERRIDES) && !defined(NO_CERTS) && \ defined(WOLFSSL_CERT_GEN) && defined(WOLFSSL_CERT_REQ) @@ -26462,7 +26463,7 @@ static void test_wolfSSL_ASN1_STRING_print_ex(void){ } static void test_wolfSSL_ASN1_TIME_to_generalizedtime(void){ -#if defined(OPENSSL_EXTRA) && !defined(NO_ASN1_TIME) +#if defined(OPENSSL_EXTRA) && !defined(NO_ASN_TIME) WOLFSSL_ASN1_TIME *t; WOLFSSL_ASN1_TIME *out; WOLFSSL_ASN1_TIME *gtime; diff --git a/wolfssl/wolfcrypt/settings.h b/wolfssl/wolfcrypt/settings.h index 594e73f91..dd047c2a4 100644 --- a/wolfssl/wolfcrypt/settings.h +++ b/wolfssl/wolfcrypt/settings.h @@ -2168,6 +2168,12 @@ extern void uITRON4_free(void *p) ; #undef WOLFSSL_SMALL_STACK #endif +/* The client session cache requires time for timeout */ +#if defined(NO_ASN_TIME) && !defined(NO_SESSION_CACHE) + #define NO_SESSION_CACHE +#endif + + #ifdef __cplusplus } /* extern "C" */ #endif From debb79269017a647260c3a97560b467cf8837b35 Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Fri, 28 Feb 2020 17:55:19 -0700 Subject: [PATCH 168/649] fix PKCS7 encrypted content decoding for streaming API usage --- wolfcrypt/src/pkcs7.c | 117 ++++++++++++++++++++++-------------------- 1 file changed, 62 insertions(+), 55 deletions(-) diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 12494d970..9142d7eb1 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -84,6 +84,7 @@ struct PKCS7State { word32 varOne; int varTwo; int varThree; + int varFour; word32 vers; word32 idx; /* index read into current input buffer */ @@ -373,23 +374,25 @@ static long wc_PKCS7_GetMaxStream(PKCS7* pkcs7, byte flag, byte* in, /* setter function for stored variables */ static void wc_PKCS7_StreamStoreVar(PKCS7* pkcs7, word32 var1, int var2, - int var3) + int var3, int var4) { if (pkcs7 != NULL && pkcs7->stream != NULL) { pkcs7->stream->varOne = var1; pkcs7->stream->varTwo = var2; pkcs7->stream->varThree = var3; + pkcs7->stream->varFour = var4; } } /* getter function for stored variables */ static void wc_PKCS7_StreamGetVar(PKCS7* pkcs7, word32* var1, int* var2, - int* var3) + int* var3, int* var4) { if (pkcs7 != NULL && pkcs7->stream != NULL) { if (var1 != NULL) *var1 = pkcs7->stream->varOne; if (var2 != NULL) *var2 = pkcs7->stream->varTwo; if (var3 != NULL) *var3 = pkcs7->stream->varThree; + if (var4 != NULL) *var4 = pkcs7->stream->varFour; } } @@ -4286,7 +4289,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, if (pkiMsg2 && pkiMsg2Sz > 0) { pkcs7->stream->maxLen += pkiMsg2Sz + pkcs7->contentSz; } - wc_PKCS7_StreamStoreVar(pkcs7, totalSz, 0, 0); + wc_PKCS7_StreamStoreVar(pkcs7, totalSz, 0, 0, 0); #endif wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE2); @@ -4300,7 +4303,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, break; } - wc_PKCS7_StreamGetVar(pkcs7, &totalSz, 0, 0); + wc_PKCS7_StreamGetVar(pkcs7, &totalSz, 0, 0, 0); if (pkcs7->stream->length > 0) pkiMsgSz = pkcs7->stream->length; #ifdef ASN_BER_TO_DER @@ -4458,7 +4461,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) { break; } - wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, localIdx, length); + wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, localIdx, length, 0); /* content length is in multiple parts */ if (multiPart) { @@ -4489,7 +4492,8 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, else #endif pkiMsgSz = (word32)rc; - wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, (int*)&localIdx, &length); + wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, (int*)&localIdx, + &length, 0); if (pkcs7->stream->length > 0) { localIdx = 0; @@ -4649,7 +4653,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) { break; } - wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, 0, length); + wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, 0, length, 0); if (length > 0) { pkcs7->stream->expected = length; } @@ -4672,7 +4676,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, break; } - wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, &length); + wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, &length, 0); if (pkcs7->stream->flagOne) { pkiMsg2 = pkiMsg; } @@ -4851,8 +4855,8 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, pkcs7->stream->expected = (pkcs7->stream->maxLen - pkcs7->stream->totalRd) + pkcs7->stream->length; - wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, 0); - wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, 0, length); + wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, 0, 0); + wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, 0, length, 0); #endif wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE5); FALL_THROUGH; @@ -4863,7 +4867,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, pkcs7->stream->expected, &pkiMsg, &idx)) != 0) { break; } - wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, &length); + wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, &length, 0); if (pkcs7->stream->flagOne) { pkiMsg2 = pkiMsg; } @@ -4914,7 +4918,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) { break; } - wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, 0, length); + wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, 0, length, 0); if (in2 && in2Sz > 0 && hashBuf && hashSz > 0) { if (length > 0) { @@ -4941,7 +4945,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, break; } - wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, &length); + wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, &length, 0); if (pkcs7->stream->flagOne) { pkiMsg2 = pkiMsg; } @@ -8022,7 +8026,7 @@ static int wc_PKCS7_DecryptKtri(PKCS7* pkcs7, byte* in, word32 inSz, if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) { break; } - wc_PKCS7_StreamStoreVar(pkcs7, 0, sidType, version); + wc_PKCS7_StreamStoreVar(pkcs7, 0, sidType, version, 0); /* @TODO getting total amount left because of GetInt call later on * this could be optimized to stream better */ @@ -8048,7 +8052,7 @@ static int wc_PKCS7_DecryptKtri(PKCS7* pkcs7, byte* in, word32 inSz, } pkiMsgSz = (word32)rc; - wc_PKCS7_StreamGetVar(pkcs7, NULL, &sidType, &version); + wc_PKCS7_StreamGetVar(pkcs7, NULL, &sidType, &version, 0); /* @TODO get expected size for next part, does not account for * GetInt call well */ @@ -8165,7 +8169,7 @@ static int wc_PKCS7_DecryptKtri(PKCS7* pkcs7, byte* in, word32 inSz, if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) { break; } - wc_PKCS7_StreamStoreVar(pkcs7, encryptedKeySz, sidType, version); + wc_PKCS7_StreamStoreVar(pkcs7, encryptedKeySz, sidType, version, 0); pkcs7->stream->expected = encryptedKeySz; #endif wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_KTRI_3); @@ -10212,7 +10216,7 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* in, if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) { break; } - wc_PKCS7_StreamStoreVar(pkcs7, encOID, expBlockSz, length); + wc_PKCS7_StreamStoreVar(pkcs7, encOID, expBlockSz, length, 0); pkcs7->stream->contentSz = blockKeySz; pkcs7->stream->expected = length + MAX_LENGTH_SZ + MAX_LENGTH_SZ + ASN_TAG_SZ + ASN_TAG_SZ; @@ -10236,7 +10240,7 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* in, } pkiMsgSz = (word32)rc; - wc_PKCS7_StreamGetVar(pkcs7, 0, 0, &length); + wc_PKCS7_StreamGetVar(pkcs7, 0, 0, &length, 0); tmpIv = pkcs7->stream->tmpIv; if (tmpIv == NULL) { /* check added to help out static analysis tool */ @@ -10269,7 +10273,42 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* in, ret = ASN_PARSE_E; } - if (ret == 0 && explicitOctet) { + if (ret != 0) + break; + + #ifndef NO_PKCS7_STREAM + if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) { + break; + } + pkcs7->stream->expected = encryptedContentTotalSz; + wc_PKCS7_StreamGetVar(pkcs7, &encOID, &expBlockSz, 0, 0); + wc_PKCS7_StreamStoreVar(pkcs7, encOID, expBlockSz, explicitOctet, + encryptedContentTotalSz); + #endif + wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_ENV_5); + FALL_THROUGH; + + case WC_PKCS7_ENV_5: + + #ifndef NO_PKCS7_STREAM + if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, + pkcs7->stream->expected, &pkiMsg, &idx)) != 0) { + return ret; + } + + wc_PKCS7_StreamGetVar(pkcs7, &encOID, &expBlockSz, &explicitOctet, + &encryptedContentTotalSz); + tmpIv = pkcs7->stream->tmpIv; + + /* restore decrypted key */ + decryptedKey = pkcs7->stream->aad; + decryptedKeySz = pkcs7->stream->aadSz; + blockKeySz = pkcs7->stream->contentSz; + #else + ret = 0; + #endif + + if (explicitOctet) { /* encrypted content may be fragmented into multiple * consecutive OCTET STRINGs, if so loop through * collecting and caching encrypted content bytes */ @@ -10311,39 +10350,6 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* in, idx += encryptedContentTotalSz; } - if (ret != 0) - break; - - #ifndef NO_PKCS7_STREAM - if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) { - break; - } - pkcs7->stream->expected = 0; - wc_PKCS7_StreamGetVar(pkcs7, &encOID, &expBlockSz, 0); - wc_PKCS7_StreamStoreVar(pkcs7, encOID, expBlockSz, 0); - #endif - wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_ENV_5); - FALL_THROUGH; - - case WC_PKCS7_ENV_5: - - #ifndef NO_PKCS7_STREAM - if ((ret = wc_PKCS7_AddDataToStream(pkcs7, in, inSz, - pkcs7->stream->expected, &pkiMsg, &idx)) != 0) { - return ret; - } - - wc_PKCS7_StreamGetVar(pkcs7, &encOID, &expBlockSz, NULL); - tmpIv = pkcs7->stream->tmpIv; - - /* restore decrypted key */ - decryptedKey = pkcs7->stream->aad; - decryptedKeySz = pkcs7->stream->aadSz; - blockKeySz = pkcs7->stream->contentSz; - #else - ret = 0; - #endif - /* use cached content */ encryptedContent = pkcs7->cachedEncryptedContent; encryptedContentSz = pkcs7->cachedEncryptedContentSz; @@ -11108,7 +11114,7 @@ WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(PKCS7* pkcs7, byte* in, if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) { break; } - wc_PKCS7_StreamStoreVar(pkcs7, encOID, blockKeySz, 0); + wc_PKCS7_StreamStoreVar(pkcs7, encOID, blockKeySz, 0, 0); #endif wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_4); FALL_THROUGH; @@ -11211,7 +11217,7 @@ WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(PKCS7* pkcs7, byte* in, pkcs7->stream->expected = encryptedContentSz; wc_PKCS7_StreamStoreVar(pkcs7, encOID, blockKeySz, - encryptedContentSz); + encryptedContentSz, 0); #endif wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_5); @@ -11456,7 +11462,8 @@ authenv_atrbend: encodedAttribs = pkcs7->stream->aad; } - wc_PKCS7_StreamGetVar(pkcs7, &encOID, &blockKeySz, &encryptedContentSz); + wc_PKCS7_StreamGetVar(pkcs7, &encOID, &blockKeySz, + &encryptedContentSz, 0); encryptedContent = pkcs7->stream->bufferPt; #ifdef WOLFSSL_SMALL_STACK decryptedKey = pkcs7->stream->key; From 6334dd9cb0ea24f84f593321641a4d93fce6a5c7 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Thu, 20 Feb 2020 16:15:30 +1000 Subject: [PATCH 169/649] Allow mutual authentication to be required for TLS 1.3 --- examples/server/server.c | 47 +++++++++++++++++++++++++++++----------- scripts/tls13.test | 16 ++++++++++++++ src/internal.c | 13 +++++++++++ src/tls13.c | 42 +++++++++++++++++++++++++++++++++++ wolfssl/internal.h | 4 ++++ wolfssl/ssl.h | 3 +++ 6 files changed, 112 insertions(+), 13 deletions(-) diff --git a/examples/server/server.c b/examples/server/server.c index b9350292a..b891e3965 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -614,23 +614,26 @@ static const char* server_usage_msg[][49] = { #ifdef HAVE_SESSION_TICKET "-T Do not generate session ticket\n", /* 44 */ #endif +#ifdef WOLFSSL_TLS13 + "-F Mutual authentication is required\n", /* 45 */ +#endif #ifdef WOLFSSL_POST_HANDSHAKE_AUTH - "-Q Request certificate from client post-handshake\n", /* 45 */ + "-Q Request certificate from client post-handshake\n", /* 46 */ #endif #ifdef WOLFSSL_SEND_HRR_COOKIE - "-J Server sends Cookie Extension containing state\n", /* 46 */ + "-J Server sends Cookie Extension containing state\n", /* 47 */ #endif #endif /* WOLFSSL_TLS13 */ #ifdef WOLFSSL_EARLY_DATA - "-0 Early data read from client (0-RTT handshake)\n", /* 47 */ + "-0 Early data read from client (0-RTT handshake)\n", /* 48 */ #endif #ifdef WOLFSSL_MULTICAST - "-3 Multicast, grpid < 256\n", /* 48 */ + "-3 Multicast, grpid < 256\n", /* 49 */ #endif "-1 Display a result by specified language." - "\n 0: English, 1: Japanese\n", /* 49 */ + "\n 0: English, 1: Japanese\n", /* 50 */ #ifdef HAVE_TRUSTED_CA - "-5 Use Trusted CA Key Indication\n", /* 52 */ + "-5 Use Trusted CA Key Indication\n", /* 53 */ #endif #ifdef HAVE_CURVE448 "-8 Pre-generate Key share using Curve448 only\n", /* 55 */ @@ -734,25 +737,28 @@ static const char* server_usage_msg[][49] = { #ifdef HAVE_SESSION_TICKET "-T セッションチケットを生成しない\n", /* 44 */ #endif +#ifdef WOLFSSL_TLS13 + "-F Mutual authentication is required\n", /* 45 */ +#endif #ifdef WOLFSSL_POST_HANDSHAKE_AUTH "-Q クライアントのポストハンドシェイクから" - "証明書を要求する\n", /* 45 */ + "証明書を要求する\n", /* 46 */ #endif #ifdef WOLFSSL_SEND_HRR_COOKIE - "-J サーバーの状態を含むTLS Cookie 拡張を送信する\n", /* 46 */ + "-J サーバーの状態を含むTLS Cookie 拡張を送信する\n", /* 47 */ #endif #endif /* WOLFSSL_TLS13 */ #ifdef WOLFSSL_EARLY_DATA "-0 クライアントからの Early Data 読み取り" - "(0-RTTハンドシェイク)\n", /* 47 */ + "(0-RTTハンドシェイク)\n", /* 48 */ #endif #ifdef WOLFSSL_MULTICAST - "-3 マルチキャスト, grpid < 256\n", /* 48 */ + "-3 マルチキャスト, grpid < 256\n", /* 49 */ #endif "-1 指定された言語で結果を表示します。" - "\n 0: 英語、 1: 日本語\n", /* 49 */ + "\n 0: 英語、 1: 日本語\n", /* 50 */ #ifdef HAVE_TRUSTED_CA - "-5 信頼できる認証局の鍵表示を使用する\n", /* 52 */ + "-5 信頼できる認証局の鍵表示を使用する\n", /* 53 */ #endif #ifdef HAVE_CURVE448 "-8 Pre-generate Key share using Curve448 only\n", /* 55 */ @@ -852,6 +858,9 @@ static void Usage(void) #ifdef HAVE_SESSION_TICKET printf("%s", msg[++msgId]); /* -T */ #endif +#ifdef WOLFSSL_TLS13 + printf("%s", msg[++msgId]); /* -F */ +#endif #ifdef WOLFSSL_POST_HANDSHAKE_AUTH printf("%s", msg[++msgId]); /* -Q */ #endif @@ -986,6 +995,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) int noPskDheKe = 0; #endif int updateKeysIVs = 0; + int tls13MutualAuth = 0; int postHandAuth = 0; #ifdef WOLFSSL_EARLY_DATA int earlyData = 0; @@ -1071,6 +1081,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) (void)crlFlags; (void)readySignal; (void)updateKeysIVs; + (void)tls13MutualAuth; (void)postHandAuth; (void)mcastID; (void)loadCertKeyIntoSSLObj; @@ -1087,7 +1098,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) /* Not Used: h, z, F, T, V, W, X */ while ((ch = mygetopt(argc, argv, "?:" "abc:defgijk:l:mnop:q:rstuv:wxy" - "A:B:C:D:E:GH:IJKL:MNO:PQR:S:TUVYZ:" + "A:B:C:D:E:FGH:IJKL:MNO:PQR:S:TUVYZ:" "01:23:4:58")) != -1) { switch (ch) { case '?' : @@ -1402,6 +1413,12 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) #endif break; + case 'F' : + #ifdef WOLFSSL_TLS13 + tls13MutualAuth = 1; + #endif + break; + case 'Q' : #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH) postHandAuth = 1; @@ -1745,6 +1762,10 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) } #endif } +#ifdef WOLFSSL_TLS13 + if (tls13MutualAuth) + wolfSSL_CTX_mutual_auth(ctx, 1); +#endif #ifdef HAVE_ECC diff --git a/scripts/tls13.test b/scripts/tls13.test index ba999f41f..7beb9a56b 100755 --- a/scripts/tls13.test +++ b/scripts/tls13.test @@ -111,6 +111,22 @@ if [ $RESULT -eq 0 ]; then fi echo "" +# TLS 1.3 mutual auth required but client doesn't send certificates. +echo -e "\n\nTLS v1.3 mutual auth fail" +port=0 +./examples/server/server -v 4 -F -R $ready_file -p $port & +server_pid=$! +create_port +./examples/client/client -v 4 -x -p $port +RESULT=$? +remove_ready_file +if [ $RESULT -eq 0 ]; then + echo -e "\n\nIssue with requiring mutual authentication" + do_cleanup + exit 1 +fi +echo "" + ./examples/client/client -v 3 2>&1 | grep -- 'Bad SSL version' if [ $? -ne 0 ]; then diff --git a/src/internal.c b/src/internal.c index d73a881c7..bfae99953 100644 --- a/src/internal.c +++ b/src/internal.c @@ -5673,6 +5673,7 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) ssl->options.noTicketTls13 = ctx->noTicketTls13; #endif ssl->options.noPskDheKe = ctx->noPskDheKe; + ssl->options.mutualAuth = ctx->mutualAuth; #if defined(WOLFSSL_POST_HANDSHAKE_AUTH) ssl->options.postHandshakeAuth = ctx->postHandshakeAuth; #endif @@ -9829,6 +9830,9 @@ static void DoCertFatalAlert(WOLFSSL* ssl, int ret) alertWhy = certificate_revoked; } #endif + else if (ret == NO_PEER_CERT) { + alertWhy = certificate_required; + } /* send fatal alert and mark connection closed */ SendAlert(ssl, alert_fatal, alertWhy); /* try to send */ @@ -10600,6 +10604,15 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, args->count = args->totalCerts; args->certIdx = 0; /* select peer cert (first one) */ + #ifdef WOLFSSL_TLS13 + if (args->count == 0 && ssl->options.tls1_3 && + ssl->options.mutualAuth && + ssl->options.side == WOLFSSL_SERVER_END) { + ret = NO_PEER_CERT; + DoCertFatalAlert(ssl, ret); + } + #endif + args->dCertInit = 0; #ifndef WOLFSSL_SMALL_CERT_VERIFY args->dCert = (DecodedCert*)XMALLOC(sizeof(DecodedCert), ssl->heap, diff --git a/src/tls13.c b/src/tls13.c index e5fd49d8b..e2fdfa73e 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -8292,6 +8292,48 @@ int wolfSSL_update_keys(WOLFSSL* ssl) return ret; } +#if !defined(NO_CERTS) +/* Set whether mutual authentication is required for TLS v1.3 connections. + * Server side only. + * + * ctx The SSL/TLS CTX object. + * req 1 to indicate required and 0 when not. + * returns BAD_FUNC_ARG when ctx is NULL, SIDE_ERROR when not a server and + * 0 on success. + */ +int wolfSSL_CTX_mutual_auth(WOLFSSL_CTX* ctx, int req) +{ + if (ctx == NULL || !IsAtLeastTLSv1_3(ctx->method->version)) + return BAD_FUNC_ARG; + if (ctx->method->side == WOLFSSL_CLIENT_END) + return SIDE_ERROR; + + ctx->mutualAuth = req; + + return 0; +} + +/* Set whether mutual authentication is required for a TLS v1.3 connection. + * Server side only. + * + * ssl The SSL/TLS object. + * req 1 to indicate required and 0 when not. + * returns BAD_FUNC_ARG when ssl is NULL, or not using TLS v1.3, + * SIDE_ERROR when not a client and 0 on success. + */ +int wolfSSL_mutual_auth(WOLFSSL* ssl, int req) +{ + if (ssl == NULL || !IsAtLeastTLSv1_3(ssl->version)) + return BAD_FUNC_ARG; + if (ssl->options.side == WOLFSSL_SERVER_END) + return SIDE_ERROR; + + ssl->options.mutualAuth = req; + + return 0; +} +#endif /* NO_CERTS */ + #if !defined(NO_CERTS) && defined(WOLFSSL_POST_HANDSHAKE_AUTH) /* Allow post-handshake authentication in TLS v1.3 connections. * diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 262d8b6b6..776732303 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2658,6 +2658,7 @@ struct WOLFSSL_CTX { #ifdef WOLFSSL_TLS13 byte noTicketTls13:1; /* Server won't create new Ticket */ byte noPskDheKe:1; /* Don't use (EC)DHE with PSK */ + byte mutualAuth:1; /* Mutual authentication required */ #endif #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH) byte postHandshakeAuth:1; /* Post-handshake auth supported. */ @@ -3411,6 +3412,9 @@ typedef struct Options { #endif word16 keepResources:1; /* Keep resources after handshake */ word16 useClientOrder:1; /* Use client's cipher order */ +#ifdef WOLFSSL_TLS13 + word16 mutualAuth:1; /* Mutual authentication is rquired */ +#endif #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH) word16 postHandshakeAuth:1;/* Client send post_handshake_auth * extension */ diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 6397fa177..f2ec11915 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -627,6 +627,7 @@ enum AlertDescription { unrecognized_name = 112, /**< RFC 6066, section 3 */ bad_certificate_status_response = 113, /**< RFC 6066, section 8 */ unknown_psk_identity = 115, /**< RFC 4279, section 2 */ + certificate_required = 116, /**< RFC 8446, section 8.2 */ no_application_protocol = 120 }; @@ -866,6 +867,8 @@ WOLFSSL_API int wolfSSL_no_ticket_TLSv13(WOLFSSL* ssl); WOLFSSL_API int wolfSSL_CTX_no_dhe_psk(WOLFSSL_CTX* ctx); WOLFSSL_API int wolfSSL_no_dhe_psk(WOLFSSL* ssl); WOLFSSL_API int wolfSSL_update_keys(WOLFSSL* ssl); +WOLFSSL_API int wolfSSL_CTX_mutual_auth(WOLFSSL_CTX* ctx, int req); +WOLFSSL_API int wolfSSL_mutual_auth(WOLFSSL* ssl, int req); WOLFSSL_API int wolfSSL_CTX_allow_post_handshake_auth(WOLFSSL_CTX* ctx); WOLFSSL_API int wolfSSL_allow_post_handshake_auth(WOLFSSL* ssl); WOLFSSL_API int wolfSSL_request_certificate(WOLFSSL* ssl); From 8cccb9008b0a38872255ac7426525e19677e7b99 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Fri, 21 Feb 2020 09:43:32 +1000 Subject: [PATCH 170/649] Change to work for other TLS versions Send alert when client doesn't send a certificate on request. --- examples/server/server.c | 22 +++++++-------------- src/internal.c | 17 ++++++++++------ src/ssl.c | 41 +++++++++++++++++++++++++++++++++++++++ src/tls13.c | 42 ---------------------------------------- tests/test-fails.conf | 8 ++++++++ wolfssl/internal.h | 4 +--- wolfssl/ssl.h | 4 ++-- 7 files changed, 70 insertions(+), 68 deletions(-) diff --git a/examples/server/server.c b/examples/server/server.c index b891e3965..12d312cc1 100644 --- a/examples/server/server.c +++ b/examples/server/server.c @@ -614,9 +614,7 @@ static const char* server_usage_msg[][49] = { #ifdef HAVE_SESSION_TICKET "-T Do not generate session ticket\n", /* 44 */ #endif -#ifdef WOLFSSL_TLS13 - "-F Mutual authentication is required\n", /* 45 */ -#endif + "-F Send alert if no mutual authentication\n", /* 45 */ #ifdef WOLFSSL_POST_HANDSHAKE_AUTH "-Q Request certificate from client post-handshake\n", /* 46 */ #endif @@ -737,9 +735,7 @@ static const char* server_usage_msg[][49] = { #ifdef HAVE_SESSION_TICKET "-T セッションチケットを生成しない\n", /* 44 */ #endif -#ifdef WOLFSSL_TLS13 - "-F Mutual authentication is required\n", /* 45 */ -#endif + "-F Send alert if no mutual authentication\n", /* 45 */ #ifdef WOLFSSL_POST_HANDSHAKE_AUTH "-Q クライアントのポストハンドシェイクから" "証明書を要求する\n", /* 46 */ @@ -858,9 +854,7 @@ static void Usage(void) #ifdef HAVE_SESSION_TICKET printf("%s", msg[++msgId]); /* -T */ #endif -#ifdef WOLFSSL_TLS13 printf("%s", msg[++msgId]); /* -F */ -#endif #ifdef WOLFSSL_POST_HANDSHAKE_AUTH printf("%s", msg[++msgId]); /* -Q */ #endif @@ -995,7 +989,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) int noPskDheKe = 0; #endif int updateKeysIVs = 0; - int tls13MutualAuth = 0; + int mutualAuth = 0; int postHandAuth = 0; #ifdef WOLFSSL_EARLY_DATA int earlyData = 0; @@ -1081,7 +1075,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) (void)crlFlags; (void)readySignal; (void)updateKeysIVs; - (void)tls13MutualAuth; + (void)mutualAuth; (void)postHandAuth; (void)mcastID; (void)loadCertKeyIntoSSLObj; @@ -1414,9 +1408,7 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) break; case 'F' : - #ifdef WOLFSSL_TLS13 - tls13MutualAuth = 1; - #endif + mutualAuth = 1; break; case 'Q' : @@ -1762,8 +1754,8 @@ THREAD_RETURN WOLFSSL_THREAD server_test(void* args) } #endif } -#ifdef WOLFSSL_TLS13 - if (tls13MutualAuth) +#ifndef NO_CERTS + if (mutualAuth) wolfSSL_CTX_mutual_auth(ctx, 1); #endif diff --git a/src/internal.c b/src/internal.c index bfae99953..0ffb0d670 100644 --- a/src/internal.c +++ b/src/internal.c @@ -5667,13 +5667,13 @@ int InitSSL(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup) ssl->options.haveEMS = ctx->haveEMS; #endif ssl->options.useClientOrder = ctx->useClientOrder; + ssl->options.mutualAuth = ctx->mutualAuth; #ifdef WOLFSSL_TLS13 #ifdef HAVE_SESSION_TICKET ssl->options.noTicketTls13 = ctx->noTicketTls13; #endif ssl->options.noPskDheKe = ctx->noPskDheKe; - ssl->options.mutualAuth = ctx->mutualAuth; #if defined(WOLFSSL_POST_HANDSHAKE_AUTH) ssl->options.postHandshakeAuth = ctx->postHandshakeAuth; #endif @@ -9831,7 +9831,15 @@ static void DoCertFatalAlert(WOLFSSL* ssl, int ret) } #endif else if (ret == NO_PEER_CERT) { - alertWhy = certificate_required; +#ifdef WOLFSSL_TLS13 + if (ssl->options.tls1_3) { + alertWhy = certificate_required; + } + else +#endif + { + alertWhy = handshake_failure; + } } /* send fatal alert and mark connection closed */ @@ -10604,14 +10612,11 @@ int ProcessPeerCerts(WOLFSSL* ssl, byte* input, word32* inOutIdx, args->count = args->totalCerts; args->certIdx = 0; /* select peer cert (first one) */ - #ifdef WOLFSSL_TLS13 - if (args->count == 0 && ssl->options.tls1_3 && - ssl->options.mutualAuth && + if (args->count == 0 && ssl->options.mutualAuth && ssl->options.side == WOLFSSL_SERVER_END) { ret = NO_PEER_CERT; DoCertFatalAlert(ssl, ret); } - #endif args->dCertInit = 0; #ifndef WOLFSSL_SMALL_CERT_VERIFY diff --git a/src/ssl.c b/src/ssl.c index 96b99596c..54b8e55ff 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -956,6 +956,47 @@ int wolfSSL_dtls(WOLFSSL* ssl) return dtlsOpt; } +#if !defined(NO_CERTS) +/* Set whether mutual authentication is required for connections. + * Server side only. + * + * ctx The SSL/TLS CTX object. + * req 1 to indicate required and 0 when not. + * returns BAD_FUNC_ARG when ctx is NULL, SIDE_ERROR when not a server and + * 0 on success. + */ +int wolfSSL_CTX_mutual_auth(WOLFSSL_CTX* ctx, int req) +{ + if (ctx == NULL) + return BAD_FUNC_ARG; + if (ctx->method->side == WOLFSSL_CLIENT_END) + return SIDE_ERROR; + + ctx->mutualAuth = (byte)req; + + return 0; +} + +/* Set whether mutual authentication is required for the connection. + * Server side only. + * + * ssl The SSL/TLS object. + * req 1 to indicate required and 0 when not. + * returns BAD_FUNC_ARG when ssl is NULL, or not using TLS v1.3, + * SIDE_ERROR when not a client and 0 on success. + */ +int wolfSSL_mutual_auth(WOLFSSL* ssl, int req) +{ + if (ssl == NULL) + return BAD_FUNC_ARG; + if (ssl->options.side == WOLFSSL_SERVER_END) + return SIDE_ERROR; + + ssl->options.mutualAuth = (word16)req; + + return 0; +} +#endif /* NO_CERTS */ #ifndef WOLFSSL_LEANPSK int wolfSSL_dtls_set_peer(WOLFSSL* ssl, void* peer, unsigned int peerSz) diff --git a/src/tls13.c b/src/tls13.c index e2fdfa73e..e5fd49d8b 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -8292,48 +8292,6 @@ int wolfSSL_update_keys(WOLFSSL* ssl) return ret; } -#if !defined(NO_CERTS) -/* Set whether mutual authentication is required for TLS v1.3 connections. - * Server side only. - * - * ctx The SSL/TLS CTX object. - * req 1 to indicate required and 0 when not. - * returns BAD_FUNC_ARG when ctx is NULL, SIDE_ERROR when not a server and - * 0 on success. - */ -int wolfSSL_CTX_mutual_auth(WOLFSSL_CTX* ctx, int req) -{ - if (ctx == NULL || !IsAtLeastTLSv1_3(ctx->method->version)) - return BAD_FUNC_ARG; - if (ctx->method->side == WOLFSSL_CLIENT_END) - return SIDE_ERROR; - - ctx->mutualAuth = req; - - return 0; -} - -/* Set whether mutual authentication is required for a TLS v1.3 connection. - * Server side only. - * - * ssl The SSL/TLS object. - * req 1 to indicate required and 0 when not. - * returns BAD_FUNC_ARG when ssl is NULL, or not using TLS v1.3, - * SIDE_ERROR when not a client and 0 on success. - */ -int wolfSSL_mutual_auth(WOLFSSL* ssl, int req) -{ - if (ssl == NULL || !IsAtLeastTLSv1_3(ssl->version)) - return BAD_FUNC_ARG; - if (ssl->options.side == WOLFSSL_SERVER_END) - return SIDE_ERROR; - - ssl->options.mutualAuth = req; - - return 0; -} -#endif /* NO_CERTS */ - #if !defined(NO_CERTS) && defined(WOLFSSL_POST_HANDSHAKE_AUTH) /* Allow post-handshake authentication in TLS v1.3 connections. * diff --git a/tests/test-fails.conf b/tests/test-fails.conf index 86fb3d4e3..d8ea91fd4 100644 --- a/tests/test-fails.conf +++ b/tests/test-fails.conf @@ -169,3 +169,11 @@ -v 3 -l ECDHE-ECDSA-AES128-GCM-SHA256 -H verifyFail + +# server send alert on no mutual authentication +-v 3 +-F + +# client send alert on no mutual authentication +-v 3 +-x diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 776732303..62a881f1c 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2658,8 +2658,8 @@ struct WOLFSSL_CTX { #ifdef WOLFSSL_TLS13 byte noTicketTls13:1; /* Server won't create new Ticket */ byte noPskDheKe:1; /* Don't use (EC)DHE with PSK */ - byte mutualAuth:1; /* Mutual authentication required */ #endif + byte mutualAuth:1; /* Mutual authentication required */ #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH) byte postHandshakeAuth:1; /* Post-handshake auth supported. */ #endif @@ -3412,9 +3412,7 @@ typedef struct Options { #endif word16 keepResources:1; /* Keep resources after handshake */ word16 useClientOrder:1; /* Use client's cipher order */ -#ifdef WOLFSSL_TLS13 word16 mutualAuth:1; /* Mutual authentication is rquired */ -#endif #if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH) word16 postHandshakeAuth:1;/* Client send post_handshake_auth * extension */ diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index f2ec11915..b1d6f69f7 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -859,6 +859,8 @@ WOLFSSL_ABI WOLFSSL_API int wolfSSL_write(WOLFSSL*, const void*, int); WOLFSSL_ABI WOLFSSL_API int wolfSSL_read(WOLFSSL*, void*, int); WOLFSSL_API int wolfSSL_peek(WOLFSSL*, void*, int); WOLFSSL_API int wolfSSL_accept(WOLFSSL*); +WOLFSSL_API int wolfSSL_CTX_mutual_auth(WOLFSSL_CTX* ctx, int req); +WOLFSSL_API int wolfSSL_mutual_auth(WOLFSSL* ssl, int req); #ifdef WOLFSSL_TLS13 WOLFSSL_API int wolfSSL_send_hrr_cookie(WOLFSSL* ssl, const unsigned char* secret, unsigned int secretSz); @@ -867,8 +869,6 @@ WOLFSSL_API int wolfSSL_no_ticket_TLSv13(WOLFSSL* ssl); WOLFSSL_API int wolfSSL_CTX_no_dhe_psk(WOLFSSL_CTX* ctx); WOLFSSL_API int wolfSSL_no_dhe_psk(WOLFSSL* ssl); WOLFSSL_API int wolfSSL_update_keys(WOLFSSL* ssl); -WOLFSSL_API int wolfSSL_CTX_mutual_auth(WOLFSSL_CTX* ctx, int req); -WOLFSSL_API int wolfSSL_mutual_auth(WOLFSSL* ssl, int req); WOLFSSL_API int wolfSSL_CTX_allow_post_handshake_auth(WOLFSSL_CTX* ctx); WOLFSSL_API int wolfSSL_allow_post_handshake_auth(WOLFSSL* ssl); WOLFSSL_API int wolfSSL_request_certificate(WOLFSSL* ssl); From 127e304901ddb23d8ae130de76ab4c60fbd2347a Mon Sep 17 00:00:00 2001 From: John Safranek Date: Sun, 1 Mar 2020 16:43:10 -0800 Subject: [PATCH 171/649] DTLS Fix An endpoint's retransmit pool was being reset when receiving its peer's change cipher spec message. When the finished message was lost, and retransmits need to happen, they weren't available, so nothing happened. Moved the reset to the finished case rather than CCS. --- src/internal.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/internal.c b/src/internal.c index 0d6fa1630..eeff0e1bf 100644 --- a/src/internal.c +++ b/src/internal.c @@ -11376,6 +11376,11 @@ int DoFinished(WOLFSSL* ssl, const byte* input, word32* inOutIdx, word32 size, ssl->options.handShakeDone = 1; } } +#ifdef WOLFSSL_DTLS + if (ssl->options.dtls) { + DtlsMsgPoolReset(ssl); + } +#endif WOLFSSL_LEAVE("DoFinished", 0); WOLFSSL_END(WC_FUNC_FINISHED_DO); @@ -14735,7 +14740,6 @@ int ProcessReply(WOLFSSL* ssl) ssl->ctx->mcastMaxSeq); } #endif - DtlsMsgPoolReset(ssl); peerSeq->nextEpoch++; peerSeq->prevSeq_lo = peerSeq->nextSeq_lo; peerSeq->prevSeq_hi = peerSeq->nextSeq_hi; From d8eeefb4b7394fd43cd70d8b645ee698c8108e3b Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Mon, 2 Mar 2020 09:13:11 -0700 Subject: [PATCH 172/649] initialize explicitOctet to 0 in pwc_PKCS7_DecodeEnvelopedData() --- wolfcrypt/src/pkcs7.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 9142d7eb1..54c2eae18 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -10057,7 +10057,7 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* in, int encryptedContentSz = 0; byte padLen; byte* encryptedContent = NULL; - int explicitOctet; + int explicitOctet = 0; word32 localIdx; byte tag; From 41ff54f8736fdab5fece93f02f524c6b1f23f167 Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 3 Mar 2020 09:16:48 -0800 Subject: [PATCH 173/649] Fix for typo with `wc_ecc_init` in documentation. --- doc/dox_comments/header_files/asn_public.h | 2 +- doc/dox_comments/header_files/ecc.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/dox_comments/header_files/asn_public.h b/doc/dox_comments/header_files/asn_public.h index cb6090c17..e4f2cf69d 100644 --- a/doc/dox_comments/header_files/asn_public.h +++ b/doc/dox_comments/header_files/asn_public.h @@ -1481,7 +1481,7 @@ WOLFSSL_API int wc_EccKeyToDer(ecc_key*, byte* output, word32 inLen); word32 idx = 0; byte buff[] = { // initialize with key }; ecc_key pubKey; - wc_ecc_init_key(&pubKey); + wc_ecc_init(&pubKey); if ( wc_EccPublicKeyDecode(buff, &idx, &pubKey, sizeof(buff)) != 0) { // error decoding key } diff --git a/doc/dox_comments/header_files/ecc.h b/doc/dox_comments/header_files/ecc.h index 0299756fe..70029a4f3 100644 --- a/doc/dox_comments/header_files/ecc.h +++ b/doc/dox_comments/header_files/ecc.h @@ -1012,7 +1012,7 @@ int wc_ecc_export_x963_ex(ecc_key*, byte* out, word32* outLen, int compressed); byte buff[] = { initialize with ANSI X9.63 formatted key }; ecc_key pubKey; - wc_ecc_init_key(&pubKey); + wc_ecc_init(&pubKey); ret = wc_ecc_import_x963(buff, sizeof(buff), &pubKey); if ( ret != 0) { @@ -1081,7 +1081,7 @@ NOT_COMPILED_IN Returned if the HAVE_COMP_KEY was not enabled at compile byte priv[] = { initialize with the raw private key }; ecc_key key; - wc_ecc_init_key(&key); + wc_ecc_init(&key); ret = wc_ecc_import_private_key(priv, sizeof(priv), pub, sizeof(pub), &key); if ( ret != 0) { From 4895fd7b0b063d5737325b857db0b8b928b11320 Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 3 Mar 2020 09:18:11 -0800 Subject: [PATCH 174/649] Added "either" side functions for SSLv3. These are only enabled with `WOLFSSL_EITHER_SIDE` and `WOLFSSL_ALLOW_SSLV3`. ZD 9984. --- src/ssl.c | 31 ++++++++++++++++++++++++++----- wolfssl/ssl.h | 2 ++ 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 96b99596c..62015efd8 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -11963,20 +11963,41 @@ int wolfSSL_DTLS_SetCookieSecret(WOLFSSL* ssl, } WOLFSSL_METHOD* wolfSSLv23_method_ex(void* heap) { - WOLFSSL_METHOD* m; + WOLFSSL_METHOD* m = NULL; WOLFSSL_ENTER("SSLv23_method"); #if !defined(NO_WOLFSSL_CLIENT) m = wolfSSLv23_client_method_ex(heap); - m->side = WOLFSSL_NEITHER_END; #elif !defined(NO_WOLFSSL_SERVER) m = wolfSSLv23_server_method_ex(heap); - m->side = WOLFSSL_NEITHER_END; - #else - m = NULL; #endif + if (m != NULL) { + m->side = WOLFSSL_NEITHER_END; + } return m; } + + #ifdef WOLFSSL_ALLOW_SSLV3 + WOLFSSL_METHOD* wolfSSLv3_method(void) + { + return wolfSSLv3_method_ex(NULL); + } + WOLFSSL_METHOD* wolfSSLv3_method_ex(void* heap) + { + WOLFSSL_METHOD* m = NULL; + WOLFSSL_ENTER("SSLv3_method"); + #if !defined(NO_WOLFSSL_CLIENT) + m = wolfSSLv3_client_method_ex(heap); + #elif !defined(NO_WOLFSSL_SERVER) + m = wolfSSLv3_server_method_ex(heap); + #endif + if (m != NULL) { + m->side = WOLFSSL_NEITHER_END; + } + + return m; + } + #endif #endif /* OPENSSL_EXTRA || WOLFSSL_EITHER_SIDE */ /* client only parts */ diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 6397fa177..b04415f72 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -659,6 +659,7 @@ typedef WOLFSSL_METHOD* (*wolfSSL_method_func)(void* heap); /* CTX Method EX Constructor Functions */ WOLFSSL_API WOLFSSL_METHOD *wolfTLS_client_method_ex(void* heap); WOLFSSL_API WOLFSSL_METHOD *wolfTLS_server_method_ex(void* heap); +WOLFSSL_API WOLFSSL_METHOD *wolfSSLv3_method_ex(void* heap); WOLFSSL_API WOLFSSL_METHOD *wolfSSLv3_server_method_ex(void* heap); WOLFSSL_API WOLFSSL_METHOD *wolfSSLv3_client_method_ex(void* heap); WOLFSSL_API WOLFSSL_METHOD *wolfTLSv1_method_ex(void* heap); @@ -695,6 +696,7 @@ WOLFSSL_API WOLFSSL_METHOD *wolfSSLv23_client_method_ex(void* heap); /* CTX Method Constructor Functions */ WOLFSSL_API WOLFSSL_METHOD *wolfTLS_client_method(void); WOLFSSL_API WOLFSSL_METHOD *wolfTLS_server_method(void); +WOLFSSL_API WOLFSSL_METHOD *wolfSSLv3_method(void); WOLFSSL_API WOLFSSL_METHOD *wolfSSLv23_method(void); WOLFSSL_API WOLFSSL_METHOD *wolfSSLv3_server_method(void); WOLFSSL_API WOLFSSL_METHOD *wolfSSLv3_client_method(void); From 730c95cf38c3e9768bef0b518c51bbcc32833504 Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 3 Mar 2020 09:20:58 -0800 Subject: [PATCH 175/649] Fix for TLS server incorrectly showing "FFDHE_2048" for "SSL curve name is" when using ECDHE and TLS v1.2 or less. The `PickHashSigAlgo` should be resetting `ssl->namedGroup` to indicate a named group was not used. --- src/internal.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/internal.c b/src/internal.c index d73a881c7..b08d06dd7 100644 --- a/src/internal.c +++ b/src/internal.c @@ -18915,6 +18915,7 @@ int PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, word32 hashSigAlgoSz) /* mark as highest and check remainder of hashSigAlgo list */ ssl->suites->hashAlgo = hashAlgo; ssl->suites->sigAlgo = sigAlgo; + ssl->namedGroup = 0; ret = 0; } else @@ -18955,6 +18956,7 @@ int PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, word32 hashSigAlgoSz) /* mark as highest and check remainder of hashSigAlgo list */ ssl->suites->hashAlgo = hashAlgo; ssl->suites->sigAlgo = sigAlgo; + ssl->namedGroup = 0; break; default: continue; From 44d2fc55e6bc4adcd1241146f396ff5600d4811f Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Tue, 3 Mar 2020 10:27:22 -0700 Subject: [PATCH 176/649] scan-build fixes for wc_PKCS7_DecodeEnvelopedData() --- wolfcrypt/src/pkcs7.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 54c2eae18..27fa23a60 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -10317,22 +10317,22 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* in, if (GetASNTag(pkiMsg, &idx, &tag, pkiMsgSz) < 0) { ret = ASN_PARSE_E; - break; } - if (tag != ASN_OCTET_STRING) { + if (ret == 0 && (tag != ASN_OCTET_STRING)) { ret = ASN_PARSE_E; - break; } if (ret == 0 && GetLength(pkiMsg, &idx, &encryptedContentSz, pkiMsgSz) <= 0) { ret = ASN_PARSE_E; - break; } - ret = PKCS7_CacheEncryptedContent(pkcs7, &pkiMsg[idx], - encryptedContentSz); + if (ret == 0) { + ret = PKCS7_CacheEncryptedContent(pkcs7, &pkiMsg[idx], + encryptedContentSz); + } + if (ret != 0) { break; } @@ -10340,6 +10340,11 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* in, /* advance idx past encrypted content */ idx += encryptedContentSz; } + + if (ret != 0) { + break; + } + } else { /* cache encrypted content, no OCTET STRING */ ret = PKCS7_CacheEncryptedContent(pkcs7, &pkiMsg[idx], From bb7649523336af5fbefc9ce1e10fd6bb67c72b56 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Tue, 3 Mar 2020 14:03:11 -0700 Subject: [PATCH 177/649] compile for NO_WOLFSSL_STUB --- src/ssl.c | 4 ++-- tests/api.c | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 96b99596c..d595e919c 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -21031,9 +21031,11 @@ int wolfSSL_sk_push(WOLFSSL_STACK* sk, const void *data) case STACK_TYPE_X509: ret = wolfSSL_sk_X509_push(sk, (WOLFSSL_X509*) data); break; + #ifndef NO_WOLFSSL_STUB case STACK_TYPE_CIPHER: ret = wolfSSL_sk_CIPHER_push(sk, (WOLFSSL_CIPHER*) data); break; + #endif case STACK_TYPE_GEN_NAME: ret = wolfSSL_sk_ASN1_OBJECT_push(sk, (WOLFSSL_ASN1_OBJECT*) data); break; @@ -41811,7 +41813,6 @@ err: return (ret == 0) ? WOLFSSL_SUCCESS : WOLFSSL_FAILURE; } - #ifndef NO_WOLFSSL_STUB int wolfSSL_BIO_read_filename(WOLFSSL_BIO *b, const char *name) { #ifndef NO_FILESYSTEM XFILE fp; @@ -41840,7 +41841,6 @@ err: return WOLFSSL_NOT_IMPLEMENTED; #endif } - #endif /* Return the corresponding short name for the nid . * or NULL if short name can't be found. diff --git a/tests/api.c b/tests/api.c index 8bbfbeb6c..3b01cf169 100644 --- a/tests/api.c +++ b/tests/api.c @@ -25802,6 +25802,7 @@ static void test_wolfSSL_RSA_meth(void) AssertNotNull(rsa_meth = RSA_meth_new("placeholder RSA method", RSA_METHOD_FLAG_NO_CHECK)); +#ifndef NO_WOLFSSL_STUB AssertIntEQ(RSA_meth_set_pub_enc(rsa_meth, NULL), 1); AssertIntEQ(RSA_meth_set_pub_dec(rsa_meth, NULL), 1); AssertIntEQ(RSA_meth_set_priv_enc(rsa_meth, NULL), 1); @@ -25809,6 +25810,7 @@ static void test_wolfSSL_RSA_meth(void) AssertIntEQ(RSA_meth_set_init(rsa_meth, NULL), 1); AssertIntEQ(RSA_meth_set_finish(rsa_meth, NULL), 1); AssertIntEQ(RSA_meth_set0_app_data(rsa_meth, NULL), 1); +#endif AssertNotNull(rsa = RSA_new()); AssertIntEQ(RSA_set_method(rsa, rsa_meth), 1); @@ -31177,7 +31179,9 @@ static void test_openssl_generate_key_and_cert(void) AssertNotNull(pkey); AssertNotNull(ec_key); + #ifndef NO_WOLFSSL_STUB EC_KEY_set_asn1_flag(ec_key, OPENSSL_EC_NAMED_CURVE); + #endif AssertIntNE(EC_KEY_generate_key(ec_key), 0); AssertIntNE(EVP_PKEY_assign_EC_KEY(pkey, ec_key), 0); From c5b4fe1283f362b95cf9b566ee33b4d331bb5118 Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 3 Mar 2020 15:35:56 -0800 Subject: [PATCH 178/649] Fix for `namedGroup` missing. --- src/internal.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/internal.c b/src/internal.c index b08d06dd7..896726534 100644 --- a/src/internal.c +++ b/src/internal.c @@ -18867,7 +18867,9 @@ int PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, word32 hashSigAlgoSz) ssl->suites->sigAlgo == ecc_dsa_sa_algo) { ssl->suites->sigAlgo = sigAlgo; ssl->suites->hashAlgo = sha512_mac; + #if defined(WOLFSSL_TLS13) || defined(HAVE_FFDHE) ssl->namedGroup = 0; + #endif ret = 0; break; } @@ -18882,7 +18884,9 @@ int PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, word32 hashSigAlgoSz) ssl->suites->sigAlgo == ecc_dsa_sa_algo) { ssl->suites->sigAlgo = sigAlgo; ssl->suites->hashAlgo = sha512_mac; + #if defined(WOLFSSL_TLS13) || defined(HAVE_FFDHE) ssl->namedGroup = 0; + #endif ret = 0; break; } @@ -18904,7 +18908,9 @@ int PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, word32 hashSigAlgoSz) if (digestSz == ssl->eccTempKeySz) { ssl->suites->hashAlgo = hashAlgo; ssl->suites->sigAlgo = sigAlgo; + #if defined(WOLFSSL_TLS13) || defined(HAVE_FFDHE) ssl->namedGroup = 0; + #endif ret = 0; break; /* done selected sig/hash algorithms */ } @@ -18915,7 +18921,9 @@ int PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, word32 hashSigAlgoSz) /* mark as highest and check remainder of hashSigAlgo list */ ssl->suites->hashAlgo = hashAlgo; ssl->suites->sigAlgo = sigAlgo; + #if defined(WOLFSSL_TLS13) || defined(HAVE_FFDHE) ssl->namedGroup = 0; + #endif ret = 0; } else @@ -18956,7 +18964,9 @@ int PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, word32 hashSigAlgoSz) /* mark as highest and check remainder of hashSigAlgo list */ ssl->suites->hashAlgo = hashAlgo; ssl->suites->sigAlgo = sigAlgo; + #if defined(WOLFSSL_TLS13) || defined(HAVE_FFDHE) ssl->namedGroup = 0; + #endif break; default: continue; From fca58950903fdccd5820a2180f98b5af6d5494c8 Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 3 Mar 2020 15:47:30 -0800 Subject: [PATCH 179/649] Example for FIPS Linker Descriptor to explicitly set wolfCrypt FIPS boundaries. --- IDE/GCC-ARM/include.am | 1 + IDE/GCC-ARM/linker_fips.ld | 92 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 IDE/GCC-ARM/linker_fips.ld diff --git a/IDE/GCC-ARM/include.am b/IDE/GCC-ARM/include.am index f755b35cf..3731bfdfc 100644 --- a/IDE/GCC-ARM/include.am +++ b/IDE/GCC-ARM/include.am @@ -9,6 +9,7 @@ EXTRA_DIST+= IDE/GCC-ARM/Source/benchmark_main.c EXTRA_DIST+= IDE/GCC-ARM/Source/test_main.c EXTRA_DIST+= IDE/GCC-ARM/Source/tls_client.c EXTRA_DIST+= IDE/GCC-ARM/linker.ld +EXTRA_DIST+= IDE/GCC-ARM/linker_fips.ld EXTRA_DIST+= IDE/GCC-ARM/Makefile EXTRA_DIST+= IDE/GCC-ARM/Makefile.bench EXTRA_DIST+= IDE/GCC-ARM/Makefile.client diff --git a/IDE/GCC-ARM/linker_fips.ld b/IDE/GCC-ARM/linker_fips.ld new file mode 100644 index 000000000..84155b12d --- /dev/null +++ b/IDE/GCC-ARM/linker_fips.ld @@ -0,0 +1,92 @@ +MEMORY +{ + FLASH (wx) : ORIGIN = 0x00000000, LENGTH = 256K + RAM (wx) : ORIGIN = 0x20000000, LENGTH = 64K +} + +SECTIONS +{ + __vectors_start__ = .; + .vectors : { *(.vectors) } > FLASH + __vectors_end__ = __vectors_start__ + 0x400; + + /* Custom section for wolfCrypt FIPS module */ + .wolfCryptFIPSModule_text : + { + . = ALIGN(4); + KEEP(wolfcrypt_first.o (.text .text* )) + KEEP(aes.o(.text .text* )) + KEEP(cmac.o (.text .text* )) + KEEP(des3.o (.text .text* )) + KEEP(dh.o (.text .text* )) + KEEP(ecc.o (.text .text* )) + KEEP(fips.o (.text .text* )) + KEEP(fips_test.o (.text .text* )) + KEEP(hmac.o (.text .text* )) + KEEP(random.o(.text .text* )) + KEEP(rsa.o (.text .text* )) + KEEP(sha.o (.text .text* )) + KEEP(sha256.o (.text .text* )) + KEEP(sha3.o (.text .text* )) + KEEP(sha512.o (.text .text* )) + KEEP(wolfcrypt_last.o(.text .text*)) + . = ALIGN(4); + } > FLASH + .wolfCryptFIPSModule_rodata : + { + . = ALIGN(4); + KEEP(wolfcrypt_first.o (.rodata .rodata*)) + KEEP(aes.o(.rodata .rodata*)) + KEEP(cmac.o(.rodata .rodata*)) + KEEP(des3.o(.rodata .rodata*)) + KEEP(dh.o(.rodata .rodata*)) + KEEP(ecc.o(.rodata .rodata*)) + KEEP(fips.o(.rodata .rodata*)) + KEEP(fips_test.o(.rodata .rodata*)) + KEEP(hmac.o(.rodata .rodata*)) + KEEP(random.o(.rodata .rodata*)) + KEEP(rsa.o(.rodata .rodata*)) + KEEP(sha.o(.rodata .rodata*)) + KEEP(sha256.o(.rodata .rodata*)) + KEEP(sha3.o(.rodata .rodata*)) + KEEP(sha512.o(.rodata .rodata*)) + KEEP(wolfcrypt_last.o(.rodata .rodata*)) + . = ALIGN(4); + } > FLASH + + /* Custom section for wolfCrypt and LibC to prevent FIPS hash from changing + when application code changes are made */ + .wolfCryptNonFIPS_text : + { + . = ALIGN(4); + KEEP(*wolf*src*.o(.text .text*)) + lib_a* ( .text .text*) + . = ALIGN(4); + } > FLASH + .wolfCryptNonFIPS_rodata : + { + . = ALIGN(4); + KEEP(*wolf*src*.o(.rodata .rodata*)) + lib_a* (.rodata .rodata*) + . = ALIGN(4); + } > FLASH + + .sys : { *(.sys*) } > FLASH + .text : { *(.text*) } > FLASH + .rodata : { *(.text*) } > FLASH + + __data_load_start__ = .; + __data_start__ = .; + .data : { *(.data*) } > RAM + __data_end__ = __data_start__ + SIZEOF(.data); + + __bss_start__ = .; + .bss : { *(.bss*) } > RAM + __bss_end__ = __bss_start__ + SIZEOF(.bss); + + __heap_start__ = .; + .heap : { *(.heap*) } > RAM + __heap_end__ = __heap_start__ + SIZEOF(.heap); + + end = .; +} From 3707eea2f368c2904fa9d0aa39e53cfc1079dbb6 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Wed, 4 Mar 2020 15:54:17 +1000 Subject: [PATCH 180/649] Fix SP x64 RSA Private op tmpa - tmpb can be less than -p. Need to conditionally add p twice. --- wolfcrypt/src/sp_x86_64.c | 60 +- wolfcrypt/src/sp_x86_64_asm.S | 1014 +++++++++++++++++++++++++++++++++ 2 files changed, 1056 insertions(+), 18 deletions(-) diff --git a/wolfcrypt/src/sp_x86_64.c b/wolfcrypt/src/sp_x86_64.c index b73db77c4..f9fb6d179 100644 --- a/wolfcrypt/src/sp_x86_64.c +++ b/wolfcrypt/src/sp_x86_64.c @@ -1466,6 +1466,8 @@ int sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm, return err; } +extern sp_digit sp_2048_cond_add_16(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m); +extern sp_digit sp_2048_cond_add_avx2_16(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m); /* RSA private key operation. * * in Array of bytes representing the number to exponentiate, base. @@ -1500,7 +1502,6 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, sp_digit* dp; sp_digit* dq; sp_digit* qi; - sp_digit* tmp; sp_digit* tmpa; sp_digit* tmpb; sp_digit* r; @@ -1533,8 +1534,7 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, tmpa = qi + 16; tmpb = tmpa + 32; - tmp = t; - r = tmp + 32; + r = t + 32; } #else r = a = ad; @@ -1543,7 +1543,6 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, qi = dq = dp = dpd; tmpa = tmpad; tmpb = tmpbd; - tmp = a + 32; #endif if (err == MP_OKAY) { @@ -1571,8 +1570,17 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, if (err == MP_OKAY) { c = sp_2048_sub_in_place_16(tmpa, tmpb); - sp_2048_mask_16(tmp, p, c); - sp_2048_add_16(tmpa, tmpa, tmp); +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) { + c += sp_2048_cond_add_avx2_16(tmpa, tmpa, p, c); + c += sp_2048_cond_add_avx2_16(tmpa, tmpa, p, c); + } + else +#endif + { + c += sp_2048_cond_add_16(tmpa, tmpa, p, c); + c += sp_2048_cond_add_16(tmpa, tmpa, p, c); + } sp_2048_from_mp(qi, 16, qim); #ifdef HAVE_INTEL_AVX2 @@ -3512,6 +3520,8 @@ int sp_RsaPublic_3072(const byte* in, word32 inLen, mp_int* em, mp_int* mm, return err; } +extern sp_digit sp_3072_cond_add_24(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m); +extern sp_digit sp_3072_cond_add_avx2_24(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m); /* RSA private key operation. * * in Array of bytes representing the number to exponentiate, base. @@ -3546,7 +3556,6 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, sp_digit* dp; sp_digit* dq; sp_digit* qi; - sp_digit* tmp; sp_digit* tmpa; sp_digit* tmpb; sp_digit* r; @@ -3579,8 +3588,7 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, tmpa = qi + 24; tmpb = tmpa + 48; - tmp = t; - r = tmp + 48; + r = t + 48; } #else r = a = ad; @@ -3589,7 +3597,6 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, qi = dq = dp = dpd; tmpa = tmpad; tmpb = tmpbd; - tmp = a + 48; #endif if (err == MP_OKAY) { @@ -3617,8 +3624,17 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, if (err == MP_OKAY) { c = sp_3072_sub_in_place_24(tmpa, tmpb); - sp_3072_mask_24(tmp, p, c); - sp_3072_add_24(tmpa, tmpa, tmp); +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) { + c += sp_3072_cond_add_avx2_24(tmpa, tmpa, p, c); + c += sp_3072_cond_add_avx2_24(tmpa, tmpa, p, c); + } + else +#endif + { + c += sp_3072_cond_add_24(tmpa, tmpa, p, c); + c += sp_3072_cond_add_24(tmpa, tmpa, p, c); + } sp_3072_from_mp(qi, 24, qim); #ifdef HAVE_INTEL_AVX2 @@ -5012,6 +5028,8 @@ int sp_RsaPublic_4096(const byte* in, word32 inLen, mp_int* em, mp_int* mm, return err; } +extern sp_digit sp_4096_cond_add_32(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m); +extern sp_digit sp_4096_cond_add_avx2_32(sp_digit* r, const sp_digit* a, const sp_digit* b, sp_digit m); /* RSA private key operation. * * in Array of bytes representing the number to exponentiate, base. @@ -5046,7 +5064,6 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, sp_digit* dp; sp_digit* dq; sp_digit* qi; - sp_digit* tmp; sp_digit* tmpa; sp_digit* tmpb; sp_digit* r; @@ -5079,8 +5096,7 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, tmpa = qi + 32; tmpb = tmpa + 64; - tmp = t; - r = tmp + 64; + r = t + 64; } #else r = a = ad; @@ -5089,7 +5105,6 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, qi = dq = dp = dpd; tmpa = tmpad; tmpb = tmpbd; - tmp = a + 64; #endif if (err == MP_OKAY) { @@ -5117,8 +5132,17 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, if (err == MP_OKAY) { c = sp_2048_sub_in_place_32(tmpa, tmpb); - sp_2048_mask_32(tmp, p, c); - sp_2048_add_32(tmpa, tmpa, tmp); +#ifdef HAVE_INTEL_AVX2 + if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) { + c += sp_4096_cond_add_avx2_32(tmpa, tmpa, p, c); + c += sp_4096_cond_add_avx2_32(tmpa, tmpa, p, c); + } + else +#endif + { + c += sp_4096_cond_add_32(tmpa, tmpa, p, c); + c += sp_4096_cond_add_32(tmpa, tmpa, p, c); + } sp_2048_from_mp(qi, 32, qim); #ifdef HAVE_INTEL_AVX2 diff --git a/wolfcrypt/src/sp_x86_64_asm.S b/wolfcrypt/src/sp_x86_64_asm.S index 4d9b51f1d..b01c6276f 100644 --- a/wolfcrypt/src/sp_x86_64_asm.S +++ b/wolfcrypt/src/sp_x86_64_asm.S @@ -11924,6 +11924,248 @@ L_mont_loop_avx2_32: .size sp_2048_mont_reduce_avx2_32,.-sp_2048_mont_reduce_avx2_32 #endif /* __APPLE__ */ #endif /* 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. + */ +#ifndef __APPLE__ +.globl sp_2048_cond_add_16 +.type sp_2048_cond_add_16,@function +.align 16 +sp_2048_cond_add_16: +#else +.globl _sp_2048_cond_add_16 +.p2align 4 +_sp_2048_cond_add_16: +#endif /* __APPLE__ */ + subq $128, %rsp + movq $0, %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 + addq %rdx, %r8 + movq 8(%rsi), %r9 + movq 8(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, (%rdi) + movq 16(%rsi), %r8 + movq 16(%rsp), %rdx + adcq %rdx, %r8 + movq %r9, 8(%rdi) + movq 24(%rsi), %r9 + movq 24(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, 16(%rdi) + movq 32(%rsi), %r8 + movq 32(%rsp), %rdx + adcq %rdx, %r8 + movq %r9, 24(%rdi) + movq 40(%rsi), %r9 + movq 40(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, 32(%rdi) + movq 48(%rsi), %r8 + movq 48(%rsp), %rdx + adcq %rdx, %r8 + movq %r9, 40(%rdi) + movq 56(%rsi), %r9 + movq 56(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, 48(%rdi) + movq 64(%rsi), %r8 + movq 64(%rsp), %rdx + adcq %rdx, %r8 + movq %r9, 56(%rdi) + movq 72(%rsi), %r9 + movq 72(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, 64(%rdi) + movq 80(%rsi), %r8 + movq 80(%rsp), %rdx + adcq %rdx, %r8 + movq %r9, 72(%rdi) + movq 88(%rsi), %r9 + movq 88(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, 80(%rdi) + movq 96(%rsi), %r8 + movq 96(%rsp), %rdx + adcq %rdx, %r8 + movq %r9, 88(%rdi) + movq 104(%rsi), %r9 + movq 104(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, 96(%rdi) + movq 112(%rsi), %r8 + movq 112(%rsp), %rdx + adcq %rdx, %r8 + movq %r9, 104(%rdi) + movq 120(%rsi), %r9 + movq 120(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, 112(%rdi) + movq %r9, 120(%rdi) + adcq $0, %rax + addq $128, %rsp + repz retq +#ifndef __APPLE__ +.size sp_2048_cond_add_16,.-sp_2048_cond_add_16 +#endif /* __APPLE__ */ +/* 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. + */ +#ifndef __APPLE__ +.globl sp_2048_cond_add_avx2_16 +.type sp_2048_cond_add_avx2_16,@function +.align 16 +sp_2048_cond_add_avx2_16: +#else +.globl _sp_2048_cond_add_avx2_16 +.p2align 4 +_sp_2048_cond_add_avx2_16: +#endif /* __APPLE__ */ + movq $0, %rax + movq (%rdx), %r10 + movq (%rsi), %r8 + pextq %rcx, %r10, %r10 + addq %r10, %r8 + movq 8(%rdx), %r10 + movq 8(%rsi), %r9 + pextq %rcx, %r10, %r10 + movq %r8, (%rdi) + adcq %r10, %r9 + movq 16(%rdx), %r8 + movq 16(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 8(%rdi) + adcq %r8, %r10 + movq 24(%rdx), %r9 + movq 24(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 16(%rdi) + adcq %r9, %r8 + movq 32(%rdx), %r10 + movq 32(%rsi), %r9 + pextq %rcx, %r10, %r10 + movq %r8, 24(%rdi) + adcq %r10, %r9 + movq 40(%rdx), %r8 + movq 40(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 32(%rdi) + adcq %r8, %r10 + movq 48(%rdx), %r9 + movq 48(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 40(%rdi) + adcq %r9, %r8 + movq 56(%rdx), %r10 + movq 56(%rsi), %r9 + pextq %rcx, %r10, %r10 + movq %r8, 48(%rdi) + adcq %r10, %r9 + movq 64(%rdx), %r8 + movq 64(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 56(%rdi) + adcq %r8, %r10 + movq 72(%rdx), %r9 + movq 72(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 64(%rdi) + adcq %r9, %r8 + movq 80(%rdx), %r10 + movq 80(%rsi), %r9 + pextq %rcx, %r10, %r10 + movq %r8, 72(%rdi) + adcq %r10, %r9 + movq 88(%rdx), %r8 + movq 88(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 80(%rdi) + adcq %r8, %r10 + movq 96(%rdx), %r9 + movq 96(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 88(%rdi) + adcq %r9, %r8 + movq 104(%rdx), %r10 + movq 104(%rsi), %r9 + pextq %rcx, %r10, %r10 + movq %r8, 96(%rdi) + adcq %r10, %r9 + movq 112(%rdx), %r8 + movq 112(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 104(%rdi) + adcq %r8, %r10 + movq 120(%rdx), %r9 + movq 120(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 112(%rdi) + adcq %r9, %r8 + movq %r8, 120(%rdi) + adcq $0, %rax + repz retq +#ifndef __APPLE__ +.size sp_2048_cond_add_avx2_16,.-sp_2048_cond_add_avx2_16 +#endif /* __APPLE__ */ /* Shift number left by n bit. (r = a << n) * * r Result of left shift by n. @@ -26417,6 +26659,344 @@ L_mont_loop_avx2_48: .size sp_3072_mont_reduce_avx2_48,.-sp_3072_mont_reduce_avx2_48 #endif /* __APPLE__ */ #endif /* 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. + */ +#ifndef __APPLE__ +.globl sp_3072_cond_add_24 +.type sp_3072_cond_add_24,@function +.align 16 +sp_3072_cond_add_24: +#else +.globl _sp_3072_cond_add_24 +.p2align 4 +_sp_3072_cond_add_24: +#endif /* __APPLE__ */ + subq $192, %rsp + movq $0, %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 128(%rdx), %r8 + movq 136(%rdx), %r9 + andq %rcx, %r8 + andq %rcx, %r9 + movq %r8, 128(%rsp) + movq %r9, 136(%rsp) + movq 144(%rdx), %r8 + movq 152(%rdx), %r9 + andq %rcx, %r8 + andq %rcx, %r9 + movq %r8, 144(%rsp) + movq %r9, 152(%rsp) + movq 160(%rdx), %r8 + movq 168(%rdx), %r9 + andq %rcx, %r8 + andq %rcx, %r9 + movq %r8, 160(%rsp) + movq %r9, 168(%rsp) + movq 176(%rdx), %r8 + movq 184(%rdx), %r9 + andq %rcx, %r8 + andq %rcx, %r9 + movq %r8, 176(%rsp) + movq %r9, 184(%rsp) + movq (%rsi), %r8 + movq (%rsp), %rdx + addq %rdx, %r8 + movq 8(%rsi), %r9 + movq 8(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, (%rdi) + movq 16(%rsi), %r8 + movq 16(%rsp), %rdx + adcq %rdx, %r8 + movq %r9, 8(%rdi) + movq 24(%rsi), %r9 + movq 24(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, 16(%rdi) + movq 32(%rsi), %r8 + movq 32(%rsp), %rdx + adcq %rdx, %r8 + movq %r9, 24(%rdi) + movq 40(%rsi), %r9 + movq 40(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, 32(%rdi) + movq 48(%rsi), %r8 + movq 48(%rsp), %rdx + adcq %rdx, %r8 + movq %r9, 40(%rdi) + movq 56(%rsi), %r9 + movq 56(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, 48(%rdi) + movq 64(%rsi), %r8 + movq 64(%rsp), %rdx + adcq %rdx, %r8 + movq %r9, 56(%rdi) + movq 72(%rsi), %r9 + movq 72(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, 64(%rdi) + movq 80(%rsi), %r8 + movq 80(%rsp), %rdx + adcq %rdx, %r8 + movq %r9, 72(%rdi) + movq 88(%rsi), %r9 + movq 88(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, 80(%rdi) + movq 96(%rsi), %r8 + movq 96(%rsp), %rdx + adcq %rdx, %r8 + movq %r9, 88(%rdi) + movq 104(%rsi), %r9 + movq 104(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, 96(%rdi) + movq 112(%rsi), %r8 + movq 112(%rsp), %rdx + adcq %rdx, %r8 + movq %r9, 104(%rdi) + movq 120(%rsi), %r9 + movq 120(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, 112(%rdi) + movq 128(%rsi), %r8 + movq 128(%rsp), %rdx + adcq %rdx, %r8 + movq %r9, 120(%rdi) + movq 136(%rsi), %r9 + movq 136(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, 128(%rdi) + movq 144(%rsi), %r8 + movq 144(%rsp), %rdx + adcq %rdx, %r8 + movq %r9, 136(%rdi) + movq 152(%rsi), %r9 + movq 152(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, 144(%rdi) + movq 160(%rsi), %r8 + movq 160(%rsp), %rdx + adcq %rdx, %r8 + movq %r9, 152(%rdi) + movq 168(%rsi), %r9 + movq 168(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, 160(%rdi) + movq 176(%rsi), %r8 + movq 176(%rsp), %rdx + adcq %rdx, %r8 + movq %r9, 168(%rdi) + movq 184(%rsi), %r9 + movq 184(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, 176(%rdi) + movq %r9, 184(%rdi) + adcq $0, %rax + addq $192, %rsp + repz retq +#ifndef __APPLE__ +.size sp_3072_cond_add_24,.-sp_3072_cond_add_24 +#endif /* __APPLE__ */ +/* 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. + */ +#ifndef __APPLE__ +.globl sp_3072_cond_add_avx2_24 +.type sp_3072_cond_add_avx2_24,@function +.align 16 +sp_3072_cond_add_avx2_24: +#else +.globl _sp_3072_cond_add_avx2_24 +.p2align 4 +_sp_3072_cond_add_avx2_24: +#endif /* __APPLE__ */ + movq $0, %rax + movq (%rdx), %r10 + movq (%rsi), %r8 + pextq %rcx, %r10, %r10 + addq %r10, %r8 + movq 8(%rdx), %r10 + movq 8(%rsi), %r9 + pextq %rcx, %r10, %r10 + movq %r8, (%rdi) + adcq %r10, %r9 + movq 16(%rdx), %r8 + movq 16(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 8(%rdi) + adcq %r8, %r10 + movq 24(%rdx), %r9 + movq 24(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 16(%rdi) + adcq %r9, %r8 + movq 32(%rdx), %r10 + movq 32(%rsi), %r9 + pextq %rcx, %r10, %r10 + movq %r8, 24(%rdi) + adcq %r10, %r9 + movq 40(%rdx), %r8 + movq 40(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 32(%rdi) + adcq %r8, %r10 + movq 48(%rdx), %r9 + movq 48(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 40(%rdi) + adcq %r9, %r8 + movq 56(%rdx), %r10 + movq 56(%rsi), %r9 + pextq %rcx, %r10, %r10 + movq %r8, 48(%rdi) + adcq %r10, %r9 + movq 64(%rdx), %r8 + movq 64(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 56(%rdi) + adcq %r8, %r10 + movq 72(%rdx), %r9 + movq 72(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 64(%rdi) + adcq %r9, %r8 + movq 80(%rdx), %r10 + movq 80(%rsi), %r9 + pextq %rcx, %r10, %r10 + movq %r8, 72(%rdi) + adcq %r10, %r9 + movq 88(%rdx), %r8 + movq 88(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 80(%rdi) + adcq %r8, %r10 + movq 96(%rdx), %r9 + movq 96(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 88(%rdi) + adcq %r9, %r8 + movq 104(%rdx), %r10 + movq 104(%rsi), %r9 + pextq %rcx, %r10, %r10 + movq %r8, 96(%rdi) + adcq %r10, %r9 + movq 112(%rdx), %r8 + movq 112(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 104(%rdi) + adcq %r8, %r10 + movq 120(%rdx), %r9 + movq 120(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 112(%rdi) + adcq %r9, %r8 + movq 128(%rdx), %r10 + movq 128(%rsi), %r9 + pextq %rcx, %r10, %r10 + movq %r8, 120(%rdi) + adcq %r10, %r9 + movq 136(%rdx), %r8 + movq 136(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 128(%rdi) + adcq %r8, %r10 + movq 144(%rdx), %r9 + movq 144(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 136(%rdi) + adcq %r9, %r8 + movq 152(%rdx), %r10 + movq 152(%rsi), %r9 + pextq %rcx, %r10, %r10 + movq %r8, 144(%rdi) + adcq %r10, %r9 + movq 160(%rdx), %r8 + movq 160(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 152(%rdi) + adcq %r8, %r10 + movq 168(%rdx), %r9 + movq 168(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 160(%rdi) + adcq %r9, %r8 + movq 176(%rdx), %r10 + movq 176(%rsi), %r9 + pextq %rcx, %r10, %r10 + movq %r8, 168(%rdi) + adcq %r10, %r9 + movq 184(%rdx), %r8 + movq 184(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 176(%rdi) + adcq %r8, %r10 + movq %r10, 184(%rdi) + adcq $0, %rax + repz retq +#ifndef __APPLE__ +.size sp_3072_cond_add_avx2_24,.-sp_3072_cond_add_avx2_24 +#endif /* __APPLE__ */ /* Shift number left by n bit. (r = a << n) * * r Result of left shift by n. @@ -36089,6 +36669,440 @@ L_mont_loop_avx2_64: .size sp_4096_mont_reduce_avx2_64,.-sp_4096_mont_reduce_avx2_64 #endif /* __APPLE__ */ #endif /* 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. + */ +#ifndef __APPLE__ +.globl sp_4096_cond_add_32 +.type sp_4096_cond_add_32,@function +.align 16 +sp_4096_cond_add_32: +#else +.globl _sp_4096_cond_add_32 +.p2align 4 +_sp_4096_cond_add_32: +#endif /* __APPLE__ */ + subq $256, %rsp + movq $0, %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 128(%rdx), %r8 + movq 136(%rdx), %r9 + andq %rcx, %r8 + andq %rcx, %r9 + movq %r8, 128(%rsp) + movq %r9, 136(%rsp) + movq 144(%rdx), %r8 + movq 152(%rdx), %r9 + andq %rcx, %r8 + andq %rcx, %r9 + movq %r8, 144(%rsp) + movq %r9, 152(%rsp) + movq 160(%rdx), %r8 + movq 168(%rdx), %r9 + andq %rcx, %r8 + andq %rcx, %r9 + movq %r8, 160(%rsp) + movq %r9, 168(%rsp) + movq 176(%rdx), %r8 + movq 184(%rdx), %r9 + andq %rcx, %r8 + andq %rcx, %r9 + movq %r8, 176(%rsp) + movq %r9, 184(%rsp) + movq 192(%rdx), %r8 + movq 200(%rdx), %r9 + andq %rcx, %r8 + andq %rcx, %r9 + movq %r8, 192(%rsp) + movq %r9, 200(%rsp) + movq 208(%rdx), %r8 + movq 216(%rdx), %r9 + andq %rcx, %r8 + andq %rcx, %r9 + movq %r8, 208(%rsp) + movq %r9, 216(%rsp) + movq 224(%rdx), %r8 + movq 232(%rdx), %r9 + andq %rcx, %r8 + andq %rcx, %r9 + movq %r8, 224(%rsp) + movq %r9, 232(%rsp) + movq 240(%rdx), %r8 + movq 248(%rdx), %r9 + andq %rcx, %r8 + andq %rcx, %r9 + movq %r8, 240(%rsp) + movq %r9, 248(%rsp) + movq (%rsi), %r8 + movq (%rsp), %rdx + addq %rdx, %r8 + movq 8(%rsi), %r9 + movq 8(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, (%rdi) + movq 16(%rsi), %r8 + movq 16(%rsp), %rdx + adcq %rdx, %r8 + movq %r9, 8(%rdi) + movq 24(%rsi), %r9 + movq 24(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, 16(%rdi) + movq 32(%rsi), %r8 + movq 32(%rsp), %rdx + adcq %rdx, %r8 + movq %r9, 24(%rdi) + movq 40(%rsi), %r9 + movq 40(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, 32(%rdi) + movq 48(%rsi), %r8 + movq 48(%rsp), %rdx + adcq %rdx, %r8 + movq %r9, 40(%rdi) + movq 56(%rsi), %r9 + movq 56(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, 48(%rdi) + movq 64(%rsi), %r8 + movq 64(%rsp), %rdx + adcq %rdx, %r8 + movq %r9, 56(%rdi) + movq 72(%rsi), %r9 + movq 72(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, 64(%rdi) + movq 80(%rsi), %r8 + movq 80(%rsp), %rdx + adcq %rdx, %r8 + movq %r9, 72(%rdi) + movq 88(%rsi), %r9 + movq 88(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, 80(%rdi) + movq 96(%rsi), %r8 + movq 96(%rsp), %rdx + adcq %rdx, %r8 + movq %r9, 88(%rdi) + movq 104(%rsi), %r9 + movq 104(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, 96(%rdi) + movq 112(%rsi), %r8 + movq 112(%rsp), %rdx + adcq %rdx, %r8 + movq %r9, 104(%rdi) + movq 120(%rsi), %r9 + movq 120(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, 112(%rdi) + movq 128(%rsi), %r8 + movq 128(%rsp), %rdx + adcq %rdx, %r8 + movq %r9, 120(%rdi) + movq 136(%rsi), %r9 + movq 136(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, 128(%rdi) + movq 144(%rsi), %r8 + movq 144(%rsp), %rdx + adcq %rdx, %r8 + movq %r9, 136(%rdi) + movq 152(%rsi), %r9 + movq 152(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, 144(%rdi) + movq 160(%rsi), %r8 + movq 160(%rsp), %rdx + adcq %rdx, %r8 + movq %r9, 152(%rdi) + movq 168(%rsi), %r9 + movq 168(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, 160(%rdi) + movq 176(%rsi), %r8 + movq 176(%rsp), %rdx + adcq %rdx, %r8 + movq %r9, 168(%rdi) + movq 184(%rsi), %r9 + movq 184(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, 176(%rdi) + movq 192(%rsi), %r8 + movq 192(%rsp), %rdx + adcq %rdx, %r8 + movq %r9, 184(%rdi) + movq 200(%rsi), %r9 + movq 200(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, 192(%rdi) + movq 208(%rsi), %r8 + movq 208(%rsp), %rdx + adcq %rdx, %r8 + movq %r9, 200(%rdi) + movq 216(%rsi), %r9 + movq 216(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, 208(%rdi) + movq 224(%rsi), %r8 + movq 224(%rsp), %rdx + adcq %rdx, %r8 + movq %r9, 216(%rdi) + movq 232(%rsi), %r9 + movq 232(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, 224(%rdi) + movq 240(%rsi), %r8 + movq 240(%rsp), %rdx + adcq %rdx, %r8 + movq %r9, 232(%rdi) + movq 248(%rsi), %r9 + movq 248(%rsp), %rdx + adcq %rdx, %r9 + movq %r8, 240(%rdi) + movq %r9, 248(%rdi) + adcq $0, %rax + addq $256, %rsp + repz retq +#ifndef __APPLE__ +.size sp_4096_cond_add_32,.-sp_4096_cond_add_32 +#endif /* __APPLE__ */ +/* 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. + */ +#ifndef __APPLE__ +.globl sp_4096_cond_add_avx2_32 +.type sp_4096_cond_add_avx2_32,@function +.align 16 +sp_4096_cond_add_avx2_32: +#else +.globl _sp_4096_cond_add_avx2_32 +.p2align 4 +_sp_4096_cond_add_avx2_32: +#endif /* __APPLE__ */ + movq $0, %rax + movq (%rdx), %r10 + movq (%rsi), %r8 + pextq %rcx, %r10, %r10 + addq %r10, %r8 + movq 8(%rdx), %r10 + movq 8(%rsi), %r9 + pextq %rcx, %r10, %r10 + movq %r8, (%rdi) + adcq %r10, %r9 + movq 16(%rdx), %r8 + movq 16(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 8(%rdi) + adcq %r8, %r10 + movq 24(%rdx), %r9 + movq 24(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 16(%rdi) + adcq %r9, %r8 + movq 32(%rdx), %r10 + movq 32(%rsi), %r9 + pextq %rcx, %r10, %r10 + movq %r8, 24(%rdi) + adcq %r10, %r9 + movq 40(%rdx), %r8 + movq 40(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 32(%rdi) + adcq %r8, %r10 + movq 48(%rdx), %r9 + movq 48(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 40(%rdi) + adcq %r9, %r8 + movq 56(%rdx), %r10 + movq 56(%rsi), %r9 + pextq %rcx, %r10, %r10 + movq %r8, 48(%rdi) + adcq %r10, %r9 + movq 64(%rdx), %r8 + movq 64(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 56(%rdi) + adcq %r8, %r10 + movq 72(%rdx), %r9 + movq 72(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 64(%rdi) + adcq %r9, %r8 + movq 80(%rdx), %r10 + movq 80(%rsi), %r9 + pextq %rcx, %r10, %r10 + movq %r8, 72(%rdi) + adcq %r10, %r9 + movq 88(%rdx), %r8 + movq 88(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 80(%rdi) + adcq %r8, %r10 + movq 96(%rdx), %r9 + movq 96(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 88(%rdi) + adcq %r9, %r8 + movq 104(%rdx), %r10 + movq 104(%rsi), %r9 + pextq %rcx, %r10, %r10 + movq %r8, 96(%rdi) + adcq %r10, %r9 + movq 112(%rdx), %r8 + movq 112(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 104(%rdi) + adcq %r8, %r10 + movq 120(%rdx), %r9 + movq 120(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 112(%rdi) + adcq %r9, %r8 + movq 128(%rdx), %r10 + movq 128(%rsi), %r9 + pextq %rcx, %r10, %r10 + movq %r8, 120(%rdi) + adcq %r10, %r9 + movq 136(%rdx), %r8 + movq 136(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 128(%rdi) + adcq %r8, %r10 + movq 144(%rdx), %r9 + movq 144(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 136(%rdi) + adcq %r9, %r8 + movq 152(%rdx), %r10 + movq 152(%rsi), %r9 + pextq %rcx, %r10, %r10 + movq %r8, 144(%rdi) + adcq %r10, %r9 + movq 160(%rdx), %r8 + movq 160(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 152(%rdi) + adcq %r8, %r10 + movq 168(%rdx), %r9 + movq 168(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 160(%rdi) + adcq %r9, %r8 + movq 176(%rdx), %r10 + movq 176(%rsi), %r9 + pextq %rcx, %r10, %r10 + movq %r8, 168(%rdi) + adcq %r10, %r9 + movq 184(%rdx), %r8 + movq 184(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 176(%rdi) + adcq %r8, %r10 + movq 192(%rdx), %r9 + movq 192(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 184(%rdi) + adcq %r9, %r8 + movq 200(%rdx), %r10 + movq 200(%rsi), %r9 + pextq %rcx, %r10, %r10 + movq %r8, 192(%rdi) + adcq %r10, %r9 + movq 208(%rdx), %r8 + movq 208(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 200(%rdi) + adcq %r8, %r10 + movq 216(%rdx), %r9 + movq 216(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 208(%rdi) + adcq %r9, %r8 + movq 224(%rdx), %r10 + movq 224(%rsi), %r9 + pextq %rcx, %r10, %r10 + movq %r8, 216(%rdi) + adcq %r10, %r9 + movq 232(%rdx), %r8 + movq 232(%rsi), %r10 + pextq %rcx, %r8, %r8 + movq %r9, 224(%rdi) + adcq %r8, %r10 + movq 240(%rdx), %r9 + movq 240(%rsi), %r8 + pextq %rcx, %r9, %r9 + movq %r10, 232(%rdi) + adcq %r9, %r8 + movq 248(%rdx), %r10 + movq 248(%rsi), %r9 + pextq %rcx, %r10, %r10 + movq %r8, 240(%rdi) + adcq %r10, %r9 + movq %r9, 248(%rdi) + adcq $0, %rax + repz retq +#ifndef __APPLE__ +.size sp_4096_cond_add_avx2_32,.-sp_4096_cond_add_avx2_32 +#endif /* __APPLE__ */ /* Shift number left by n bit. (r = a << n) * * r Result of left shift by n. From 6fcfde06519044ca7f71ea4af9bd900383b47bee Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Thu, 5 Mar 2020 11:20:50 +1000 Subject: [PATCH 181/649] Fix to show the FFDHE group when negotiated --- src/internal.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/internal.c b/src/internal.c index 2885a5df8..68491dc4e 100644 --- a/src/internal.c +++ b/src/internal.c @@ -4298,6 +4298,9 @@ int EccMakeKey(WOLFSSL* ssl, ecc_key* key, ecc_key* peer) /* make sure the curve is set for TLS */ if (ret == 0 && key->dp) { ssl->ecdhCurveOID = key->dp->oidSum; + #if defined(WOLFSSL_TLS13) || defined(HAVE_FFDHE) + ssl->namedGroup = 0; + #endif } /* Handle async pending response */ @@ -4600,6 +4603,9 @@ static int X25519MakeKey(WOLFSSL* ssl, curve25519_key* key, if (ret == 0) { ssl->ecdhCurveOID = ECC_X25519_OID; + #if defined(WOLFSSL_TLS13) || defined(HAVE_FFDHE) + ssl->namedGroup = 0; + #endif } /* Handle async pending response */ @@ -4899,6 +4905,9 @@ static int X448MakeKey(WOLFSSL* ssl, curve448_key* key, curve448_key* peer) if (ret == 0) { ssl->ecdhCurveOID = ECC_X448_OID; + #if defined(WOLFSSL_TLS13) || defined(HAVE_FFDHE) + ssl->namedGroup = 0; + #endif } /* Handle async pending response */ @@ -18885,9 +18894,6 @@ int PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, word32 hashSigAlgoSz) ssl->suites->sigAlgo == ecc_dsa_sa_algo) { ssl->suites->sigAlgo = sigAlgo; ssl->suites->hashAlgo = sha512_mac; - #if defined(WOLFSSL_TLS13) || defined(HAVE_FFDHE) - ssl->namedGroup = 0; - #endif ret = 0; break; } @@ -18902,9 +18908,6 @@ int PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, word32 hashSigAlgoSz) ssl->suites->sigAlgo == ecc_dsa_sa_algo) { ssl->suites->sigAlgo = sigAlgo; ssl->suites->hashAlgo = sha512_mac; - #if defined(WOLFSSL_TLS13) || defined(HAVE_FFDHE) - ssl->namedGroup = 0; - #endif ret = 0; break; } @@ -18939,9 +18942,6 @@ int PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, word32 hashSigAlgoSz) /* mark as highest and check remainder of hashSigAlgo list */ ssl->suites->hashAlgo = hashAlgo; ssl->suites->sigAlgo = sigAlgo; - #if defined(WOLFSSL_TLS13) || defined(HAVE_FFDHE) - ssl->namedGroup = 0; - #endif ret = 0; } else @@ -18982,9 +18982,6 @@ int PickHashSigAlgo(WOLFSSL* ssl, const byte* hashSigAlgo, word32 hashSigAlgoSz) /* mark as highest and check remainder of hashSigAlgo list */ ssl->suites->hashAlgo = hashAlgo; ssl->suites->sigAlgo = sigAlgo; - #if defined(WOLFSSL_TLS13) || defined(HAVE_FFDHE) - ssl->namedGroup = 0; - #endif break; default: continue; @@ -20792,6 +20789,9 @@ static int DoServerKeyExchange(WOLFSSL* ssl, const byte* input, ERROR_OUT(ECC_CURVE_ERROR, exit_dske); } ssl->ecdhCurveOID = curveOid; + #if defined(WOLFSSL_TLS13) || defined(HAVE_FFDHE) + ssl->namedGroup = 0; + #endif length = input[args->idx++]; if ((args->idx - args->begin) + length > size) { From 9fe2ddacf45174f7d4b4d0da046a3a397b72a559 Mon Sep 17 00:00:00 2001 From: John Safranek Date: Thu, 5 Mar 2020 13:38:02 -0800 Subject: [PATCH 182/649] HMAC Init 1. wc_HmacSetKey() has a check against the hmac's type that assumes one has called wc_HmacInit() on the object first. In FIPS Ready builds we do not have wc_HmacInit() in the boundary. This change removes that check and action when making a FIPS build. The free called doesn't do anything in the FIPS build case. 2. Initialize the Hmac's macType to WC_HASH_TYPE_NONE. Check the macType against that rather than 0. There are some build configs where none isn't 0. --- wolfcrypt/src/hmac.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/wolfcrypt/src/hmac.c b/wolfcrypt/src/hmac.c index be26310cf..bcebc1ce2 100644 --- a/wolfcrypt/src/hmac.c +++ b/wolfcrypt/src/hmac.c @@ -293,10 +293,16 @@ int wc_HmacSetKey(Hmac* hmac, int type, const byte* key, word32 length) return BAD_FUNC_ARG; } +#ifndef HAVE_FIPS /* if set key has already been run then make sure and free existing */ - if (hmac->macType != 0) { + /* This is for async and PIC32MZ situations, and just normally OK, + provided the user calls wc_HmacInit() first. That function is not + available in FIPS builds. In current FIPS builds, the hashes are + not allocating resources. */ + if (hmac->macType != WC_HASH_TYPE_NONE) { wc_HmacFree(hmac); } +#endif hmac->innerHashKeyed = 0; hmac->macType = (byte)type; @@ -979,6 +985,7 @@ int wc_HmacInit(Hmac* hmac, void* heap, int devId) return BAD_FUNC_ARG; XMEMSET(hmac, 0, sizeof(Hmac)); + hmac->macType = WC_HASH_TYPE_NONE; hmac->heap = heap; #ifdef WOLF_CRYPTO_CB hmac->devId = devId; From 1035d73a052ec54bafe33370257348074701cf4c Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Thu, 5 Mar 2020 16:29:55 -0700 Subject: [PATCH 183/649] add function wolfSSL_X509_NAME_ENTRY_create_by_txt --- src/ssl.c | 42 ++++++++++++++++++++++++++++++++++++++++++ tests/api.c | 6 ++++++ wolfssl/openssl/ssl.h | 2 ++ wolfssl/ssl.h | 3 +++ 4 files changed, 53 insertions(+) diff --git a/src/ssl.c b/src/ssl.c index 1ba0b7296..c66eb80c6 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -40693,6 +40693,48 @@ err: } + /* Create a new WOLFSSL_X509_NAME_ENTRY structure based on the text passed + * in. Returns NULL on failure */ + WOLFSSL_X509_NAME_ENTRY* wolfSSL_X509_NAME_ENTRY_create_by_txt( + WOLFSSL_X509_NAME_ENTRY **neIn, const char *txt, int type, + const unsigned char *data, int dataSz) + { + int nid = -1; + WOLFSSL_X509_NAME_ENTRY* ne = NULL; + + WOLFSSL_ENTER("wolfSSL_X509_NAME_ENTRY_create_by_txt()"); + + if (txt == NULL) { + return NULL; + } + + if (neIn != NULL) { + ne = *neIn; + } + + nid = wolfSSL_OBJ_txt2nid(txt); + if (nid == NID_undef) { + WOLFSSL_MSG("Unable to find text"); + } + else { + if (ne == NULL) { + ne = wolfSSL_X509_NAME_ENTRY_new(); + if (ne == NULL) { + return NULL; + } + } + ne->nid = nid; + ne->value = wolfSSL_ASN1_STRING_type_new(type); + if (ne->value != NULL) { + wolfSSL_ASN1_STRING_set(ne->value, (const void*)data, dataSz); + ne->set = 1; + } + } + + return ne; + } + + WOLFSSL_X509_NAME_ENTRY* wolfSSL_X509_NAME_ENTRY_create_by_NID( WOLFSSL_X509_NAME_ENTRY** out, int nid, int type, const unsigned char* data, int dataSz) diff --git a/tests/api.c b/tests/api.c index 23f51d060..d26cc6e94 100644 --- a/tests/api.c +++ b/tests/api.c @@ -24598,6 +24598,12 @@ static void test_wolfSSL_X509_NAME_ENTRY(void) #endif X509_NAME_ENTRY_free(entry); + /* Test add entry by text */ + AssertNotNull(entry = X509_NAME_ENTRY_create_by_txt(NULL, "commonName", + 0x0c, cn, (int)sizeof(cn))); + AssertIntEQ(X509_NAME_add_entry(nm, entry, -1, 0), SSL_SUCCESS); + X509_NAME_ENTRY_free(entry); + /* Test add entry by NID */ AssertIntEQ(X509_NAME_add_entry_by_NID(nm, NID_commonName, MBSTRING_UTF8, cn, -1, -1, 0), WOLFSSL_SUCCESS); diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 0edecbab5..25181c6cb 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -459,8 +459,10 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; #define X509_NAME_get_text_by_NID wolfSSL_X509_NAME_get_text_by_NID #define X509_NAME_get_index_by_OBJ wolfSSL_X509_NAME_get_index_by_OBJ #define X509_NAME_cmp wolfSSL_X509_NAME_cmp +#define X509_NAME_ENTRY_new wolfSSL_X509_NAME_ENTRY_new #define X509_NAME_ENTRY_free wolfSSL_X509_NAME_ENTRY_free #define X509_NAME_ENTRY_create_by_NID wolfSSL_X509_NAME_ENTRY_create_by_NID +#define X509_NAME_ENTRY_create_by_txt wolfSSL_X509_NAME_ENTRY_create_by_txt #define X509_NAME_add_entry wolfSSL_X509_NAME_add_entry #define X509_NAME_add_entry_by_txt wolfSSL_X509_NAME_add_entry_by_txt #define X509_NAME_add_entry_by_NID wolfSSL_X509_NAME_add_entry_by_NID diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index afdf288c9..bd97ac23e 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -3270,6 +3270,9 @@ WOLFSSL_API long wolfSSL_CTX_clear_extra_chain_certs(WOLFSSL_CTX* ctx); WOLFSSL_API WOLFSSL_X509_NAME_ENTRY* wolfSSL_X509_NAME_ENTRY_create_by_NID( WOLFSSL_X509_NAME_ENTRY** out, int nid, int type, const unsigned char* data, int dataSz); +WOLFSSL_API WOLFSSL_X509_NAME_ENTRY* wolfSSL_X509_NAME_ENTRY_create_by_txt( + WOLFSSL_X509_NAME_ENTRY **neIn, const char *txt, int format, + const unsigned char *data, int dataSz); WOLFSSL_API int wolfSSL_X509_NAME_add_entry(WOLFSSL_X509_NAME* name, WOLFSSL_X509_NAME_ENTRY* entry, int idx, int set); WOLFSSL_API int wolfSSL_X509_NAME_add_entry_by_txt(WOLFSSL_X509_NAME *name, From fe9a876895349e2948b522142baa63575e88396c Mon Sep 17 00:00:00 2001 From: Juliusz Sosinowicz Date: Fri, 6 Mar 2020 17:13:59 +0100 Subject: [PATCH 184/649] Check length to avoid XSTRNCMP accessing memory after `list` --- src/ssl.c | 3 ++- wolfssl/internal.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 945ac32e5..4f6af78f4 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -33160,7 +33160,8 @@ static int populate_groups(int* groups, int max_count, char *list) return -1; } for (nist_name = kNistCurves; nist_name->name != NULL; nist_name++) { - if (XSTRNCMP(list, nist_name->name, nist_name->name_len) == 0) { + if (len == nist_name->name_len && + XSTRNCMP(list, nist_name->name, nist_name->name_len) == 0) { break; } } diff --git a/wolfssl/internal.h b/wolfssl/internal.h index a586184d7..5238f62cb 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -4239,7 +4239,7 @@ static const byte tls_server[FINISHED_LABEL_SZ + 1] = "server finished"; #ifdef OPENSSL_EXTRA typedef struct { - int name_len; + size_t name_len; const char *name; int nid; } WOLF_EC_NIST_NAME; From 4ad8a2bacb1a7e0914c57f9967aa2fece2000cfc Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Fri, 6 Mar 2020 10:50:00 -0700 Subject: [PATCH 185/649] store wc_PKCS7_DecodeEnvelopedData encryptedContentTotalSz in existing variable instead of adding another --- wolfcrypt/src/pkcs7.c | 55 ++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/wolfcrypt/src/pkcs7.c b/wolfcrypt/src/pkcs7.c index 27fa23a60..dbebf2534 100644 --- a/wolfcrypt/src/pkcs7.c +++ b/wolfcrypt/src/pkcs7.c @@ -84,7 +84,6 @@ struct PKCS7State { word32 varOne; int varTwo; int varThree; - int varFour; word32 vers; word32 idx; /* index read into current input buffer */ @@ -374,25 +373,23 @@ static long wc_PKCS7_GetMaxStream(PKCS7* pkcs7, byte flag, byte* in, /* setter function for stored variables */ static void wc_PKCS7_StreamStoreVar(PKCS7* pkcs7, word32 var1, int var2, - int var3, int var4) + int var3) { if (pkcs7 != NULL && pkcs7->stream != NULL) { pkcs7->stream->varOne = var1; pkcs7->stream->varTwo = var2; pkcs7->stream->varThree = var3; - pkcs7->stream->varFour = var4; } } /* getter function for stored variables */ static void wc_PKCS7_StreamGetVar(PKCS7* pkcs7, word32* var1, int* var2, - int* var3, int* var4) + int* var3) { if (pkcs7 != NULL && pkcs7->stream != NULL) { if (var1 != NULL) *var1 = pkcs7->stream->varOne; if (var2 != NULL) *var2 = pkcs7->stream->varTwo; if (var3 != NULL) *var3 = pkcs7->stream->varThree; - if (var4 != NULL) *var4 = pkcs7->stream->varFour; } } @@ -4289,7 +4286,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, if (pkiMsg2 && pkiMsg2Sz > 0) { pkcs7->stream->maxLen += pkiMsg2Sz + pkcs7->contentSz; } - wc_PKCS7_StreamStoreVar(pkcs7, totalSz, 0, 0, 0); + wc_PKCS7_StreamStoreVar(pkcs7, totalSz, 0, 0); #endif wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE2); @@ -4303,7 +4300,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, break; } - wc_PKCS7_StreamGetVar(pkcs7, &totalSz, 0, 0, 0); + wc_PKCS7_StreamGetVar(pkcs7, &totalSz, 0, 0); if (pkcs7->stream->length > 0) pkiMsgSz = pkcs7->stream->length; #ifdef ASN_BER_TO_DER @@ -4461,7 +4458,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) { break; } - wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, localIdx, length, 0); + wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, localIdx, length); /* content length is in multiple parts */ if (multiPart) { @@ -4492,8 +4489,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, else #endif pkiMsgSz = (word32)rc; - wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, (int*)&localIdx, - &length, 0); + wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, (int*)&localIdx, &length); if (pkcs7->stream->length > 0) { localIdx = 0; @@ -4653,7 +4649,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) { break; } - wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, 0, length, 0); + wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, 0, length); if (length > 0) { pkcs7->stream->expected = length; } @@ -4676,7 +4672,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, break; } - wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, &length, 0); + wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, &length); if (pkcs7->stream->flagOne) { pkiMsg2 = pkiMsg; } @@ -4855,8 +4851,8 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, pkcs7->stream->expected = (pkcs7->stream->maxLen - pkcs7->stream->totalRd) + pkcs7->stream->length; - wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, 0, 0); - wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, 0, length, 0); + wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, 0); + wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, 0, length); #endif wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_VERIFY_STAGE5); FALL_THROUGH; @@ -4867,7 +4863,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, pkcs7->stream->expected, &pkiMsg, &idx)) != 0) { break; } - wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, &length, 0); + wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, &length); if (pkcs7->stream->flagOne) { pkiMsg2 = pkiMsg; } @@ -4918,7 +4914,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &stateIdx, &idx)) != 0) { break; } - wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, 0, length, 0); + wc_PKCS7_StreamStoreVar(pkcs7, pkiMsg2Sz, 0, length); if (in2 && in2Sz > 0 && hashBuf && hashSz > 0) { if (length > 0) { @@ -4945,7 +4941,7 @@ static int PKCS7_VerifySignedData(PKCS7* pkcs7, const byte* hashBuf, break; } - wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, &length, 0); + wc_PKCS7_StreamGetVar(pkcs7, &pkiMsg2Sz, 0, &length); if (pkcs7->stream->flagOne) { pkiMsg2 = pkiMsg; } @@ -8026,7 +8022,7 @@ static int wc_PKCS7_DecryptKtri(PKCS7* pkcs7, byte* in, word32 inSz, if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) { break; } - wc_PKCS7_StreamStoreVar(pkcs7, 0, sidType, version, 0); + wc_PKCS7_StreamStoreVar(pkcs7, 0, sidType, version); /* @TODO getting total amount left because of GetInt call later on * this could be optimized to stream better */ @@ -8052,7 +8048,7 @@ static int wc_PKCS7_DecryptKtri(PKCS7* pkcs7, byte* in, word32 inSz, } pkiMsgSz = (word32)rc; - wc_PKCS7_StreamGetVar(pkcs7, NULL, &sidType, &version, 0); + wc_PKCS7_StreamGetVar(pkcs7, NULL, &sidType, &version); /* @TODO get expected size for next part, does not account for * GetInt call well */ @@ -8169,7 +8165,7 @@ static int wc_PKCS7_DecryptKtri(PKCS7* pkcs7, byte* in, word32 inSz, if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, idx)) != 0) { break; } - wc_PKCS7_StreamStoreVar(pkcs7, encryptedKeySz, sidType, version, 0); + wc_PKCS7_StreamStoreVar(pkcs7, encryptedKeySz, sidType, version); pkcs7->stream->expected = encryptedKeySz; #endif wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_DECRYPT_KTRI_3); @@ -10216,7 +10212,7 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* in, if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) { break; } - wc_PKCS7_StreamStoreVar(pkcs7, encOID, expBlockSz, length, 0); + wc_PKCS7_StreamStoreVar(pkcs7, encOID, expBlockSz, length); pkcs7->stream->contentSz = blockKeySz; pkcs7->stream->expected = length + MAX_LENGTH_SZ + MAX_LENGTH_SZ + ASN_TAG_SZ + ASN_TAG_SZ; @@ -10240,7 +10236,7 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* in, } pkiMsgSz = (word32)rc; - wc_PKCS7_StreamGetVar(pkcs7, 0, 0, &length, 0); + wc_PKCS7_StreamGetVar(pkcs7, 0, 0, &length); tmpIv = pkcs7->stream->tmpIv; if (tmpIv == NULL) { /* check added to help out static analysis tool */ @@ -10281,9 +10277,8 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* in, break; } pkcs7->stream->expected = encryptedContentTotalSz; - wc_PKCS7_StreamGetVar(pkcs7, &encOID, &expBlockSz, 0, 0); - wc_PKCS7_StreamStoreVar(pkcs7, encOID, expBlockSz, explicitOctet, - encryptedContentTotalSz); + wc_PKCS7_StreamGetVar(pkcs7, &encOID, &expBlockSz, 0); + wc_PKCS7_StreamStoreVar(pkcs7, encOID, expBlockSz, explicitOctet); #endif wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_ENV_5); FALL_THROUGH; @@ -10296,9 +10291,9 @@ WOLFSSL_API int wc_PKCS7_DecodeEnvelopedData(PKCS7* pkcs7, byte* in, return ret; } - wc_PKCS7_StreamGetVar(pkcs7, &encOID, &expBlockSz, &explicitOctet, - &encryptedContentTotalSz); + wc_PKCS7_StreamGetVar(pkcs7, &encOID, &expBlockSz, &explicitOctet); tmpIv = pkcs7->stream->tmpIv; + encryptedContentTotalSz = pkcs7->stream->expected; /* restore decrypted key */ decryptedKey = pkcs7->stream->aad; @@ -11119,7 +11114,7 @@ WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(PKCS7* pkcs7, byte* in, if ((ret = wc_PKCS7_StreamEndCase(pkcs7, &tmpIdx, &idx)) != 0) { break; } - wc_PKCS7_StreamStoreVar(pkcs7, encOID, blockKeySz, 0, 0); + wc_PKCS7_StreamStoreVar(pkcs7, encOID, blockKeySz, 0); #endif wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_4); FALL_THROUGH; @@ -11222,7 +11217,7 @@ WOLFSSL_API int wc_PKCS7_DecodeAuthEnvelopedData(PKCS7* pkcs7, byte* in, pkcs7->stream->expected = encryptedContentSz; wc_PKCS7_StreamStoreVar(pkcs7, encOID, blockKeySz, - encryptedContentSz, 0); + encryptedContentSz); #endif wc_PKCS7_ChangeState(pkcs7, WC_PKCS7_AUTHENV_5); @@ -11468,7 +11463,7 @@ authenv_atrbend: } wc_PKCS7_StreamGetVar(pkcs7, &encOID, &blockKeySz, - &encryptedContentSz, 0); + &encryptedContentSz); encryptedContent = pkcs7->stream->bufferPt; #ifdef WOLFSSL_SMALL_STACK decryptedKey = pkcs7->stream->key; From 3fcbcbf42a8ac52b9a09725f93483abc27f577ed Mon Sep 17 00:00:00 2001 From: Stanislav Klima Date: Mon, 9 Mar 2020 17:45:15 +0100 Subject: [PATCH 186/649] Revert "Logically dead code." This reverts commit 2db62f744ab72df4e00c89093c034616b53b4184. --- src/ssl.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 95191dac1..b418f7f80 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -17124,14 +17124,39 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) case AES_256_GCM_TYPE : WOLFSSL_MSG("AES GCM"); if (ctx->enc) { - ret = wc_AesGcmEncrypt(&ctx->cipher.aes, dst, src, len, + if (dst){ + /* encrypt confidential data*/ + ret = wc_AesGcmEncrypt(&ctx->cipher.aes, dst, src, len, ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz, NULL, 0); + } + else { + /* authenticated, non-confidential data */ + ret = wc_AesGcmEncrypt(&ctx->cipher.aes, NULL, NULL, 0, + ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz, + src, len); + /* Reset partial authTag error for AAD*/ + if (ret == AES_GCM_AUTH_E) + ret = 0; + } } else { - ret = wc_AesGcmDecrypt(&ctx->cipher.aes, dst, src, len, + if (dst){ + /* decrypt confidential data*/ + ret = wc_AesGcmDecrypt(&ctx->cipher.aes, dst, src, len, ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz, NULL, 0); + } + else { + /* authenticated, non-confidential data*/ + ret = wc_AesGcmDecrypt(&ctx->cipher.aes, NULL, NULL, 0, + ctx->iv, ctx->ivSz, + ctx->authTag, ctx->authTagSz, + src, len); + /* Reset partial authTag error for AAD*/ + if (ret == AES_GCM_AUTH_E) + ret = 0; + } } break; #endif /* HAVE_AESGCM */ From fb0ad6532f624b95c8a0328f3d6582353bd5dfbf Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Mon, 9 Mar 2020 15:13:01 -0600 Subject: [PATCH 187/649] set inital state of TLS 1.3 peerSuites structure --- src/tls.c | 2 ++ src/tls13.c | 3 +++ 2 files changed, 5 insertions(+) diff --git a/src/tls.c b/src/tls.c index e5c451469..f041d16a9 100644 --- a/src/tls.c +++ b/src/tls.c @@ -11165,6 +11165,8 @@ int TLSX_Parse(WOLFSSL* ssl, byte* input, word16 length, byte msgType, ret = KS_PARSE(ssl, input + offset, size, msgType); break; #endif + default: + WOLFSSL_MSG("Unknown TLS extension type"); } /* offset should be updated here! */ diff --git a/src/tls13.c b/src/tls13.c index e5fd49d8b..639cc9ef5 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -3379,6 +3379,9 @@ static int DoTls13CertificateRequest(WOLFSSL* ssl, const byte* input, WOLFSSL_START(WC_FUNC_CERTIFICATE_REQUEST_DO); WOLFSSL_ENTER("DoTls13CertificateRequest"); +#ifndef WOLFSSL_TLS13_DRAFT_18 + XMEMSET(&peerSuites, 0, sizeof(Suites)); +#endif #ifdef WOLFSSL_CALLBACKS if (ssl->hsInfoOn) AddPacketName(ssl, "CertificateRequest"); if (ssl->toInfoOn) AddLateName("CertificateRequest", &ssl->timeoutInfo); From 93326a7aeb46c48c1b61aec0077cb6a298c98908 Mon Sep 17 00:00:00 2001 From: Stanislav Klima Date: Tue, 10 Mar 2020 09:55:27 +0100 Subject: [PATCH 188/649] Changed dst NULL check. --- src/ssl.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ssl.c b/src/ssl.c index b418f7f80..e7d099a10 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -17094,7 +17094,11 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) int ret = 0; WOLFSSL_ENTER("wolfSSL_EVP_Cipher"); - if (ctx == NULL || dst == NULL || src == NULL) { + if (ctx == NULL || src == NULL || + (dst == NULL && + ctx->cipherType != AES_128_GCM_TYPE && + ctx->cipherType != AES_192_GCM_TYPE && + ctx->cipherType != AES_256_GCM_TYPE)) { WOLFSSL_MSG("Bad function argument"); return 0; /* failure */ } From 0be0cf44e49c3abeee67eb9de005199226919271 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Tue, 10 Mar 2020 09:54:31 -0600 Subject: [PATCH 189/649] fix for returning NULL when text not found and add test case --- src/ssl.c | 1 + tests/api.c | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/src/ssl.c b/src/ssl.c index c66eb80c6..a52cef729 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -40715,6 +40715,7 @@ err: nid = wolfSSL_OBJ_txt2nid(txt); if (nid == NID_undef) { WOLFSSL_MSG("Unable to find text"); + ne = NULL; } else { if (ne == NULL) { diff --git a/tests/api.c b/tests/api.c index d26cc6e94..69681e5f5 100644 --- a/tests/api.c +++ b/tests/api.c @@ -24601,6 +24601,11 @@ static void test_wolfSSL_X509_NAME_ENTRY(void) /* Test add entry by text */ AssertNotNull(entry = X509_NAME_ENTRY_create_by_txt(NULL, "commonName", 0x0c, cn, (int)sizeof(cn))); + #if defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO) \ + || defined(WOLFSSL_HAPROXY) || defined(WOLFSSL_NGINX) + AssertNull(X509_NAME_ENTRY_create_by_txt(&entry, "unknown", + V_ASN1_UTF8STRING, cn, (int)sizeof(cn))); + #endif AssertIntEQ(X509_NAME_add_entry(nm, entry, -1, 0), SSL_SUCCESS); X509_NAME_ENTRY_free(entry); From 6321eabf86a30210adb3856049767dd3fbf79e81 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Thu, 12 Mar 2020 09:33:52 +1000 Subject: [PATCH 190/649] Fix SP RSA private op tmpa - tmpb can be less than -p. Need to conditionally add p twice. C and multiple platform fix. --- wolfcrypt/src/sp_arm32.c | 1037 +++++++++++++++++++++++--- wolfcrypt/src/sp_arm64.c | 1373 +++++++++++++++++++---------------- wolfcrypt/src/sp_armthumb.c | 184 ++++- wolfcrypt/src/sp_c32.c | 157 +--- wolfcrypt/src/sp_c64.c | 159 +--- wolfcrypt/src/sp_cortexm.c | 161 +++- wolfcrypt/src/sp_x86_64.c | 12 +- 7 files changed, 2047 insertions(+), 1036 deletions(-) diff --git a/wolfcrypt/src/sp_arm32.c b/wolfcrypt/src/sp_arm32.c index ef47c8f7b..9692dd4f5 100644 --- a/wolfcrypt/src/sp_arm32.c +++ b/wolfcrypt/src/sp_arm32.c @@ -7486,6 +7486,212 @@ int sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm, } #ifndef WOLFSSL_RSA_PUBLIC_ONLY +/* 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_2048_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" + "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" + "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; +} + /* RSA private key operation. * * in Array of bytes representing the number to exponentiate, base. @@ -7520,7 +7726,6 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, sp_digit* dp; sp_digit* dq; sp_digit* qi; - sp_digit* tmp; sp_digit* tmpa; sp_digit* tmpb; sp_digit* r; @@ -7550,8 +7755,7 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, tmpa = qi + 32; tmpb = tmpa + 64; - tmp = t; - r = tmp + 64; + r = t + 64; } #else r = a = ad; @@ -7560,7 +7764,6 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, qi = dq = dp = dpd; tmpa = tmpad; tmpb = tmpbd; - tmp = a + 64; #endif if (err == MP_OKAY) { @@ -7578,8 +7781,8 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, if (err == MP_OKAY) { c = sp_2048_sub_in_place_32(tmpa, tmpb); - sp_2048_mask_32(tmp, p, c); - sp_2048_add_32(tmpa, tmpa, tmp); + c += sp_2048_cond_add_32(tmpa, tmpa, p, c); + sp_2048_cond_add_32(tmpa, tmpa, p, c); sp_2048_from_mp(qi, 32, qim); sp_2048_mul_32(tmpa, tmpa, qi); @@ -7610,7 +7813,7 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, return err; } -#endif +#endif /* WOLFSSL_RSA_PUBLIC_ONLY */ #endif /* WOLFSSL_HAVE_SP_RSA */ #if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \ !defined(WOLFSSL_RSA_PUBLIC_ONLY)) @@ -18769,6 +18972,292 @@ int sp_RsaPublic_3072(const byte* in, word32 inLen, mp_int* em, mp_int* mm, } #ifndef WOLFSSL_RSA_PUBLIC_ONLY +/* 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_3072_cond_add_48(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" + "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, #192\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" + "ldr r4, [%[a], #128]\n\t" + "ldr r6, [%[a], #132]\n\t" + "ldr r5, [%[b], #128]\n\t" + "ldr r7, [%[b], #132]\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], #128]\n\t" + "str r6, [%[r], #132]\n\t" + "ldr r4, [%[a], #136]\n\t" + "ldr r6, [%[a], #140]\n\t" + "ldr r5, [%[b], #136]\n\t" + "ldr r7, [%[b], #140]\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], #136]\n\t" + "str r6, [%[r], #140]\n\t" + "ldr r4, [%[a], #144]\n\t" + "ldr r6, [%[a], #148]\n\t" + "ldr r5, [%[b], #144]\n\t" + "ldr r7, [%[b], #148]\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], #144]\n\t" + "str r6, [%[r], #148]\n\t" + "ldr r4, [%[a], #152]\n\t" + "ldr r6, [%[a], #156]\n\t" + "ldr r5, [%[b], #152]\n\t" + "ldr r7, [%[b], #156]\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], #152]\n\t" + "str r6, [%[r], #156]\n\t" + "ldr r4, [%[a], #160]\n\t" + "ldr r6, [%[a], #164]\n\t" + "ldr r5, [%[b], #160]\n\t" + "ldr r7, [%[b], #164]\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], #160]\n\t" + "str r6, [%[r], #164]\n\t" + "ldr r4, [%[a], #168]\n\t" + "ldr r6, [%[a], #172]\n\t" + "ldr r5, [%[b], #168]\n\t" + "ldr r7, [%[b], #172]\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], #168]\n\t" + "str r6, [%[r], #172]\n\t" + "ldr r4, [%[a], #176]\n\t" + "ldr r6, [%[a], #180]\n\t" + "ldr r5, [%[b], #176]\n\t" + "ldr r7, [%[b], #180]\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], #176]\n\t" + "str r6, [%[r], #180]\n\t" + "ldr r4, [%[a], #184]\n\t" + "ldr r6, [%[a], #188]\n\t" + "ldr r5, [%[b], #184]\n\t" + "ldr r7, [%[b], #188]\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], #184]\n\t" + "str r6, [%[r], #188]\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; +} + /* RSA private key operation. * * in Array of bytes representing the number to exponentiate, base. @@ -18803,7 +19292,6 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, sp_digit* dp; sp_digit* dq; sp_digit* qi; - sp_digit* tmp; sp_digit* tmpa; sp_digit* tmpb; sp_digit* r; @@ -18833,8 +19321,7 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, tmpa = qi + 48; tmpb = tmpa + 96; - tmp = t; - r = tmp + 96; + r = t + 96; } #else r = a = ad; @@ -18843,7 +19330,6 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, qi = dq = dp = dpd; tmpa = tmpad; tmpb = tmpbd; - tmp = a + 96; #endif if (err == MP_OKAY) { @@ -18861,8 +19347,8 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, if (err == MP_OKAY) { c = sp_3072_sub_in_place_48(tmpa, tmpb); - sp_3072_mask_48(tmp, p, c); - sp_3072_add_48(tmpa, tmpa, tmp); + c += sp_3072_cond_add_48(tmpa, tmpa, p, c); + sp_3072_cond_add_48(tmpa, tmpa, p, c); sp_3072_from_mp(qi, 48, qim); sp_3072_mul_48(tmpa, tmpa, qi); @@ -18893,7 +19379,7 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, return err; } -#endif +#endif /* WOLFSSL_RSA_PUBLIC_ONLY */ #endif /* WOLFSSL_HAVE_SP_RSA */ #if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \ !defined(WOLFSSL_RSA_PUBLIC_ONLY)) @@ -71046,6 +71532,372 @@ int sp_RsaPublic_4096(const byte* in, word32 inLen, mp_int* em, mp_int* mm, } #ifndef WOLFSSL_RSA_PUBLIC_ONLY +/* 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_4096_cond_add_64(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" + "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, #256\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" + "ldr r4, [%[a], #128]\n\t" + "ldr r6, [%[a], #132]\n\t" + "ldr r5, [%[b], #128]\n\t" + "ldr r7, [%[b], #132]\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], #128]\n\t" + "str r6, [%[r], #132]\n\t" + "ldr r4, [%[a], #136]\n\t" + "ldr r6, [%[a], #140]\n\t" + "ldr r5, [%[b], #136]\n\t" + "ldr r7, [%[b], #140]\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], #136]\n\t" + "str r6, [%[r], #140]\n\t" + "ldr r4, [%[a], #144]\n\t" + "ldr r6, [%[a], #148]\n\t" + "ldr r5, [%[b], #144]\n\t" + "ldr r7, [%[b], #148]\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], #144]\n\t" + "str r6, [%[r], #148]\n\t" + "ldr r4, [%[a], #152]\n\t" + "ldr r6, [%[a], #156]\n\t" + "ldr r5, [%[b], #152]\n\t" + "ldr r7, [%[b], #156]\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], #152]\n\t" + "str r6, [%[r], #156]\n\t" + "ldr r4, [%[a], #160]\n\t" + "ldr r6, [%[a], #164]\n\t" + "ldr r5, [%[b], #160]\n\t" + "ldr r7, [%[b], #164]\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], #160]\n\t" + "str r6, [%[r], #164]\n\t" + "ldr r4, [%[a], #168]\n\t" + "ldr r6, [%[a], #172]\n\t" + "ldr r5, [%[b], #168]\n\t" + "ldr r7, [%[b], #172]\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], #168]\n\t" + "str r6, [%[r], #172]\n\t" + "ldr r4, [%[a], #176]\n\t" + "ldr r6, [%[a], #180]\n\t" + "ldr r5, [%[b], #176]\n\t" + "ldr r7, [%[b], #180]\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], #176]\n\t" + "str r6, [%[r], #180]\n\t" + "ldr r4, [%[a], #184]\n\t" + "ldr r6, [%[a], #188]\n\t" + "ldr r5, [%[b], #184]\n\t" + "ldr r7, [%[b], #188]\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], #184]\n\t" + "str r6, [%[r], #188]\n\t" + "ldr r4, [%[a], #192]\n\t" + "ldr r6, [%[a], #196]\n\t" + "ldr r5, [%[b], #192]\n\t" + "ldr r7, [%[b], #196]\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], #192]\n\t" + "str r6, [%[r], #196]\n\t" + "ldr r4, [%[a], #200]\n\t" + "ldr r6, [%[a], #204]\n\t" + "ldr r5, [%[b], #200]\n\t" + "ldr r7, [%[b], #204]\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], #200]\n\t" + "str r6, [%[r], #204]\n\t" + "ldr r4, [%[a], #208]\n\t" + "ldr r6, [%[a], #212]\n\t" + "ldr r5, [%[b], #208]\n\t" + "ldr r7, [%[b], #212]\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], #208]\n\t" + "str r6, [%[r], #212]\n\t" + "ldr r4, [%[a], #216]\n\t" + "ldr r6, [%[a], #220]\n\t" + "ldr r5, [%[b], #216]\n\t" + "ldr r7, [%[b], #220]\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], #216]\n\t" + "str r6, [%[r], #220]\n\t" + "ldr r4, [%[a], #224]\n\t" + "ldr r6, [%[a], #228]\n\t" + "ldr r5, [%[b], #224]\n\t" + "ldr r7, [%[b], #228]\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], #224]\n\t" + "str r6, [%[r], #228]\n\t" + "ldr r4, [%[a], #232]\n\t" + "ldr r6, [%[a], #236]\n\t" + "ldr r5, [%[b], #232]\n\t" + "ldr r7, [%[b], #236]\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], #232]\n\t" + "str r6, [%[r], #236]\n\t" + "ldr r4, [%[a], #240]\n\t" + "ldr r6, [%[a], #244]\n\t" + "ldr r5, [%[b], #240]\n\t" + "ldr r7, [%[b], #244]\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], #240]\n\t" + "str r6, [%[r], #244]\n\t" + "ldr r4, [%[a], #248]\n\t" + "ldr r6, [%[a], #252]\n\t" + "ldr r5, [%[b], #248]\n\t" + "ldr r7, [%[b], #252]\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], #248]\n\t" + "str r6, [%[r], #252]\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; +} + /* RSA private key operation. * * in Array of bytes representing the number to exponentiate, base. @@ -71080,7 +71932,6 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, sp_digit* dp; sp_digit* dq; sp_digit* qi; - sp_digit* tmp; sp_digit* tmpa; sp_digit* tmpb; sp_digit* r; @@ -71110,8 +71961,7 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, tmpa = qi + 64; tmpb = tmpa + 128; - tmp = t; - r = tmp + 128; + r = t + 128; } #else r = a = ad; @@ -71120,7 +71970,6 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, qi = dq = dp = dpd; tmpa = tmpad; tmpb = tmpbd; - tmp = a + 128; #endif if (err == MP_OKAY) { @@ -71138,8 +71987,8 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, if (err == MP_OKAY) { c = sp_4096_sub_in_place_64(tmpa, tmpb); - sp_4096_mask_64(tmp, p, c); - sp_4096_add_64(tmpa, tmpa, tmp); + c += sp_4096_cond_add_64(tmpa, tmpa, p, c); + sp_4096_cond_add_64(tmpa, tmpa, p, c); sp_4096_from_mp(qi, 64, qim); sp_4096_mul_64(tmpa, tmpa, qi); @@ -71170,7 +72019,7 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, return err; } -#endif +#endif /* WOLFSSL_RSA_PUBLIC_ONLY */ #endif /* WOLFSSL_HAVE_SP_RSA */ #if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \ !defined(WOLFSSL_RSA_PUBLIC_ONLY)) @@ -83497,73 +84346,95 @@ static sp_digit sp_384_cond_add_12(sp_digit* r, const sp_digit* a, const sp_digi { sp_digit c = 0; +#ifdef WOLFSSL_SP_SMALL __asm__ __volatile__ ( + "mov r9, #0\n\t" "mov r8, #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" - "adc %[c], r8, r8\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" + "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, #48\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" + : "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" + "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; } diff --git a/wolfcrypt/src/sp_arm64.c b/wolfcrypt/src/sp_arm64.c index 30e7d0ff5..dcee7ffdb 100644 --- a/wolfcrypt/src/sp_arm64.c +++ b/wolfcrypt/src/sp_arm64.c @@ -2275,86 +2275,62 @@ static sp_digit sp_2048_cond_sub_16(sp_digit* r, const sp_digit* a, const sp_dig #else __asm__ __volatile__ ( - "ldr x4, [%[a], 0]\n\t" - "ldr x6, [%[a], 8]\n\t" - "ldr x5, [%[b], 0]\n\t" - "ldr x7, [%[b], 8]\n\t" + "ldp x4, x6, [%[a], 0]\n\t" + "ldp x5, x7, [%[b], 0]\n\t" "and x5, x5, %[m]\n\t" "and x7, x7, %[m]\n\t" "subs x4, x4, x5\n\t" "sbcs x6, x6, x7\n\t" - "str x4, [%[r], 0]\n\t" - "str x6, [%[r], 8]\n\t" - "ldr x4, [%[a], 16]\n\t" - "ldr x6, [%[a], 24]\n\t" - "ldr x5, [%[b], 16]\n\t" - "ldr x7, [%[b], 24]\n\t" + "stp x4, x6, [%[r], 0]\n\t" + "ldp x4, x6, [%[a], 16]\n\t" + "ldp x5, x7, [%[b], 16]\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" - "str x4, [%[r], 16]\n\t" - "str x6, [%[r], 24]\n\t" - "ldr x4, [%[a], 32]\n\t" - "ldr x6, [%[a], 40]\n\t" - "ldr x5, [%[b], 32]\n\t" - "ldr x7, [%[b], 40]\n\t" + "stp x4, x6, [%[r], 16]\n\t" + "ldp x4, x6, [%[a], 32]\n\t" + "ldp x5, x7, [%[b], 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" - "str x4, [%[r], 32]\n\t" - "str x6, [%[r], 40]\n\t" - "ldr x4, [%[a], 48]\n\t" - "ldr x6, [%[a], 56]\n\t" - "ldr x5, [%[b], 48]\n\t" - "ldr x7, [%[b], 56]\n\t" + "stp x4, x6, [%[r], 32]\n\t" + "ldp x4, x6, [%[a], 48]\n\t" + "ldp x5, x7, [%[b], 48]\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" - "str x4, [%[r], 48]\n\t" - "str x6, [%[r], 56]\n\t" - "ldr x4, [%[a], 64]\n\t" - "ldr x6, [%[a], 72]\n\t" - "ldr x5, [%[b], 64]\n\t" - "ldr x7, [%[b], 72]\n\t" + "stp x4, x6, [%[r], 48]\n\t" + "ldp x4, x6, [%[a], 64]\n\t" + "ldp x5, x7, [%[b], 64]\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" - "str x4, [%[r], 64]\n\t" - "str x6, [%[r], 72]\n\t" - "ldr x4, [%[a], 80]\n\t" - "ldr x6, [%[a], 88]\n\t" - "ldr x5, [%[b], 80]\n\t" - "ldr x7, [%[b], 88]\n\t" + "stp x4, x6, [%[r], 64]\n\t" + "ldp x4, x6, [%[a], 80]\n\t" + "ldp x5, x7, [%[b], 80]\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" - "str x4, [%[r], 80]\n\t" - "str x6, [%[r], 88]\n\t" - "ldr x4, [%[a], 96]\n\t" - "ldr x6, [%[a], 104]\n\t" - "ldr x5, [%[b], 96]\n\t" - "ldr x7, [%[b], 104]\n\t" + "stp x4, x6, [%[r], 80]\n\t" + "ldp x4, x6, [%[a], 96]\n\t" + "ldp x5, x7, [%[b], 96]\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" - "str x4, [%[r], 96]\n\t" - "str x6, [%[r], 104]\n\t" - "ldr x4, [%[a], 112]\n\t" - "ldr x6, [%[a], 120]\n\t" - "ldr x5, [%[b], 112]\n\t" - "ldr x7, [%[b], 120]\n\t" + "stp x4, x6, [%[r], 96]\n\t" + "ldp x4, x6, [%[a], 112]\n\t" + "ldp x5, x7, [%[b], 112]\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" - "str x4, [%[r], 112]\n\t" - "str x6, [%[r], 120]\n\t" + "stp x4, x6, [%[r], 112]\n\t" "csetm %[c], cc\n\t" : [c] "+r" (c) : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) @@ -3388,166 +3364,118 @@ static sp_digit sp_2048_cond_sub_32(sp_digit* r, const sp_digit* a, const sp_dig #else __asm__ __volatile__ ( - "ldr x4, [%[a], 0]\n\t" - "ldr x6, [%[a], 8]\n\t" - "ldr x5, [%[b], 0]\n\t" - "ldr x7, [%[b], 8]\n\t" + "ldp x4, x6, [%[a], 0]\n\t" + "ldp x5, x7, [%[b], 0]\n\t" "and x5, x5, %[m]\n\t" "and x7, x7, %[m]\n\t" "subs x4, x4, x5\n\t" "sbcs x6, x6, x7\n\t" - "str x4, [%[r], 0]\n\t" - "str x6, [%[r], 8]\n\t" - "ldr x4, [%[a], 16]\n\t" - "ldr x6, [%[a], 24]\n\t" - "ldr x5, [%[b], 16]\n\t" - "ldr x7, [%[b], 24]\n\t" + "stp x4, x6, [%[r], 0]\n\t" + "ldp x4, x6, [%[a], 16]\n\t" + "ldp x5, x7, [%[b], 16]\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" - "str x4, [%[r], 16]\n\t" - "str x6, [%[r], 24]\n\t" - "ldr x4, [%[a], 32]\n\t" - "ldr x6, [%[a], 40]\n\t" - "ldr x5, [%[b], 32]\n\t" - "ldr x7, [%[b], 40]\n\t" + "stp x4, x6, [%[r], 16]\n\t" + "ldp x4, x6, [%[a], 32]\n\t" + "ldp x5, x7, [%[b], 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" - "str x4, [%[r], 32]\n\t" - "str x6, [%[r], 40]\n\t" - "ldr x4, [%[a], 48]\n\t" - "ldr x6, [%[a], 56]\n\t" - "ldr x5, [%[b], 48]\n\t" - "ldr x7, [%[b], 56]\n\t" + "stp x4, x6, [%[r], 32]\n\t" + "ldp x4, x6, [%[a], 48]\n\t" + "ldp x5, x7, [%[b], 48]\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" - "str x4, [%[r], 48]\n\t" - "str x6, [%[r], 56]\n\t" - "ldr x4, [%[a], 64]\n\t" - "ldr x6, [%[a], 72]\n\t" - "ldr x5, [%[b], 64]\n\t" - "ldr x7, [%[b], 72]\n\t" + "stp x4, x6, [%[r], 48]\n\t" + "ldp x4, x6, [%[a], 64]\n\t" + "ldp x5, x7, [%[b], 64]\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" - "str x4, [%[r], 64]\n\t" - "str x6, [%[r], 72]\n\t" - "ldr x4, [%[a], 80]\n\t" - "ldr x6, [%[a], 88]\n\t" - "ldr x5, [%[b], 80]\n\t" - "ldr x7, [%[b], 88]\n\t" + "stp x4, x6, [%[r], 64]\n\t" + "ldp x4, x6, [%[a], 80]\n\t" + "ldp x5, x7, [%[b], 80]\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" - "str x4, [%[r], 80]\n\t" - "str x6, [%[r], 88]\n\t" - "ldr x4, [%[a], 96]\n\t" - "ldr x6, [%[a], 104]\n\t" - "ldr x5, [%[b], 96]\n\t" - "ldr x7, [%[b], 104]\n\t" + "stp x4, x6, [%[r], 80]\n\t" + "ldp x4, x6, [%[a], 96]\n\t" + "ldp x5, x7, [%[b], 96]\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" - "str x4, [%[r], 96]\n\t" - "str x6, [%[r], 104]\n\t" - "ldr x4, [%[a], 112]\n\t" - "ldr x6, [%[a], 120]\n\t" - "ldr x5, [%[b], 112]\n\t" - "ldr x7, [%[b], 120]\n\t" + "stp x4, x6, [%[r], 96]\n\t" + "ldp x4, x6, [%[a], 112]\n\t" + "ldp x5, x7, [%[b], 112]\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" - "str x4, [%[r], 112]\n\t" - "str x6, [%[r], 120]\n\t" - "ldr x4, [%[a], 128]\n\t" - "ldr x6, [%[a], 136]\n\t" - "ldr x5, [%[b], 128]\n\t" - "ldr x7, [%[b], 136]\n\t" + "stp x4, x6, [%[r], 112]\n\t" + "ldp x4, x6, [%[a], 128]\n\t" + "ldp x5, x7, [%[b], 128]\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" - "str x4, [%[r], 128]\n\t" - "str x6, [%[r], 136]\n\t" - "ldr x4, [%[a], 144]\n\t" - "ldr x6, [%[a], 152]\n\t" - "ldr x5, [%[b], 144]\n\t" - "ldr x7, [%[b], 152]\n\t" + "stp x4, x6, [%[r], 128]\n\t" + "ldp x4, x6, [%[a], 144]\n\t" + "ldp x5, x7, [%[b], 144]\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" - "str x4, [%[r], 144]\n\t" - "str x6, [%[r], 152]\n\t" - "ldr x4, [%[a], 160]\n\t" - "ldr x6, [%[a], 168]\n\t" - "ldr x5, [%[b], 160]\n\t" - "ldr x7, [%[b], 168]\n\t" + "stp x4, x6, [%[r], 144]\n\t" + "ldp x4, x6, [%[a], 160]\n\t" + "ldp x5, x7, [%[b], 160]\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" - "str x4, [%[r], 160]\n\t" - "str x6, [%[r], 168]\n\t" - "ldr x4, [%[a], 176]\n\t" - "ldr x6, [%[a], 184]\n\t" - "ldr x5, [%[b], 176]\n\t" - "ldr x7, [%[b], 184]\n\t" + "stp x4, x6, [%[r], 160]\n\t" + "ldp x4, x6, [%[a], 176]\n\t" + "ldp x5, x7, [%[b], 176]\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" - "str x4, [%[r], 176]\n\t" - "str x6, [%[r], 184]\n\t" - "ldr x4, [%[a], 192]\n\t" - "ldr x6, [%[a], 200]\n\t" - "ldr x5, [%[b], 192]\n\t" - "ldr x7, [%[b], 200]\n\t" + "stp x4, x6, [%[r], 176]\n\t" + "ldp x4, x6, [%[a], 192]\n\t" + "ldp x5, x7, [%[b], 192]\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" - "str x4, [%[r], 192]\n\t" - "str x6, [%[r], 200]\n\t" - "ldr x4, [%[a], 208]\n\t" - "ldr x6, [%[a], 216]\n\t" - "ldr x5, [%[b], 208]\n\t" - "ldr x7, [%[b], 216]\n\t" + "stp x4, x6, [%[r], 192]\n\t" + "ldp x4, x6, [%[a], 208]\n\t" + "ldp x5, x7, [%[b], 208]\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" - "str x4, [%[r], 208]\n\t" - "str x6, [%[r], 216]\n\t" - "ldr x4, [%[a], 224]\n\t" - "ldr x6, [%[a], 232]\n\t" - "ldr x5, [%[b], 224]\n\t" - "ldr x7, [%[b], 232]\n\t" + "stp x4, x6, [%[r], 208]\n\t" + "ldp x4, x6, [%[a], 224]\n\t" + "ldp x5, x7, [%[b], 224]\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" - "str x4, [%[r], 224]\n\t" - "str x6, [%[r], 232]\n\t" - "ldr x4, [%[a], 240]\n\t" - "ldr x6, [%[a], 248]\n\t" - "ldr x5, [%[b], 240]\n\t" - "ldr x7, [%[b], 248]\n\t" + "stp x4, x6, [%[r], 224]\n\t" + "ldp x4, x6, [%[a], 240]\n\t" + "ldp x5, x7, [%[b], 240]\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" - "str x4, [%[r], 240]\n\t" - "str x6, [%[r], 248]\n\t" + "stp x4, x6, [%[r], 240]\n\t" "csetm %[c], cc\n\t" : [c] "+r" (c) : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) @@ -4841,6 +4769,115 @@ int sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm, return err; } +#ifndef WOLFSSL_RSA_PUBLIC_ONLY +/* 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_2048_cond_add_16(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 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" + ); +#else + __asm__ __volatile__ ( + + "ldp x4, x6, [%[a], 0]\n\t" + "ldp x5, x7, [%[b], 0]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adds x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x6, [%[r], 8]\n\t" + "stp x4, x6, [%[r], 0]\n\t" + "ldp x4, x6, [%[a], 16]\n\t" + "ldp x5, x7, [%[b], 16]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x6, [%[r], 24]\n\t" + "stp x4, x6, [%[r], 16]\n\t" + "ldp x4, x6, [%[a], 32]\n\t" + "ldp x5, x7, [%[b], 32]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x6, [%[r], 40]\n\t" + "stp x4, x6, [%[r], 32]\n\t" + "ldp x4, x6, [%[a], 48]\n\t" + "ldp x5, x7, [%[b], 48]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x6, [%[r], 56]\n\t" + "stp x4, x6, [%[r], 48]\n\t" + "ldp x4, x6, [%[a], 64]\n\t" + "ldp x5, x7, [%[b], 64]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x6, [%[r], 72]\n\t" + "stp x4, x6, [%[r], 64]\n\t" + "ldp x4, x6, [%[a], 80]\n\t" + "ldp x5, x7, [%[b], 80]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x6, [%[r], 88]\n\t" + "stp x4, x6, [%[r], 80]\n\t" + "ldp x4, x6, [%[a], 96]\n\t" + "ldp x5, x7, [%[b], 96]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x6, [%[r], 104]\n\t" + "stp x4, x6, [%[r], 96]\n\t" + "ldp x4, x6, [%[a], 112]\n\t" + "ldp x5, x7, [%[b], 112]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x6, [%[r], 120]\n\t" + "stp x4, x6, [%[r], 112]\n\t" + "cset %[c], cs\n\t" + : [c] "+r" (c) + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) + : "memory", "x4", "x6", "x5", "x7", "x8" + ); +#endif /* WOLFSSL_SP_SMALL */ + + return c; +} + /* RSA private key operation. * * in Array of bytes representing the number to exponentiate, base. @@ -4875,7 +4912,6 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, sp_digit* dp; sp_digit* dq; sp_digit* qi; - sp_digit* tmp; sp_digit* tmpa; sp_digit* tmpb; sp_digit* r; @@ -4905,8 +4941,7 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, tmpa = qi + 16; tmpb = tmpa + 32; - tmp = t; - r = tmp + 32; + r = t + 32; } #else r = a = ad; @@ -4915,7 +4950,6 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, qi = dq = dp = dpd; tmpa = tmpad; tmpb = tmpbd; - tmp = a + 32; #endif if (err == MP_OKAY) { @@ -4933,8 +4967,8 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, if (err == MP_OKAY) { c = sp_2048_sub_in_place_16(tmpa, tmpb); - sp_2048_mask_16(tmp, p, c); - sp_2048_add_16(tmpa, tmpa, tmp); + c += sp_2048_cond_add_16(tmpa, tmpa, p, c); + sp_2048_cond_add_16(tmpa, tmpa, p, c); sp_2048_from_mp(qi, 16, qim); sp_2048_mul_16(tmpa, tmpa, qi); @@ -4965,6 +4999,7 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, return err; } +#endif /* WOLFSSL_RSA_PUBLIC_ONLY */ #endif /* WOLFSSL_HAVE_SP_RSA */ #if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \ !defined(WOLFSSL_RSA_PUBLIC_ONLY)) @@ -9097,126 +9132,90 @@ static sp_digit sp_3072_cond_sub_24(sp_digit* r, const sp_digit* a, const sp_dig #else __asm__ __volatile__ ( - "ldr x4, [%[a], 0]\n\t" - "ldr x6, [%[a], 8]\n\t" - "ldr x5, [%[b], 0]\n\t" - "ldr x7, [%[b], 8]\n\t" + "ldp x4, x6, [%[a], 0]\n\t" + "ldp x5, x7, [%[b], 0]\n\t" "and x5, x5, %[m]\n\t" "and x7, x7, %[m]\n\t" "subs x4, x4, x5\n\t" "sbcs x6, x6, x7\n\t" - "str x4, [%[r], 0]\n\t" - "str x6, [%[r], 8]\n\t" - "ldr x4, [%[a], 16]\n\t" - "ldr x6, [%[a], 24]\n\t" - "ldr x5, [%[b], 16]\n\t" - "ldr x7, [%[b], 24]\n\t" + "stp x4, x6, [%[r], 0]\n\t" + "ldp x4, x6, [%[a], 16]\n\t" + "ldp x5, x7, [%[b], 16]\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" - "str x4, [%[r], 16]\n\t" - "str x6, [%[r], 24]\n\t" - "ldr x4, [%[a], 32]\n\t" - "ldr x6, [%[a], 40]\n\t" - "ldr x5, [%[b], 32]\n\t" - "ldr x7, [%[b], 40]\n\t" + "stp x4, x6, [%[r], 16]\n\t" + "ldp x4, x6, [%[a], 32]\n\t" + "ldp x5, x7, [%[b], 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" - "str x4, [%[r], 32]\n\t" - "str x6, [%[r], 40]\n\t" - "ldr x4, [%[a], 48]\n\t" - "ldr x6, [%[a], 56]\n\t" - "ldr x5, [%[b], 48]\n\t" - "ldr x7, [%[b], 56]\n\t" + "stp x4, x6, [%[r], 32]\n\t" + "ldp x4, x6, [%[a], 48]\n\t" + "ldp x5, x7, [%[b], 48]\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" - "str x4, [%[r], 48]\n\t" - "str x6, [%[r], 56]\n\t" - "ldr x4, [%[a], 64]\n\t" - "ldr x6, [%[a], 72]\n\t" - "ldr x5, [%[b], 64]\n\t" - "ldr x7, [%[b], 72]\n\t" + "stp x4, x6, [%[r], 48]\n\t" + "ldp x4, x6, [%[a], 64]\n\t" + "ldp x5, x7, [%[b], 64]\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" - "str x4, [%[r], 64]\n\t" - "str x6, [%[r], 72]\n\t" - "ldr x4, [%[a], 80]\n\t" - "ldr x6, [%[a], 88]\n\t" - "ldr x5, [%[b], 80]\n\t" - "ldr x7, [%[b], 88]\n\t" + "stp x4, x6, [%[r], 64]\n\t" + "ldp x4, x6, [%[a], 80]\n\t" + "ldp x5, x7, [%[b], 80]\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" - "str x4, [%[r], 80]\n\t" - "str x6, [%[r], 88]\n\t" - "ldr x4, [%[a], 96]\n\t" - "ldr x6, [%[a], 104]\n\t" - "ldr x5, [%[b], 96]\n\t" - "ldr x7, [%[b], 104]\n\t" + "stp x4, x6, [%[r], 80]\n\t" + "ldp x4, x6, [%[a], 96]\n\t" + "ldp x5, x7, [%[b], 96]\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" - "str x4, [%[r], 96]\n\t" - "str x6, [%[r], 104]\n\t" - "ldr x4, [%[a], 112]\n\t" - "ldr x6, [%[a], 120]\n\t" - "ldr x5, [%[b], 112]\n\t" - "ldr x7, [%[b], 120]\n\t" + "stp x4, x6, [%[r], 96]\n\t" + "ldp x4, x6, [%[a], 112]\n\t" + "ldp x5, x7, [%[b], 112]\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" - "str x4, [%[r], 112]\n\t" - "str x6, [%[r], 120]\n\t" - "ldr x4, [%[a], 128]\n\t" - "ldr x6, [%[a], 136]\n\t" - "ldr x5, [%[b], 128]\n\t" - "ldr x7, [%[b], 136]\n\t" + "stp x4, x6, [%[r], 112]\n\t" + "ldp x4, x6, [%[a], 128]\n\t" + "ldp x5, x7, [%[b], 128]\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" - "str x4, [%[r], 128]\n\t" - "str x6, [%[r], 136]\n\t" - "ldr x4, [%[a], 144]\n\t" - "ldr x6, [%[a], 152]\n\t" - "ldr x5, [%[b], 144]\n\t" - "ldr x7, [%[b], 152]\n\t" + "stp x4, x6, [%[r], 128]\n\t" + "ldp x4, x6, [%[a], 144]\n\t" + "ldp x5, x7, [%[b], 144]\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" - "str x4, [%[r], 144]\n\t" - "str x6, [%[r], 152]\n\t" - "ldr x4, [%[a], 160]\n\t" - "ldr x6, [%[a], 168]\n\t" - "ldr x5, [%[b], 160]\n\t" - "ldr x7, [%[b], 168]\n\t" + "stp x4, x6, [%[r], 144]\n\t" + "ldp x4, x6, [%[a], 160]\n\t" + "ldp x5, x7, [%[b], 160]\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" - "str x4, [%[r], 160]\n\t" - "str x6, [%[r], 168]\n\t" - "ldr x4, [%[a], 176]\n\t" - "ldr x6, [%[a], 184]\n\t" - "ldr x5, [%[b], 176]\n\t" - "ldr x7, [%[b], 184]\n\t" + "stp x4, x6, [%[r], 160]\n\t" + "ldp x4, x6, [%[a], 176]\n\t" + "ldp x5, x7, [%[b], 176]\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" - "str x4, [%[r], 176]\n\t" - "str x6, [%[r], 184]\n\t" + "stp x4, x6, [%[r], 176]\n\t" "csetm %[c], cc\n\t" : [c] "+r" (c) : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) @@ -10466,246 +10465,174 @@ static sp_digit sp_3072_cond_sub_48(sp_digit* r, const sp_digit* a, const sp_dig #else __asm__ __volatile__ ( - "ldr x4, [%[a], 0]\n\t" - "ldr x6, [%[a], 8]\n\t" - "ldr x5, [%[b], 0]\n\t" - "ldr x7, [%[b], 8]\n\t" + "ldp x4, x6, [%[a], 0]\n\t" + "ldp x5, x7, [%[b], 0]\n\t" "and x5, x5, %[m]\n\t" "and x7, x7, %[m]\n\t" "subs x4, x4, x5\n\t" "sbcs x6, x6, x7\n\t" - "str x4, [%[r], 0]\n\t" - "str x6, [%[r], 8]\n\t" - "ldr x4, [%[a], 16]\n\t" - "ldr x6, [%[a], 24]\n\t" - "ldr x5, [%[b], 16]\n\t" - "ldr x7, [%[b], 24]\n\t" + "stp x4, x6, [%[r], 0]\n\t" + "ldp x4, x6, [%[a], 16]\n\t" + "ldp x5, x7, [%[b], 16]\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" - "str x4, [%[r], 16]\n\t" - "str x6, [%[r], 24]\n\t" - "ldr x4, [%[a], 32]\n\t" - "ldr x6, [%[a], 40]\n\t" - "ldr x5, [%[b], 32]\n\t" - "ldr x7, [%[b], 40]\n\t" + "stp x4, x6, [%[r], 16]\n\t" + "ldp x4, x6, [%[a], 32]\n\t" + "ldp x5, x7, [%[b], 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" - "str x4, [%[r], 32]\n\t" - "str x6, [%[r], 40]\n\t" - "ldr x4, [%[a], 48]\n\t" - "ldr x6, [%[a], 56]\n\t" - "ldr x5, [%[b], 48]\n\t" - "ldr x7, [%[b], 56]\n\t" + "stp x4, x6, [%[r], 32]\n\t" + "ldp x4, x6, [%[a], 48]\n\t" + "ldp x5, x7, [%[b], 48]\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" - "str x4, [%[r], 48]\n\t" - "str x6, [%[r], 56]\n\t" - "ldr x4, [%[a], 64]\n\t" - "ldr x6, [%[a], 72]\n\t" - "ldr x5, [%[b], 64]\n\t" - "ldr x7, [%[b], 72]\n\t" + "stp x4, x6, [%[r], 48]\n\t" + "ldp x4, x6, [%[a], 64]\n\t" + "ldp x5, x7, [%[b], 64]\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" - "str x4, [%[r], 64]\n\t" - "str x6, [%[r], 72]\n\t" - "ldr x4, [%[a], 80]\n\t" - "ldr x6, [%[a], 88]\n\t" - "ldr x5, [%[b], 80]\n\t" - "ldr x7, [%[b], 88]\n\t" + "stp x4, x6, [%[r], 64]\n\t" + "ldp x4, x6, [%[a], 80]\n\t" + "ldp x5, x7, [%[b], 80]\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" - "str x4, [%[r], 80]\n\t" - "str x6, [%[r], 88]\n\t" - "ldr x4, [%[a], 96]\n\t" - "ldr x6, [%[a], 104]\n\t" - "ldr x5, [%[b], 96]\n\t" - "ldr x7, [%[b], 104]\n\t" + "stp x4, x6, [%[r], 80]\n\t" + "ldp x4, x6, [%[a], 96]\n\t" + "ldp x5, x7, [%[b], 96]\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" - "str x4, [%[r], 96]\n\t" - "str x6, [%[r], 104]\n\t" - "ldr x4, [%[a], 112]\n\t" - "ldr x6, [%[a], 120]\n\t" - "ldr x5, [%[b], 112]\n\t" - "ldr x7, [%[b], 120]\n\t" + "stp x4, x6, [%[r], 96]\n\t" + "ldp x4, x6, [%[a], 112]\n\t" + "ldp x5, x7, [%[b], 112]\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" - "str x4, [%[r], 112]\n\t" - "str x6, [%[r], 120]\n\t" - "ldr x4, [%[a], 128]\n\t" - "ldr x6, [%[a], 136]\n\t" - "ldr x5, [%[b], 128]\n\t" - "ldr x7, [%[b], 136]\n\t" + "stp x4, x6, [%[r], 112]\n\t" + "ldp x4, x6, [%[a], 128]\n\t" + "ldp x5, x7, [%[b], 128]\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" - "str x4, [%[r], 128]\n\t" - "str x6, [%[r], 136]\n\t" - "ldr x4, [%[a], 144]\n\t" - "ldr x6, [%[a], 152]\n\t" - "ldr x5, [%[b], 144]\n\t" - "ldr x7, [%[b], 152]\n\t" + "stp x4, x6, [%[r], 128]\n\t" + "ldp x4, x6, [%[a], 144]\n\t" + "ldp x5, x7, [%[b], 144]\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" - "str x4, [%[r], 144]\n\t" - "str x6, [%[r], 152]\n\t" - "ldr x4, [%[a], 160]\n\t" - "ldr x6, [%[a], 168]\n\t" - "ldr x5, [%[b], 160]\n\t" - "ldr x7, [%[b], 168]\n\t" + "stp x4, x6, [%[r], 144]\n\t" + "ldp x4, x6, [%[a], 160]\n\t" + "ldp x5, x7, [%[b], 160]\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" - "str x4, [%[r], 160]\n\t" - "str x6, [%[r], 168]\n\t" - "ldr x4, [%[a], 176]\n\t" - "ldr x6, [%[a], 184]\n\t" - "ldr x5, [%[b], 176]\n\t" - "ldr x7, [%[b], 184]\n\t" + "stp x4, x6, [%[r], 160]\n\t" + "ldp x4, x6, [%[a], 176]\n\t" + "ldp x5, x7, [%[b], 176]\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" - "str x4, [%[r], 176]\n\t" - "str x6, [%[r], 184]\n\t" - "ldr x4, [%[a], 192]\n\t" - "ldr x6, [%[a], 200]\n\t" - "ldr x5, [%[b], 192]\n\t" - "ldr x7, [%[b], 200]\n\t" + "stp x4, x6, [%[r], 176]\n\t" + "ldp x4, x6, [%[a], 192]\n\t" + "ldp x5, x7, [%[b], 192]\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" - "str x4, [%[r], 192]\n\t" - "str x6, [%[r], 200]\n\t" - "ldr x4, [%[a], 208]\n\t" - "ldr x6, [%[a], 216]\n\t" - "ldr x5, [%[b], 208]\n\t" - "ldr x7, [%[b], 216]\n\t" + "stp x4, x6, [%[r], 192]\n\t" + "ldp x4, x6, [%[a], 208]\n\t" + "ldp x5, x7, [%[b], 208]\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" - "str x4, [%[r], 208]\n\t" - "str x6, [%[r], 216]\n\t" - "ldr x4, [%[a], 224]\n\t" - "ldr x6, [%[a], 232]\n\t" - "ldr x5, [%[b], 224]\n\t" - "ldr x7, [%[b], 232]\n\t" + "stp x4, x6, [%[r], 208]\n\t" + "ldp x4, x6, [%[a], 224]\n\t" + "ldp x5, x7, [%[b], 224]\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" - "str x4, [%[r], 224]\n\t" - "str x6, [%[r], 232]\n\t" - "ldr x4, [%[a], 240]\n\t" - "ldr x6, [%[a], 248]\n\t" - "ldr x5, [%[b], 240]\n\t" - "ldr x7, [%[b], 248]\n\t" + "stp x4, x6, [%[r], 224]\n\t" + "ldp x4, x6, [%[a], 240]\n\t" + "ldp x5, x7, [%[b], 240]\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" - "str x4, [%[r], 240]\n\t" - "str x6, [%[r], 248]\n\t" - "ldr x4, [%[a], 256]\n\t" - "ldr x6, [%[a], 264]\n\t" - "ldr x5, [%[b], 256]\n\t" - "ldr x7, [%[b], 264]\n\t" + "stp x4, x6, [%[r], 240]\n\t" + "ldp x4, x6, [%[a], 256]\n\t" + "ldp x5, x7, [%[b], 256]\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" - "str x4, [%[r], 256]\n\t" - "str x6, [%[r], 264]\n\t" - "ldr x4, [%[a], 272]\n\t" - "ldr x6, [%[a], 280]\n\t" - "ldr x5, [%[b], 272]\n\t" - "ldr x7, [%[b], 280]\n\t" + "stp x4, x6, [%[r], 256]\n\t" + "ldp x4, x6, [%[a], 272]\n\t" + "ldp x5, x7, [%[b], 272]\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" - "str x4, [%[r], 272]\n\t" - "str x6, [%[r], 280]\n\t" - "ldr x4, [%[a], 288]\n\t" - "ldr x6, [%[a], 296]\n\t" - "ldr x5, [%[b], 288]\n\t" - "ldr x7, [%[b], 296]\n\t" + "stp x4, x6, [%[r], 272]\n\t" + "ldp x4, x6, [%[a], 288]\n\t" + "ldp x5, x7, [%[b], 288]\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" - "str x4, [%[r], 288]\n\t" - "str x6, [%[r], 296]\n\t" - "ldr x4, [%[a], 304]\n\t" - "ldr x6, [%[a], 312]\n\t" - "ldr x5, [%[b], 304]\n\t" - "ldr x7, [%[b], 312]\n\t" + "stp x4, x6, [%[r], 288]\n\t" + "ldp x4, x6, [%[a], 304]\n\t" + "ldp x5, x7, [%[b], 304]\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" - "str x4, [%[r], 304]\n\t" - "str x6, [%[r], 312]\n\t" - "ldr x4, [%[a], 320]\n\t" - "ldr x6, [%[a], 328]\n\t" - "ldr x5, [%[b], 320]\n\t" - "ldr x7, [%[b], 328]\n\t" + "stp x4, x6, [%[r], 304]\n\t" + "ldp x4, x6, [%[a], 320]\n\t" + "ldp x5, x7, [%[b], 320]\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" - "str x4, [%[r], 320]\n\t" - "str x6, [%[r], 328]\n\t" - "ldr x4, [%[a], 336]\n\t" - "ldr x6, [%[a], 344]\n\t" - "ldr x5, [%[b], 336]\n\t" - "ldr x7, [%[b], 344]\n\t" + "stp x4, x6, [%[r], 320]\n\t" + "ldp x4, x6, [%[a], 336]\n\t" + "ldp x5, x7, [%[b], 336]\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" - "str x4, [%[r], 336]\n\t" - "str x6, [%[r], 344]\n\t" - "ldr x4, [%[a], 352]\n\t" - "ldr x6, [%[a], 360]\n\t" - "ldr x5, [%[b], 352]\n\t" - "ldr x7, [%[b], 360]\n\t" + "stp x4, x6, [%[r], 336]\n\t" + "ldp x4, x6, [%[a], 352]\n\t" + "ldp x5, x7, [%[b], 352]\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" - "str x4, [%[r], 352]\n\t" - "str x6, [%[r], 360]\n\t" - "ldr x4, [%[a], 368]\n\t" - "ldr x6, [%[a], 376]\n\t" - "ldr x5, [%[b], 368]\n\t" - "ldr x7, [%[b], 376]\n\t" + "stp x4, x6, [%[r], 352]\n\t" + "ldp x4, x6, [%[a], 368]\n\t" + "ldp x5, x7, [%[b], 368]\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" - "str x4, [%[r], 368]\n\t" - "str x6, [%[r], 376]\n\t" + "stp x4, x6, [%[r], 368]\n\t" "csetm %[c], cc\n\t" : [c] "+r" (c) : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) @@ -12287,6 +12214,147 @@ int sp_RsaPublic_3072(const byte* in, word32 inLen, mp_int* em, mp_int* mm, return err; } +#ifndef WOLFSSL_RSA_PUBLIC_ONLY +/* 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_3072_cond_add_24(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 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, 192\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" + ); +#else + __asm__ __volatile__ ( + + "ldp x4, x6, [%[a], 0]\n\t" + "ldp x5, x7, [%[b], 0]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adds x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x6, [%[r], 8]\n\t" + "stp x4, x6, [%[r], 0]\n\t" + "ldp x4, x6, [%[a], 16]\n\t" + "ldp x5, x7, [%[b], 16]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x6, [%[r], 24]\n\t" + "stp x4, x6, [%[r], 16]\n\t" + "ldp x4, x6, [%[a], 32]\n\t" + "ldp x5, x7, [%[b], 32]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x6, [%[r], 40]\n\t" + "stp x4, x6, [%[r], 32]\n\t" + "ldp x4, x6, [%[a], 48]\n\t" + "ldp x5, x7, [%[b], 48]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x6, [%[r], 56]\n\t" + "stp x4, x6, [%[r], 48]\n\t" + "ldp x4, x6, [%[a], 64]\n\t" + "ldp x5, x7, [%[b], 64]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x6, [%[r], 72]\n\t" + "stp x4, x6, [%[r], 64]\n\t" + "ldp x4, x6, [%[a], 80]\n\t" + "ldp x5, x7, [%[b], 80]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x6, [%[r], 88]\n\t" + "stp x4, x6, [%[r], 80]\n\t" + "ldp x4, x6, [%[a], 96]\n\t" + "ldp x5, x7, [%[b], 96]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x6, [%[r], 104]\n\t" + "stp x4, x6, [%[r], 96]\n\t" + "ldp x4, x6, [%[a], 112]\n\t" + "ldp x5, x7, [%[b], 112]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x6, [%[r], 120]\n\t" + "stp x4, x6, [%[r], 112]\n\t" + "ldp x4, x6, [%[a], 128]\n\t" + "ldp x5, x7, [%[b], 128]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x6, [%[r], 136]\n\t" + "stp x4, x6, [%[r], 128]\n\t" + "ldp x4, x6, [%[a], 144]\n\t" + "ldp x5, x7, [%[b], 144]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x6, [%[r], 152]\n\t" + "stp x4, x6, [%[r], 144]\n\t" + "ldp x4, x6, [%[a], 160]\n\t" + "ldp x5, x7, [%[b], 160]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x6, [%[r], 168]\n\t" + "stp x4, x6, [%[r], 160]\n\t" + "ldp x4, x6, [%[a], 176]\n\t" + "ldp x5, x7, [%[b], 176]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x6, [%[r], 184]\n\t" + "stp x4, x6, [%[r], 176]\n\t" + "cset %[c], cs\n\t" + : [c] "+r" (c) + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) + : "memory", "x4", "x6", "x5", "x7", "x8" + ); +#endif /* WOLFSSL_SP_SMALL */ + + return c; +} + /* RSA private key operation. * * in Array of bytes representing the number to exponentiate, base. @@ -12321,7 +12389,6 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, sp_digit* dp; sp_digit* dq; sp_digit* qi; - sp_digit* tmp; sp_digit* tmpa; sp_digit* tmpb; sp_digit* r; @@ -12351,8 +12418,7 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, tmpa = qi + 24; tmpb = tmpa + 48; - tmp = t; - r = tmp + 48; + r = t + 48; } #else r = a = ad; @@ -12361,7 +12427,6 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, qi = dq = dp = dpd; tmpa = tmpad; tmpb = tmpbd; - tmp = a + 48; #endif if (err == MP_OKAY) { @@ -12379,8 +12444,8 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, if (err == MP_OKAY) { c = sp_3072_sub_in_place_24(tmpa, tmpb); - sp_3072_mask_24(tmp, p, c); - sp_3072_add_24(tmpa, tmpa, tmp); + c += sp_3072_cond_add_24(tmpa, tmpa, p, c); + sp_3072_cond_add_24(tmpa, tmpa, p, c); sp_3072_from_mp(qi, 24, qim); sp_3072_mul_24(tmpa, tmpa, qi); @@ -12411,6 +12476,7 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, return err; } +#endif /* WOLFSSL_RSA_PUBLIC_ONLY */ #endif /* WOLFSSL_HAVE_SP_RSA */ #if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \ !defined(WOLFSSL_RSA_PUBLIC_ONLY)) @@ -27491,326 +27557,230 @@ static sp_digit sp_4096_cond_sub_64(sp_digit* r, const sp_digit* a, const sp_dig #else __asm__ __volatile__ ( - "ldr x4, [%[a], 0]\n\t" - "ldr x6, [%[a], 8]\n\t" - "ldr x5, [%[b], 0]\n\t" - "ldr x7, [%[b], 8]\n\t" + "ldp x4, x6, [%[a], 0]\n\t" + "ldp x5, x7, [%[b], 0]\n\t" "and x5, x5, %[m]\n\t" "and x7, x7, %[m]\n\t" "subs x4, x4, x5\n\t" "sbcs x6, x6, x7\n\t" - "str x4, [%[r], 0]\n\t" - "str x6, [%[r], 8]\n\t" - "ldr x4, [%[a], 16]\n\t" - "ldr x6, [%[a], 24]\n\t" - "ldr x5, [%[b], 16]\n\t" - "ldr x7, [%[b], 24]\n\t" + "stp x4, x6, [%[r], 0]\n\t" + "ldp x4, x6, [%[a], 16]\n\t" + "ldp x5, x7, [%[b], 16]\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" - "str x4, [%[r], 16]\n\t" - "str x6, [%[r], 24]\n\t" - "ldr x4, [%[a], 32]\n\t" - "ldr x6, [%[a], 40]\n\t" - "ldr x5, [%[b], 32]\n\t" - "ldr x7, [%[b], 40]\n\t" + "stp x4, x6, [%[r], 16]\n\t" + "ldp x4, x6, [%[a], 32]\n\t" + "ldp x5, x7, [%[b], 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" - "str x4, [%[r], 32]\n\t" - "str x6, [%[r], 40]\n\t" - "ldr x4, [%[a], 48]\n\t" - "ldr x6, [%[a], 56]\n\t" - "ldr x5, [%[b], 48]\n\t" - "ldr x7, [%[b], 56]\n\t" + "stp x4, x6, [%[r], 32]\n\t" + "ldp x4, x6, [%[a], 48]\n\t" + "ldp x5, x7, [%[b], 48]\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" - "str x4, [%[r], 48]\n\t" - "str x6, [%[r], 56]\n\t" - "ldr x4, [%[a], 64]\n\t" - "ldr x6, [%[a], 72]\n\t" - "ldr x5, [%[b], 64]\n\t" - "ldr x7, [%[b], 72]\n\t" + "stp x4, x6, [%[r], 48]\n\t" + "ldp x4, x6, [%[a], 64]\n\t" + "ldp x5, x7, [%[b], 64]\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" - "str x4, [%[r], 64]\n\t" - "str x6, [%[r], 72]\n\t" - "ldr x4, [%[a], 80]\n\t" - "ldr x6, [%[a], 88]\n\t" - "ldr x5, [%[b], 80]\n\t" - "ldr x7, [%[b], 88]\n\t" + "stp x4, x6, [%[r], 64]\n\t" + "ldp x4, x6, [%[a], 80]\n\t" + "ldp x5, x7, [%[b], 80]\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" - "str x4, [%[r], 80]\n\t" - "str x6, [%[r], 88]\n\t" - "ldr x4, [%[a], 96]\n\t" - "ldr x6, [%[a], 104]\n\t" - "ldr x5, [%[b], 96]\n\t" - "ldr x7, [%[b], 104]\n\t" + "stp x4, x6, [%[r], 80]\n\t" + "ldp x4, x6, [%[a], 96]\n\t" + "ldp x5, x7, [%[b], 96]\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" - "str x4, [%[r], 96]\n\t" - "str x6, [%[r], 104]\n\t" - "ldr x4, [%[a], 112]\n\t" - "ldr x6, [%[a], 120]\n\t" - "ldr x5, [%[b], 112]\n\t" - "ldr x7, [%[b], 120]\n\t" + "stp x4, x6, [%[r], 96]\n\t" + "ldp x4, x6, [%[a], 112]\n\t" + "ldp x5, x7, [%[b], 112]\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" - "str x4, [%[r], 112]\n\t" - "str x6, [%[r], 120]\n\t" - "ldr x4, [%[a], 128]\n\t" - "ldr x6, [%[a], 136]\n\t" - "ldr x5, [%[b], 128]\n\t" - "ldr x7, [%[b], 136]\n\t" + "stp x4, x6, [%[r], 112]\n\t" + "ldp x4, x6, [%[a], 128]\n\t" + "ldp x5, x7, [%[b], 128]\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" - "str x4, [%[r], 128]\n\t" - "str x6, [%[r], 136]\n\t" - "ldr x4, [%[a], 144]\n\t" - "ldr x6, [%[a], 152]\n\t" - "ldr x5, [%[b], 144]\n\t" - "ldr x7, [%[b], 152]\n\t" + "stp x4, x6, [%[r], 128]\n\t" + "ldp x4, x6, [%[a], 144]\n\t" + "ldp x5, x7, [%[b], 144]\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" - "str x4, [%[r], 144]\n\t" - "str x6, [%[r], 152]\n\t" - "ldr x4, [%[a], 160]\n\t" - "ldr x6, [%[a], 168]\n\t" - "ldr x5, [%[b], 160]\n\t" - "ldr x7, [%[b], 168]\n\t" + "stp x4, x6, [%[r], 144]\n\t" + "ldp x4, x6, [%[a], 160]\n\t" + "ldp x5, x7, [%[b], 160]\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" - "str x4, [%[r], 160]\n\t" - "str x6, [%[r], 168]\n\t" - "ldr x4, [%[a], 176]\n\t" - "ldr x6, [%[a], 184]\n\t" - "ldr x5, [%[b], 176]\n\t" - "ldr x7, [%[b], 184]\n\t" + "stp x4, x6, [%[r], 160]\n\t" + "ldp x4, x6, [%[a], 176]\n\t" + "ldp x5, x7, [%[b], 176]\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" - "str x4, [%[r], 176]\n\t" - "str x6, [%[r], 184]\n\t" - "ldr x4, [%[a], 192]\n\t" - "ldr x6, [%[a], 200]\n\t" - "ldr x5, [%[b], 192]\n\t" - "ldr x7, [%[b], 200]\n\t" + "stp x4, x6, [%[r], 176]\n\t" + "ldp x4, x6, [%[a], 192]\n\t" + "ldp x5, x7, [%[b], 192]\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" - "str x4, [%[r], 192]\n\t" - "str x6, [%[r], 200]\n\t" - "ldr x4, [%[a], 208]\n\t" - "ldr x6, [%[a], 216]\n\t" - "ldr x5, [%[b], 208]\n\t" - "ldr x7, [%[b], 216]\n\t" + "stp x4, x6, [%[r], 192]\n\t" + "ldp x4, x6, [%[a], 208]\n\t" + "ldp x5, x7, [%[b], 208]\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" - "str x4, [%[r], 208]\n\t" - "str x6, [%[r], 216]\n\t" - "ldr x4, [%[a], 224]\n\t" - "ldr x6, [%[a], 232]\n\t" - "ldr x5, [%[b], 224]\n\t" - "ldr x7, [%[b], 232]\n\t" + "stp x4, x6, [%[r], 208]\n\t" + "ldp x4, x6, [%[a], 224]\n\t" + "ldp x5, x7, [%[b], 224]\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" - "str x4, [%[r], 224]\n\t" - "str x6, [%[r], 232]\n\t" - "ldr x4, [%[a], 240]\n\t" - "ldr x6, [%[a], 248]\n\t" - "ldr x5, [%[b], 240]\n\t" - "ldr x7, [%[b], 248]\n\t" + "stp x4, x6, [%[r], 224]\n\t" + "ldp x4, x6, [%[a], 240]\n\t" + "ldp x5, x7, [%[b], 240]\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" - "str x4, [%[r], 240]\n\t" - "str x6, [%[r], 248]\n\t" - "ldr x4, [%[a], 256]\n\t" - "ldr x6, [%[a], 264]\n\t" - "ldr x5, [%[b], 256]\n\t" - "ldr x7, [%[b], 264]\n\t" + "stp x4, x6, [%[r], 240]\n\t" + "ldp x4, x6, [%[a], 256]\n\t" + "ldp x5, x7, [%[b], 256]\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" - "str x4, [%[r], 256]\n\t" - "str x6, [%[r], 264]\n\t" - "ldr x4, [%[a], 272]\n\t" - "ldr x6, [%[a], 280]\n\t" - "ldr x5, [%[b], 272]\n\t" - "ldr x7, [%[b], 280]\n\t" + "stp x4, x6, [%[r], 256]\n\t" + "ldp x4, x6, [%[a], 272]\n\t" + "ldp x5, x7, [%[b], 272]\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" - "str x4, [%[r], 272]\n\t" - "str x6, [%[r], 280]\n\t" - "ldr x4, [%[a], 288]\n\t" - "ldr x6, [%[a], 296]\n\t" - "ldr x5, [%[b], 288]\n\t" - "ldr x7, [%[b], 296]\n\t" + "stp x4, x6, [%[r], 272]\n\t" + "ldp x4, x6, [%[a], 288]\n\t" + "ldp x5, x7, [%[b], 288]\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" - "str x4, [%[r], 288]\n\t" - "str x6, [%[r], 296]\n\t" - "ldr x4, [%[a], 304]\n\t" - "ldr x6, [%[a], 312]\n\t" - "ldr x5, [%[b], 304]\n\t" - "ldr x7, [%[b], 312]\n\t" + "stp x4, x6, [%[r], 288]\n\t" + "ldp x4, x6, [%[a], 304]\n\t" + "ldp x5, x7, [%[b], 304]\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" - "str x4, [%[r], 304]\n\t" - "str x6, [%[r], 312]\n\t" - "ldr x4, [%[a], 320]\n\t" - "ldr x6, [%[a], 328]\n\t" - "ldr x5, [%[b], 320]\n\t" - "ldr x7, [%[b], 328]\n\t" + "stp x4, x6, [%[r], 304]\n\t" + "ldp x4, x6, [%[a], 320]\n\t" + "ldp x5, x7, [%[b], 320]\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" - "str x4, [%[r], 320]\n\t" - "str x6, [%[r], 328]\n\t" - "ldr x4, [%[a], 336]\n\t" - "ldr x6, [%[a], 344]\n\t" - "ldr x5, [%[b], 336]\n\t" - "ldr x7, [%[b], 344]\n\t" + "stp x4, x6, [%[r], 320]\n\t" + "ldp x4, x6, [%[a], 336]\n\t" + "ldp x5, x7, [%[b], 336]\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" - "str x4, [%[r], 336]\n\t" - "str x6, [%[r], 344]\n\t" - "ldr x4, [%[a], 352]\n\t" - "ldr x6, [%[a], 360]\n\t" - "ldr x5, [%[b], 352]\n\t" - "ldr x7, [%[b], 360]\n\t" + "stp x4, x6, [%[r], 336]\n\t" + "ldp x4, x6, [%[a], 352]\n\t" + "ldp x5, x7, [%[b], 352]\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" - "str x4, [%[r], 352]\n\t" - "str x6, [%[r], 360]\n\t" - "ldr x4, [%[a], 368]\n\t" - "ldr x6, [%[a], 376]\n\t" - "ldr x5, [%[b], 368]\n\t" - "ldr x7, [%[b], 376]\n\t" + "stp x4, x6, [%[r], 352]\n\t" + "ldp x4, x6, [%[a], 368]\n\t" + "ldp x5, x7, [%[b], 368]\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" - "str x4, [%[r], 368]\n\t" - "str x6, [%[r], 376]\n\t" - "ldr x4, [%[a], 384]\n\t" - "ldr x6, [%[a], 392]\n\t" - "ldr x5, [%[b], 384]\n\t" - "ldr x7, [%[b], 392]\n\t" + "stp x4, x6, [%[r], 368]\n\t" + "ldp x4, x6, [%[a], 384]\n\t" + "ldp x5, x7, [%[b], 384]\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" - "str x4, [%[r], 384]\n\t" - "str x6, [%[r], 392]\n\t" - "ldr x4, [%[a], 400]\n\t" - "ldr x6, [%[a], 408]\n\t" - "ldr x5, [%[b], 400]\n\t" - "ldr x7, [%[b], 408]\n\t" + "stp x4, x6, [%[r], 384]\n\t" + "ldp x4, x6, [%[a], 400]\n\t" + "ldp x5, x7, [%[b], 400]\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" - "str x4, [%[r], 400]\n\t" - "str x6, [%[r], 408]\n\t" - "ldr x4, [%[a], 416]\n\t" - "ldr x6, [%[a], 424]\n\t" - "ldr x5, [%[b], 416]\n\t" - "ldr x7, [%[b], 424]\n\t" + "stp x4, x6, [%[r], 400]\n\t" + "ldp x4, x6, [%[a], 416]\n\t" + "ldp x5, x7, [%[b], 416]\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" - "str x4, [%[r], 416]\n\t" - "str x6, [%[r], 424]\n\t" - "ldr x4, [%[a], 432]\n\t" - "ldr x6, [%[a], 440]\n\t" - "ldr x5, [%[b], 432]\n\t" - "ldr x7, [%[b], 440]\n\t" + "stp x4, x6, [%[r], 416]\n\t" + "ldp x4, x6, [%[a], 432]\n\t" + "ldp x5, x7, [%[b], 432]\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" - "str x4, [%[r], 432]\n\t" - "str x6, [%[r], 440]\n\t" - "ldr x4, [%[a], 448]\n\t" - "ldr x6, [%[a], 456]\n\t" - "ldr x5, [%[b], 448]\n\t" - "ldr x7, [%[b], 456]\n\t" + "stp x4, x6, [%[r], 432]\n\t" + "ldp x4, x6, [%[a], 448]\n\t" + "ldp x5, x7, [%[b], 448]\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" - "str x4, [%[r], 448]\n\t" - "str x6, [%[r], 456]\n\t" - "ldr x4, [%[a], 464]\n\t" - "ldr x6, [%[a], 472]\n\t" - "ldr x5, [%[b], 464]\n\t" - "ldr x7, [%[b], 472]\n\t" + "stp x4, x6, [%[r], 448]\n\t" + "ldp x4, x6, [%[a], 464]\n\t" + "ldp x5, x7, [%[b], 464]\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" - "str x4, [%[r], 464]\n\t" - "str x6, [%[r], 472]\n\t" - "ldr x4, [%[a], 480]\n\t" - "ldr x6, [%[a], 488]\n\t" - "ldr x5, [%[b], 480]\n\t" - "ldr x7, [%[b], 488]\n\t" + "stp x4, x6, [%[r], 464]\n\t" + "ldp x4, x6, [%[a], 480]\n\t" + "ldp x5, x7, [%[b], 480]\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" - "str x4, [%[r], 480]\n\t" - "str x6, [%[r], 488]\n\t" - "ldr x4, [%[a], 496]\n\t" - "ldr x6, [%[a], 504]\n\t" - "ldr x5, [%[b], 496]\n\t" - "ldr x7, [%[b], 504]\n\t" + "stp x4, x6, [%[r], 480]\n\t" + "ldp x4, x6, [%[a], 496]\n\t" + "ldp x5, x7, [%[b], 496]\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" - "str x4, [%[r], 496]\n\t" - "str x6, [%[r], 504]\n\t" + "stp x4, x6, [%[r], 496]\n\t" "csetm %[c], cc\n\t" : [c] "+r" (c) : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) @@ -29680,6 +29650,179 @@ int sp_RsaPublic_4096(const byte* in, word32 inLen, mp_int* em, mp_int* mm, return err; } +#ifndef WOLFSSL_RSA_PUBLIC_ONLY +/* 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_4096_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 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, 256\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" + ); +#else + __asm__ __volatile__ ( + + "ldp x4, x6, [%[a], 0]\n\t" + "ldp x5, x7, [%[b], 0]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adds x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x6, [%[r], 8]\n\t" + "stp x4, x6, [%[r], 0]\n\t" + "ldp x4, x6, [%[a], 16]\n\t" + "ldp x5, x7, [%[b], 16]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x6, [%[r], 24]\n\t" + "stp x4, x6, [%[r], 16]\n\t" + "ldp x4, x6, [%[a], 32]\n\t" + "ldp x5, x7, [%[b], 32]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x6, [%[r], 40]\n\t" + "stp x4, x6, [%[r], 32]\n\t" + "ldp x4, x6, [%[a], 48]\n\t" + "ldp x5, x7, [%[b], 48]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x6, [%[r], 56]\n\t" + "stp x4, x6, [%[r], 48]\n\t" + "ldp x4, x6, [%[a], 64]\n\t" + "ldp x5, x7, [%[b], 64]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x6, [%[r], 72]\n\t" + "stp x4, x6, [%[r], 64]\n\t" + "ldp x4, x6, [%[a], 80]\n\t" + "ldp x5, x7, [%[b], 80]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x6, [%[r], 88]\n\t" + "stp x4, x6, [%[r], 80]\n\t" + "ldp x4, x6, [%[a], 96]\n\t" + "ldp x5, x7, [%[b], 96]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x6, [%[r], 104]\n\t" + "stp x4, x6, [%[r], 96]\n\t" + "ldp x4, x6, [%[a], 112]\n\t" + "ldp x5, x7, [%[b], 112]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x6, [%[r], 120]\n\t" + "stp x4, x6, [%[r], 112]\n\t" + "ldp x4, x6, [%[a], 128]\n\t" + "ldp x5, x7, [%[b], 128]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x6, [%[r], 136]\n\t" + "stp x4, x6, [%[r], 128]\n\t" + "ldp x4, x6, [%[a], 144]\n\t" + "ldp x5, x7, [%[b], 144]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x6, [%[r], 152]\n\t" + "stp x4, x6, [%[r], 144]\n\t" + "ldp x4, x6, [%[a], 160]\n\t" + "ldp x5, x7, [%[b], 160]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x6, [%[r], 168]\n\t" + "stp x4, x6, [%[r], 160]\n\t" + "ldp x4, x6, [%[a], 176]\n\t" + "ldp x5, x7, [%[b], 176]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x6, [%[r], 184]\n\t" + "stp x4, x6, [%[r], 176]\n\t" + "ldp x4, x6, [%[a], 192]\n\t" + "ldp x5, x7, [%[b], 192]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x6, [%[r], 200]\n\t" + "stp x4, x6, [%[r], 192]\n\t" + "ldp x4, x6, [%[a], 208]\n\t" + "ldp x5, x7, [%[b], 208]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x6, [%[r], 216]\n\t" + "stp x4, x6, [%[r], 208]\n\t" + "ldp x4, x6, [%[a], 224]\n\t" + "ldp x5, x7, [%[b], 224]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x6, [%[r], 232]\n\t" + "stp x4, x6, [%[r], 224]\n\t" + "ldp x4, x6, [%[a], 240]\n\t" + "ldp x5, x7, [%[b], 240]\n\t" + "and x5, x5, %[m]\n\t" + "and x7, x7, %[m]\n\t" + "adcs x4, x4, x5\n\t" + "adcs x6, x6, x7\n\t" + "str x6, [%[r], 248]\n\t" + "stp x4, x6, [%[r], 240]\n\t" + "cset %[c], cs\n\t" + : [c] "+r" (c) + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) + : "memory", "x4", "x6", "x5", "x7", "x8" + ); +#endif /* WOLFSSL_SP_SMALL */ + + return c; +} + /* RSA private key operation. * * in Array of bytes representing the number to exponentiate, base. @@ -29714,7 +29857,6 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, sp_digit* dp; sp_digit* dq; sp_digit* qi; - sp_digit* tmp; sp_digit* tmpa; sp_digit* tmpb; sp_digit* r; @@ -29744,8 +29886,7 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, tmpa = qi + 32; tmpb = tmpa + 64; - tmp = t; - r = tmp + 64; + r = t + 64; } #else r = a = ad; @@ -29754,7 +29895,6 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, qi = dq = dp = dpd; tmpa = tmpad; tmpb = tmpbd; - tmp = a + 64; #endif if (err == MP_OKAY) { @@ -29772,8 +29912,8 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, if (err == MP_OKAY) { c = sp_4096_sub_in_place_32(tmpa, tmpb); - sp_4096_mask_32(tmp, p, c); - sp_4096_add_32(tmpa, tmpa, tmp); + c += sp_4096_cond_add_32(tmpa, tmpa, p, c); + sp_4096_cond_add_32(tmpa, tmpa, p, c); sp_4096_from_mp(qi, 32, qim); sp_4096_mul_32(tmpa, tmpa, qi); @@ -29804,6 +29944,7 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, return err; } +#endif /* WOLFSSL_RSA_PUBLIC_ONLY */ #endif /* WOLFSSL_HAVE_SP_RSA */ #if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \ !defined(WOLFSSL_RSA_PUBLIC_ONLY)) @@ -31467,26 +31608,20 @@ static sp_digit sp_256_cond_sub_4(sp_digit* r, const sp_digit* a, const sp_digit __asm__ __volatile__ ( - "ldr x4, [%[a], 0]\n\t" - "ldr x6, [%[a], 8]\n\t" - "ldr x5, [%[b], 0]\n\t" - "ldr x7, [%[b], 8]\n\t" + "ldp x4, x6, [%[a], 0]\n\t" + "ldp x5, x7, [%[b], 0]\n\t" "and x5, x5, %[m]\n\t" "and x7, x7, %[m]\n\t" "subs x4, x4, x5\n\t" "sbcs x6, x6, x7\n\t" - "str x4, [%[r], 0]\n\t" - "str x6, [%[r], 8]\n\t" - "ldr x4, [%[a], 16]\n\t" - "ldr x6, [%[a], 24]\n\t" - "ldr x5, [%[b], 16]\n\t" - "ldr x7, [%[b], 24]\n\t" + "stp x4, x6, [%[r], 0]\n\t" + "ldp x4, x6, [%[a], 16]\n\t" + "ldp x5, x7, [%[b], 16]\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" - "str x4, [%[r], 16]\n\t" - "str x6, [%[r], 24]\n\t" + "stp x4, x6, [%[r], 16]\n\t" "csetm %[c], cc\n\t" : [c] "+r" (c) : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) @@ -49133,36 +49268,27 @@ static sp_digit sp_384_cond_sub_6(sp_digit* r, const sp_digit* a, const sp_digit #else __asm__ __volatile__ ( - "ldr x4, [%[a], 0]\n\t" - "ldr x6, [%[a], 8]\n\t" - "ldr x5, [%[b], 0]\n\t" - "ldr x7, [%[b], 8]\n\t" + "ldp x4, x6, [%[a], 0]\n\t" + "ldp x5, x7, [%[b], 0]\n\t" "and x5, x5, %[m]\n\t" "and x7, x7, %[m]\n\t" "subs x4, x4, x5\n\t" "sbcs x6, x6, x7\n\t" - "str x4, [%[r], 0]\n\t" - "str x6, [%[r], 8]\n\t" - "ldr x4, [%[a], 16]\n\t" - "ldr x6, [%[a], 24]\n\t" - "ldr x5, [%[b], 16]\n\t" - "ldr x7, [%[b], 24]\n\t" + "stp x4, x6, [%[r], 0]\n\t" + "ldp x4, x6, [%[a], 16]\n\t" + "ldp x5, x7, [%[b], 16]\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" - "str x4, [%[r], 16]\n\t" - "str x6, [%[r], 24]\n\t" - "ldr x4, [%[a], 32]\n\t" - "ldr x6, [%[a], 40]\n\t" - "ldr x5, [%[b], 32]\n\t" - "ldr x7, [%[b], 40]\n\t" + "stp x4, x6, [%[r], 16]\n\t" + "ldp x4, x6, [%[a], 32]\n\t" + "ldp x5, x7, [%[b], 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" - "str x4, [%[r], 32]\n\t" - "str x6, [%[r], 40]\n\t" + "stp x4, x6, [%[r], 32]\n\t" "csetm %[c], cc\n\t" : [c] "+r" (c) : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) @@ -49948,42 +50074,57 @@ static sp_digit sp_384_cond_add_6(sp_digit* r, const sp_digit* a, const sp_digit { sp_digit c = 0; +#ifdef WOLFSSL_SP_SMALL __asm__ __volatile__ ( - "ldr x4, [%[a], 0]\n\t" - "ldr x6, [%[a], 8]\n\t" - "ldr x5, [%[b], 0]\n\t" - "ldr x7, [%[b], 8]\n\t" + "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, 48\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" + ); +#else + __asm__ __volatile__ ( + + "ldp x4, x6, [%[a], 0]\n\t" + "ldp x5, x7, [%[b], 0]\n\t" "and x5, x5, %[m]\n\t" "and x7, x7, %[m]\n\t" "adds x4, x4, x5\n\t" "adcs x6, x6, x7\n\t" - "str x4, [%[r], 0]\n\t" "str x6, [%[r], 8]\n\t" - "ldr x4, [%[a], 16]\n\t" - "ldr x6, [%[a], 24]\n\t" - "ldr x5, [%[b], 16]\n\t" - "ldr x7, [%[b], 24]\n\t" + "stp x4, x6, [%[r], 0]\n\t" + "ldp x4, x6, [%[a], 16]\n\t" + "ldp x5, x7, [%[b], 16]\n\t" "and x5, x5, %[m]\n\t" "and x7, x7, %[m]\n\t" "adcs x4, x4, x5\n\t" "adcs x6, x6, x7\n\t" - "str x4, [%[r], 16]\n\t" "str x6, [%[r], 24]\n\t" - "ldr x4, [%[a], 32]\n\t" - "ldr x6, [%[a], 40]\n\t" - "ldr x5, [%[b], 32]\n\t" - "ldr x7, [%[b], 40]\n\t" + "stp x4, x6, [%[r], 16]\n\t" + "ldp x4, x6, [%[a], 32]\n\t" + "ldp x5, x7, [%[b], 32]\n\t" "and x5, x5, %[m]\n\t" "and x7, x7, %[m]\n\t" "adcs x4, x4, x5\n\t" "adcs x6, x6, x7\n\t" - "str x4, [%[r], 32]\n\t" "str x6, [%[r], 40]\n\t" + "stp x4, x6, [%[r], 32]\n\t" "cset %[c], cs\n\t" : [c] "+r" (c) : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) - : "memory", "x4", "x6", "x5", "x7" + : "memory", "x4", "x6", "x5", "x7", "x8" ); +#endif /* WOLFSSL_SP_SMALL */ return c; } diff --git a/wolfcrypt/src/sp_armthumb.c b/wolfcrypt/src/sp_armthumb.c index 5c6b01ab0..38fd06ecd 100644 --- a/wolfcrypt/src/sp_armthumb.c +++ b/wolfcrypt/src/sp_armthumb.c @@ -4358,6 +4358,46 @@ int sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm, return err; } +#ifndef WOLFSSL_RSA_PUBLIC_ONLY +/* 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_2048_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; +} + /* RSA private key operation. * * in Array of bytes representing the number to exponentiate, base. @@ -4392,7 +4432,6 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, sp_digit* dp; sp_digit* dq; sp_digit* qi; - sp_digit* tmp; sp_digit* tmpa; sp_digit* tmpb; sp_digit* r; @@ -4422,8 +4461,7 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, tmpa = qi + 32; tmpb = tmpa + 64; - tmp = t; - r = tmp + 64; + r = t + 64; } #else r = a = ad; @@ -4432,7 +4470,6 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, qi = dq = dp = dpd; tmpa = tmpad; tmpb = tmpbd; - tmp = a + 64; #endif if (err == MP_OKAY) { @@ -4450,8 +4487,8 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, if (err == MP_OKAY) { c = sp_2048_sub_in_place_32(tmpa, tmpb); - sp_2048_mask_32(tmp, p, c); - sp_2048_add_32(tmpa, tmpa, tmp); + c += sp_2048_cond_add_32(tmpa, tmpa, p, c); + sp_2048_cond_add_32(tmpa, tmpa, p, c); sp_2048_from_mp(qi, 32, qim); sp_2048_mul_32(tmpa, tmpa, qi); @@ -4482,6 +4519,7 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, return err; } +#endif /* WOLFSSL_RSA_PUBLIC_ONLY */ #endif /* WOLFSSL_HAVE_SP_RSA */ #if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \ !defined(WOLFSSL_RSA_PUBLIC_ONLY)) @@ -10061,6 +10099,46 @@ int sp_RsaPublic_3072(const byte* in, word32 inLen, mp_int* em, mp_int* mm, return err; } +#ifndef WOLFSSL_RSA_PUBLIC_ONLY +/* 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_3072_cond_add_48(sp_digit* r, const sp_digit* a, const sp_digit* b, + sp_digit m) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "mov r5, #192\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; +} + /* RSA private key operation. * * in Array of bytes representing the number to exponentiate, base. @@ -10095,7 +10173,6 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, sp_digit* dp; sp_digit* dq; sp_digit* qi; - sp_digit* tmp; sp_digit* tmpa; sp_digit* tmpb; sp_digit* r; @@ -10125,8 +10202,7 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, tmpa = qi + 48; tmpb = tmpa + 96; - tmp = t; - r = tmp + 96; + r = t + 96; } #else r = a = ad; @@ -10135,7 +10211,6 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, qi = dq = dp = dpd; tmpa = tmpad; tmpb = tmpbd; - tmp = a + 96; #endif if (err == MP_OKAY) { @@ -10153,8 +10228,8 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, if (err == MP_OKAY) { c = sp_3072_sub_in_place_48(tmpa, tmpb); - sp_3072_mask_48(tmp, p, c); - sp_3072_add_48(tmpa, tmpa, tmp); + c += sp_3072_cond_add_48(tmpa, tmpa, p, c); + sp_3072_cond_add_48(tmpa, tmpa, p, c); sp_3072_from_mp(qi, 48, qim); sp_3072_mul_48(tmpa, tmpa, qi); @@ -10185,6 +10260,7 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, return err; } +#endif /* WOLFSSL_RSA_PUBLIC_ONLY */ #endif /* WOLFSSL_HAVE_SP_RSA */ #if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \ !defined(WOLFSSL_RSA_PUBLIC_ONLY)) @@ -14423,6 +14499,47 @@ int sp_RsaPublic_4096(const byte* in, word32 inLen, mp_int* em, mp_int* mm, return err; } +#ifndef WOLFSSL_RSA_PUBLIC_ONLY +/* 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_4096_cond_add_64(sp_digit* r, const sp_digit* a, const sp_digit* b, + sp_digit m) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "mov r5, #1\n\t" + "lsl r5, r5, #8\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; +} + /* RSA private key operation. * * in Array of bytes representing the number to exponentiate, base. @@ -14457,7 +14574,6 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, sp_digit* dp; sp_digit* dq; sp_digit* qi; - sp_digit* tmp; sp_digit* tmpa; sp_digit* tmpb; sp_digit* r; @@ -14487,8 +14603,7 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, tmpa = qi + 64; tmpb = tmpa + 128; - tmp = t; - r = tmp + 128; + r = t + 128; } #else r = a = ad; @@ -14497,7 +14612,6 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, qi = dq = dp = dpd; tmpa = tmpad; tmpb = tmpbd; - tmp = a + 128; #endif if (err == MP_OKAY) { @@ -14515,8 +14629,8 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, if (err == MP_OKAY) { c = sp_4096_sub_in_place_64(tmpa, tmpb); - sp_4096_mask_64(tmp, p, c); - sp_4096_add_64(tmpa, tmpa, tmp); + c += sp_4096_cond_add_64(tmpa, tmpa, p, c); + sp_4096_cond_add_64(tmpa, tmpa, p, c); sp_4096_from_mp(qi, 64, qim); sp_4096_mul_64(tmpa, tmpa, qi); @@ -14547,6 +14661,7 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, return err; } +#endif /* WOLFSSL_RSA_PUBLIC_ONLY */ #endif /* WOLFSSL_HAVE_SP_RSA */ #if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \ !defined(WOLFSSL_RSA_PUBLIC_ONLY)) @@ -23083,28 +23198,25 @@ SP_NOINLINE static sp_digit sp_384_cond_add_12(sp_digit* r, const sp_digit* a, c sp_digit c = 0; __asm__ __volatile__ ( - "mov r5, #0\n\t" - "mov r7, %[a]\n\t" - "add r7, #48\n\t" - "sub r5, #1\n\t" - "mov r8, r7\n\t" + "mov r5, #48\n\t" + "mov r8, r5\n\t" + "mov r7, #0\n\t" "1:\n\t" - "ldr r6, [%[a]]\n\t" - "ldr r7, [%[b]]\n\t" - "and r7, %[m]\n\t" - "add %[c], r5\n\t" - "adc r6, r7\n\t" - "str r6, [%[r]]\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" - "add %[a], $4\n\t" - "add %[b], $4\n\t" - "add %[r], $4\n\t" - "mov r7, r8\n\t" - "cmp %[a], r7\n\t" + "str r5, [%[r], r7]\n\t" + "add r7, #4\n\t" + "cmp r7, r8\n\t" "blt 1b\n\t" - : [r] "+r" (r), [a] "+r" (a), [b] "+r" (b), [c] "+r" (c) - : [m] "r" (m) + : [c] "+r" (c) + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) : "memory", "r5", "r6", "r7", "r8" ); diff --git a/wolfcrypt/src/sp_c32.c b/wolfcrypt/src/sp_c32.c index a308dcf0c..b3d5ade05 100644 --- a/wolfcrypt/src/sp_c32.c +++ b/wolfcrypt/src/sp_c32.c @@ -3128,44 +3128,6 @@ static int sp_2048_mod_exp_90(sp_digit* r, const sp_digit* a, const sp_digit* e, #endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || */ /* WOLFSSL_HAVE_SP_DH */ -#if defined(WOLFSSL_HAVE_SP_RSA) && !defined(SP_RSA_PRIVATE_EXP_D) && \ - !defined(RSA_LOW_MEM) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) -/* 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_2048_mask_45(sp_digit* r, const sp_digit* a, sp_digit m) -{ -#ifdef WOLFSSL_SP_SMALL - int i; - - for (i=0; i<45; i++) { - r[i] = a[i] & m; - } -#else - int i; - - for (i = 0; i < 40; 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; - } - r[40] = a[40] & m; - r[41] = a[41] & m; - r[42] = a[42] & m; - r[43] = a[43] & m; - r[44] = a[44] & m; -#endif -} - -#endif #ifdef WOLFSSL_HAVE_SP_RSA /* RSA public key operation. * @@ -3397,6 +3359,8 @@ 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 */ /* RSA private key operation. * * in Array of bytes representing the number to exponentiate, base. @@ -3526,7 +3490,6 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, sp_digit* dp; sp_digit* dq; sp_digit* qi; - sp_digit* tmp; sp_digit* tmpa; sp_digit* tmpb; sp_digit* r; @@ -3562,8 +3525,7 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, tmpa = qi + 45; tmpb = tmpa + 90; - tmp = t; - r = tmp + 90; + r = t + 90; sp_2048_from_bin(a, 90, in, inLen); sp_2048_from_mp(p, 45, pm); @@ -3577,8 +3539,8 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, } if (err == MP_OKAY) { (void)sp_2048_sub_45(tmpa, tmpa, tmpb); - sp_2048_mask_45(tmp, p, 0 - ((sp_int_digit)tmpa[44] >> 31)); - (void)sp_2048_add_45(tmpa, tmpa, tmp); + sp_2048_cond_add_45(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[44] >> 31)); + sp_2048_cond_add_45(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[44] >> 31)); sp_2048_from_mp(qi, 45, qim); sp_2048_mul_45(tmpa, tmpa, qi); @@ -3603,7 +3565,7 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, #else sp_digit a[90 * 2]; sp_digit p[45], q[45], dp[45], dq[45], qi[45]; - sp_digit tmp[90], tmpa[90], tmpb[90]; + sp_digit tmpa[90], tmpb[90]; sp_digit* r = a; int err = MP_OKAY; @@ -3638,8 +3600,8 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, if (err == MP_OKAY) { (void)sp_2048_sub_45(tmpa, tmpa, tmpb); - sp_2048_mask_45(tmp, p, 0 - ((sp_int_digit)tmpa[44] >> 31)); - (void)sp_2048_add_45(tmpa, tmpa, tmp); + sp_2048_cond_add_45(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[44] >> 31)); + sp_2048_cond_add_45(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[44] >> 31)); sp_2048_mul_45(tmpa, tmpa, qi); err = sp_2048_mod_45(tmpa, tmpa, p); } @@ -7003,42 +6965,6 @@ static int sp_3072_mod_exp_134(sp_digit* r, const sp_digit* a, const sp_digit* e #endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || */ /* WOLFSSL_HAVE_SP_DH */ -#if defined(WOLFSSL_HAVE_SP_RSA) && !defined(SP_RSA_PRIVATE_EXP_D) && \ - !defined(RSA_LOW_MEM) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) -/* 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_3072_mask_67(sp_digit* r, const sp_digit* a, sp_digit m) -{ -#ifdef WOLFSSL_SP_SMALL - int i; - - for (i=0; i<67; i++) { - r[i] = a[i] & m; - } -#else - int i; - - for (i = 0; i < 64; 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; - } - r[64] = a[64] & m; - r[65] = a[65] & m; - r[66] = a[66] & m; -#endif -} - -#endif #ifdef WOLFSSL_HAVE_SP_RSA /* RSA public key operation. * @@ -7270,6 +7196,8 @@ 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 */ /* RSA private key operation. * * in Array of bytes representing the number to exponentiate, base. @@ -7399,7 +7327,6 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, sp_digit* dp; sp_digit* dq; sp_digit* qi; - sp_digit* tmp; sp_digit* tmpa; sp_digit* tmpb; sp_digit* r; @@ -7435,8 +7362,7 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, tmpa = qi + 67; tmpb = tmpa + 134; - tmp = t; - r = tmp + 134; + r = t + 134; sp_3072_from_bin(a, 134, in, inLen); sp_3072_from_mp(p, 67, pm); @@ -7450,8 +7376,8 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, } if (err == MP_OKAY) { (void)sp_3072_sub_67(tmpa, tmpa, tmpb); - sp_3072_mask_67(tmp, p, 0 - ((sp_int_digit)tmpa[66] >> 31)); - (void)sp_3072_add_67(tmpa, tmpa, tmp); + sp_3072_cond_add_67(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[66] >> 31)); + sp_3072_cond_add_67(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[66] >> 31)); sp_3072_from_mp(qi, 67, qim); sp_3072_mul_67(tmpa, tmpa, qi); @@ -7476,7 +7402,7 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, #else sp_digit a[134 * 2]; sp_digit p[67], q[67], dp[67], dq[67], qi[67]; - sp_digit tmp[134], tmpa[134], tmpb[134]; + sp_digit tmpa[134], tmpb[134]; sp_digit* r = a; int err = MP_OKAY; @@ -7511,8 +7437,8 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, if (err == MP_OKAY) { (void)sp_3072_sub_67(tmpa, tmpa, tmpb); - sp_3072_mask_67(tmp, p, 0 - ((sp_int_digit)tmpa[66] >> 31)); - (void)sp_3072_add_67(tmpa, tmpa, tmp); + sp_3072_cond_add_67(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[66] >> 31)); + sp_3072_cond_add_67(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[66] >> 31)); sp_3072_mul_67(tmpa, tmpa, qi); err = sp_3072_mod_67(tmpa, tmpa, p); } @@ -11040,41 +10966,6 @@ static int sp_4096_mod_exp_196(sp_digit* r, const sp_digit* a, const sp_digit* e #endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || */ /* WOLFSSL_HAVE_SP_DH */ -#if defined(WOLFSSL_HAVE_SP_RSA) && !defined(SP_RSA_PRIVATE_EXP_D) && \ - !defined(RSA_LOW_MEM) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) -/* 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_4096_mask_98(sp_digit* r, const sp_digit* a, sp_digit m) -{ -#ifdef WOLFSSL_SP_SMALL - int i; - - for (i=0; i<98; i++) { - r[i] = a[i] & m; - } -#else - int i; - - for (i = 0; i < 96; 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; - } - r[96] = a[96] & m; - r[97] = a[97] & m; -#endif -} - -#endif #ifdef WOLFSSL_HAVE_SP_RSA /* RSA public key operation. * @@ -11306,6 +11197,8 @@ 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 */ /* RSA private key operation. * * in Array of bytes representing the number to exponentiate, base. @@ -11435,7 +11328,6 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, sp_digit* dp; sp_digit* dq; sp_digit* qi; - sp_digit* tmp; sp_digit* tmpa; sp_digit* tmpb; sp_digit* r; @@ -11471,8 +11363,7 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, tmpa = qi + 98; tmpb = tmpa + 196; - tmp = t; - r = tmp + 196; + r = t + 196; sp_4096_from_bin(a, 196, in, inLen); sp_4096_from_mp(p, 98, pm); @@ -11486,8 +11377,8 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, } if (err == MP_OKAY) { (void)sp_4096_sub_98(tmpa, tmpa, tmpb); - sp_4096_mask_98(tmp, p, 0 - ((sp_int_digit)tmpa[97] >> 31)); - (void)sp_4096_add_98(tmpa, tmpa, tmp); + sp_4096_cond_add_98(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[97] >> 31)); + sp_4096_cond_add_98(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[97] >> 31)); sp_4096_from_mp(qi, 98, qim); sp_4096_mul_98(tmpa, tmpa, qi); @@ -11512,7 +11403,7 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, #else sp_digit a[196 * 2]; sp_digit p[98], q[98], dp[98], dq[98], qi[98]; - sp_digit tmp[196], tmpa[196], tmpb[196]; + sp_digit tmpa[196], tmpb[196]; sp_digit* r = a; int err = MP_OKAY; @@ -11547,8 +11438,8 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, if (err == MP_OKAY) { (void)sp_4096_sub_98(tmpa, tmpa, tmpb); - sp_4096_mask_98(tmp, p, 0 - ((sp_int_digit)tmpa[97] >> 31)); - (void)sp_4096_add_98(tmpa, tmpa, tmp); + sp_4096_cond_add_98(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[97] >> 31)); + sp_4096_cond_add_98(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[97] >> 31)); sp_4096_mul_98(tmpa, tmpa, qi); err = sp_4096_mod_98(tmpa, tmpa, p); } diff --git a/wolfcrypt/src/sp_c64.c b/wolfcrypt/src/sp_c64.c index 814d06d46..36fcbf4ba 100644 --- a/wolfcrypt/src/sp_c64.c +++ b/wolfcrypt/src/sp_c64.c @@ -2768,41 +2768,6 @@ static int sp_2048_mod_exp_36(sp_digit* r, const sp_digit* a, const sp_digit* e, #endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || */ /* WOLFSSL_HAVE_SP_DH */ -#if defined(WOLFSSL_HAVE_SP_RSA) && !defined(SP_RSA_PRIVATE_EXP_D) && \ - !defined(RSA_LOW_MEM) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) -/* 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_2048_mask_18(sp_digit* r, const sp_digit* a, sp_digit m) -{ -#ifdef WOLFSSL_SP_SMALL - int i; - - for (i=0; i<18; 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; - } - r[16] = a[16] & m; - r[17] = a[17] & m; -#endif -} - -#endif #ifdef WOLFSSL_HAVE_SP_RSA /* RSA public key operation. * @@ -3034,6 +2999,8 @@ 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 */ /* RSA private key operation. * * in Array of bytes representing the number to exponentiate, base. @@ -3163,7 +3130,6 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, sp_digit* dp; sp_digit* dq; sp_digit* qi; - sp_digit* tmp; sp_digit* tmpa; sp_digit* tmpb; sp_digit* r; @@ -3199,8 +3165,7 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, tmpa = qi + 18; tmpb = tmpa + 36; - tmp = t; - r = tmp + 36; + r = t + 36; sp_2048_from_bin(a, 36, in, inLen); sp_2048_from_mp(p, 18, pm); @@ -3214,8 +3179,8 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, } if (err == MP_OKAY) { (void)sp_2048_sub_18(tmpa, tmpa, tmpb); - sp_2048_mask_18(tmp, p, 0 - ((sp_int_digit)tmpa[17] >> 63)); - (void)sp_2048_add_18(tmpa, tmpa, tmp); + sp_2048_cond_add_18(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[17] >> 63)); + sp_2048_cond_add_18(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[17] >> 63)); sp_2048_from_mp(qi, 18, qim); sp_2048_mul_18(tmpa, tmpa, qi); @@ -3240,7 +3205,7 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, #else sp_digit a[36 * 2]; sp_digit p[18], q[18], dp[18], dq[18], qi[18]; - sp_digit tmp[36], tmpa[36], tmpb[36]; + sp_digit tmpa[36], tmpb[36]; sp_digit* r = a; int err = MP_OKAY; @@ -3275,8 +3240,8 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, if (err == MP_OKAY) { (void)sp_2048_sub_18(tmpa, tmpa, tmpb); - sp_2048_mask_18(tmp, p, 0 - ((sp_int_digit)tmpa[17] >> 63)); - (void)sp_2048_add_18(tmpa, tmpa, tmp); + sp_2048_cond_add_18(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[17] >> 63)); + sp_2048_cond_add_18(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[17] >> 63)); sp_2048_mul_18(tmpa, tmpa, qi); err = sp_2048_mod_18(tmpa, tmpa, p); } @@ -6914,42 +6879,6 @@ static int sp_3072_mod_exp_54(sp_digit* r, const sp_digit* a, const sp_digit* e, #endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || */ /* WOLFSSL_HAVE_SP_DH */ -#if defined(WOLFSSL_HAVE_SP_RSA) && !defined(SP_RSA_PRIVATE_EXP_D) && \ - !defined(RSA_LOW_MEM) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) -/* 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_3072_mask_27(sp_digit* r, const sp_digit* a, sp_digit m) -{ -#ifdef WOLFSSL_SP_SMALL - int i; - - for (i=0; i<27; i++) { - r[i] = a[i] & m; - } -#else - int i; - - for (i = 0; i < 24; 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; - } - r[24] = a[24] & m; - r[25] = a[25] & m; - r[26] = a[26] & m; -#endif -} - -#endif #ifdef WOLFSSL_HAVE_SP_RSA /* RSA public key operation. * @@ -7181,6 +7110,8 @@ 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 */ /* RSA private key operation. * * in Array of bytes representing the number to exponentiate, base. @@ -7310,7 +7241,6 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, sp_digit* dp; sp_digit* dq; sp_digit* qi; - sp_digit* tmp; sp_digit* tmpa; sp_digit* tmpb; sp_digit* r; @@ -7346,8 +7276,7 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, tmpa = qi + 27; tmpb = tmpa + 54; - tmp = t; - r = tmp + 54; + r = t + 54; sp_3072_from_bin(a, 54, in, inLen); sp_3072_from_mp(p, 27, pm); @@ -7361,8 +7290,8 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, } if (err == MP_OKAY) { (void)sp_3072_sub_27(tmpa, tmpa, tmpb); - sp_3072_mask_27(tmp, p, 0 - ((sp_int_digit)tmpa[26] >> 63)); - (void)sp_3072_add_27(tmpa, tmpa, tmp); + sp_3072_cond_add_27(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[26] >> 63)); + sp_3072_cond_add_27(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[26] >> 63)); sp_3072_from_mp(qi, 27, qim); sp_3072_mul_27(tmpa, tmpa, qi); @@ -7387,7 +7316,7 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, #else sp_digit a[54 * 2]; sp_digit p[27], q[27], dp[27], dq[27], qi[27]; - sp_digit tmp[54], tmpa[54], tmpb[54]; + sp_digit tmpa[54], tmpb[54]; sp_digit* r = a; int err = MP_OKAY; @@ -7422,8 +7351,8 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, if (err == MP_OKAY) { (void)sp_3072_sub_27(tmpa, tmpa, tmpb); - sp_3072_mask_27(tmp, p, 0 - ((sp_int_digit)tmpa[26] >> 63)); - (void)sp_3072_add_27(tmpa, tmpa, tmp); + sp_3072_cond_add_27(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[26] >> 63)); + sp_3072_cond_add_27(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[26] >> 63)); sp_3072_mul_27(tmpa, tmpa, qi); err = sp_3072_mod_27(tmpa, tmpa, p); } @@ -11306,46 +11235,6 @@ static int sp_4096_mod_exp_78(sp_digit* r, const sp_digit* a, const sp_digit* e, #endif /* (WOLFSSL_HAVE_SP_RSA && !WOLFSSL_RSA_PUBLIC_ONLY) || */ /* WOLFSSL_HAVE_SP_DH */ -#if defined(WOLFSSL_HAVE_SP_RSA) && !defined(SP_RSA_PRIVATE_EXP_D) && \ - !defined(RSA_LOW_MEM) && !defined(WOLFSSL_RSA_PUBLIC_ONLY) -/* 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_4096_mask_39(sp_digit* r, const sp_digit* a, sp_digit m) -{ -#ifdef WOLFSSL_SP_SMALL - int i; - - for (i=0; i<39; 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; - } - r[32] = a[32] & m; - r[33] = a[33] & m; - r[34] = a[34] & m; - r[35] = a[35] & m; - r[36] = a[36] & m; - r[37] = a[37] & m; - r[38] = a[38] & m; -#endif -} - -#endif #ifdef WOLFSSL_HAVE_SP_RSA /* RSA public key operation. * @@ -11577,6 +11466,8 @@ 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 */ /* RSA private key operation. * * in Array of bytes representing the number to exponentiate, base. @@ -11706,7 +11597,6 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, sp_digit* dp; sp_digit* dq; sp_digit* qi; - sp_digit* tmp; sp_digit* tmpa; sp_digit* tmpb; sp_digit* r; @@ -11742,8 +11632,7 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, tmpa = qi + 39; tmpb = tmpa + 78; - tmp = t; - r = tmp + 78; + r = t + 78; sp_4096_from_bin(a, 78, in, inLen); sp_4096_from_mp(p, 39, pm); @@ -11757,8 +11646,8 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, } if (err == MP_OKAY) { (void)sp_4096_sub_39(tmpa, tmpa, tmpb); - sp_4096_mask_39(tmp, p, 0 - ((sp_int_digit)tmpa[38] >> 63)); - (void)sp_4096_add_39(tmpa, tmpa, tmp); + sp_4096_cond_add_39(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[38] >> 63)); + sp_4096_cond_add_39(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[38] >> 63)); sp_4096_from_mp(qi, 39, qim); sp_4096_mul_39(tmpa, tmpa, qi); @@ -11783,7 +11672,7 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, #else sp_digit a[78 * 2]; sp_digit p[39], q[39], dp[39], dq[39], qi[39]; - sp_digit tmp[78], tmpa[78], tmpb[78]; + sp_digit tmpa[78], tmpb[78]; sp_digit* r = a; int err = MP_OKAY; @@ -11818,8 +11707,8 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, if (err == MP_OKAY) { (void)sp_4096_sub_39(tmpa, tmpa, tmpb); - sp_4096_mask_39(tmp, p, 0 - ((sp_int_digit)tmpa[38] >> 63)); - (void)sp_4096_add_39(tmpa, tmpa, tmp); + sp_4096_cond_add_39(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[38] >> 63)); + sp_4096_cond_add_39(tmpa, tmpa, p, 0 - ((sp_int_digit)tmpa[38] >> 63)); sp_4096_mul_39(tmpa, tmpa, qi); err = sp_4096_mod_39(tmpa, tmpa, p); } diff --git a/wolfcrypt/src/sp_cortexm.c b/wolfcrypt/src/sp_cortexm.c index 39a27d630..bd4a01482 100644 --- a/wolfcrypt/src/sp_cortexm.c +++ b/wolfcrypt/src/sp_cortexm.c @@ -4112,6 +4112,44 @@ int sp_RsaPublic_2048(const byte* in, word32 inLen, mp_int* em, mp_int* mm, return err; } +#ifndef WOLFSSL_RSA_PUBLIC_ONLY +/* 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_2048_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" + "blt 1b\n\t" + : [c] "+r" (c) + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) + : "memory", "r5", "r6", "r8", "r9" + ); + + return c; +} + /* RSA private key operation. * * in Array of bytes representing the number to exponentiate, base. @@ -4146,7 +4184,6 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, sp_digit* dp; sp_digit* dq; sp_digit* qi; - sp_digit* tmp; sp_digit* tmpa; sp_digit* tmpb; sp_digit* r; @@ -4176,8 +4213,7 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, tmpa = qi + 32; tmpb = tmpa + 64; - tmp = t; - r = tmp + 64; + r = t + 64; } #else r = a = ad; @@ -4186,7 +4222,6 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, qi = dq = dp = dpd; tmpa = tmpad; tmpb = tmpbd; - tmp = a + 64; #endif if (err == MP_OKAY) { @@ -4204,8 +4239,8 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, if (err == MP_OKAY) { c = sp_2048_sub_in_place_32(tmpa, tmpb); - sp_2048_mask_32(tmp, p, c); - sp_2048_add_32(tmpa, tmpa, tmp); + c += sp_2048_cond_add_32(tmpa, tmpa, p, c); + sp_2048_cond_add_32(tmpa, tmpa, p, c); sp_2048_from_mp(qi, 32, qim); sp_2048_mul_32(tmpa, tmpa, qi); @@ -4236,6 +4271,7 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, return err; } +#endif /* WOLFSSL_RSA_PUBLIC_ONLY */ #endif /* WOLFSSL_HAVE_SP_RSA */ #if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \ !defined(WOLFSSL_RSA_PUBLIC_ONLY)) @@ -8666,6 +8702,44 @@ int sp_RsaPublic_3072(const byte* in, word32 inLen, mp_int* em, mp_int* mm, return err; } +#ifndef WOLFSSL_RSA_PUBLIC_ONLY +/* 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_3072_cond_add_48(sp_digit* r, const sp_digit* a, const sp_digit* b, + sp_digit m) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "mov r5, #192\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" + "blt 1b\n\t" + : [c] "+r" (c) + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) + : "memory", "r5", "r6", "r8", "r9" + ); + + return c; +} + /* RSA private key operation. * * in Array of bytes representing the number to exponentiate, base. @@ -8700,7 +8774,6 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, sp_digit* dp; sp_digit* dq; sp_digit* qi; - sp_digit* tmp; sp_digit* tmpa; sp_digit* tmpb; sp_digit* r; @@ -8730,8 +8803,7 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, tmpa = qi + 48; tmpb = tmpa + 96; - tmp = t; - r = tmp + 96; + r = t + 96; } #else r = a = ad; @@ -8740,7 +8812,6 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, qi = dq = dp = dpd; tmpa = tmpad; tmpb = tmpbd; - tmp = a + 96; #endif if (err == MP_OKAY) { @@ -8758,8 +8829,8 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, if (err == MP_OKAY) { c = sp_3072_sub_in_place_48(tmpa, tmpb); - sp_3072_mask_48(tmp, p, c); - sp_3072_add_48(tmpa, tmpa, tmp); + c += sp_3072_cond_add_48(tmpa, tmpa, p, c); + sp_3072_cond_add_48(tmpa, tmpa, p, c); sp_3072_from_mp(qi, 48, qim); sp_3072_mul_48(tmpa, tmpa, qi); @@ -8790,6 +8861,7 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, return err; } +#endif /* WOLFSSL_RSA_PUBLIC_ONLY */ #endif /* WOLFSSL_HAVE_SP_RSA */ #if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \ !defined(WOLFSSL_RSA_PUBLIC_ONLY)) @@ -12166,6 +12238,45 @@ int sp_RsaPublic_4096(const byte* in, word32 inLen, mp_int* em, mp_int* mm, return err; } +#ifndef WOLFSSL_RSA_PUBLIC_ONLY +/* 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_4096_cond_add_64(sp_digit* r, const sp_digit* a, const sp_digit* b, + sp_digit m) +{ + sp_digit c = 0; + + __asm__ __volatile__ ( + "mov r5, #1\n\t" + "lsl r5, r5, #8\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" + "blt 1b\n\t" + : [c] "+r" (c) + : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) + : "memory", "r5", "r6", "r8", "r9" + ); + + return c; +} + /* RSA private key operation. * * in Array of bytes representing the number to exponentiate, base. @@ -12200,7 +12311,6 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, sp_digit* dp; sp_digit* dq; sp_digit* qi; - sp_digit* tmp; sp_digit* tmpa; sp_digit* tmpb; sp_digit* r; @@ -12230,8 +12340,7 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, tmpa = qi + 64; tmpb = tmpa + 128; - tmp = t; - r = tmp + 128; + r = t + 128; } #else r = a = ad; @@ -12240,7 +12349,6 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, qi = dq = dp = dpd; tmpa = tmpad; tmpb = tmpbd; - tmp = a + 128; #endif if (err == MP_OKAY) { @@ -12258,8 +12366,8 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, if (err == MP_OKAY) { c = sp_4096_sub_in_place_64(tmpa, tmpb); - sp_4096_mask_64(tmp, p, c); - sp_4096_add_64(tmpa, tmpa, tmp); + c += sp_4096_cond_add_64(tmpa, tmpa, p, c); + sp_4096_cond_add_64(tmpa, tmpa, p, c); sp_4096_from_mp(qi, 64, qim); sp_4096_mul_64(tmpa, tmpa, qi); @@ -12290,6 +12398,7 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, return err; } +#endif /* WOLFSSL_RSA_PUBLIC_ONLY */ #endif /* WOLFSSL_HAVE_SP_RSA */ #if defined(WOLFSSL_HAVE_SP_DH) || (defined(WOLFSSL_HAVE_SP_RSA) && \ !defined(WOLFSSL_RSA_PUBLIC_ONLY)) @@ -21053,26 +21162,24 @@ SP_NOINLINE static sp_digit sp_384_cond_add_12(sp_digit* r, const sp_digit* a, c sp_digit c = 0; __asm__ __volatile__ ( - "mov r10, #0\n\t" - "mov r6, #48\n\t" - "sub r10, #1\n\t" - "mov r9, r6\n\t" + "mov r5, #48\n\t" + "mov r9, r5\n\t" "mov r8, #0\n\t" "\n1:\n\t" - "ldr r5, [%[a], r8]\n\t" "ldr r6, [%[b], r8]\n\t" "and r6, r6, %[m]\n\t" - "adds %[c], %[c], r10\n\t" + "adds r5, %[c], #-1\n\t" + "ldr r5, [%[a], r8]\n\t" "adcs r5, r5, r6\n\t" - "str r5, [%[r], r8]\n\t" "mov %[c], #0\n\t" - "adc %[c], %[c], %[c]\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" "blt 1b\n\t" : [c] "+r" (c) : [r] "r" (r), [a] "r" (a), [b] "r" (b), [m] "r" (m) - : "memory", "r5", "r6", "r8", "r9", "r10" + : "memory", "r5", "r6", "r8", "r9" ); return c; diff --git a/wolfcrypt/src/sp_x86_64.c b/wolfcrypt/src/sp_x86_64.c index f9fb6d179..75dcfd78d 100644 --- a/wolfcrypt/src/sp_x86_64.c +++ b/wolfcrypt/src/sp_x86_64.c @@ -1573,13 +1573,13 @@ int sp_RsaPrivate_2048(const byte* in, word32 inLen, mp_int* dm, #ifdef HAVE_INTEL_AVX2 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) { c += sp_2048_cond_add_avx2_16(tmpa, tmpa, p, c); - c += sp_2048_cond_add_avx2_16(tmpa, tmpa, p, c); + sp_2048_cond_add_avx2_16(tmpa, tmpa, p, c); } else #endif { c += sp_2048_cond_add_16(tmpa, tmpa, p, c); - c += sp_2048_cond_add_16(tmpa, tmpa, p, c); + sp_2048_cond_add_16(tmpa, tmpa, p, c); } sp_2048_from_mp(qi, 16, qim); @@ -3627,13 +3627,13 @@ int sp_RsaPrivate_3072(const byte* in, word32 inLen, mp_int* dm, #ifdef HAVE_INTEL_AVX2 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) { c += sp_3072_cond_add_avx2_24(tmpa, tmpa, p, c); - c += sp_3072_cond_add_avx2_24(tmpa, tmpa, p, c); + sp_3072_cond_add_avx2_24(tmpa, tmpa, p, c); } else #endif { c += sp_3072_cond_add_24(tmpa, tmpa, p, c); - c += sp_3072_cond_add_24(tmpa, tmpa, p, c); + sp_3072_cond_add_24(tmpa, tmpa, p, c); } sp_3072_from_mp(qi, 24, qim); @@ -5135,13 +5135,13 @@ int sp_RsaPrivate_4096(const byte* in, word32 inLen, mp_int* dm, #ifdef HAVE_INTEL_AVX2 if (IS_INTEL_BMI2(cpuid_flags) && IS_INTEL_ADX(cpuid_flags)) { c += sp_4096_cond_add_avx2_32(tmpa, tmpa, p, c); - c += sp_4096_cond_add_avx2_32(tmpa, tmpa, p, c); + sp_4096_cond_add_avx2_32(tmpa, tmpa, p, c); } else #endif { c += sp_4096_cond_add_32(tmpa, tmpa, p, c); - c += sp_4096_cond_add_32(tmpa, tmpa, p, c); + sp_4096_cond_add_32(tmpa, tmpa, p, c); } sp_2048_from_mp(qi, 32, qim); From 452b4c03a60ba85ca3cc68b559ed10428983dad7 Mon Sep 17 00:00:00 2001 From: Tesfa Mael Date: Thu, 12 Mar 2020 23:24:44 -0700 Subject: [PATCH 191/649] Fix memory leak --- src/ssl.c | 7 +++++-- tests/api.c | 1 - 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 2352a7b6d..b39ccdd24 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -18298,7 +18298,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; if (key) { - ret = wc_AesXtsSetKey(&ctx->cipher.xts, key, ctx->keyLen, + ret = wc_AesXtsSetKey(&ctx->cipher.xts, key, ctx->keyLen, ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION, NULL, 0); if (ret != 0) { WOLFSSL_MSG("wc_AesXtsSetKey() failed"); @@ -18328,7 +18328,7 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md) if (enc == 0 || enc == 1) ctx->enc = enc ? 1 : 0; if (key) { - ret = wc_AesXtsSetKey(&ctx->cipher.xts, key, ctx->keyLen, + ret = wc_AesXtsSetKey(&ctx->cipher.xts, key, ctx->keyLen, ctx->enc ? AES_ENCRYPTION : AES_DECRYPTION, NULL, 0); if (ret != 0) { WOLFSSL_MSG("wc_AesXtsSetKey() failed"); @@ -36137,6 +36137,7 @@ int wolfSSL_EC_POINT_get_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group, BN_copy(x, point->X); BN_copy(y, point->Y); + mp_clear(&modulus); return WOLFSSL_SUCCESS; } @@ -48640,8 +48641,10 @@ int wolfSSL_BN_clear_bit(WOLFSSL_BIGNUM* bn, int n) goto cleanup; } } + ret = WOLFSSL_SUCCESS; cleanup: + mp_clear(tmp); #ifdef WOLFSSL_SMALL_STACK if (tmp) XFREE(tmp, NULL, DYNAMIC_TYPE_BIGINT); diff --git a/tests/api.c b/tests/api.c index 58a5e4f7f..a6d862174 100644 --- a/tests/api.c +++ b/tests/api.c @@ -1839,7 +1839,6 @@ static void test_wolfSSL_EC(void) /* Force non-affine coordinates */ AssertIntEQ(wolfSSL_BN_add(new_point->Z, (WOLFSSL_BIGNUM*)BN_value_one(), (WOLFSSL_BIGNUM*)BN_value_one()), 1); - new_point->inSet = 0; /* extract the coordinates from point */ AssertIntEQ(EC_POINT_get_affine_coordinates_GFp(group, new_point, X, Y, ctx), WOLFSSL_SUCCESS); From a6b01904d2ed10c45ce7263516bb43db31cf74e7 Mon Sep 17 00:00:00 2001 From: Tesfa Mael Date: Fri, 13 Mar 2020 14:22:06 -0700 Subject: [PATCH 192/649] Release mem during failure --- src/ssl.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ssl.c b/src/ssl.c index b39ccdd24..fad32158b 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -36119,18 +36119,22 @@ int wolfSSL_EC_POINT_get_affine_coordinates_GFp(const WOLFSSL_EC_GROUP *group, /* Map the Jacobian point back to affine space */ if (mp_read_radix(&modulus, ecc_sets[group->curve_idx].prime, MP_RADIX_HEX) != MP_OKAY) { WOLFSSL_MSG("mp_read_radix failed"); + mp_clear(&modulus); return WOLFSSL_FAILURE; } if (mp_montgomery_setup(&modulus, &mp) != MP_OKAY) { WOLFSSL_MSG("mp_montgomery_setup failed"); + mp_clear(&modulus); return WOLFSSL_FAILURE; } if (ecc_map((ecc_point*)point->internal, &modulus, mp) != MP_OKAY) { WOLFSSL_MSG("ecc_map failed"); + mp_clear(&modulus); return WOLFSSL_FAILURE; } if (SetECPointExternal((WOLFSSL_EC_POINT *)point) != WOLFSSL_SUCCESS) { WOLFSSL_MSG("SetECPointExternal failed"); + mp_clear(&modulus); return WOLFSSL_FAILURE; } } From 6498cb48bc007353606e8e1b9b44e5d7b7991d9d Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 13 Mar 2020 14:54:57 -0700 Subject: [PATCH 193/649] CSharp wrapper improvements. Added TLS client example. Added TLS v1.3 methods. Added `set_verify` and `CTX_set_verify`. Added example code for `CTX_set_cipher_list`. --- .../Properties/AssemblyInfo.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 +- wrapper/CSharp/wolfSSL-TLS-Client/App.config | 6 + .../Properties/AssemblyInfo.cs | 36 ++++ .../Properties/Settings.Designer.cs | 26 +++ .../Properties/Settings.settings | 6 + .../wolfSSL-TLS-Client/wolfSSL-TLS-Client.cs | 192 ++++++++++++++++++ .../wolfSSL-TLS-Client.csproj | 132 ++++++++++++ .../Properties/AssemblyInfo.cs | 2 +- .../Properties/AssemblyInfo.cs | 2 +- wrapper/CSharp/wolfSSL_CSharp.sln | 157 ++++++++++++++ .../wolfSSL_CSharp/Properties/AssemblyInfo.cs | 2 +- wrapper/CSharp/wolfSSL_CSharp/wolfSSL.cs | 108 ++++++++++ .../wolfSSL_CSharp/wolfSSL_CSharp.csproj | 3 +- 15 files changed, 671 insertions(+), 7 deletions(-) create mode 100644 wrapper/CSharp/wolfSSL-TLS-Client/App.config create mode 100644 wrapper/CSharp/wolfSSL-TLS-Client/Properties/AssemblyInfo.cs create mode 100644 wrapper/CSharp/wolfSSL-TLS-Client/Properties/Settings.Designer.cs create mode 100755 wrapper/CSharp/wolfSSL-TLS-Client/Properties/Settings.settings create mode 100755 wrapper/CSharp/wolfSSL-TLS-Client/wolfSSL-TLS-Client.cs create mode 100755 wrapper/CSharp/wolfSSL-TLS-Client/wolfSSL-TLS-Client.csproj diff --git a/wrapper/CSharp/wolfSSL-DTLS-PSK-Server/Properties/AssemblyInfo.cs b/wrapper/CSharp/wolfSSL-DTLS-PSK-Server/Properties/AssemblyInfo.cs index 7e22f5faf..2ee49afdb 100644 --- a/wrapper/CSharp/wolfSSL-DTLS-PSK-Server/Properties/AssemblyInfo.cs +++ b/wrapper/CSharp/wolfSSL-DTLS-PSK-Server/Properties/AssemblyInfo.cs @@ -10,7 +10,7 @@ using System.Runtime.InteropServices; [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("wolfSSL")] [assembly: AssemblyProduct("wolfSSL-DTLS-PSK-Server")] -[assembly: AssemblyCopyright("Copyright wolfSSL 2015")] +[assembly: AssemblyCopyright("Copyright wolfSSL 2020")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] diff --git a/wrapper/CSharp/wolfSSL-DTLS-Server/Properties/AssemblyInfo.cs b/wrapper/CSharp/wolfSSL-DTLS-Server/Properties/AssemblyInfo.cs index f047e5351..56a4dcf9e 100644 --- a/wrapper/CSharp/wolfSSL-DTLS-Server/Properties/AssemblyInfo.cs +++ b/wrapper/CSharp/wolfSSL-DTLS-Server/Properties/AssemblyInfo.cs @@ -10,7 +10,7 @@ using System.Runtime.InteropServices; [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("wolfSSL")] [assembly: AssemblyProduct("wolfSSL-DTLS-Server")] -[assembly: AssemblyCopyright("Copyright wolfSSL 2015")] +[assembly: AssemblyCopyright("Copyright wolfSSL 2020")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] diff --git a/wrapper/CSharp/wolfSSL-Example-IOCallbacks/Properties/AssemblyInfo.cs b/wrapper/CSharp/wolfSSL-Example-IOCallbacks/Properties/AssemblyInfo.cs index a19cd0ad7..066aa71c2 100644 --- a/wrapper/CSharp/wolfSSL-Example-IOCallbacks/Properties/AssemblyInfo.cs +++ b/wrapper/CSharp/wolfSSL-Example-IOCallbacks/Properties/AssemblyInfo.cs @@ -10,7 +10,7 @@ using System.Runtime.InteropServices; [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("wolfSSL")] [assembly: AssemblyProduct("wolfSSL-Example-IOCallbacks")] -[assembly: AssemblyCopyright("Copyright wolfSSL 2015")] +[assembly: AssemblyCopyright("Copyright wolfSSL 2020")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] diff --git a/wrapper/CSharp/wolfSSL-TLS-Client/App.config b/wrapper/CSharp/wolfSSL-TLS-Client/App.config new file mode 100644 index 000000000..b540b1fdf --- /dev/null +++ b/wrapper/CSharp/wolfSSL-TLS-Client/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/wrapper/CSharp/wolfSSL-TLS-Client/Properties/AssemblyInfo.cs b/wrapper/CSharp/wolfSSL-TLS-Client/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..a1063125b --- /dev/null +++ b/wrapper/CSharp/wolfSSL-TLS-Client/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("wolfSSL-TLS-Client")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("wolfSSL")] +[assembly: AssemblyProduct("wolfSSL-TLS-Client")] +[assembly: AssemblyCopyright("Copyright wolfSSL 2020")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("05aad2b4-445e-4f0e-8e16-8f8512696505")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.1.0.0")] +[assembly: AssemblyFileVersion("1.1.0.0")] diff --git a/wrapper/CSharp/wolfSSL-TLS-Client/Properties/Settings.Designer.cs b/wrapper/CSharp/wolfSSL-TLS-Client/Properties/Settings.Designer.cs new file mode 100644 index 000000000..524c01375 --- /dev/null +++ b/wrapper/CSharp/wolfSSL-TLS-Client/Properties/Settings.Designer.cs @@ -0,0 +1,26 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.17929 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace wolfSSL_TLS_CSharp.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + } +} diff --git a/wrapper/CSharp/wolfSSL-TLS-Client/Properties/Settings.settings b/wrapper/CSharp/wolfSSL-TLS-Client/Properties/Settings.settings new file mode 100755 index 000000000..049245f40 --- /dev/null +++ b/wrapper/CSharp/wolfSSL-TLS-Client/Properties/Settings.settings @@ -0,0 +1,6 @@ + + + + + + diff --git a/wrapper/CSharp/wolfSSL-TLS-Client/wolfSSL-TLS-Client.cs b/wrapper/CSharp/wolfSSL-TLS-Client/wolfSSL-TLS-Client.cs new file mode 100755 index 000000000..ca4b5f803 --- /dev/null +++ b/wrapper/CSharp/wolfSSL-TLS-Client/wolfSSL-TLS-Client.cs @@ -0,0 +1,192 @@ +/* wolfSSL-TLS-Client.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 + */ + + +using System; +using System.Runtime.InteropServices; +using System.Text; +using System.IO; +using System.Net; +using System.Net.Sockets; +using wolfSSL.CSharp; + +public class wolfSSL_TLS_CSHarp +{ + /// + /// Example of a logging function + /// + /// level of log + /// message to log + public static void standard_log(int lvl, StringBuilder msg) + { + Console.WriteLine(msg); + } + + + private static void clean(IntPtr ssl, IntPtr ctx) + { + wolfssl.free(ssl); + wolfssl.CTX_free(ctx); + wolfssl.Cleanup(); + } + + /// + /// Verification callback + /// + /// 1=Verify Okay, 0=Failure + /// Certificate in WOLFSSL_X509_STORE_CTX format + private static int myVerify(int preverify, IntPtr x509_ctx) + { + /* Use the provided verification */ + /* Can optionally override failures by returning non-zero value */ + return preverify; + } + + public static void Main(string[] args) + { + IntPtr ctx; + IntPtr ssl; + Socket tcp; + + /* These paths should be changed for use */ + string caCert = @"ca-cert.pem"; + StringBuilder dhparam = new StringBuilder("dh2048.pem"); + + StringBuilder buff = new StringBuilder(1024); + StringBuilder reply = new StringBuilder("Hello, this is the wolfSSL C# wrapper"); + + //example of function used for setting logging + wolfssl.SetLogging(standard_log); + + wolfssl.Init(); + + + Console.WriteLine("Calling ctx Init from wolfSSL"); + ctx = wolfssl.CTX_new(wolfssl.usev23_client()); + if (ctx == IntPtr.Zero) + { + Console.WriteLine("Error in creating ctx structure"); + return; + } + Console.WriteLine("Finished init of ctx .... now load in CA"); + + + if (!File.Exists(caCert)) + { + Console.WriteLine("Could not find CA cert file"); + wolfssl.CTX_free(ctx); + return; + } + + + if (wolfssl.CTX_load_verify_locations(ctx, caCert, null) + != wolfssl.SUCCESS) + { + Console.WriteLine("Error loading CA cert"); + } + + StringBuilder ciphers = new StringBuilder(new String(' ', 4096)); + wolfssl.get_ciphers(ciphers, 4096); + Console.WriteLine("Ciphers : " + ciphers.ToString()); + + //ciphers = new StringBuilder("ECDHE-ECDSA-AES128-GCM-SHA256"); + //if (wolfssl.CTX_set_cipher_list(ctx, ciphers) != wolfssl.SUCCESS) + //{ + // Console.WriteLine("ERROR CTX_set_cipher_list()"); + // wolfssl.CTX_free(ctx); + // return; + //} + + short minDhKey = 128; + wolfssl.CTX_SetMinDhKey_Sz(ctx, minDhKey); + + /* Setup Verify Callback */ + if (wolfssl.CTX_set_verify(ctx, wolfssl.SSL_VERIFY_PEER, myVerify) + != wolfssl.SUCCESS) + { + Console.WriteLine("Error setting verify callback!"); + } + + + /* set up TCP socket */ + tcp = new Socket(AddressFamily.InterNetwork, SocketType.Stream, + ProtocolType.Tcp); + tcp.Connect("127.0.0.1", 11111); + Console.WriteLine("Connection established"); + + Console.WriteLine("Connected TCP"); + ssl = wolfssl.new_ssl(ctx); + if (ssl == IntPtr.Zero) + { + Console.WriteLine("Error in creating ssl object"); + wolfssl.CTX_free(ctx); + return; + } + + Console.WriteLine("Connection made wolfSSL_connect "); + if (wolfssl.set_fd(ssl, tcp) != wolfssl.SUCCESS) + { + /* get and print out the error */ + Console.Write(wolfssl.get_error(ssl)); + tcp.Close(); + clean(ssl, ctx); + return; + } + + wolfssl.SetTmpDH_file(ssl, dhparam, wolfssl.SSL_FILETYPE_PEM); + + if (wolfssl.connect(ssl) != wolfssl.SUCCESS) + { + /* get and print out the error */ + Console.Write(wolfssl.get_error(ssl)); + tcp.Close(); + clean(ssl, ctx); + return; + } + + /* print out results of TLS/SSL accept */ + Console.WriteLine("SSL version is " + wolfssl.get_version(ssl)); + Console.WriteLine("SSL cipher suite is " + wolfssl.get_current_cipher(ssl)); + + + if (wolfssl.write(ssl, reply, reply.Length) != reply.Length) + { + Console.WriteLine("Error in write"); + tcp.Close(); + clean(ssl, ctx); + return; + } + + /* read and print out the message then reply */ + if (wolfssl.read(ssl, buff, 1023) < 0) + { + Console.WriteLine("Error in read"); + tcp.Close(); + clean(ssl, ctx); + return; + } + Console.WriteLine(buff); + + wolfssl.shutdown(ssl); + tcp.Close(); + clean(ssl, ctx); + } +} diff --git a/wrapper/CSharp/wolfSSL-TLS-Client/wolfSSL-TLS-Client.csproj b/wrapper/CSharp/wolfSSL-TLS-Client/wolfSSL-TLS-Client.csproj new file mode 100755 index 000000000..19544e8a6 --- /dev/null +++ b/wrapper/CSharp/wolfSSL-TLS-Client/wolfSSL-TLS-Client.csproj @@ -0,0 +1,132 @@ + + + + + Debug + AnyCPU + {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8} + Exe + Properties + wolfSSL_TLS_CSharp + wolfSSL-TLS-Client + v4.5 + 512 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + AnyCPU + true + full + false + ..\DLL Debug\ + DEBUG;TRACE + prompt + 3 + + + AnyCPU + pdbonly + true + ..\DLL Release\ + TRACE + prompt + 4 + + + + + + true + ..\x64\DLL Debug\ + DEBUG;TRACE + 4 + full + x64 + prompt + MinimumRecommendedRules.ruleset + true + + + ..\x64\DLL Release\ + TRACE + true + pdbonly + x64 + prompt + MinimumRecommendedRules.ruleset + true + + + + + + + + + + + + + True + True + Settings.settings + + + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + {52609808-0418-46d3-8e17-141927a1a39a} + wolfSSL_CSharp + + + + + False + Microsoft .NET Framework 4.5 %28x86 and x64%29 + true + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + false + + + + + + + + + \ No newline at end of file diff --git a/wrapper/CSharp/wolfSSL-TLS-PSK-Server/Properties/AssemblyInfo.cs b/wrapper/CSharp/wolfSSL-TLS-PSK-Server/Properties/AssemblyInfo.cs index 35acba0e3..5704ac236 100644 --- a/wrapper/CSharp/wolfSSL-TLS-PSK-Server/Properties/AssemblyInfo.cs +++ b/wrapper/CSharp/wolfSSL-TLS-PSK-Server/Properties/AssemblyInfo.cs @@ -10,7 +10,7 @@ using System.Runtime.InteropServices; [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("wolfSSL")] [assembly: AssemblyProduct("wolfSSL-TLS-PSK-Server")] -[assembly: AssemblyCopyright("Copyright wolfSSL 2015")] +[assembly: AssemblyCopyright("Copyright wolfSSL 2020")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] diff --git a/wrapper/CSharp/wolfSSL-TLS-Server/Properties/AssemblyInfo.cs b/wrapper/CSharp/wolfSSL-TLS-Server/Properties/AssemblyInfo.cs index cab955e7d..ef8b02522 100644 --- a/wrapper/CSharp/wolfSSL-TLS-Server/Properties/AssemblyInfo.cs +++ b/wrapper/CSharp/wolfSSL-TLS-Server/Properties/AssemblyInfo.cs @@ -10,7 +10,7 @@ using System.Runtime.InteropServices; [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("wolfSSL")] [assembly: AssemblyProduct("wolfSSL-TLS-Server")] -[assembly: AssemblyCopyright("Copyright wolfSSL 2015")] +[assembly: AssemblyCopyright("Copyright wolfSSL 2020")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] diff --git a/wrapper/CSharp/wolfSSL_CSharp.sln b/wrapper/CSharp/wolfSSL_CSharp.sln index f7c63d7c1..12e1a828a 100755 --- a/wrapper/CSharp/wolfSSL_CSharp.sln +++ b/wrapper/CSharp/wolfSSL_CSharp.sln @@ -25,78 +25,232 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testsuite", "..\..\testsuit EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wolfSSL-Example-IOCallbacks", "wolfSSL-Example-IOCallbacks\wolfSSL-Example-IOCallbacks.csproj", "{E2415718-0A15-48DB-A774-01FB0093B626}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wolfSSL-TLS-Client", "wolfSSL-TLS-Client\wolfSSL-TLS-Client.csproj", "{B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + DLL Debug|Any CPU = DLL Debug|Any CPU DLL Debug|Win32 = DLL Debug|Win32 DLL Debug|x64 = DLL Debug|x64 + DLL Release|Any CPU = DLL Release|Any CPU DLL Release|Win32 = DLL Release|Win32 DLL Release|x64 = DLL Release|x64 + Release|Any CPU = Release|Any CPU + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution + {52609808-0418-46D3-8E17-141927A1A39A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {52609808-0418-46D3-8E17-141927A1A39A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {52609808-0418-46D3-8E17-141927A1A39A}.Debug|Win32.ActiveCfg = Debug|Any CPU + {52609808-0418-46D3-8E17-141927A1A39A}.Debug|Win32.Build.0 = Debug|Any CPU + {52609808-0418-46D3-8E17-141927A1A39A}.Debug|x64.ActiveCfg = Debug|x64 + {52609808-0418-46D3-8E17-141927A1A39A}.Debug|x64.Build.0 = Debug|x64 + {52609808-0418-46D3-8E17-141927A1A39A}.DLL Debug|Any CPU.ActiveCfg = Debug|Any CPU + {52609808-0418-46D3-8E17-141927A1A39A}.DLL Debug|Any CPU.Build.0 = Debug|Any CPU {52609808-0418-46D3-8E17-141927A1A39A}.DLL Debug|Win32.ActiveCfg = Debug|Any CPU {52609808-0418-46D3-8E17-141927A1A39A}.DLL Debug|Win32.Build.0 = Debug|Any CPU {52609808-0418-46D3-8E17-141927A1A39A}.DLL Debug|x64.ActiveCfg = Debug|x64 {52609808-0418-46D3-8E17-141927A1A39A}.DLL Debug|x64.Build.0 = Debug|x64 + {52609808-0418-46D3-8E17-141927A1A39A}.DLL Release|Any CPU.ActiveCfg = Release|Any CPU + {52609808-0418-46D3-8E17-141927A1A39A}.DLL Release|Any CPU.Build.0 = Release|Any CPU {52609808-0418-46D3-8E17-141927A1A39A}.DLL Release|Win32.ActiveCfg = Release|Any CPU {52609808-0418-46D3-8E17-141927A1A39A}.DLL Release|Win32.Build.0 = Release|Any CPU {52609808-0418-46D3-8E17-141927A1A39A}.DLL Release|x64.ActiveCfg = Release|x64 {52609808-0418-46D3-8E17-141927A1A39A}.DLL Release|x64.Build.0 = Release|x64 + {52609808-0418-46D3-8E17-141927A1A39A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {52609808-0418-46D3-8E17-141927A1A39A}.Release|Any CPU.Build.0 = Release|Any CPU + {52609808-0418-46D3-8E17-141927A1A39A}.Release|Win32.ActiveCfg = Release|Any CPU + {52609808-0418-46D3-8E17-141927A1A39A}.Release|Win32.Build.0 = Release|Any CPU + {52609808-0418-46D3-8E17-141927A1A39A}.Release|x64.ActiveCfg = Release|x64 + {52609808-0418-46D3-8E17-141927A1A39A}.Release|x64.Build.0 = Release|x64 + {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.Debug|Win32.ActiveCfg = Debug|Any CPU + {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.Debug|Win32.Build.0 = Debug|Any CPU + {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.Debug|x64.ActiveCfg = Debug|x64 + {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.Debug|x64.Build.0 = Debug|x64 + {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.DLL Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.DLL Debug|Any CPU.Build.0 = Debug|Any CPU {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.DLL Debug|Win32.ActiveCfg = Debug|Any CPU {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.DLL Debug|Win32.Build.0 = Debug|Any CPU {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.DLL Debug|x64.ActiveCfg = Debug|x64 {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.DLL Debug|x64.Build.0 = Debug|x64 + {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.DLL Release|Any CPU.ActiveCfg = Release|Any CPU + {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.DLL Release|Any CPU.Build.0 = Release|Any CPU {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.DLL Release|Win32.ActiveCfg = Release|Any CPU {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.DLL Release|Win32.Build.0 = Release|Any CPU {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.DLL Release|x64.ActiveCfg = Release|x64 {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.DLL Release|x64.Build.0 = Release|x64 + {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.Release|Any CPU.Build.0 = Release|Any CPU + {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.Release|Win32.ActiveCfg = Release|Any CPU + {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.Release|Win32.Build.0 = Release|Any CPU + {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.Release|x64.ActiveCfg = Release|x64 + {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.Release|x64.Build.0 = Release|x64 + {030431C7-26AB-4447-815B-F27E88BE5D5B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {030431C7-26AB-4447-815B-F27E88BE5D5B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {030431C7-26AB-4447-815B-F27E88BE5D5B}.Debug|Win32.ActiveCfg = Debug|Any CPU + {030431C7-26AB-4447-815B-F27E88BE5D5B}.Debug|Win32.Build.0 = Debug|Any CPU + {030431C7-26AB-4447-815B-F27E88BE5D5B}.Debug|x64.ActiveCfg = Debug|x64 + {030431C7-26AB-4447-815B-F27E88BE5D5B}.Debug|x64.Build.0 = Debug|x64 + {030431C7-26AB-4447-815B-F27E88BE5D5B}.DLL Debug|Any CPU.ActiveCfg = Debug|Any CPU + {030431C7-26AB-4447-815B-F27E88BE5D5B}.DLL Debug|Any CPU.Build.0 = Debug|Any CPU {030431C7-26AB-4447-815B-F27E88BE5D5B}.DLL Debug|Win32.ActiveCfg = Debug|Any CPU {030431C7-26AB-4447-815B-F27E88BE5D5B}.DLL Debug|Win32.Build.0 = Debug|Any CPU {030431C7-26AB-4447-815B-F27E88BE5D5B}.DLL Debug|x64.ActiveCfg = Debug|x64 {030431C7-26AB-4447-815B-F27E88BE5D5B}.DLL Debug|x64.Build.0 = Debug|x64 + {030431C7-26AB-4447-815B-F27E88BE5D5B}.DLL Release|Any CPU.ActiveCfg = Release|Any CPU + {030431C7-26AB-4447-815B-F27E88BE5D5B}.DLL Release|Any CPU.Build.0 = Release|Any CPU {030431C7-26AB-4447-815B-F27E88BE5D5B}.DLL Release|Win32.ActiveCfg = Release|Any CPU {030431C7-26AB-4447-815B-F27E88BE5D5B}.DLL Release|Win32.Build.0 = Release|Any CPU {030431C7-26AB-4447-815B-F27E88BE5D5B}.DLL Release|x64.ActiveCfg = Release|x64 {030431C7-26AB-4447-815B-F27E88BE5D5B}.DLL Release|x64.Build.0 = Release|x64 + {030431C7-26AB-4447-815B-F27E88BE5D5B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {030431C7-26AB-4447-815B-F27E88BE5D5B}.Release|Any CPU.Build.0 = Release|Any CPU + {030431C7-26AB-4447-815B-F27E88BE5D5B}.Release|Win32.ActiveCfg = Release|Any CPU + {030431C7-26AB-4447-815B-F27E88BE5D5B}.Release|Win32.Build.0 = Release|Any CPU + {030431C7-26AB-4447-815B-F27E88BE5D5B}.Release|x64.ActiveCfg = Release|x64 + {030431C7-26AB-4447-815B-F27E88BE5D5B}.Release|x64.Build.0 = Release|x64 + {730F047E-37A6-498F-A543-B6C98AA7B338}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {730F047E-37A6-498F-A543-B6C98AA7B338}.Debug|Any CPU.Build.0 = Debug|Any CPU + {730F047E-37A6-498F-A543-B6C98AA7B338}.Debug|Win32.ActiveCfg = Debug|Any CPU + {730F047E-37A6-498F-A543-B6C98AA7B338}.Debug|Win32.Build.0 = Debug|Any CPU + {730F047E-37A6-498F-A543-B6C98AA7B338}.Debug|x64.ActiveCfg = Debug|x64 + {730F047E-37A6-498F-A543-B6C98AA7B338}.Debug|x64.Build.0 = Debug|x64 + {730F047E-37A6-498F-A543-B6C98AA7B338}.DLL Debug|Any CPU.ActiveCfg = Debug|Any CPU + {730F047E-37A6-498F-A543-B6C98AA7B338}.DLL Debug|Any CPU.Build.0 = Debug|Any CPU {730F047E-37A6-498F-A543-B6C98AA7B338}.DLL Debug|Win32.ActiveCfg = Debug|Any CPU {730F047E-37A6-498F-A543-B6C98AA7B338}.DLL Debug|Win32.Build.0 = Debug|Any CPU {730F047E-37A6-498F-A543-B6C98AA7B338}.DLL Debug|x64.ActiveCfg = Debug|x64 {730F047E-37A6-498F-A543-B6C98AA7B338}.DLL Debug|x64.Build.0 = Debug|x64 + {730F047E-37A6-498F-A543-B6C98AA7B338}.DLL Release|Any CPU.ActiveCfg = Release|Any CPU + {730F047E-37A6-498F-A543-B6C98AA7B338}.DLL Release|Any CPU.Build.0 = Release|Any CPU {730F047E-37A6-498F-A543-B6C98AA7B338}.DLL Release|Win32.ActiveCfg = Release|Any CPU {730F047E-37A6-498F-A543-B6C98AA7B338}.DLL Release|Win32.Build.0 = Release|Any CPU {730F047E-37A6-498F-A543-B6C98AA7B338}.DLL Release|x64.ActiveCfg = Release|x64 {730F047E-37A6-498F-A543-B6C98AA7B338}.DLL Release|x64.Build.0 = Release|x64 + {730F047E-37A6-498F-A543-B6C98AA7B338}.Release|Any CPU.ActiveCfg = Release|Any CPU + {730F047E-37A6-498F-A543-B6C98AA7B338}.Release|Any CPU.Build.0 = Release|Any CPU + {730F047E-37A6-498F-A543-B6C98AA7B338}.Release|Win32.ActiveCfg = Release|Any CPU + {730F047E-37A6-498F-A543-B6C98AA7B338}.Release|Win32.Build.0 = Release|Any CPU + {730F047E-37A6-498F-A543-B6C98AA7B338}.Release|x64.ActiveCfg = Release|x64 + {730F047E-37A6-498F-A543-B6C98AA7B338}.Release|x64.Build.0 = Release|x64 + {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.Debug|Win32.ActiveCfg = Debug|Any CPU + {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.Debug|Win32.Build.0 = Debug|Any CPU + {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.Debug|x64.ActiveCfg = Debug|x64 + {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.Debug|x64.Build.0 = Debug|x64 + {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.DLL Debug|Any CPU.ActiveCfg = Debug|Any CPU + {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.DLL Debug|Any CPU.Build.0 = Debug|Any CPU {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.DLL Debug|Win32.ActiveCfg = Debug|Any CPU {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.DLL Debug|Win32.Build.0 = Debug|Any CPU {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.DLL Debug|x64.ActiveCfg = Debug|x64 {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.DLL Debug|x64.Build.0 = Debug|x64 + {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.DLL Release|Any CPU.ActiveCfg = Release|Any CPU + {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.DLL Release|Any CPU.Build.0 = Release|Any CPU {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.DLL Release|Win32.ActiveCfg = Release|Any CPU {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.DLL Release|Win32.Build.0 = Release|Any CPU {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.DLL Release|x64.ActiveCfg = Release|x64 {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.DLL Release|x64.Build.0 = Release|x64 + {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.Release|Any CPU.Build.0 = Release|Any CPU + {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.Release|Win32.ActiveCfg = Release|Any CPU + {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.Release|Win32.Build.0 = Release|Any CPU + {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.Release|x64.ActiveCfg = Release|x64 + {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.Release|x64.Build.0 = Release|x64 + {73973223-5EE8-41CA-8E88-1D60E89A237B}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {73973223-5EE8-41CA-8E88-1D60E89A237B}.Debug|Win32.ActiveCfg = Debug|Win32 + {73973223-5EE8-41CA-8E88-1D60E89A237B}.Debug|Win32.Build.0 = Debug|Win32 + {73973223-5EE8-41CA-8E88-1D60E89A237B}.Debug|x64.ActiveCfg = Debug|x64 + {73973223-5EE8-41CA-8E88-1D60E89A237B}.Debug|x64.Build.0 = Debug|x64 + {73973223-5EE8-41CA-8E88-1D60E89A237B}.DLL Debug|Any CPU.ActiveCfg = DLL Debug|Win32 {73973223-5EE8-41CA-8E88-1D60E89A237B}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32 {73973223-5EE8-41CA-8E88-1D60E89A237B}.DLL Debug|Win32.Build.0 = DLL Debug|Win32 {73973223-5EE8-41CA-8E88-1D60E89A237B}.DLL Debug|x64.ActiveCfg = DLL Debug|x64 {73973223-5EE8-41CA-8E88-1D60E89A237B}.DLL Debug|x64.Build.0 = DLL Debug|x64 + {73973223-5EE8-41CA-8E88-1D60E89A237B}.DLL Release|Any CPU.ActiveCfg = DLL Release|Win32 {73973223-5EE8-41CA-8E88-1D60E89A237B}.DLL Release|Win32.ActiveCfg = DLL Release|Win32 {73973223-5EE8-41CA-8E88-1D60E89A237B}.DLL Release|Win32.Build.0 = DLL Release|Win32 {73973223-5EE8-41CA-8E88-1D60E89A237B}.DLL Release|x64.ActiveCfg = DLL Release|x64 {73973223-5EE8-41CA-8E88-1D60E89A237B}.DLL Release|x64.Build.0 = DLL Release|x64 + {73973223-5EE8-41CA-8E88-1D60E89A237B}.Release|Any CPU.ActiveCfg = Release|Win32 + {73973223-5EE8-41CA-8E88-1D60E89A237B}.Release|Win32.ActiveCfg = Release|Win32 + {73973223-5EE8-41CA-8E88-1D60E89A237B}.Release|Win32.Build.0 = Release|Win32 + {73973223-5EE8-41CA-8E88-1D60E89A237B}.Release|x64.ActiveCfg = Release|x64 + {73973223-5EE8-41CA-8E88-1D60E89A237B}.Release|x64.Build.0 = Release|x64 + {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.Debug|Any CPU.ActiveCfg = Debug|Win32 + {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.Debug|Win32.ActiveCfg = Debug|Win32 + {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.Debug|Win32.Build.0 = Debug|Win32 + {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.Debug|x64.ActiveCfg = Debug|x64 + {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.Debug|x64.Build.0 = Debug|x64 + {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.DLL Debug|Any CPU.ActiveCfg = DLL Debug|Win32 {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32 {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.DLL Debug|Win32.Build.0 = DLL Debug|Win32 {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.DLL Debug|x64.ActiveCfg = DLL Debug|x64 {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.DLL Debug|x64.Build.0 = DLL Debug|x64 + {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.DLL Release|Any CPU.ActiveCfg = DLL Release|Win32 {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.DLL Release|Win32.ActiveCfg = DLL Release|Win32 {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.DLL Release|Win32.Build.0 = DLL Release|Win32 {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.DLL Release|x64.ActiveCfg = DLL Release|x64 {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.DLL Release|x64.Build.0 = DLL Release|x64 + {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.Release|Any CPU.ActiveCfg = Release|Win32 + {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.Release|Win32.ActiveCfg = Release|Win32 + {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.Release|Win32.Build.0 = Release|Win32 + {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.Release|x64.ActiveCfg = Release|x64 + {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.Release|x64.Build.0 = Release|x64 + {E2415718-0A15-48DB-A774-01FB0093B626}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E2415718-0A15-48DB-A774-01FB0093B626}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E2415718-0A15-48DB-A774-01FB0093B626}.Debug|Win32.ActiveCfg = Debug|Any CPU + {E2415718-0A15-48DB-A774-01FB0093B626}.Debug|Win32.Build.0 = Debug|Any CPU + {E2415718-0A15-48DB-A774-01FB0093B626}.Debug|x64.ActiveCfg = Debug|x64 + {E2415718-0A15-48DB-A774-01FB0093B626}.Debug|x64.Build.0 = Debug|x64 + {E2415718-0A15-48DB-A774-01FB0093B626}.DLL Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E2415718-0A15-48DB-A774-01FB0093B626}.DLL Debug|Any CPU.Build.0 = Debug|Any CPU {E2415718-0A15-48DB-A774-01FB0093B626}.DLL Debug|Win32.ActiveCfg = Debug|Any CPU {E2415718-0A15-48DB-A774-01FB0093B626}.DLL Debug|Win32.Build.0 = Debug|Any CPU {E2415718-0A15-48DB-A774-01FB0093B626}.DLL Debug|x64.ActiveCfg = Debug|x64 {E2415718-0A15-48DB-A774-01FB0093B626}.DLL Debug|x64.Build.0 = Debug|x64 + {E2415718-0A15-48DB-A774-01FB0093B626}.DLL Release|Any CPU.ActiveCfg = Release|Any CPU + {E2415718-0A15-48DB-A774-01FB0093B626}.DLL Release|Any CPU.Build.0 = Release|Any CPU {E2415718-0A15-48DB-A774-01FB0093B626}.DLL Release|Win32.ActiveCfg = Release|Any CPU {E2415718-0A15-48DB-A774-01FB0093B626}.DLL Release|Win32.Build.0 = Release|Any CPU {E2415718-0A15-48DB-A774-01FB0093B626}.DLL Release|x64.ActiveCfg = Release|x64 {E2415718-0A15-48DB-A774-01FB0093B626}.DLL Release|x64.Build.0 = Release|x64 + {E2415718-0A15-48DB-A774-01FB0093B626}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E2415718-0A15-48DB-A774-01FB0093B626}.Release|Any CPU.Build.0 = Release|Any CPU + {E2415718-0A15-48DB-A774-01FB0093B626}.Release|Win32.ActiveCfg = Release|Any CPU + {E2415718-0A15-48DB-A774-01FB0093B626}.Release|Win32.Build.0 = Release|Any CPU + {E2415718-0A15-48DB-A774-01FB0093B626}.Release|x64.ActiveCfg = Release|x64 + {E2415718-0A15-48DB-A774-01FB0093B626}.Release|x64.Build.0 = Release|x64 + {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.Debug|Win32.ActiveCfg = Debug|Any CPU + {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.Debug|Win32.Build.0 = Debug|Any CPU + {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.Debug|x64.ActiveCfg = Debug|x64 + {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.Debug|x64.Build.0 = Debug|x64 + {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.DLL Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.DLL Debug|Any CPU.Build.0 = Debug|Any CPU + {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.DLL Debug|Win32.ActiveCfg = Debug|Any CPU + {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.DLL Debug|Win32.Build.0 = Debug|Any CPU + {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.DLL Debug|x64.ActiveCfg = Debug|x64 + {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.DLL Debug|x64.Build.0 = Debug|x64 + {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.DLL Release|Any CPU.ActiveCfg = Release|Any CPU + {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.DLL Release|Any CPU.Build.0 = Release|Any CPU + {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.DLL Release|Win32.ActiveCfg = Release|Any CPU + {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.DLL Release|Win32.Build.0 = Release|Any CPU + {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.DLL Release|x64.ActiveCfg = Release|x64 + {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.DLL Release|x64.Build.0 = Release|x64 + {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.Release|Any CPU.Build.0 = Release|Any CPU + {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.Release|Win32.ActiveCfg = Release|Any CPU + {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.Release|Win32.Build.0 = Release|Any CPU + {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.Release|x64.ActiveCfg = Release|x64 + {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -105,4 +259,7 @@ Global {73973223-5EE8-41CA-8E88-1D60E89A237B} = {252D09D0-D007-4AEB-9F7A-A74408039A8A} {611E8971-46E0-4D0A-B5A1-632C3B00CB80} = {252D09D0-D007-4AEB-9F7A-A74408039A8A} EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {63D316F8-C4EE-449A-B9A6-FC673C4D5D31} + EndGlobalSection EndGlobal diff --git a/wrapper/CSharp/wolfSSL_CSharp/Properties/AssemblyInfo.cs b/wrapper/CSharp/wolfSSL_CSharp/Properties/AssemblyInfo.cs index b4df96b9d..d34afd6b9 100644 --- a/wrapper/CSharp/wolfSSL_CSharp/Properties/AssemblyInfo.cs +++ b/wrapper/CSharp/wolfSSL_CSharp/Properties/AssemblyInfo.cs @@ -10,7 +10,7 @@ using System.Runtime.InteropServices; [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("wolfSSL")] [assembly: AssemblyProduct("wolfSSL.CSharp")] -[assembly: AssemblyCopyright("Copyright wolfSSL 2015")] +[assembly: AssemblyCopyright("Copyright wolfSSL 2020")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] diff --git a/wrapper/CSharp/wolfSSL_CSharp/wolfSSL.cs b/wrapper/CSharp/wolfSSL_CSharp/wolfSSL.cs index f0c555b2d..6953c8505 100644 --- a/wrapper/CSharp/wolfSSL_CSharp/wolfSSL.cs +++ b/wrapper/CSharp/wolfSSL_CSharp/wolfSSL.cs @@ -152,10 +152,14 @@ namespace wolfSSL.CSharp { [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] private extern static IntPtr wolfTLSv1_2_server_method(); [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] + private extern static IntPtr wolfTLSv1_3_server_method(); + [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] private extern static IntPtr wolfSSLv23_server_method(); [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] private extern static IntPtr wolfTLSv1_2_client_method(); [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] + private extern static IntPtr wolfTLSv1_3_client_method(); + [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] private extern static IntPtr wolfSSLv23_client_method(); [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] private extern static IntPtr wolfDTLSv1_2_server_method(); @@ -280,12 +284,29 @@ namespace wolfSSL.CSharp { private extern static int wolfSSL_SetTmpDH_file(IntPtr ssl, StringBuilder dhParam, int type); + /******************************** + * Verify Callback + */ + public delegate int CallbackVerify_delegate(int ret, IntPtr x509_ctx); + [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] + private extern static void wolfSSL_CTX_set_verify(IntPtr ctx, int mode, CallbackVerify_delegate vc); + [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] + private extern static void wolfSSL_set_verify(IntPtr ssl, int mode, CallbackVerify_delegate vc); + + /******************************** * Enum types from wolfSSL library */ public static readonly int SSL_FILETYPE_PEM = 1; public static readonly int SSL_FILETYPE_ASN1= 2; public static readonly int SSL_FILETYPE_RAW = 3; + + public static readonly int SSL_VERIFY_NONE = 0; + public static readonly int SSL_VERIFY_PEER = 1; + public static readonly int SSL_VERIFY_FAIL_IF_NO_PEER_CERT = 2; + public static readonly int SSL_VERIFY_CLIENT_ONCE = 4; + public static readonly int SSL_VERIFY_FAIL_EXCEPT_PSK = 8; + public static readonly int CBIO_ERR_GENERAL = -1; public static readonly int CBIO_ERR_WANT_READ = -2; public static readonly int CBIO_ERR_WANT_WRITE = -2; @@ -1283,6 +1304,23 @@ namespace wolfSSL.CSharp { } } + /// + /// Set up TLS version 1.3 method + /// + /// pointer to TLSv1.3 method + public static IntPtr useTLSv1_3_server() + { + try + { + return wolfTLSv1_3_server_method(); + } + catch (Exception e) + { + log(ERROR_LOG, "wolfssl error " + e.ToString()); + return IntPtr.Zero; + } + } + /// /// Use any TLS version @@ -1319,6 +1357,22 @@ namespace wolfSSL.CSharp { } } + /// + /// Set up TLS version 1.3 method + /// + /// pointer to TLSv1.3 method + public static IntPtr useTLSv1_3_client() + { + try + { + return wolfTLSv1_3_client_method(); + } + catch (Exception e) + { + log(ERROR_LOG, "wolfssl error " + e.ToString()); + return IntPtr.Zero; + } + } /// /// Use any TLS version @@ -1676,6 +1730,60 @@ namespace wolfSSL.CSharp { } } + /// + /// Set the certificate verification mode and optional callback function + /// + /// pointer to CTX that the function is set in + /// See SSL_VERIFY options + /// Optional verify callback function to use + public static int CTX_set_verify(IntPtr ctx, int mode, CallbackVerify_delegate vc) + { + try + { + IntPtr local_ctx = unwrap(ctx); + if (local_ctx == IntPtr.Zero) + { + log(ERROR_LOG, "CTX set_verify error"); + return FAILURE; + } + + wolfSSL_CTX_set_verify(local_ctx, mode, vc); + return SUCCESS; + } + catch (Exception e) + { + log(ERROR_LOG, "wolfssl ctx set verify error " + e.ToString()); + return FAILURE; + } + } + + /// + /// Set the certificate verification mode and optional callback function + /// + /// pointer to SSL object that the function is set in + /// See SSL_VERIFY options + /// Optional verify callback function to use + public static int set_verify(IntPtr ssl, int mode, CallbackVerify_delegate vc) + { + try + { + IntPtr local_ssl = unwrap(ssl); + if (local_ssl == IntPtr.Zero) + { + log(ERROR_LOG, "set_verify error"); + return FAILURE; + } + + wolfSSL_set_verify(local_ssl, mode, vc); + return SUCCESS; + } + catch (Exception e) + { + log(ERROR_LOG, "wolfssl set verify error " + e.ToString()); + return FAILURE; + } + + } /// /// Set the function to use for logging diff --git a/wrapper/CSharp/wolfSSL_CSharp/wolfSSL_CSharp.csproj b/wrapper/CSharp/wolfSSL_CSharp/wolfSSL_CSharp.csproj index d5eabceba..128b84a37 100755 --- a/wrapper/CSharp/wolfSSL_CSharp/wolfSSL_CSharp.csproj +++ b/wrapper/CSharp/wolfSSL_CSharp/wolfSSL_CSharp.csproj @@ -67,7 +67,8 @@ xcopy "$(ProjectDir)..\..\..\certs\server-key.pem" "$(TargetDir)" /Y /R xcopy "$(ProjectDir)..\..\..\certs\server-cert.pem" "$(TargetDir)" /Y /R -xcopy "$(ProjectDir)..\..\..\certs\dh2048.pem" "$(TargetDir)" /Y /R +xcopy "$(ProjectDir)..\..\..\certs\dh2048.pem" "$(TargetDir)" /Y /R +xcopy "$(ProjectDir)..\..\..\certs\ca-cert.pem" "$(TargetDir)" /Y /R + \ No newline at end of file diff --git a/wrapper/CSharp/wolfSSL_CSharp.sln b/wrapper/CSharp/wolfSSL_CSharp.sln index 12e1a828a..a90e05bd2 100755 --- a/wrapper/CSharp/wolfSSL_CSharp.sln +++ b/wrapper/CSharp/wolfSSL_CSharp.sln @@ -27,6 +27,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wolfSSL-Example-IOCallbacks EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wolfSSL-TLS-Client", "wolfSSL-TLS-Client\wolfSSL-TLS-Client.csproj", "{B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wolfSSL-TLS-ServerThreaded", "wolfSSL-TLS-ServerThreaded\wolfSSL-TLS-ServerThreaded.csproj", "{8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -251,6 +253,30 @@ Global {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.Release|Win32.Build.0 = Release|Any CPU {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.Release|x64.ActiveCfg = Release|x64 {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.Release|x64.Build.0 = Release|x64 + {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.Debug|Win32.ActiveCfg = Debug|Any CPU + {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.Debug|Win32.Build.0 = Debug|Any CPU + {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.Debug|x64.ActiveCfg = Debug|x64 + {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.Debug|x64.Build.0 = Debug|x64 + {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.DLL Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.DLL Debug|Any CPU.Build.0 = Debug|Any CPU + {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.DLL Debug|Win32.ActiveCfg = Debug|Any CPU + {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.DLL Debug|Win32.Build.0 = Debug|Any CPU + {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.DLL Debug|x64.ActiveCfg = Debug|x64 + {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.DLL Debug|x64.Build.0 = Debug|x64 + {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.DLL Release|Any CPU.ActiveCfg = Release|Any CPU + {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.DLL Release|Any CPU.Build.0 = Release|Any CPU + {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.DLL Release|Win32.ActiveCfg = Release|Any CPU + {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.DLL Release|Win32.Build.0 = Release|Any CPU + {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.DLL Release|x64.ActiveCfg = Release|x64 + {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.DLL Release|x64.Build.0 = Release|x64 + {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.Release|Any CPU.Build.0 = Release|Any CPU + {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.Release|Win32.ActiveCfg = Release|Any CPU + {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.Release|Win32.Build.0 = Release|Any CPU + {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.Release|x64.ActiveCfg = Release|x64 + {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/wrapper/CSharp/wolfSSL_CSharp/wolfSSL.cs b/wrapper/CSharp/wolfSSL_CSharp/wolfSSL.cs old mode 100644 new mode 100755 index 6953c8505..7acbe77ea --- a/wrapper/CSharp/wolfSSL_CSharp/wolfSSL.cs +++ b/wrapper/CSharp/wolfSSL_CSharp/wolfSSL.cs @@ -50,22 +50,20 @@ namespace wolfSSL.CSharp { /******************************** - * Class for keeping ctx/ssl handles alive + * Class for keeping ctx handles alive */ [StructLayout(LayoutKind.Sequential)] - private class ctx_handles + private class ctx_handle { private GCHandle rec_cb; private GCHandle snd_cb; private GCHandle psk_cb; - private GCHandle fd_pin; private IntPtr ctx; public void set_receive(GCHandle input) { this.rec_cb = input; } - public GCHandle get_receive() { return this.rec_cb; @@ -75,7 +73,6 @@ namespace wolfSSL.CSharp { { this.snd_cb = input; } - public GCHandle get_send() { return this.snd_cb; @@ -85,27 +82,15 @@ namespace wolfSSL.CSharp { { this.psk_cb = input; } - public GCHandle get_psk() { return this.psk_cb; } - public void set_fd(GCHandle input) - { - this.fd_pin = input; - } - - public GCHandle get_fd() - { - return this.fd_pin; - } - public void set_ctx(IntPtr input) { this.ctx = input; } - public IntPtr get_ctx() { return this.ctx; @@ -116,7 +101,7 @@ namespace wolfSSL.CSharp { /// public void free() { - log(INFO_LOG, "freeing handles"); + log(INFO_LOG, "freeing ctx handle"); if (!Object.Equals(this.rec_cb, default(GCHandle))) { this.rec_cb.Free(); @@ -129,10 +114,57 @@ namespace wolfSSL.CSharp { { this.psk_cb.Free(); } + } + } + + /******************************** + * Class for keeping ssl handle alive + */ + [StructLayout(LayoutKind.Sequential)] + private class ssl_handle + { + private GCHandle fd_pin; + private GCHandle psk_cb; + private IntPtr ssl; + + public void set_fd(GCHandle input) + { + this.fd_pin = input; + } + public GCHandle get_fd() + { + return this.fd_pin; + } + + public void set_psk(GCHandle input) + { + this.psk_cb = input; + } + public GCHandle get_psk() + { + return this.psk_cb; + } + + public void set_ssl(IntPtr input) + { + this.ssl = input; + } + public IntPtr get_ssl() + { + return this.ssl; + } + public void free() + { + log(INFO_LOG, "freeing ssl handle"); + if (!Object.Equals(this.fd_pin, default(GCHandle))) { this.fd_pin.Free(); } + if (!Object.Equals(this.psk_cb, default(GCHandle))) + { + this.psk_cb.Free(); + } } } @@ -282,6 +314,8 @@ namespace wolfSSL.CSharp { private extern static int wolfSSL_CTX_SetMinDhKey_Sz(IntPtr ctx, short size); [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] private extern static int wolfSSL_SetTmpDH_file(IntPtr ssl, StringBuilder dhParam, int type); + [DllImport(wolfssl_dll, CallingConvention = CallingConvention.Cdecl)] + private extern static int wolfSSL_CTX_SetTmpDH_file(IntPtr ctx, StringBuilder dhParam, int type); /******************************** @@ -325,13 +359,25 @@ namespace wolfSSL.CSharp { public static readonly int FAILURE = 0; - private static IntPtr unwrap(IntPtr ctx) + private static IntPtr unwrap_ctx(IntPtr ctx) { try { GCHandle gch = GCHandle.FromIntPtr(ctx); - ctx_handles handles = (ctx_handles)gch.Target; + ctx_handle handles = (ctx_handle)gch.Target; return handles.get_ctx(); } catch (Exception e) + { + log(ERROR_LOG, "wolfssl ctx pointer is incorrect " + e); + return IntPtr.Zero; + } + } + private static IntPtr unwrap_ssl(IntPtr ssl) + { + try { + GCHandle gch = GCHandle.FromIntPtr(ssl); + ssl_handle handles = (ssl_handle)gch.Target; + return handles.get_ssl(); + } catch (Exception e) { log(ERROR_LOG, "wolfssl pointer is incorrect " + e); return IntPtr.Zero; @@ -517,19 +563,19 @@ namespace wolfSSL.CSharp { try { - ctx_handles io; - IntPtr local_ctx = unwrap(ctx); + ssl_handle io; + IntPtr local_ctx = unwrap_ctx(ctx); if (local_ctx == IntPtr.Zero) { - log(ERROR_LOG, "new_ssl error"); + log(ERROR_LOG, "new_ssl ctx unwrap error"); return IntPtr.Zero; } - io = new ctx_handles(); - io.set_ctx(wolfSSL_new(local_ctx)); + io = new ssl_handle(); + io.set_ssl(wolfSSL_new(local_ctx)); /* check if null */ - if (io.get_ctx() == IntPtr.Zero) + if (io.get_ssl() == IntPtr.Zero) { return IntPtr.Zero; } @@ -556,10 +602,10 @@ namespace wolfSSL.CSharp { return FAILURE; try { - IntPtr sslCtx = unwrap(ssl); + IntPtr sslCtx = unwrap_ssl(ssl); if (sslCtx == IntPtr.Zero) { - log(ERROR_LOG, "accept error"); + log(ERROR_LOG, "accept ssl unwrap error"); return FAILURE; } @@ -584,10 +630,10 @@ namespace wolfSSL.CSharp { return FAILURE; try { - IntPtr sslCtx = unwrap(ssl); + IntPtr sslCtx = unwrap_ssl(ssl); if (sslCtx == IntPtr.Zero) { - log(ERROR_LOG, "connect error"); + log(ERROR_LOG, "connect ssl unwrap error"); return FAILURE; } @@ -614,14 +660,16 @@ namespace wolfSSL.CSharp { return FAILURE; try { - IntPtr sslCtx = unwrap(ssl); + IntPtr sslCtx = unwrap_ssl(ssl); IntPtr data; int ret; byte[] msg; + buf.Clear(); /* Clear incomming buffer */ + if (sslCtx == IntPtr.Zero) { - log(ERROR_LOG, "read error"); + log(ERROR_LOG, "read ssl unwrap error"); return FAILURE; } data = Marshal.AllocHGlobal(sz); @@ -666,13 +714,13 @@ namespace wolfSSL.CSharp { return FAILURE; try { - IntPtr sslCtx = unwrap(ssl); + IntPtr sslCtx = unwrap_ssl(ssl); IntPtr data; int ret; if (sslCtx == IntPtr.Zero) { - log(ERROR_LOG, "wolfssl read error"); + log(ERROR_LOG, "read ssl unwrap error"); return FAILURE; } data = Marshal.AllocHGlobal(sz); @@ -709,13 +757,13 @@ namespace wolfSSL.CSharp { return FAILURE; try { - IntPtr sslCtx = unwrap(ssl); + IntPtr sslCtx = unwrap_ssl(ssl); IntPtr data; int ret; if (sslCtx == IntPtr.Zero) { - log(ERROR_LOG, "write error"); + log(ERROR_LOG, "write ssl unwrap error"); return FAILURE; } @@ -748,13 +796,13 @@ namespace wolfSSL.CSharp { return FAILURE; try { - IntPtr sslCtx = unwrap(ssl); + IntPtr sslCtx = unwrap_ssl(ssl); IntPtr data; int ret; if (sslCtx == IntPtr.Zero) { - log(ERROR_LOG, "write error"); + log(ERROR_LOG, "write ssl unwrap error"); return FAILURE; } data = Marshal.AllocHGlobal(sz); @@ -782,9 +830,9 @@ namespace wolfSSL.CSharp { { IntPtr sslCtx; GCHandle gch = GCHandle.FromIntPtr(ssl); - ctx_handles handles = (ctx_handles)gch.Target; + ssl_handle handles = (ssl_handle)gch.Target; - sslCtx = handles.get_ctx(); + sslCtx = handles.get_ssl(); wolfSSL_free(sslCtx); handles.free(); gch.Free(); @@ -807,10 +855,10 @@ namespace wolfSSL.CSharp { return FAILURE; try { - IntPtr sslCtx = unwrap(ssl); + IntPtr sslCtx = unwrap_ssl(ssl); if (sslCtx == IntPtr.Zero) { - log(ERROR_LOG, "wolfssl shutdown error"); + log(ERROR_LOG, "shutdown ssl unwrap error"); return FAILURE; } @@ -834,7 +882,7 @@ namespace wolfSSL.CSharp { try { GCHandle gch = GCHandle.FromIntPtr(ctx); - ctx_handles handles = (ctx_handles)gch.Target; + ctx_handle handles = (ctx_handle)gch.Target; /* check if already stored handle needs freed */ gch = handles.get_receive(); @@ -865,7 +913,7 @@ namespace wolfSSL.CSharp { try { GCHandle gch = GCHandle.FromIntPtr(ctx); - ctx_handles handles = (ctx_handles)gch.Target; + ctx_handle handles = (ctx_handle)gch.Target; /* check if already stored handle needs freed */ gch = handles.get_send(); @@ -899,7 +947,7 @@ namespace wolfSSL.CSharp { if (ctx == IntPtr.Zero) return ctx; - ctx_handles io = new ctx_handles(); + ctx_handle io = new ctx_handle(); io.set_ctx(ctx); CallbackIORecv_delegate recv = new CallbackIORecv_delegate(wolfssl.wolfSSLCbIORecv); @@ -934,7 +982,7 @@ namespace wolfSSL.CSharp { if (ctx == IntPtr.Zero) return ctx; - ctx_handles io = new ctx_handles(); + ctx_handle io = new ctx_handle(); io.set_ctx(ctx); CallbackIORecv_delegate recv = new CallbackIORecv_delegate(wolfssl.wolfSSL_dtlsCbIORecv); @@ -965,7 +1013,7 @@ namespace wolfSSL.CSharp { try { GCHandle gch = GCHandle.FromIntPtr(ctx); - ctx_handles handles = (ctx_handles)gch.Target; + ctx_handle handles = (ctx_handle)gch.Target; wolfSSL_CTX_free(handles.get_ctx()); handles.free(); gch.Free(); @@ -987,10 +1035,10 @@ namespace wolfSSL.CSharp { { try { - IntPtr local_ctx = unwrap(ctx); + IntPtr local_ctx = unwrap_ctx(ctx); if (local_ctx == IntPtr.Zero) { - log(ERROR_LOG, "CTX use psk identity hint error"); + log(ERROR_LOG, "CTX use psk identity hint unwrap error"); return FAILURE; } @@ -1014,7 +1062,7 @@ namespace wolfSSL.CSharp { try { GCHandle gch = GCHandle.FromIntPtr(ctx); - ctx_handles handles = (ctx_handles)gch.Target; + ctx_handle handles = (ctx_handle)gch.Target; handles.set_psk(GCHandle.Alloc(psk_cb)); wolfSSL_CTX_set_psk_server_callback(handles.get_ctx(), psk_cb); @@ -1036,7 +1084,7 @@ namespace wolfSSL.CSharp { try { GCHandle gch = GCHandle.FromIntPtr(ctx); - ctx_handles handles = (ctx_handles)gch.Target; + ctx_handle handles = (ctx_handle)gch.Target; handles.set_psk(GCHandle.Alloc(psk_cb)); wolfSSL_CTX_set_psk_client_callback(handles.get_ctx(), psk_cb); @@ -1058,10 +1106,10 @@ namespace wolfSSL.CSharp { try { GCHandle gch = GCHandle.FromIntPtr(ssl); - ctx_handles handles = (ctx_handles)gch.Target; + ssl_handle handles = (ssl_handle)gch.Target; handles.set_psk(GCHandle.Alloc(psk_cb)); - wolfSSL_set_psk_server_callback(handles.get_ctx(), psk_cb); + wolfSSL_set_psk_server_callback(handles.get_ssl(), psk_cb); } catch (Exception e) { @@ -1089,8 +1137,8 @@ namespace wolfSSL.CSharp { if (!fd.Equals(null)) { GCHandle gch = GCHandle.FromIntPtr(ssl); - ctx_handles handles = (ctx_handles)gch.Target; - IntPtr sslCtx = handles.get_ctx(); + ssl_handle handles = (ssl_handle)gch.Target; + IntPtr sslCtx = handles.get_ssl(); IntPtr ptr; GCHandle fd_pin = GCHandle.Alloc(fd); @@ -1128,7 +1176,7 @@ namespace wolfSSL.CSharp { try { IntPtr ptr; - IntPtr sslCtx = unwrap(ssl); + IntPtr sslCtx = unwrap_ssl(ssl); if (sslCtx == IntPtr.Zero) { log(ERROR_LOG, "wolfssl get_fd error"); @@ -1174,7 +1222,7 @@ namespace wolfSSL.CSharp { IntPtr ptr; DTLS_con con; GCHandle gch = GCHandle.FromIntPtr(ssl); - ctx_handles handles = (ctx_handles)gch.Target; + ssl_handle handles = (ssl_handle)gch.Target; GCHandle fd_pin; con = new DTLS_con(); @@ -1183,8 +1231,8 @@ namespace wolfSSL.CSharp { fd_pin = GCHandle.Alloc(con); handles.set_fd(fd_pin); ptr = GCHandle.ToIntPtr(fd_pin); - wolfSSL_SetIOWriteCtx(handles.get_ctx(), ptr); //pass along the socket for writing to - wolfSSL_SetIOReadCtx(handles.get_ctx(), ptr); //pass along the socket for reading from + wolfSSL_SetIOWriteCtx(handles.get_ssl(), ptr); //pass along the socket for writing to + wolfSSL_SetIOReadCtx(handles.get_ssl(), ptr); //pass along the socket for reading from return SUCCESS; } @@ -1208,7 +1256,7 @@ namespace wolfSSL.CSharp { try { IntPtr ptr; - IntPtr sslCtx = unwrap(ssl); + IntPtr sslCtx = unwrap_ssl(ssl); if (sslCtx == IntPtr.Zero) { log(ERROR_LOG, "wolfssl get_dtls_fd error"); @@ -1443,7 +1491,7 @@ namespace wolfSSL.CSharp { IntPtr ssl_cipher_ptr; string ssl_cipher_str; - IntPtr sslCtx = unwrap(ssl); + IntPtr sslCtx = unwrap_ssl(ssl); if (sslCtx == IntPtr.Zero) { log(ERROR_LOG, "wolfssl get_current_cipher error"); @@ -1474,7 +1522,7 @@ namespace wolfSSL.CSharp { { try { - IntPtr local_ctx = unwrap(ctx); + IntPtr local_ctx = unwrap_ctx(ctx); if (local_ctx == IntPtr.Zero) { log(ERROR_LOG, "CTX set cipher list error"); @@ -1501,7 +1549,7 @@ namespace wolfSSL.CSharp { { try { - IntPtr sslCtx = unwrap(ssl); + IntPtr sslCtx = unwrap_ssl(ssl); if (sslCtx == IntPtr.Zero) { log(ERROR_LOG, "wolfssl set_cipher_list error"); @@ -1533,7 +1581,7 @@ namespace wolfSSL.CSharp { IntPtr version_ptr; string version; - IntPtr sslCtx = unwrap(ssl); + IntPtr sslCtx = unwrap_ssl(ssl); if (sslCtx == IntPtr.Zero) { log(ERROR_LOG, "wolfssl get_version error"); @@ -1569,7 +1617,7 @@ namespace wolfSSL.CSharp { StringBuilder err_name; StringBuilder ret; - IntPtr sslCtx = unwrap(ssl); + IntPtr sslCtx = unwrap_ssl(ssl); if (sslCtx == IntPtr.Zero) { log(ERROR_LOG, "wolfssl get_error error"); @@ -1604,7 +1652,7 @@ namespace wolfSSL.CSharp { { try { - IntPtr local_ctx = unwrap(ctx); + IntPtr local_ctx = unwrap_ctx(ctx); if (local_ctx == IntPtr.Zero) { log(ERROR_LOG, "CTX use certificate file error"); @@ -1632,7 +1680,7 @@ namespace wolfSSL.CSharp { { try { - IntPtr local_ctx = unwrap(ctx); + IntPtr local_ctx = unwrap_ctx(ctx); if (local_ctx == IntPtr.Zero) { log(ERROR_LOG, "CTX load verify locations certificate file error"); @@ -1659,7 +1707,7 @@ namespace wolfSSL.CSharp { { try { - IntPtr local_ctx = unwrap(ctx); + IntPtr local_ctx = unwrap_ctx(ctx); if (local_ctx == IntPtr.Zero) { log(ERROR_LOG, "CTX use PrivateKey file error"); @@ -1687,10 +1735,10 @@ namespace wolfSSL.CSharp { { try { - IntPtr sslCtx = unwrap(ssl); + IntPtr sslCtx = unwrap_ssl(ssl); if (sslCtx == IntPtr.Zero) { - log(ERROR_LOG, "wolfssl SetTmpDH_file error"); + log(ERROR_LOG, "SetTmpDH_file ssl unwrap error"); return FAILURE; } @@ -1698,7 +1746,34 @@ namespace wolfSSL.CSharp { } catch (Exception e) { - log(ERROR_LOG, "wolfssl set tmp dh file error " + e.ToString()); + log(ERROR_LOG, "SetTmpDH_file error " + e.ToString()); + return FAILURE; + } + } + + /// + /// Set temporary DH parameters + /// + /// Structure to set in + /// file name + /// type of file ie PEM + /// 1 on success + public static int CTX_SetTmpDH_file(IntPtr ctx, StringBuilder dhparam, int file_type) + { + try + { + IntPtr local_ctx = unwrap_ctx(ctx); + if (local_ctx == IntPtr.Zero) + { + log(ERROR_LOG, "CTX_SetTmpDH_file ctx unwrap error"); + return FAILURE; + } + + return wolfSSL_CTX_SetTmpDH_file(local_ctx, dhparam, file_type); + } + catch (Exception e) + { + log(ERROR_LOG, "CTX_SetTmpDH_file error " + e.ToString()); return FAILURE; } } @@ -1714,7 +1789,7 @@ namespace wolfSSL.CSharp { { try { - IntPtr local_ctx = unwrap(ctx); + IntPtr local_ctx = unwrap_ctx(ctx); if (local_ctx == IntPtr.Zero) { log(ERROR_LOG, "CTX SetMinDhKey_Sz error"); @@ -1740,7 +1815,7 @@ namespace wolfSSL.CSharp { { try { - IntPtr local_ctx = unwrap(ctx); + IntPtr local_ctx = unwrap_ctx(ctx); if (local_ctx == IntPtr.Zero) { log(ERROR_LOG, "CTX set_verify error"); @@ -1767,7 +1842,7 @@ namespace wolfSSL.CSharp { { try { - IntPtr local_ssl = unwrap(ssl); + IntPtr local_ssl = unwrap_ssl(ssl); if (local_ssl == IntPtr.Zero) { log(ERROR_LOG, "set_verify error"); diff --git a/wrapper/include.am b/wrapper/include.am index 9c4fa5d7f..5185523e6 100644 --- a/wrapper/include.am +++ b/wrapper/include.am @@ -4,39 +4,4 @@ include wrapper/python/wolfcrypt/include.am include wrapper/python/wolfssl/include.am - -# wolfSSL CSharp wrapper files -EXTRA_DIST+= wrapper/CSharp/wolfSSL-DTLS-PSK-Server/App.config -EXTRA_DIST+= wrapper/CSharp/wolfSSL-DTLS-PSK-Server/Properties/AssemblyInfo.cs -EXTRA_DIST+= wrapper/CSharp/wolfSSL-DTLS-PSK-Server/wolfSSL-DTLS-PSK-Server.cs -EXTRA_DIST+= wrapper/CSharp/wolfSSL-DTLS-PSK-Server/wolfSSL-DTLS-PSK-Server.csproj -EXTRA_DIST+= wrapper/CSharp/wolfSSL-DTLS-Server/App.config -EXTRA_DIST+= wrapper/CSharp/wolfSSL-DTLS-Server/Properties/AssemblyInfo.cs -EXTRA_DIST+= wrapper/CSharp/wolfSSL-DTLS-Server/wolfSSL-DTLS-Server.cs -EXTRA_DIST+= wrapper/CSharp/wolfSSL-DTLS-Server/wolfSSL-DTLS-Server.csproj -EXTRA_DIST+= wrapper/CSharp/wolfSSL-TLS-PSK-Server/App.config -EXTRA_DIST+= wrapper/CSharp/wolfSSL-TLS-PSK-Server/Properties/AssemblyInfo.cs -EXTRA_DIST+= wrapper/CSharp/wolfSSL-TLS-PSK-Server/wolfSSL-TLS-PSK-Server.cs -EXTRA_DIST+= wrapper/CSharp/wolfSSL-TLS-PSK-Server/wolfSSL-TLS-PSK-Server.csproj -EXTRA_DIST+= wrapper/CSharp/wolfSSL-TLS-Server/App.config -EXTRA_DIST+= wrapper/CSharp/wolfSSL-TLS-Server/Properties/AssemblyInfo.cs -EXTRA_DIST+= wrapper/CSharp/wolfSSL-TLS-Server/Properties/Settings.Designer.cs -EXTRA_DIST+= wrapper/CSharp/wolfSSL-TLS-Server/Properties/Settings.settings -EXTRA_DIST+= wrapper/CSharp/wolfSSL-TLS-Server/wolfSSL-TLS-Server.cs -EXTRA_DIST+= wrapper/CSharp/wolfSSL-TLS-Server/wolfSSL-TLS-Server.csproj -EXTRA_DIST+= wrapper/CSharp/wolfSSL-Example-IOCallbacks/App.config -EXTRA_DIST+= wrapper/CSharp/wolfSSL-Example-IOCallbacks/Properties/AssemblyInfo.cs -EXTRA_DIST+= wrapper/CSharp/wolfSSL-Example-IOCallbacks/wolfSSL-Example-IOCallbacks.cs -EXTRA_DIST+= wrapper/CSharp/wolfSSL-Example-IOCallbacks/wolfSSL-Example-IOCallbacks.csproj -EXTRA_DIST+= wrapper/CSharp/wolfSSL_CSharp.sln -EXTRA_DIST+= wrapper/CSharp/wolfSSL_CSharp/Properties/AssemblyInfo.cs -EXTRA_DIST+= wrapper/CSharp/wolfSSL_CSharp/Properties/Resources.Designer.cs -EXTRA_DIST+= wrapper/CSharp/wolfSSL_CSharp/Properties/Resources.resx -EXTRA_DIST+= wrapper/CSharp/wolfSSL_CSharp/wolfSSL.cs -EXTRA_DIST+= wrapper/CSharp/wolfSSL_CSharp/wolfSSL_CSharp.csproj -EXTRA_DIST+= wrapper/CSharp/wolfSSL-TLS-Client/App.config -EXTRA_DIST+= wrapper/CSharp/wolfSSL-TLS-Client/Properties/AssemblyInfo.cs -EXTRA_DIST+= wrapper/CSharp/wolfSSL-TLS-Client/Properties/Settings.Designer.cs -EXTRA_DIST+= wrapper/CSharp/wolfSSL-TLS-Client/Properties/Settings.settings -EXTRA_DIST+= wrapper/CSharp/wolfSSL-TLS-Client/wolfSSL-TLS-Client.cs -EXTRA_DIST+= wrapper/CSharp/wolfSSL-TLS-Client/wolfSSL-TLS-Client.csproj +include wrapper/CSharp/include.am From 7d4b4e499417b433365beca8e64f907810a53010 Mon Sep 17 00:00:00 2001 From: Hideki Miyazaki Date: Sun, 15 Mar 2020 13:52:37 +0900 Subject: [PATCH 210/649] added dtls benchmark --- examples/benchmark/tls_bench.c | 335 +++++++++++++++++++++++++++++++-- wolfssl/test.h | 7 + 2 files changed, 328 insertions(+), 14 deletions(-) diff --git a/examples/benchmark/tls_bench.c b/examples/benchmark/tls_bench.c index dcfb07948..7c7200e15 100644 --- a/examples/benchmark/tls_bench.c +++ b/examples/benchmark/tls_bench.c @@ -105,6 +105,14 @@ bench_tls(args); #endif #endif +#ifdef WOLFSSL_DTLS + #ifdef BENCH_EMBEDDED + #define TEST_DTLS_PACKET_SIZE (2 * 1024 - 100) + #else + #define TEST_DTLS_PACKET_SIZE (8192 - 100) + #endif +#endif + /* In memory transfer buffer maximum size */ /* Must be large enough to handle max TLS packet size plus max TLS header MAX_MSG_EXTRA */ #define MEM_BUFFER_SZ (TEST_PACKET_SIZE + 38 + WC_MAX_DIGEST_SIZE) @@ -275,6 +283,16 @@ typedef struct { int showVerbose; #ifndef NO_WOLFSSL_SERVER int listenFd; +#endif +#ifdef WOLFSSL_DTLS + int doDTLS; + int serverReady; + struct sockaddr_in serverAddr; + struct sockaddr_in clientAddr; +#ifdef HAVE_PTHREAD + pthread_mutex_t dtls_mutex; + pthread_cond_t dtls_cond; +#endif #endif side_t client; side_t server; @@ -299,7 +317,7 @@ typedef struct { /* Global vars for argument parsing */ int myoptind = 0; char* myoptarg = NULL; - +int DoneHandShake = 0; static double gettime_secs(int reset) { @@ -495,6 +513,99 @@ static int SocketSend(int sockFd, char* buf, int sz) } return sent; } +#ifdef WOLFSSL_DTLS +static int ReceiveFrom(WOLFSSL *ssl, int sd, char *buf, int sz) +{ + int recvd; + int dtls_timeout = wolfSSL_dtls_get_current_timeout(ssl); + struct sockaddr peer; + socklen_t peerSz; + + if (DoneHandShake) dtls_timeout = 0; + + if (!wolfSSL_get_using_nonblock(ssl)) { + struct timeval timeout; + XMEMSET(&timeout, 0, sizeof(timeout)); + timeout.tv_sec = dtls_timeout; + + if (setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, + sizeof(timeout)) != 0) { + printf("setsockopt rcvtimeo failed\n"); + } + } + + recvd = (int)recvfrom(sd, buf, sz, 0, (SOCKADDR*)&peer, &peerSz); + + if (recvd < 0) { + + if (errno == SOCKET_EWOULDBLOCK || errno == SOCKET_EAGAIN) { + if (wolfSSL_dtls_get_using_nonblock(ssl)) { + return WOLFSSL_CBIO_ERR_WANT_READ; + } + else { + return WOLFSSL_CBIO_ERR_TIMEOUT; + } + } + else if (errno == SOCKET_ECONNRESET) { + return WOLFSSL_CBIO_ERR_CONN_RST; + } + else if (errno == SOCKET_EINTR) { + return WOLFSSL_CBIO_ERR_ISR; + } + else if (errno == SOCKET_ECONNREFUSED) { + return WOLFSSL_CBIO_ERR_WANT_READ; + } + else { + return WOLFSSL_CBIO_ERR_GENERAL; + } + } + else { + if (recvd == 0) { + return WOLFSSL_CBIO_ERR_CONN_CLOSE; + } + } + + return recvd; +} + +static int SendTo(int sd, char *buf, int sz, const struct sockaddr *peer, + socklen_t peerSz) +{ + int sent; + int len = sz; + + sent = (int)sendto(sd, &buf[sz - len], len, 0, peer, peerSz); + + if (sent < 0) { + if (errno == SOCKET_EWOULDBLOCK || errno == SOCKET_EAGAIN) { + return WOLFSSL_CBIO_ERR_WANT_WRITE; + } + else if (errno == SOCKET_ECONNRESET) { + return WOLFSSL_CBIO_ERR_CONN_RST; + } + else if (errno == SOCKET_EINTR) { + return WOLFSSL_CBIO_ERR_ISR; + } + else if (errno == SOCKET_EPIPE) { + return WOLFSSL_CBIO_ERR_CONN_CLOSE; + } + else { + return WOLFSSL_CBIO_ERR_GENERAL; + } + } + + return sent; +} + +static int myDoneHsCb(WOLFSSL* ssl, void* user_ctx) +{ + (void) ssl; + (void) user_ctx; + + DoneHandShake = 1; + return 1; +} +#endif #ifndef NO_WOLFSSL_SERVER static int ServerSend(WOLFSSL* ssl, char* buf, int sz, void* ctx) @@ -505,7 +616,13 @@ static int ServerSend(WOLFSSL* ssl, char* buf, int sz, void* ctx) if (info->useLocalMem) return ServerMemSend(info, buf, sz); #endif - return SocketSend(info->server.sockFd, buf, sz); +#ifdef WOLFSSL_DTLS + if (info->doDTLS) { + return SendTo(info->server.sockFd, buf, sz, + (const struct sockaddr*)&info->clientAddr, sizeof(info->clientAddr)); + } else +#endif + return SocketSend(info->server.sockFd, buf, sz); } static int ServerRecv(WOLFSSL* ssl, char* buf, int sz, void* ctx) { @@ -515,7 +632,12 @@ static int ServerRecv(WOLFSSL* ssl, char* buf, int sz, void* ctx) if (info->useLocalMem) return ServerMemRecv(info, buf, sz); #endif - return SocketRecv(info->server.sockFd, buf, sz); +#ifdef WOLFSSL_DTLS + if (info->doDTLS) { + return ReceiveFrom(ssl, info->server.sockFd, buf, sz); + } else +#endif + return SocketRecv(info->server.sockFd, buf, sz); } #endif /* !NO_WOLFSSL_SERVER */ @@ -528,7 +650,13 @@ static int ClientSend(WOLFSSL* ssl, char* buf, int sz, void* ctx) if (info->useLocalMem) return ClientMemSend(info, buf, sz); #endif - return SocketSend(info->client.sockFd, buf, sz); +#ifdef WOLFSSL_DTLS + if (info->doDTLS) { + return SendTo(info->client.sockFd, buf, sz, + (const struct sockaddr*)&info->serverAddr, sizeof(info->serverAddr)); + } else +#endif + return SocketSend(info->client.sockFd, buf, sz); } static int ClientRecv(WOLFSSL* ssl, char* buf, int sz, void* ctx) { @@ -538,7 +666,12 @@ static int ClientRecv(WOLFSSL* ssl, char* buf, int sz, void* ctx) if (info->useLocalMem) return ClientMemRecv(info, buf, sz); #endif - return SocketRecv(info->client.sockFd, buf, sz); +#ifdef WOLFSSL_DTLS + if (info->doDTLS) { + return ReceiveFrom(ssl, info->client.sockFd, buf, sz); + } else +#endif + return SocketRecv(info->client.sockFd, buf, sz); } #endif /* !NO_WOLFSSL_CLIENT */ @@ -548,6 +681,8 @@ static void CloseAndCleanupSocket(int* sockFd) close(*sockFd); *sockFd = -1; } + + DoneHandShake = 0; } #ifdef BENCH_USE_NONBLOCK @@ -589,6 +724,17 @@ static int SetupSocketAndConnect(info_t* info, const char* host, servAddr.sin_addr.s_addr = inet_addr(host); } +#ifdef WOLFSSL_DTLS + if (info->doDTLS) { + /* Create the SOCK_DGRAM socket type is implemented on the User + * Datagram Protocol/Internet Protocol(UDP/IP protocol).*/ + if ((info->client.sockFd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + printf("ERROR: failed to create the SOCK_DGRAM socket\n"); + return -1; + } + XMEMCPY(&info->serverAddr, &servAddr, sizeof(servAddr)); + } else { +#endif /* Create a socket that uses an Internet IPv4 address, * Sets the socket to be stream based (TCP), * 0 means choose the default protocol. */ @@ -603,6 +749,9 @@ static int SetupSocketAndConnect(info_t* info, const char* host, printf("ERROR: failed to connect\n"); return -1; } +#ifdef WOLFSSL_DTLS + } +#endif #ifdef BENCH_USE_NONBLOCK if (SetSocketNonBlocking(info->client.sockFd) != 0) { @@ -631,11 +780,20 @@ static int bench_tls_client(info_t* info) total = gettime_secs(0); /* set up client */ +#ifdef WOLFSSL_DTLS + if(info->doDTLS) { + if (tls13) return WOLFSSL_SUCCESS; + cli_ctx = wolfSSL_CTX_new(wolfDTLSv1_2_client_method()); + } else +#endif #ifdef WOLFSSL_TLS13 if (tls13) cli_ctx = wolfSSL_CTX_new(wolfTLSv1_3_client_method()); #endif if (!tls13) +#ifdef WOLFSSL_DTLS + if(!info->doDTLS) +#endif #if !defined(WOLFSSL_TLS13) cli_ctx = wolfSSL_CTX_new(wolfSSLv23_client_method()); #elif !defined(WOLFSSL_NO_TLS12) @@ -721,9 +879,36 @@ static int bench_tls_client(info_t* info) goto exit; } +#ifdef WOLFSSL_DTLS + if (info->doDTLS) { + ret = wolfSSL_dtls_set_peer(cli_ssl, &info->serverAddr, + sizeof(info->serverAddr)); + if (ret != WOLFSSL_SUCCESS) { + printf("error setting dtls peer\n"); + goto exit; + } + ret = wolfSSL_SetHsDoneCb(cli_ssl, myDoneHsCb, NULL); + if (ret != WOLFSSL_SUCCESS) { + printf("error handshake done callback\n"); + goto exit; + } + } +#endif wolfSSL_SetIOReadCtx(cli_ssl, info); wolfSSL_SetIOWriteCtx(cli_ssl, info); +#if defined(HAVE_PTHREAD) && defined(WOLFSSL_DTLS) + /* synchronize with server */ + if (info->doDTLS) { + pthread_mutex_lock(&info->dtls_mutex); + if (info->serverReady != 1) { + pthread_cond_wait(&info->dtls_cond, &info->dtls_mutex); + } + /* for next loop */ + info->serverReady = 0; + pthread_mutex_unlock(&info->dtls_mutex); + } +#endif /* perform connect */ start = gettime_secs(1); #ifndef BENCH_USE_NONBLOCK @@ -870,7 +1055,7 @@ static void* client_thread(void* args) #ifndef NO_WOLFSSL_SERVER -static int SetupSocketAndListen(int* listenFd, word32 port) +static int SetupSocketAndListen(int* listenFd, word32 port, int doDTLS) { struct sockaddr_in servAddr; #if defined(_MSC_VER) || defined(__MINGW32__) @@ -878,13 +1063,25 @@ static int SetupSocketAndListen(int* listenFd, word32 port) #else int optval = 1; #endif - +#ifndef WOLFSSL_DTLS + (void) doDTLS; +#endif /* Setup server address */ XMEMSET(&servAddr, 0, sizeof(servAddr)); servAddr.sin_family = AF_INET; servAddr.sin_port = htons(port); servAddr.sin_addr.s_addr = INADDR_ANY; +#ifdef WOLFSSL_DTLS + if (doDTLS) { + /* Create a socket that is implemented on the User Datagram Protocol/ + * Interet Protocol(UDP/IP protocol). */ + if((*listenFd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { + printf("ERROR: failed to create the socket\n"); + return -1; + } + } else +#endif /* Create a socket that uses an Internet IPv4 address, * Sets the socket to be stream based (TCP), * 0 means choose the default protocol. */ @@ -906,7 +1103,9 @@ static int SetupSocketAndListen(int* listenFd, word32 port) printf("ERROR: failed to bind\n"); return -1; } - +#ifdef WOLFSSL_DTLS + if (!doDTLS) +#endif if (listen(*listenFd, 5) != 0) { printf("ERROR: failed to listen\n"); return -1; @@ -926,7 +1125,32 @@ static int SocketWaitClient(info_t* info) int connd; struct sockaddr_in clientAddr; socklen_t size = sizeof(clientAddr); +#ifdef WOLFSSL_DTLS + char msg[64]; + if (info->doDTLS) { +#ifdef HAVE_PTHREAD + pthread_mutex_lock(&info->dtls_mutex); + info->serverReady = 1; + pthread_cond_signal(&info->dtls_cond); + pthread_mutex_unlock(&info->dtls_mutex); +#endif + connd = (int)recvfrom(info->listenFd, (char *)msg, sizeof(msg), + MSG_PEEK, (struct sockaddr*)&clientAddr, &size); + if (connd < -1) { + printf("ERROR: failed to accept the connection\n"); + return -1; + } else if (connd > 0) { + if (connect(info->listenFd, (const struct sockaddr *)&clientAddr, + size) != 0) { + printf("ERROR: Udp connet failed.\n"); + return -1; + } + } + XMEMCPY(&info->clientAddr, &clientAddr, sizeof(clientAddr)); + info->server.sockFd = info->listenFd; + } else { +#endif if ((connd = accept(info->listenFd, (struct sockaddr*)&clientAddr, &size)) == -1) { if (errno == SOCKET_EWOULDBLOCK) return -2; @@ -934,6 +1158,9 @@ static int SocketWaitClient(info_t* info) return -1; } info->server.sockFd = connd; +#ifdef WOLFSSL_DTLS + } +#endif if (info->showVerbose) { printf("Got client %d\n", connd); @@ -960,12 +1187,21 @@ static int bench_tls_server(info_t* info) int total_sz; /* set up server */ +#ifdef WOLFSSL_DTLS + if(info->doDTLS) { + if(tls13) return WOLFSSL_SUCCESS; + srv_ctx = wolfSSL_CTX_new(wolfDTLSv1_2_server_method()); + } else { +#endif #ifdef WOLFSSL_TLS13 if (tls13) srv_ctx = wolfSSL_CTX_new(wolfTLSv1_3_server_method()); #endif if (!tls13) srv_ctx = wolfSSL_CTX_new(wolfSSLv23_server_method()); +#ifdef WOLFSSL_DTLS + } +#endif if (srv_ctx == NULL) { printf("error creating server ctx\n"); ret = MEMORY_E; goto exit; @@ -1059,10 +1295,19 @@ static int bench_tls_server(info_t* info) printf("error creating server object\n"); ret = MEMORY_E; goto exit; } +#ifdef WOLFSSL_DTLS + if (info->doDTLS) { + ret = wolfSSL_dtls_set_peer(srv_ssl, &info->clientAddr, + sizeof(info->clientAddr)); + if (ret != WOLFSSL_SUCCESS) { + printf("error setting dtls peer\n"); + goto exit; + } + } +#endif wolfSSL_SetIOReadCtx(srv_ssl, info); wolfSSL_SetIOWriteCtx(srv_ssl, info); - #ifndef NO_DH wolfSSL_SetTmpDH(srv_ssl, p, sizeof(p), g, sizeof(g)); #endif @@ -1153,6 +1398,12 @@ static int bench_tls_server(info_t* info) wolfSSL_free(srv_ssl); srv_ssl = NULL; +#ifdef WOLFSSL_DTLS + if (info->doDTLS) { + SetupSocketAndListen(&info->listenFd, info->port, info->doDTLS); + } +#endif + } exit: @@ -1182,7 +1433,11 @@ static void* server_thread(void* args) if (!info->useLocalMem) { /* Setup TLS server listener */ - ret = SetupSocketAndListen(&info->listenFd, info->port); +#ifdef WOLFSSL_DTLS + ret = SetupSocketAndListen(&info->listenFd, info->port, info->doDTLS); +#else + ret = SetupSocketAndListen(&info->listenFd, info->port, 0); +#endif } if (ret == 0) { ret = bench_tls_server(info); @@ -1252,6 +1507,9 @@ static void Usage(void) printf("-l Cipher suite list (: delimited)\n"); printf("-t Time (seconds) to run each test (default %d)\n", BENCH_RUNTIME_SEC); printf("-p The packet size in bytes [1-16kB] (default %d)\n", TEST_PACKET_SIZE); +#ifdef WOLFSSL_DTLS + printf(" In the case of DTLS, [1-8kB] (default %d)\n", TEST_DTLS_PACKET_SIZE); +#endif printf("-S The total size in bytes (default %d)\n", TEST_MAX_SIZE); printf("-v Show verbose output\n"); #ifdef DEBUG_WOLFSSL @@ -1261,6 +1519,9 @@ static void Usage(void) printf("-T Number of threaded server/client pairs (default %d)\n", NUM_THREAD_PAIRS); printf("-m Use local memory, not socket\n"); #endif +#ifdef WOLFSSL_DTLS + printf("-u Use DTLS\n"); +#endif } static void ShowCiphers(void) @@ -1307,7 +1568,10 @@ int bench_tls(void* args) int argLocalMem = 0; int listenFd = -1; #endif - +#ifdef WOLFSSL_DTLS + int doDTLS = 0; + int option_p = 0; +#endif if (args != NULL) { argc = ((func_args*)args)->argc; argv = ((func_args*)args)->argv; @@ -1318,7 +1582,7 @@ int bench_tls(void* args) wolfSSL_Init(); /* Parse command line arguments */ - while ((ch = mygetopt(argc, argv, "?" "deil:p:t:vT:sch:P:mS:")) != -1) { + while ((ch = mygetopt(argc, argv, "?" "udeil:p:t:vT:sch:P:mS:")) != -1) { switch (ch) { case '?' : Usage(); @@ -1365,6 +1629,9 @@ int bench_tls(void* args) Usage(); ret = MY_EX_USAGE; goto exit; } + #ifdef WOLFSSL_DTLS + option_p = 1; + #endif break; case 'S' : @@ -1390,7 +1657,17 @@ int bench_tls(void* args) argLocalMem = 1; #endif break; - + case 'u': + #ifdef WOLFSSL_DTLS + doDTLS = 1; + #ifdef BENCH_USE_NONBLOCK + printf("tls_bench hasn't yet supported DTLS " + "non-blocking mode.\n"); + Usage(); + ret = MY_EX_USAGE; goto exit; + #endif + #endif + break; default: Usage(); ret = MY_EX_USAGE; goto exit; @@ -1438,11 +1715,32 @@ int bench_tls(void* args) /* Use same listen socket to avoid timing issues between client and server */ if (argServerOnly && !argLocalMem) { /* Setup TLS server listener */ - ret = SetupSocketAndListen(&listenFd, argPort); +#ifdef WOLFSSL_DTLS + ret = SetupSocketAndListen(&listenFd, argPort, doDTLS); +#else + ret = SetupSocketAndListen(&listenFd, argPort, 0); +#endif if (ret != 0) goto exit; } #endif +#ifdef WOLFSSL_DTLS + if (doDTLS) { + if (argLocalMem) { + printf("tls_bench hasn't yet supported DTLS with local memory.\n"); + ret = MY_EX_USAGE; goto exit; + } + if (option_p && argTestPacketSize > TEST_DTLS_PACKET_SIZE){ + printf("Invalid packet size %d\n", argTestPacketSize); + Usage(); + ret = MY_EX_USAGE; goto exit; + } else { + /* argTestPacketSize would be default for tcp packet */ + if (argTestPacketSize >= TEST_PACKET_SIZE) + argTestPacketSize = TEST_DTLS_PACKET_SIZE; + } + } +#endif printf("Running TLS Benchmarks...\n"); /* parse by : */ @@ -1464,6 +1762,7 @@ int bench_tls(void* args) info->port = argPort + i; /* threads must have separate ports */ info->cipher = cipher; info->packetSize = argTestPacketSize; + info->runTimeSec = argRuntimeSec; info->maxSize = argTestMaxSize; info->showPeerInfo = argShowPeerInfo; @@ -1474,6 +1773,10 @@ int bench_tls(void* args) info->client.sockFd = -1; info->server.sockFd = -1; + #ifdef WOLFSSL_DTLS + info->doDTLS = doDTLS; + info->serverReady = 0; + #endif if (argClientOnly) { #ifndef NO_WOLFSSL_CLIENT ret = bench_tls_client(info); @@ -1489,6 +1792,10 @@ int bench_tls(void* args) info->useLocalMem = argLocalMem; pthread_mutex_init(&info->to_server.mutex, NULL); pthread_mutex_init(&info->to_client.mutex, NULL); + #ifdef WOLFSSL_DTLS + pthread_mutex_init(&info->dtls_mutex, NULL); + pthread_cond_init(&info->dtls_cond, NULL); + #endif pthread_cond_init(&info->to_server.cond, NULL); pthread_cond_init(&info->to_client.cond, NULL); diff --git a/wolfssl/test.h b/wolfssl/test.h index e521c3a11..2f133f985 100644 --- a/wolfssl/test.h +++ b/wolfssl/test.h @@ -498,6 +498,13 @@ static WC_INLINE int mygetopt(int argc, char** argv, const char* optstring) char c; char* cp; + /* Added sanity check becuase scan-build complains argv[myoptind] access + * results in a null pointer dereference. */ + if (argv == NULL) { + myoptarg = NULL; + return -1; + } + if (myoptind == 0) next = NULL; /* we're starting new/over */ From 5c424769a03cfcdcceab2a43e4b9edb580641cc4 Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 23 Mar 2020 09:08:45 -0700 Subject: [PATCH 211/649] Added DH and Curve/Ed25519. --- IDE/XilinxSDK/user_settings.h | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/IDE/XilinxSDK/user_settings.h b/IDE/XilinxSDK/user_settings.h index f2604982d..670cc9cc7 100755 --- a/IDE/XilinxSDK/user_settings.h +++ b/IDE/XilinxSDK/user_settings.h @@ -74,6 +74,24 @@ extern unsigned char my_rng_seed_gen(void); #define TFM_ECC256 #define ECC_SHAMIR +/* DH */ +#undef NO_DH +#define WOLFSSL_DH_CONST +#define HAVE_FFDHE_2048 +#define HAVE_FFDHE_4096 + +/* Curve25519 / Ed25519 */ +#define HAVE_CURVE25519 +#define HAVE_ED25519 /* ED25519 Requires SHA512 */ +/* 25519 assumes UINT128_T is available for Aarch64 */ +#ifndef HAVE___UINT128_T +#define HAVE___UINT128_T +#endif + +/* ChaCha20 / Poly1305 */ +#define HAVE_CHACHA +#define HAVE_POLY1305 + /* AES-GCM Only */ #define NO_AES_CBC #define HAVE_AESGCM @@ -84,12 +102,10 @@ extern unsigned char my_rng_seed_gen(void); #define WOLFSSL_SHA3 #define WOLFSSL_NO_HASH_RAW /* not supported with ARMASM */ -/* ChaCha20 / Poly1305 */ -#define HAVE_CHACHA -#define HAVE_POLY1305 +/* HKDF */ +#define HAVE_HKDF /* Disable Algorithms */ -#define NO_DH #define NO_DSA #define NO_RC4 #define NO_MD4 From dde1c3bc085f1d3a64fc304bbfac8f765691b3a4 Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Mon, 23 Mar 2020 15:08:28 -0600 Subject: [PATCH 212/649] Fix for clang warning with ARM assembly build --- tests/api.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/api.c b/tests/api.c index 42357ea1c..73ed50964 100644 --- a/tests/api.c +++ b/tests/api.c @@ -22474,7 +22474,7 @@ static void test_wolfSSL_BN(void) AssertIntEQ(BN_set_word(a, 1), SSL_SUCCESS); AssertIntEQ(BN_set_word(b, 5), SSL_SUCCESS); - AssertIntEQ(BN_is_word(a, BN_get_word(a)), SSL_SUCCESS); + AssertIntEQ(BN_is_word(a, (WOLFSSL_BN_ULONG)BN_get_word(a)), SSL_SUCCESS); AssertIntEQ(BN_is_word(a, 3), SSL_FAILURE); AssertIntEQ(BN_sub(c, a, b), SSL_SUCCESS); #if defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) From a7d265bf46d3ab312eac14e377353db360fb3dea Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Tue, 24 Mar 2020 12:41:25 +1000 Subject: [PATCH 213/649] Fix casting warning in SP when mp_digit < sp_digit --- wolfcrypt/src/sp_arm32.c | 34 +++++++++++++++++----------------- wolfcrypt/src/sp_arm64.c | 34 +++++++++++++++++----------------- wolfcrypt/src/sp_armthumb.c | 34 +++++++++++++++++----------------- wolfcrypt/src/sp_c32.c | 34 +++++++++++++++++----------------- wolfcrypt/src/sp_c64.c | 34 +++++++++++++++++----------------- wolfcrypt/src/sp_cortexm.c | 34 +++++++++++++++++----------------- wolfcrypt/src/sp_x86_64.c | 34 +++++++++++++++++----------------- 7 files changed, 119 insertions(+), 119 deletions(-) diff --git a/wolfcrypt/src/sp_arm32.c b/wolfcrypt/src/sp_arm32.c index ac19eb36f..e7643eba2 100644 --- a/wolfcrypt/src/sp_arm32.c +++ b/wolfcrypt/src/sp_arm32.c @@ -7837,10 +7837,10 @@ static int sp_2048_to_mp(const sp_digit* a, mp_int* r) r->dp[0] = 0; for (i = 0; i < 64; i++) { - r->dp[j] |= a[i] << s; + r->dp[j] |= (mp_digit)(a[i] << s); r->dp[j] &= (1L << DIGIT_BIT) - 1; s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; + r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 32) { s += DIGIT_BIT; r->dp[j++] &= (1L << DIGIT_BIT) - 1; @@ -7848,7 +7848,7 @@ static int sp_2048_to_mp(const sp_digit* a, mp_int* r) r->dp[j] = 0; } else { - r->dp[j] = a[i] >> s; + r->dp[j] = (mp_digit)(a[i] >> s); } } s = 32 - s; @@ -19403,10 +19403,10 @@ static int sp_3072_to_mp(const sp_digit* a, mp_int* r) r->dp[0] = 0; for (i = 0; i < 96; i++) { - r->dp[j] |= a[i] << s; + r->dp[j] |= (mp_digit)(a[i] << s); r->dp[j] &= (1L << DIGIT_BIT) - 1; s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; + r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 32) { s += DIGIT_BIT; r->dp[j++] &= (1L << DIGIT_BIT) - 1; @@ -19414,7 +19414,7 @@ static int sp_3072_to_mp(const sp_digit* a, mp_int* r) r->dp[j] = 0; } else { - r->dp[j] = a[i] >> s; + r->dp[j] = (mp_digit)(a[i] >> s); } } s = 32 - s; @@ -72043,10 +72043,10 @@ static int sp_4096_to_mp(const sp_digit* a, mp_int* r) r->dp[0] = 0; for (i = 0; i < 128; i++) { - r->dp[j] |= a[i] << s; + r->dp[j] |= (mp_digit)(a[i] << s); r->dp[j] &= (1L << DIGIT_BIT) - 1; s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; + r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 32) { s += DIGIT_BIT; r->dp[j++] &= (1L << DIGIT_BIT) - 1; @@ -72054,7 +72054,7 @@ static int sp_4096_to_mp(const sp_digit* a, mp_int* r) r->dp[j] = 0; } else { - r->dp[j] = a[i] >> s; + r->dp[j] = (mp_digit)(a[i] >> s); } } s = 32 - s; @@ -73186,7 +73186,7 @@ static int sp_256_point_new_ex_8(void* heap, sp_point_256* sp, sp_point_256** p) #else *p = sp; #endif - if (*p == NULL) { + if (p == NULL) { ret = MEMORY_E; } return ret; @@ -73573,10 +73573,10 @@ static int sp_256_to_mp(const sp_digit* a, mp_int* r) r->dp[0] = 0; for (i = 0; i < 8; i++) { - r->dp[j] |= a[i] << s; + r->dp[j] |= (mp_digit)(a[i] << s); r->dp[j] &= (1L << DIGIT_BIT) - 1; s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; + r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 32) { s += DIGIT_BIT; r->dp[j++] &= (1L << DIGIT_BIT) - 1; @@ -73584,7 +73584,7 @@ static int sp_256_to_mp(const sp_digit* a, mp_int* r) r->dp[j] = 0; } else { - r->dp[j] = a[i] >> s; + r->dp[j] = (mp_digit)(a[i] >> s); } } s = 32 - s; @@ -81205,7 +81205,7 @@ static int sp_384_point_new_ex_12(void* heap, sp_point_384* sp, sp_point_384** p #else *p = sp; #endif - if (*p == NULL) { + if (p == NULL) { ret = MEMORY_E; } return ret; @@ -81459,10 +81459,10 @@ static int sp_384_to_mp(const sp_digit* a, mp_int* r) r->dp[0] = 0; for (i = 0; i < 12; i++) { - r->dp[j] |= a[i] << s; + r->dp[j] |= (mp_digit)(a[i] << s); r->dp[j] &= (1L << DIGIT_BIT) - 1; s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; + r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 32) { s += DIGIT_BIT; r->dp[j++] &= (1L << DIGIT_BIT) - 1; @@ -81470,7 +81470,7 @@ static int sp_384_to_mp(const sp_digit* a, mp_int* r) r->dp[j] = 0; } else { - r->dp[j] = a[i] >> s; + r->dp[j] = (mp_digit)(a[i] >> s); } } s = 32 - s; diff --git a/wolfcrypt/src/sp_arm64.c b/wolfcrypt/src/sp_arm64.c index 42d22f7af..0ba12ec38 100644 --- a/wolfcrypt/src/sp_arm64.c +++ b/wolfcrypt/src/sp_arm64.c @@ -5023,10 +5023,10 @@ static int sp_2048_to_mp(const sp_digit* a, mp_int* r) r->dp[0] = 0; for (i = 0; i < 32; i++) { - r->dp[j] |= a[i] << s; + r->dp[j] |= (mp_digit)(a[i] << s); r->dp[j] &= (1L << DIGIT_BIT) - 1; s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; + r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 64) { s += DIGIT_BIT; r->dp[j++] &= (1L << DIGIT_BIT) - 1; @@ -5034,7 +5034,7 @@ static int sp_2048_to_mp(const sp_digit* a, mp_int* r) r->dp[j] = 0; } else { - r->dp[j] = a[i] >> s; + r->dp[j] = (mp_digit)(a[i] >> s); } } s = 64 - s; @@ -12500,10 +12500,10 @@ static int sp_3072_to_mp(const sp_digit* a, mp_int* r) r->dp[0] = 0; for (i = 0; i < 48; i++) { - r->dp[j] |= a[i] << s; + r->dp[j] |= (mp_digit)(a[i] << s); r->dp[j] &= (1L << DIGIT_BIT) - 1; s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; + r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 64) { s += DIGIT_BIT; r->dp[j++] &= (1L << DIGIT_BIT) - 1; @@ -12511,7 +12511,7 @@ static int sp_3072_to_mp(const sp_digit* a, mp_int* r) r->dp[j] = 0; } else { - r->dp[j] = a[i] >> s; + r->dp[j] = (mp_digit)(a[i] >> s); } } s = 64 - s; @@ -29968,10 +29968,10 @@ static int sp_4096_to_mp(const sp_digit* a, mp_int* r) r->dp[0] = 0; for (i = 0; i < 64; i++) { - r->dp[j] |= a[i] << s; + r->dp[j] |= (mp_digit)(a[i] << s); r->dp[j] &= (1L << DIGIT_BIT) - 1; s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; + r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 64) { s += DIGIT_BIT; r->dp[j++] &= (1L << DIGIT_BIT) - 1; @@ -29979,7 +29979,7 @@ static int sp_4096_to_mp(const sp_digit* a, mp_int* r) r->dp[j] = 0; } else { - r->dp[j] = a[i] >> s; + r->dp[j] = (mp_digit)(a[i] >> s); } } s = 64 - s; @@ -30730,7 +30730,7 @@ static int sp_256_point_new_ex_4(void* heap, sp_point_256* sp, sp_point_256** p) #else *p = sp; #endif - if (*p == NULL) { + if (p == NULL) { ret = MEMORY_E; } return ret; @@ -30949,10 +30949,10 @@ static int sp_256_to_mp(const sp_digit* a, mp_int* r) r->dp[0] = 0; for (i = 0; i < 4; i++) { - r->dp[j] |= a[i] << s; + r->dp[j] |= (mp_digit)(a[i] << s); r->dp[j] &= (1L << DIGIT_BIT) - 1; s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; + r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 64) { s += DIGIT_BIT; r->dp[j++] &= (1L << DIGIT_BIT) - 1; @@ -30960,7 +30960,7 @@ static int sp_256_to_mp(const sp_digit* a, mp_int* r) r->dp[j] = 0; } else { - r->dp[j] = a[i] >> s; + r->dp[j] = (mp_digit)(a[i] >> s); } } s = 64 - s; @@ -48544,7 +48544,7 @@ static int sp_384_point_new_ex_6(void* heap, sp_point_384* sp, sp_point_384** p) #else *p = sp; #endif - if (*p == NULL) { + if (p == NULL) { ret = MEMORY_E; } return ret; @@ -48816,10 +48816,10 @@ static int sp_384_to_mp(const sp_digit* a, mp_int* r) r->dp[0] = 0; for (i = 0; i < 6; i++) { - r->dp[j] |= a[i] << s; + r->dp[j] |= (mp_digit)(a[i] << s); r->dp[j] &= (1L << DIGIT_BIT) - 1; s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; + r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 64) { s += DIGIT_BIT; r->dp[j++] &= (1L << DIGIT_BIT) - 1; @@ -48827,7 +48827,7 @@ static int sp_384_to_mp(const sp_digit* a, mp_int* r) r->dp[j] = 0; } else { - r->dp[j] = a[i] >> s; + r->dp[j] = (mp_digit)(a[i] >> s); } } s = 64 - s; diff --git a/wolfcrypt/src/sp_armthumb.c b/wolfcrypt/src/sp_armthumb.c index 22ce6e01f..22552396c 100644 --- a/wolfcrypt/src/sp_armthumb.c +++ b/wolfcrypt/src/sp_armthumb.c @@ -4543,10 +4543,10 @@ static int sp_2048_to_mp(const sp_digit* a, mp_int* r) r->dp[0] = 0; for (i = 0; i < 64; i++) { - r->dp[j] |= a[i] << s; + r->dp[j] |= (mp_digit)(a[i] << s); r->dp[j] &= (1L << DIGIT_BIT) - 1; s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; + r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 32) { s += DIGIT_BIT; r->dp[j++] &= (1L << DIGIT_BIT) - 1; @@ -4554,7 +4554,7 @@ static int sp_2048_to_mp(const sp_digit* a, mp_int* r) r->dp[j] = 0; } else { - r->dp[j] = a[i] >> s; + r->dp[j] = (mp_digit)(a[i] >> s); } } s = 32 - s; @@ -10284,10 +10284,10 @@ static int sp_3072_to_mp(const sp_digit* a, mp_int* r) r->dp[0] = 0; for (i = 0; i < 96; i++) { - r->dp[j] |= a[i] << s; + r->dp[j] |= (mp_digit)(a[i] << s); r->dp[j] &= (1L << DIGIT_BIT) - 1; s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; + r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 32) { s += DIGIT_BIT; r->dp[j++] &= (1L << DIGIT_BIT) - 1; @@ -10295,7 +10295,7 @@ static int sp_3072_to_mp(const sp_digit* a, mp_int* r) r->dp[j] = 0; } else { - r->dp[j] = a[i] >> s; + r->dp[j] = (mp_digit)(a[i] >> s); } } s = 32 - s; @@ -14685,10 +14685,10 @@ static int sp_4096_to_mp(const sp_digit* a, mp_int* r) r->dp[0] = 0; for (i = 0; i < 128; i++) { - r->dp[j] |= a[i] << s; + r->dp[j] |= (mp_digit)(a[i] << s); r->dp[j] &= (1L << DIGIT_BIT) - 1; s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; + r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 32) { s += DIGIT_BIT; r->dp[j++] &= (1L << DIGIT_BIT) - 1; @@ -14696,7 +14696,7 @@ static int sp_4096_to_mp(const sp_digit* a, mp_int* r) r->dp[j] = 0; } else { - r->dp[j] = a[i] >> s; + r->dp[j] = (mp_digit)(a[i] >> s); } } s = 32 - s; @@ -15846,7 +15846,7 @@ static int sp_256_point_new_ex_8(void* heap, sp_point_256* sp, sp_point_256** p) #else *p = sp; #endif - if (*p == NULL) { + if (p == NULL) { ret = MEMORY_E; } return ret; @@ -16069,10 +16069,10 @@ static int sp_256_to_mp(const sp_digit* a, mp_int* r) r->dp[0] = 0; for (i = 0; i < 8; i++) { - r->dp[j] |= a[i] << s; + r->dp[j] |= (mp_digit)(a[i] << s); r->dp[j] &= (1L << DIGIT_BIT) - 1; s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; + r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 32) { s += DIGIT_BIT; r->dp[j++] &= (1L << DIGIT_BIT) - 1; @@ -16080,7 +16080,7 @@ static int sp_256_to_mp(const sp_digit* a, mp_int* r) r->dp[j] = 0; } else { - r->dp[j] = a[i] >> s; + r->dp[j] = (mp_digit)(a[i] >> s); } } s = 32 - s; @@ -21938,7 +21938,7 @@ static int sp_384_point_new_ex_12(void* heap, sp_point_384* sp, sp_point_384** p #else *p = sp; #endif - if (*p == NULL) { + if (p == NULL) { ret = MEMORY_E; } return ret; @@ -22192,10 +22192,10 @@ static int sp_384_to_mp(const sp_digit* a, mp_int* r) r->dp[0] = 0; for (i = 0; i < 12; i++) { - r->dp[j] |= a[i] << s; + r->dp[j] |= (mp_digit)(a[i] << s); r->dp[j] &= (1L << DIGIT_BIT) - 1; s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; + r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 32) { s += DIGIT_BIT; r->dp[j++] &= (1L << DIGIT_BIT) - 1; @@ -22203,7 +22203,7 @@ static int sp_384_to_mp(const sp_digit* a, mp_int* r) r->dp[j] = 0; } else { - r->dp[j] = a[i] >> s; + r->dp[j] = (mp_digit)(a[i] >> s); } } s = 32 - s; diff --git a/wolfcrypt/src/sp_c32.c b/wolfcrypt/src/sp_c32.c index f72b317e3..b433be64e 100644 --- a/wolfcrypt/src/sp_c32.c +++ b/wolfcrypt/src/sp_c32.c @@ -3652,10 +3652,10 @@ static int sp_2048_to_mp(const sp_digit* a, mp_int* r) r->dp[0] = 0; for (i = 0; i < 90; i++) { - r->dp[j] |= a[i] << s; + r->dp[j] |= (mp_digit)(a[i] << s); r->dp[j] &= (1L << DIGIT_BIT) - 1; s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; + r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 23) { s += DIGIT_BIT; r->dp[j++] &= (1L << DIGIT_BIT) - 1; @@ -3663,7 +3663,7 @@ static int sp_2048_to_mp(const sp_digit* a, mp_int* r) r->dp[j] = 0; } else { - r->dp[j] = a[i] >> s; + r->dp[j] = (mp_digit)(a[i] >> s); } } s = 23 - s; @@ -7489,10 +7489,10 @@ static int sp_3072_to_mp(const sp_digit* a, mp_int* r) r->dp[0] = 0; for (i = 0; i < 134; i++) { - r->dp[j] |= a[i] << s; + r->dp[j] |= (mp_digit)(a[i] << s); r->dp[j] &= (1L << DIGIT_BIT) - 1; s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; + r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 23) { s += DIGIT_BIT; r->dp[j++] &= (1L << DIGIT_BIT) - 1; @@ -7500,7 +7500,7 @@ static int sp_3072_to_mp(const sp_digit* a, mp_int* r) r->dp[j] = 0; } else { - r->dp[j] = a[i] >> s; + r->dp[j] = (mp_digit)(a[i] >> s); } } s = 23 - s; @@ -11490,10 +11490,10 @@ static int sp_4096_to_mp(const sp_digit* a, mp_int* r) r->dp[0] = 0; for (i = 0; i < 196; i++) { - r->dp[j] |= a[i] << s; + r->dp[j] |= (mp_digit)(a[i] << s); r->dp[j] &= (1L << DIGIT_BIT) - 1; s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; + r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 21) { s += DIGIT_BIT; r->dp[j++] &= (1L << DIGIT_BIT) - 1; @@ -11501,7 +11501,7 @@ static int sp_4096_to_mp(const sp_digit* a, mp_int* r) r->dp[j] = 0; } else { - r->dp[j] = a[i] >> s; + r->dp[j] = (mp_digit)(a[i] >> s); } } s = 21 - s; @@ -12454,7 +12454,7 @@ static int sp_256_point_new_ex_10(void* heap, sp_point_256* sp, sp_point_256** p #else *p = sp; #endif - if (*p == NULL) { + if (p == NULL) { ret = MEMORY_E; } return ret; @@ -12742,10 +12742,10 @@ static int sp_256_to_mp(const sp_digit* a, mp_int* r) r->dp[0] = 0; for (i = 0; i < 10; i++) { - r->dp[j] |= a[i] << s; + r->dp[j] |= (mp_digit)(a[i] << s); r->dp[j] &= (1L << DIGIT_BIT) - 1; s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; + r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 26) { s += DIGIT_BIT; r->dp[j++] &= (1L << DIGIT_BIT) - 1; @@ -12753,7 +12753,7 @@ static int sp_256_to_mp(const sp_digit* a, mp_int* r) r->dp[j] = 0; } else { - r->dp[j] = a[i] >> s; + r->dp[j] = (mp_digit)(a[i] >> s); } } s = 26 - s; @@ -17786,7 +17786,7 @@ static int sp_384_point_new_ex_15(void* heap, sp_point_384* sp, sp_point_384** p #else *p = sp; #endif - if (*p == NULL) { + if (p == NULL) { ret = MEMORY_E; } return ret; @@ -18115,10 +18115,10 @@ static int sp_384_to_mp(const sp_digit* a, mp_int* r) r->dp[0] = 0; for (i = 0; i < 15; i++) { - r->dp[j] |= a[i] << s; + r->dp[j] |= (mp_digit)(a[i] << s); r->dp[j] &= (1L << DIGIT_BIT) - 1; s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; + r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 26) { s += DIGIT_BIT; r->dp[j++] &= (1L << DIGIT_BIT) - 1; @@ -18126,7 +18126,7 @@ static int sp_384_to_mp(const sp_digit* a, mp_int* r) r->dp[j] = 0; } else { - r->dp[j] = a[i] >> s; + r->dp[j] = (mp_digit)(a[i] >> s); } } s = 26 - s; diff --git a/wolfcrypt/src/sp_c64.c b/wolfcrypt/src/sp_c64.c index 434db37d6..c49850909 100644 --- a/wolfcrypt/src/sp_c64.c +++ b/wolfcrypt/src/sp_c64.c @@ -3292,10 +3292,10 @@ static int sp_2048_to_mp(const sp_digit* a, mp_int* r) r->dp[0] = 0; for (i = 0; i < 36; i++) { - r->dp[j] |= a[i] << s; + r->dp[j] |= (mp_digit)(a[i] << s); r->dp[j] &= (1L << DIGIT_BIT) - 1; s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; + r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 57) { s += DIGIT_BIT; r->dp[j++] &= (1L << DIGIT_BIT) - 1; @@ -3303,7 +3303,7 @@ static int sp_2048_to_mp(const sp_digit* a, mp_int* r) r->dp[j] = 0; } else { - r->dp[j] = a[i] >> s; + r->dp[j] = (mp_digit)(a[i] >> s); } } s = 57 - s; @@ -7403,10 +7403,10 @@ static int sp_3072_to_mp(const sp_digit* a, mp_int* r) r->dp[0] = 0; for (i = 0; i < 54; i++) { - r->dp[j] |= a[i] << s; + r->dp[j] |= (mp_digit)(a[i] << s); r->dp[j] &= (1L << DIGIT_BIT) - 1; s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; + r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 57) { s += DIGIT_BIT; r->dp[j++] &= (1L << DIGIT_BIT) - 1; @@ -7414,7 +7414,7 @@ static int sp_3072_to_mp(const sp_digit* a, mp_int* r) r->dp[j] = 0; } else { - r->dp[j] = a[i] >> s; + r->dp[j] = (mp_digit)(a[i] >> s); } } s = 57 - s; @@ -11759,10 +11759,10 @@ static int sp_4096_to_mp(const sp_digit* a, mp_int* r) r->dp[0] = 0; for (i = 0; i < 78; i++) { - r->dp[j] |= a[i] << s; + r->dp[j] |= (mp_digit)(a[i] << s); r->dp[j] &= (1L << DIGIT_BIT) - 1; s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; + r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 53) { s += DIGIT_BIT; r->dp[j++] &= (1L << DIGIT_BIT) - 1; @@ -11770,7 +11770,7 @@ static int sp_4096_to_mp(const sp_digit* a, mp_int* r) r->dp[j] = 0; } else { - r->dp[j] = a[i] >> s; + r->dp[j] = (mp_digit)(a[i] >> s); } } s = 53 - s; @@ -12488,7 +12488,7 @@ static int sp_256_point_new_ex_5(void* heap, sp_point_256* sp, sp_point_256** p) #else *p = sp; #endif - if (*p == NULL) { + if (p == NULL) { ret = MEMORY_E; } return ret; @@ -12759,10 +12759,10 @@ static int sp_256_to_mp(const sp_digit* a, mp_int* r) r->dp[0] = 0; for (i = 0; i < 5; i++) { - r->dp[j] |= a[i] << s; + r->dp[j] |= (mp_digit)(a[i] << s); r->dp[j] &= (1L << DIGIT_BIT) - 1; s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; + r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 52) { s += DIGIT_BIT; r->dp[j++] &= (1L << DIGIT_BIT) - 1; @@ -12770,7 +12770,7 @@ static int sp_256_to_mp(const sp_digit* a, mp_int* r) r->dp[j] = 0; } else { - r->dp[j] = a[i] >> s; + r->dp[j] = (mp_digit)(a[i] >> s); } } s = 52 - s; @@ -17573,7 +17573,7 @@ static int sp_384_point_new_ex_7(void* heap, sp_point_384* sp, sp_point_384** p) #else *p = sp; #endif - if (*p == NULL) { + if (p == NULL) { ret = MEMORY_E; } return ret; @@ -17875,10 +17875,10 @@ static int sp_384_to_mp(const sp_digit* a, mp_int* r) r->dp[0] = 0; for (i = 0; i < 7; i++) { - r->dp[j] |= a[i] << s; + r->dp[j] |= (mp_digit)(a[i] << s); r->dp[j] &= (1L << DIGIT_BIT) - 1; s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; + r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 55) { s += DIGIT_BIT; r->dp[j++] &= (1L << DIGIT_BIT) - 1; @@ -17886,7 +17886,7 @@ static int sp_384_to_mp(const sp_digit* a, mp_int* r) r->dp[j] = 0; } else { - r->dp[j] = a[i] >> s; + r->dp[j] = (mp_digit)(a[i] >> s); } } s = 55 - s; diff --git a/wolfcrypt/src/sp_cortexm.c b/wolfcrypt/src/sp_cortexm.c index cda654e51..9dc77df90 100644 --- a/wolfcrypt/src/sp_cortexm.c +++ b/wolfcrypt/src/sp_cortexm.c @@ -4295,10 +4295,10 @@ static int sp_2048_to_mp(const sp_digit* a, mp_int* r) r->dp[0] = 0; for (i = 0; i < 64; i++) { - r->dp[j] |= a[i] << s; + r->dp[j] |= (mp_digit)(a[i] << s); r->dp[j] &= (1L << DIGIT_BIT) - 1; s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; + r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 32) { s += DIGIT_BIT; r->dp[j++] &= (1L << DIGIT_BIT) - 1; @@ -4306,7 +4306,7 @@ static int sp_2048_to_mp(const sp_digit* a, mp_int* r) r->dp[j] = 0; } else { - r->dp[j] = a[i] >> s; + r->dp[j] = (mp_digit)(a[i] >> s); } } s = 32 - s; @@ -8885,10 +8885,10 @@ static int sp_3072_to_mp(const sp_digit* a, mp_int* r) r->dp[0] = 0; for (i = 0; i < 96; i++) { - r->dp[j] |= a[i] << s; + r->dp[j] |= (mp_digit)(a[i] << s); r->dp[j] &= (1L << DIGIT_BIT) - 1; s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; + r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 32) { s += DIGIT_BIT; r->dp[j++] &= (1L << DIGIT_BIT) - 1; @@ -8896,7 +8896,7 @@ static int sp_3072_to_mp(const sp_digit* a, mp_int* r) r->dp[j] = 0; } else { - r->dp[j] = a[i] >> s; + r->dp[j] = (mp_digit)(a[i] >> s); } } s = 32 - s; @@ -12422,10 +12422,10 @@ static int sp_4096_to_mp(const sp_digit* a, mp_int* r) r->dp[0] = 0; for (i = 0; i < 128; i++) { - r->dp[j] |= a[i] << s; + r->dp[j] |= (mp_digit)(a[i] << s); r->dp[j] &= (1L << DIGIT_BIT) - 1; s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; + r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 32) { s += DIGIT_BIT; r->dp[j++] &= (1L << DIGIT_BIT) - 1; @@ -12433,7 +12433,7 @@ static int sp_4096_to_mp(const sp_digit* a, mp_int* r) r->dp[j] = 0; } else { - r->dp[j] = a[i] >> s; + r->dp[j] = (mp_digit)(a[i] >> s); } } s = 32 - s; @@ -13581,7 +13581,7 @@ static int sp_256_point_new_ex_8(void* heap, sp_point_256* sp, sp_point_256** p) #else *p = sp; #endif - if (*p == NULL) { + if (p == NULL) { ret = MEMORY_E; } return ret; @@ -13804,10 +13804,10 @@ static int sp_256_to_mp(const sp_digit* a, mp_int* r) r->dp[0] = 0; for (i = 0; i < 8; i++) { - r->dp[j] |= a[i] << s; + r->dp[j] |= (mp_digit)(a[i] << s); r->dp[j] &= (1L << DIGIT_BIT) - 1; s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; + r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 32) { s += DIGIT_BIT; r->dp[j++] &= (1L << DIGIT_BIT) - 1; @@ -13815,7 +13815,7 @@ static int sp_256_to_mp(const sp_digit* a, mp_int* r) r->dp[j] = 0; } else { - r->dp[j] = a[i] >> s; + r->dp[j] = (mp_digit)(a[i] >> s); } } s = 32 - s; @@ -20049,7 +20049,7 @@ static int sp_384_point_new_ex_12(void* heap, sp_point_384* sp, sp_point_384** p #else *p = sp; #endif - if (*p == NULL) { + if (p == NULL) { ret = MEMORY_E; } return ret; @@ -20303,10 +20303,10 @@ static int sp_384_to_mp(const sp_digit* a, mp_int* r) r->dp[0] = 0; for (i = 0; i < 12; i++) { - r->dp[j] |= a[i] << s; + r->dp[j] |= (mp_digit)(a[i] << s); r->dp[j] &= (1L << DIGIT_BIT) - 1; s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; + r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 32) { s += DIGIT_BIT; r->dp[j++] &= (1L << DIGIT_BIT) - 1; @@ -20314,7 +20314,7 @@ static int sp_384_to_mp(const sp_digit* a, mp_int* r) r->dp[j] = 0; } else { - r->dp[j] = a[i] >> s; + r->dp[j] = (mp_digit)(a[i] >> s); } } s = 32 - s; diff --git a/wolfcrypt/src/sp_x86_64.c b/wolfcrypt/src/sp_x86_64.c index 41d7191e8..4a965b921 100644 --- a/wolfcrypt/src/sp_x86_64.c +++ b/wolfcrypt/src/sp_x86_64.c @@ -1650,10 +1650,10 @@ static int sp_2048_to_mp(const sp_digit* a, mp_int* r) r->dp[0] = 0; for (i = 0; i < 32; i++) { - r->dp[j] |= a[i] << s; + r->dp[j] |= (mp_digit)(a[i] << s); r->dp[j] &= (1L << DIGIT_BIT) - 1; s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; + r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 64) { s += DIGIT_BIT; r->dp[j++] &= (1L << DIGIT_BIT) - 1; @@ -1661,7 +1661,7 @@ static int sp_2048_to_mp(const sp_digit* a, mp_int* r) r->dp[j] = 0; } else { - r->dp[j] = a[i] >> s; + r->dp[j] = (mp_digit)(a[i] >> s); } } s = 64 - s; @@ -3704,10 +3704,10 @@ static int sp_3072_to_mp(const sp_digit* a, mp_int* r) r->dp[0] = 0; for (i = 0; i < 48; i++) { - r->dp[j] |= a[i] << s; + r->dp[j] |= (mp_digit)(a[i] << s); r->dp[j] &= (1L << DIGIT_BIT) - 1; s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; + r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 64) { s += DIGIT_BIT; r->dp[j++] &= (1L << DIGIT_BIT) - 1; @@ -3715,7 +3715,7 @@ static int sp_3072_to_mp(const sp_digit* a, mp_int* r) r->dp[j] = 0; } else { - r->dp[j] = a[i] >> s; + r->dp[j] = (mp_digit)(a[i] >> s); } } s = 64 - s; @@ -5212,10 +5212,10 @@ static int sp_4096_to_mp(const sp_digit* a, mp_int* r) r->dp[0] = 0; for (i = 0; i < 64; i++) { - r->dp[j] |= a[i] << s; + r->dp[j] |= (mp_digit)(a[i] << s); r->dp[j] &= (1L << DIGIT_BIT) - 1; s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; + r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 64) { s += DIGIT_BIT; r->dp[j++] &= (1L << DIGIT_BIT) - 1; @@ -5223,7 +5223,7 @@ static int sp_4096_to_mp(const sp_digit* a, mp_int* r) r->dp[j] = 0; } else { - r->dp[j] = a[i] >> s; + r->dp[j] = (mp_digit)(a[i] >> s); } } s = 64 - s; @@ -5693,7 +5693,7 @@ static int sp_256_point_new_ex_4(void* heap, sp_point_256* sp, sp_point_256** p) #else *p = sp; #endif - if (*p == NULL) { + if (p == NULL) { ret = MEMORY_E; } return ret; @@ -5912,10 +5912,10 @@ static int sp_256_to_mp(const sp_digit* a, mp_int* r) r->dp[0] = 0; for (i = 0; i < 4; i++) { - r->dp[j] |= a[i] << s; + r->dp[j] |= (mp_digit)(a[i] << s); r->dp[j] &= (1L << DIGIT_BIT) - 1; s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; + r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 64) { s += DIGIT_BIT; r->dp[j++] &= (1L << DIGIT_BIT) - 1; @@ -5923,7 +5923,7 @@ static int sp_256_to_mp(const sp_digit* a, mp_int* r) r->dp[j] = 0; } else { - r->dp[j] = a[i] >> s; + r->dp[j] = (mp_digit)(a[i] >> s); } } s = 64 - s; @@ -23543,7 +23543,7 @@ static int sp_384_point_new_ex_6(void* heap, sp_point_384* sp, sp_point_384** p) #else *p = sp; #endif - if (*p == NULL) { + if (p == NULL) { ret = MEMORY_E; } return ret; @@ -23815,10 +23815,10 @@ static int sp_384_to_mp(const sp_digit* a, mp_int* r) r->dp[0] = 0; for (i = 0; i < 6; i++) { - r->dp[j] |= a[i] << s; + r->dp[j] |= (mp_digit)(a[i] << s); r->dp[j] &= (1L << DIGIT_BIT) - 1; s = DIGIT_BIT - s; - r->dp[++j] = a[i] >> s; + r->dp[++j] = (mp_digit)(a[i] >> s); while (s + DIGIT_BIT <= 64) { s += DIGIT_BIT; r->dp[j++] &= (1L << DIGIT_BIT) - 1; @@ -23826,7 +23826,7 @@ static int sp_384_to_mp(const sp_digit* a, mp_int* r) r->dp[j] = 0; } else { - r->dp[j] = a[i] >> s; + r->dp[j] = (mp_digit)(a[i] >> s); } } s = 64 - s; From c95e7f88aac43b279ebe2eb6b070dfbce4daf578 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Tue, 24 Mar 2020 16:28:14 +1000 Subject: [PATCH 214/649] Curve448 - 128-bit impl workaround for compiler Old gcc compilers can keep track of the 128-bit multiplication and left shift results' size. Split all multiplication and left shift results into separate variables. Add/subtract into the correct variable at end. Don't want variable declarations after statements so reduce doesn't use 'tr' anymore. --- wolfcrypt/src/fe_448.c | 732 ++++++++++++++++++++++------------------- 1 file changed, 398 insertions(+), 334 deletions(-) diff --git a/wolfcrypt/src/fe_448.c b/wolfcrypt/src/fe_448.c index a75f73cdb..bc38c112f 100644 --- a/wolfcrypt/src/fe_448.c +++ b/wolfcrypt/src/fe_448.c @@ -575,6 +575,7 @@ void fe448_from_bytes(int64_t* r, const unsigned char* b) */ void fe448_to_bytes(unsigned char* b, const int64_t* a) { + int128_t t; /* Mod */ int64_t in0 = a[0]; int64_t in1 = a[1]; @@ -599,15 +600,15 @@ void fe448_to_bytes(unsigned char* b, const int64_t* a) in0 += o; in4 += o; in7 -= o << 56; - o = in0 >> 56; in1 += o; in0 -= o << 56; - o = in1 >> 56; in2 += o; in1 -= o << 56; - o = in2 >> 56; in3 += o; in2 -= o << 56; - o = in3 >> 56; in4 += o; in3 -= o << 56; - o = in4 >> 56; in5 += o; in4 -= o << 56; - o = in5 >> 56; in6 += o; in5 -= o << 56; - o = in6 >> 56; in7 += o; in6 -= o << 56; + o = in0 >> 56; in1 += o; t = o << 56; in0 -= t; + o = in1 >> 56; in2 += o; t = o << 56; in1 -= t; + o = in2 >> 56; in3 += o; t = o << 56; in2 -= t; + o = in3 >> 56; in4 += o; t = o << 56; in3 -= t; + o = in4 >> 56; in5 += o; t = o << 56; in4 -= t; + o = in5 >> 56; in6 += o; t = o << 56; in5 -= t; + o = in6 >> 56; in7 += o; t = o << 56; in6 -= t; o = in7 >> 56; in0 += o; - in4 += o; in7 -= o << 56; + in4 += o; t = o << 56; in7 -= t; /* Output as bytes */ b[ 0] = (in0 >> 0); @@ -796,6 +797,7 @@ void fe448_sub(int64_t* r, const int64_t* a, const int64_t* b) */ void fe448_mul39081(int64_t* r, const int64_t* a) { + int128_t t; int64_t o; int128_t t0 = a[0] * (int128_t)39081; int128_t t1 = a[1] * (int128_t)39081; @@ -805,15 +807,15 @@ void fe448_mul39081(int64_t* r, const int64_t* a) int128_t t5 = a[5] * (int128_t)39081; int128_t t6 = a[6] * (int128_t)39081; int128_t t7 = a[7] * (int128_t)39081; - o = t0 >> 56; t1 += o; t0 -= (int128_t)o << 56; - o = t1 >> 56; t2 += o; t1 -= (int128_t)o << 56; - o = t2 >> 56; t3 += o; t2 -= (int128_t)o << 56; - o = t3 >> 56; t4 += o; t3 -= (int128_t)o << 56; - o = t4 >> 56; t5 += o; t4 -= (int128_t)o << 56; - o = t5 >> 56; t6 += o; t5 -= (int128_t)o << 56; - o = t6 >> 56; t7 += o; t6 -= (int128_t)o << 56; + o = t0 >> 56; t1 += o; t = (int128_t)o << 56; t0 -= t; + o = t1 >> 56; t2 += o; t = (int128_t)o << 56; t1 -= t; + o = t2 >> 56; t3 += o; t = (int128_t)o << 56; t2 -= t; + o = t3 >> 56; t4 += o; t = (int128_t)o << 56; t3 -= t; + o = t4 >> 56; t5 += o; t = (int128_t)o << 56; t4 -= t; + o = t5 >> 56; t6 += o; t = (int128_t)o << 56; t5 -= t; + o = t6 >> 56; t7 += o; t = (int128_t)o << 56; t6 -= t; o = t7 >> 56; t0 += o; - t4 += o; t7 -= (int128_t)o << 56; + t4 += o; t = (int128_t)o << 56; t7 -= t; /* Store */ r[0] = t0; @@ -834,102 +836,120 @@ void fe448_mul39081(int64_t* r, const int64_t* a) */ void fe448_mul(int64_t* r, const int64_t* a, const int64_t* b) { + int128_t t; int64_t o; - 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[ 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 t9 = (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 t10 = (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 t11 = (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 t12 = (int128_t)a[ 5] * b[ 7] - + (int128_t)a[ 6] * b[ 6] - + (int128_t)a[ 7] * b[ 5]; - int128_t t13 = (int128_t)a[ 6] * b[ 7] - + (int128_t)a[ 7] * b[ 6]; - int128_t t14 = (int128_t)a[ 7] * b[ 7]; + int128_t t0 = (int128_t)a[ 0] * b[ 0]; + int128_t t1 = (int128_t)a[ 0] * b[ 1]; + int128_t t101 = (int128_t)a[ 1] * b[ 0]; + int128_t t2 = (int128_t)a[ 0] * b[ 2]; + int128_t t102 = (int128_t)a[ 1] * b[ 1]; + int128_t t202 = (int128_t)a[ 2] * b[ 0]; + int128_t t3 = (int128_t)a[ 0] * b[ 3]; + int128_t t103 = (int128_t)a[ 1] * b[ 2]; + int128_t t203 = (int128_t)a[ 2] * b[ 1]; + int128_t t303 = (int128_t)a[ 3] * b[ 0]; + int128_t t4 = (int128_t)a[ 0] * b[ 4]; + int128_t t104 = (int128_t)a[ 1] * b[ 3]; + int128_t t204 = (int128_t)a[ 2] * b[ 2]; + int128_t t304 = (int128_t)a[ 3] * b[ 1]; + int128_t t404 = (int128_t)a[ 4] * b[ 0]; + int128_t t5 = (int128_t)a[ 0] * b[ 5]; + int128_t t105 = (int128_t)a[ 1] * b[ 4]; + int128_t t205 = (int128_t)a[ 2] * b[ 3]; + int128_t t305 = (int128_t)a[ 3] * b[ 2]; + int128_t t405 = (int128_t)a[ 4] * b[ 1]; + int128_t t505 = (int128_t)a[ 5] * b[ 0]; + int128_t t6 = (int128_t)a[ 0] * b[ 6]; + int128_t t106 = (int128_t)a[ 1] * b[ 5]; + int128_t t206 = (int128_t)a[ 2] * b[ 4]; + int128_t t306 = (int128_t)a[ 3] * b[ 3]; + int128_t t406 = (int128_t)a[ 4] * b[ 2]; + int128_t t506 = (int128_t)a[ 5] * b[ 1]; + int128_t t606 = (int128_t)a[ 6] * b[ 0]; + int128_t t7 = (int128_t)a[ 0] * b[ 7]; + int128_t t107 = (int128_t)a[ 1] * b[ 6]; + int128_t t207 = (int128_t)a[ 2] * b[ 5]; + int128_t t307 = (int128_t)a[ 3] * b[ 4]; + int128_t t407 = (int128_t)a[ 4] * b[ 3]; + int128_t t507 = (int128_t)a[ 5] * b[ 2]; + int128_t t607 = (int128_t)a[ 6] * b[ 1]; + int128_t t707 = (int128_t)a[ 7] * b[ 0]; + int128_t t8 = (int128_t)a[ 1] * b[ 7]; + int128_t t108 = (int128_t)a[ 2] * b[ 6]; + int128_t t208 = (int128_t)a[ 3] * b[ 5]; + int128_t t308 = (int128_t)a[ 4] * b[ 4]; + int128_t t408 = (int128_t)a[ 5] * b[ 3]; + int128_t t508 = (int128_t)a[ 6] * b[ 2]; + int128_t t608 = (int128_t)a[ 7] * b[ 1]; + int128_t t9 = (int128_t)a[ 2] * b[ 7]; + int128_t t109 = (int128_t)a[ 3] * b[ 6]; + int128_t t209 = (int128_t)a[ 4] * b[ 5]; + int128_t t309 = (int128_t)a[ 5] * b[ 4]; + int128_t t409 = (int128_t)a[ 6] * b[ 3]; + int128_t t509 = (int128_t)a[ 7] * b[ 2]; + int128_t t10 = (int128_t)a[ 3] * b[ 7]; + int128_t t110 = (int128_t)a[ 4] * b[ 6]; + int128_t t210 = (int128_t)a[ 5] * b[ 5]; + int128_t t310 = (int128_t)a[ 6] * b[ 4]; + int128_t t410 = (int128_t)a[ 7] * b[ 3]; + int128_t t11 = (int128_t)a[ 4] * b[ 7]; + int128_t t111 = (int128_t)a[ 5] * b[ 6]; + int128_t t211 = (int128_t)a[ 6] * b[ 5]; + int128_t t311 = (int128_t)a[ 7] * b[ 4]; + int128_t t12 = (int128_t)a[ 5] * b[ 7]; + int128_t t112 = (int128_t)a[ 6] * b[ 6]; + int128_t t212 = (int128_t)a[ 7] * b[ 5]; + int128_t t13 = (int128_t)a[ 6] * b[ 7]; + int128_t t113 = (int128_t)a[ 7] * b[ 6]; + int128_t t14 = (int128_t)a[ 7] * b[ 7]; + t1 += t101; + t2 += t102; t2 += t202; + t3 += t103; t3 += t203; t3 += t303; + t4 += t104; t4 += t204; t4 += t304; t4 += t404; + t5 += t105; t5 += t205; t5 += t305; t5 += t405; t5 += t505; + t6 += t106; t6 += t206; t6 += t306; t6 += t406; t6 += t506; + t6 += t606; + t7 += t107; t7 += t207; t7 += t307; t7 += t407; t7 += t507; + t7 += t607; + t7 += t707; + t8 += t108; t8 += t208; t8 += t308; t8 += t408; t8 += t508; + t8 += t608; + t9 += t109; t9 += t209; t9 += t309; t9 += t409; t9 += t509; + t10 += t110; t10 += t210; t10 += t310; t10 += t410; + t11 += t111; t11 += t211; t11 += t311; + t12 += t112; t12 += t212; + t13 += t113; /* Reduce */ - int128_t tr0 = t0 + t8 + t12; - int128_t tr1 = t1 + t9 + t13; - int128_t tr2 = t2 + t10 + t14; - int128_t tr3 = t3 + t11; - int128_t tr4 = t4 + t12 + t8 + t12; - int128_t tr5 = t5 + t13 + t9 + t13; - int128_t tr6 = t6 + t14 + t10 + t14; - int128_t tr7 = t7 + t11; - o = tr7 >> 56; tr0 += o; - tr4 += o; tr7 -= (int128_t)o << 56; - o = tr0 >> 56; tr1 += o; tr0 -= (int128_t)o << 56; - o = tr1 >> 56; tr2 += o; tr1 -= (int128_t)o << 56; - o = tr2 >> 56; tr3 += o; tr2 -= (int128_t)o << 56; - o = tr3 >> 56; tr4 += o; tr3 -= (int128_t)o << 56; - o = tr4 >> 56; tr5 += o; tr4 -= (int128_t)o << 56; - o = tr5 >> 56; tr6 += o; tr5 -= (int128_t)o << 56; - o = tr6 >> 56; tr7 += o; tr6 -= (int128_t)o << 56; - o = tr7 >> 56; tr0 += o; - tr4 += o; tr7 -= (int128_t)o << 56; + t0 += t8 + t12; + t1 += t9 + t13; + t2 += t10 + t14; + t3 += t11; + t4 += t12 + t8 + t12; + t5 += t13 + t9 + t13; + t6 += t14 + t10 + t14; + t7 += t11; + o = t7 >> 56; t0 += o; + t4 += o; t = (int128_t)o << 56; t7 -= t; + o = t0 >> 56; t1 += o; t = (int128_t)o << 56; t0 -= t; + o = t1 >> 56; t2 += o; t = (int128_t)o << 56; t1 -= t; + o = t2 >> 56; t3 += o; t = (int128_t)o << 56; t2 -= t; + o = t3 >> 56; t4 += o; t = (int128_t)o << 56; t3 -= t; + o = t4 >> 56; t5 += o; t = (int128_t)o << 56; t4 -= t; + o = t5 >> 56; t6 += o; t = (int128_t)o << 56; t5 -= t; + o = t6 >> 56; t7 += o; t = (int128_t)o << 56; t6 -= t; + o = t7 >> 56; t0 += o; + t4 += o; t = (int128_t)o << 56; t7 -= t; /* Store */ - r[0] = tr0; - r[1] = tr1; - r[2] = tr2; - r[3] = tr3; - r[4] = tr4; - r[5] = tr5; - r[6] = tr6; - r[7] = tr7; + r[0] = t0; + r[1] = t1; + r[2] = t2; + r[3] = t3; + r[4] = t4; + r[5] = t5; + r[6] = t6; + r[7] = t7; } /* Square a field element. r = (a * a) mod (2^448 - 2^224 - 1) @@ -939,74 +959,86 @@ void fe448_mul(int64_t* r, const int64_t* a, const int64_t* b) */ void fe448_sqr(int64_t* r, const int64_t* a) { + int128_t t; int64_t o; - int128_t t0 = (int128_t)a[ 0] * a[ 0]; - int128_t t1 = 2 * (int128_t)a[ 0] * a[ 1]; - int128_t t2 = 2 * (int128_t)a[ 0] * a[ 2] - + (int128_t)a[ 1] * a[ 1]; - int128_t t3 = 2 * (int128_t)a[ 0] * a[ 3] - + 2 * (int128_t)a[ 1] * a[ 2]; - int128_t t4 = 2 * (int128_t)a[ 0] * a[ 4] - + 2 * (int128_t)a[ 1] * a[ 3] - + (int128_t)a[ 2] * a[ 2]; - int128_t t5 = 2 * (int128_t)a[ 0] * a[ 5] - + 2 * (int128_t)a[ 1] * a[ 4] - + 2 * (int128_t)a[ 2] * a[ 3]; - int128_t t6 = 2 * (int128_t)a[ 0] * a[ 6] - + 2 * (int128_t)a[ 1] * a[ 5] - + 2 * (int128_t)a[ 2] * a[ 4] - + (int128_t)a[ 3] * a[ 3]; - int128_t t7 = 2 * (int128_t)a[ 0] * a[ 7] - + 2 * (int128_t)a[ 1] * a[ 6] - + 2 * (int128_t)a[ 2] * a[ 5] - + 2 * (int128_t)a[ 3] * a[ 4]; - int128_t t8 = 2 * (int128_t)a[ 1] * a[ 7] - + 2 * (int128_t)a[ 2] * a[ 6] - + 2 * (int128_t)a[ 3] * a[ 5] - + (int128_t)a[ 4] * a[ 4]; - int128_t t9 = 2 * (int128_t)a[ 2] * a[ 7] - + 2 * (int128_t)a[ 3] * a[ 6] - + 2 * (int128_t)a[ 4] * a[ 5]; - int128_t t10 = 2 * (int128_t)a[ 3] * a[ 7] - + 2 * (int128_t)a[ 4] * a[ 6] - + (int128_t)a[ 5] * a[ 5]; - int128_t t11 = 2 * (int128_t)a[ 4] * a[ 7] - + 2 * (int128_t)a[ 5] * a[ 6]; - int128_t t12 = 2 * (int128_t)a[ 5] * a[ 7] - + (int128_t)a[ 6] * a[ 6]; - int128_t t13 = 2 * (int128_t)a[ 6] * a[ 7]; - int128_t t14 = (int128_t)a[ 7] * a[ 7]; + int128_t t0 = (int128_t)a[ 0] * a[ 0]; + int128_t t1 = 2 * (int128_t)a[ 0] * a[ 1]; + int128_t t2 = 2 * (int128_t)a[ 0] * a[ 2]; + int128_t t102 = (int128_t)a[ 1] * a[ 1]; + int128_t t3 = 2 * (int128_t)a[ 0] * a[ 3]; + int128_t t103 = 2 * (int128_t)a[ 1] * a[ 2]; + int128_t t4 = 2 * (int128_t)a[ 0] * a[ 4]; + int128_t t104 = 2 * (int128_t)a[ 1] * a[ 3]; + int128_t t204 = (int128_t)a[ 2] * a[ 2]; + int128_t t5 = 2 * (int128_t)a[ 0] * a[ 5]; + int128_t t105 = 2 * (int128_t)a[ 1] * a[ 4]; + int128_t t205 = 2 * (int128_t)a[ 2] * a[ 3]; + int128_t t6 = 2 * (int128_t)a[ 0] * a[ 6]; + int128_t t106 = 2 * (int128_t)a[ 1] * a[ 5]; + int128_t t206 = 2 * (int128_t)a[ 2] * a[ 4]; + int128_t t306 = (int128_t)a[ 3] * a[ 3]; + int128_t t7 = 2 * (int128_t)a[ 0] * a[ 7]; + int128_t t107 = 2 * (int128_t)a[ 1] * a[ 6]; + int128_t t207 = 2 * (int128_t)a[ 2] * a[ 5]; + int128_t t307 = 2 * (int128_t)a[ 3] * a[ 4]; + int128_t t8 = 2 * (int128_t)a[ 1] * a[ 7]; + int128_t t108 = 2 * (int128_t)a[ 2] * a[ 6]; + int128_t t208 = 2 * (int128_t)a[ 3] * a[ 5]; + int128_t t308 = (int128_t)a[ 4] * a[ 4]; + int128_t t9 = 2 * (int128_t)a[ 2] * a[ 7]; + int128_t t109 = 2 * (int128_t)a[ 3] * a[ 6]; + int128_t t209 = 2 * (int128_t)a[ 4] * a[ 5]; + int128_t t10 = 2 * (int128_t)a[ 3] * a[ 7]; + int128_t t110 = 2 * (int128_t)a[ 4] * a[ 6]; + int128_t t210 = (int128_t)a[ 5] * a[ 5]; + int128_t t11 = 2 * (int128_t)a[ 4] * a[ 7]; + int128_t t111 = 2 * (int128_t)a[ 5] * a[ 6]; + int128_t t12 = 2 * (int128_t)a[ 5] * a[ 7]; + int128_t t112 = (int128_t)a[ 6] * a[ 6]; + int128_t t13 = 2 * (int128_t)a[ 6] * a[ 7]; + int128_t t14 = (int128_t)a[ 7] * a[ 7]; + t2 += t102; + t3 += t103; + t4 += t104; t4 += t204; + t5 += t105; t5 += t205; + t6 += t106; t6 += t206; t6 += t306; + t7 += t107; t7 += t207; t7 += t307; + t8 += t108; t8 += t208; t8 += t308; + t9 += t109; t9 += t209; + t10 += t110; t10 += t210; + t11 += t111; + t12 += t112; /* Reduce */ - int128_t tr0 = t0 + t8 + t12; - int128_t tr1 = t1 + t9 + t13; - int128_t tr2 = t2 + t10 + t14; - int128_t tr3 = t3 + t11; - int128_t tr4 = t4 + t12 + t8 + t12; - int128_t tr5 = t5 + t13 + t9 + t13; - int128_t tr6 = t6 + t14 + t10 + t14; - int128_t tr7 = t7 + t11; - o = tr7 >> 56; tr0 += o; - tr4 += o; tr7 -= (int128_t)o << 56; - o = tr0 >> 56; tr1 += o; tr0 -= (int128_t)o << 56; - o = tr1 >> 56; tr2 += o; tr1 -= (int128_t)o << 56; - o = tr2 >> 56; tr3 += o; tr2 -= (int128_t)o << 56; - o = tr3 >> 56; tr4 += o; tr3 -= (int128_t)o << 56; - o = tr4 >> 56; tr5 += o; tr4 -= (int128_t)o << 56; - o = tr5 >> 56; tr6 += o; tr5 -= (int128_t)o << 56; - o = tr6 >> 56; tr7 += o; tr6 -= (int128_t)o << 56; - o = tr7 >> 56; tr0 += o; - tr4 += o; tr7 -= (int128_t)o << 56; + t0 += t8 + t12; + t1 += t9 + t13; + t2 += t10 + t14; + t3 += t11; + t4 += t12 + t8 + t12; + t5 += t13 + t9 + t13; + t6 += t14 + t10 + t14; + t7 += t11; + o = t7 >> 56; t0 += o; + t4 += o; t = (int128_t)o << 56; t7 -= t; + o = t0 >> 56; t1 += o; t = (int128_t)o << 56; t0 -= t; + o = t1 >> 56; t2 += o; t = (int128_t)o << 56; t1 -= t; + o = t2 >> 56; t3 += o; t = (int128_t)o << 56; t2 -= t; + o = t3 >> 56; t4 += o; t = (int128_t)o << 56; t3 -= t; + o = t4 >> 56; t5 += o; t = (int128_t)o << 56; t4 -= t; + o = t5 >> 56; t6 += o; t = (int128_t)o << 56; t5 -= t; + o = t6 >> 56; t7 += o; t = (int128_t)o << 56; t6 -= t; + o = t7 >> 56; t0 += o; + t4 += o; t = (int128_t)o << 56; t7 -= t; /* Store */ - r[0] = tr0; - r[1] = tr1; - r[2] = tr2; - r[3] = tr3; - r[4] = tr4; - r[5] = tr5; - r[6] = tr6; - r[7] = tr7; + r[0] = t0; + r[1] = t1; + r[2] = t2; + r[3] = t3; + r[4] = t4; + r[5] = t5; + r[6] = t6; + r[7] = t7; } /* Invert the field element. (r * a) mod (2^448 - 2^224 - 1) = 1 @@ -1396,6 +1428,7 @@ void fe448_from_bytes(int32_t* r, const unsigned char* b) */ void fe448_to_bytes(unsigned char* b, const int32_t* a) { + int64_t t; /* Mod */ int32_t in0 = a[0]; int32_t in1 = a[1]; @@ -1436,23 +1469,23 @@ void fe448_to_bytes(unsigned char* b, const int32_t* a) in0 += o; in8 += o; in15 -= o << 28; - o = in0 >> 28; in1 += o; in0 -= o << 28; - o = in1 >> 28; in2 += o; in1 -= o << 28; - o = in2 >> 28; in3 += o; in2 -= o << 28; - o = in3 >> 28; in4 += o; in3 -= o << 28; - o = in4 >> 28; in5 += o; in4 -= o << 28; - o = in5 >> 28; in6 += o; in5 -= o << 28; - o = in6 >> 28; in7 += o; in6 -= o << 28; - o = in7 >> 28; in8 += o; in7 -= o << 28; - o = in8 >> 28; in9 += o; in8 -= o << 28; - o = in9 >> 28; in10 += o; in9 -= o << 28; - o = in10 >> 28; in11 += o; in10 -= o << 28; - o = in11 >> 28; in12 += o; in11 -= o << 28; - o = in12 >> 28; in13 += o; in12 -= o << 28; - o = in13 >> 28; in14 += o; in13 -= o << 28; - o = in14 >> 28; in15 += o; in14 -= o << 28; + o = in0 >> 28; in1 += o; t = o << 28; in0 -= t; + o = in1 >> 28; in2 += o; t = o << 28; in1 -= t; + o = in2 >> 28; in3 += o; t = o << 28; in2 -= t; + o = in3 >> 28; in4 += o; t = o << 28; in3 -= t; + o = in4 >> 28; in5 += o; t = o << 28; in4 -= t; + o = in5 >> 28; in6 += o; t = o << 28; in5 -= t; + o = in6 >> 28; in7 += o; t = o << 28; in6 -= t; + o = in7 >> 28; in8 += o; t = o << 28; in7 -= t; + o = in8 >> 28; in9 += o; t = o << 28; in8 -= t; + o = in9 >> 28; in10 += o; t = o << 28; in9 -= t; + o = in10 >> 28; in11 += o; t = o << 28; in10 -= t; + o = in11 >> 28; in12 += o; t = o << 28; in11 -= t; + o = in12 >> 28; in13 += o; t = o << 28; in12 -= t; + o = in13 >> 28; in14 += o; t = o << 28; in13 -= t; + o = in14 >> 28; in15 += o; t = o << 28; in14 -= t; o = in15 >> 28; in0 += o; - in8 += o; in15 -= o << 28; + in8 += o; t = o << 28; in15 -= t; /* Output as bytes */ b[ 0] = (in0 >> 0); @@ -1727,6 +1760,7 @@ void fe448_reduce(int32_t* a) */ void fe448_mul39081(int32_t* r, const int32_t* a) { + int64_t t; int32_t o; int64_t t0 = a[0] * (int64_t)39081; int64_t t1 = a[1] * (int64_t)39081; @@ -1744,23 +1778,23 @@ void fe448_mul39081(int32_t* r, const int32_t* a) int64_t t13 = a[13] * (int64_t)39081; int64_t t14 = a[14] * (int64_t)39081; int64_t t15 = a[15] * (int64_t)39081; - o = t0 >> 28; t1 += o; t0 -= (int64_t)o << 28; - o = t1 >> 28; t2 += o; t1 -= (int64_t)o << 28; - o = t2 >> 28; t3 += o; t2 -= (int64_t)o << 28; - o = t3 >> 28; t4 += o; t3 -= (int64_t)o << 28; - o = t4 >> 28; t5 += o; t4 -= (int64_t)o << 28; - o = t5 >> 28; t6 += o; t5 -= (int64_t)o << 28; - o = t6 >> 28; t7 += o; t6 -= (int64_t)o << 28; - o = t7 >> 28; t8 += o; t7 -= (int64_t)o << 28; - o = t8 >> 28; t9 += o; t8 -= (int64_t)o << 28; - o = t9 >> 28; t10 += o; t9 -= (int64_t)o << 28; - o = t10 >> 28; t11 += o; t10 -= (int64_t)o << 28; - o = t11 >> 28; t12 += o; t11 -= (int64_t)o << 28; - o = t12 >> 28; t13 += o; t12 -= (int64_t)o << 28; - o = t13 >> 28; t14 += o; t13 -= (int64_t)o << 28; - o = t14 >> 28; t15 += o; t14 -= (int64_t)o << 28; + o = t0 >> 28; t1 += o; t = (int64_t)o << 28; t0 -= t; + o = t1 >> 28; t2 += o; t = (int64_t)o << 28; t1 -= t; + o = t2 >> 28; t3 += o; t = (int64_t)o << 28; t2 -= t; + o = t3 >> 28; t4 += o; t = (int64_t)o << 28; t3 -= t; + o = t4 >> 28; t5 += o; t = (int64_t)o << 28; t4 -= t; + o = t5 >> 28; t6 += o; t = (int64_t)o << 28; t5 -= t; + o = t6 >> 28; t7 += o; t = (int64_t)o << 28; t6 -= t; + o = t7 >> 28; t8 += o; t = (int64_t)o << 28; t7 -= t; + o = t8 >> 28; t9 += o; t = (int64_t)o << 28; t8 -= t; + o = t9 >> 28; t10 += o; t = (int64_t)o << 28; t9 -= t; + o = t10 >> 28; t11 += o; t = (int64_t)o << 28; t10 -= t; + o = t11 >> 28; t12 += o; t = (int64_t)o << 28; t11 -= t; + o = t12 >> 28; t13 += o; t = (int64_t)o << 28; t12 -= t; + o = t13 >> 28; t14 += o; t = (int64_t)o << 28; t13 -= t; + o = t14 >> 28; t15 += o; t = (int64_t)o << 28; t14 -= t; o = t15 >> 28; t0 += o; - t8 += o; t15 -= (int64_t)o << 28; + t8 += o; t = (int64_t)o << 28; t15 -= t; /* Store */ r[0] = t0; @@ -1789,90 +1823,108 @@ void fe448_mul39081(int32_t* r, const int32_t* a) */ static WC_INLINE void fe448_mul_8(int32_t* r, const int32_t* a, const int32_t* 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[ 0] * b[ 7] - + (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)a[ 7] * b[ 0]; - int64_t t8 = (int64_t)a[ 1] * b[ 7] - + (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)a[ 7] * b[ 1]; - int64_t t9 = (int64_t)a[ 2] * b[ 7] - + (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)a[ 7] * b[ 2]; - int64_t t10 = (int64_t)a[ 3] * b[ 7] - + (int64_t)a[ 4] * b[ 6] - + (int64_t)a[ 5] * b[ 5] - + (int64_t)a[ 6] * b[ 4] - + (int64_t)a[ 7] * b[ 3]; - int64_t t11 = (int64_t)a[ 4] * b[ 7] - + (int64_t)a[ 5] * b[ 6] - + (int64_t)a[ 6] * b[ 5] - + (int64_t)a[ 7] * b[ 4]; - int64_t t12 = (int64_t)a[ 5] * b[ 7] - + (int64_t)a[ 6] * b[ 6] - + (int64_t)a[ 7] * b[ 5]; - int64_t t13 = (int64_t)a[ 6] * b[ 7] - + (int64_t)a[ 7] * b[ 6]; - int64_t t14 = (int64_t)a[ 7] * b[ 7]; + int64_t t; + int64_t t0 = (int64_t)a[ 0] * b[ 0]; + int64_t t1 = (int64_t)a[ 0] * b[ 1]; + int64_t t101 = (int64_t)a[ 1] * b[ 0]; + int64_t t2 = (int64_t)a[ 0] * b[ 2]; + int64_t t102 = (int64_t)a[ 1] * b[ 1]; + int64_t t202 = (int64_t)a[ 2] * b[ 0]; + int64_t t3 = (int64_t)a[ 0] * b[ 3]; + int64_t t103 = (int64_t)a[ 1] * b[ 2]; + int64_t t203 = (int64_t)a[ 2] * b[ 1]; + int64_t t303 = (int64_t)a[ 3] * b[ 0]; + int64_t t4 = (int64_t)a[ 0] * b[ 4]; + int64_t t104 = (int64_t)a[ 1] * b[ 3]; + int64_t t204 = (int64_t)a[ 2] * b[ 2]; + int64_t t304 = (int64_t)a[ 3] * b[ 1]; + int64_t t404 = (int64_t)a[ 4] * b[ 0]; + int64_t t5 = (int64_t)a[ 0] * b[ 5]; + int64_t t105 = (int64_t)a[ 1] * b[ 4]; + int64_t t205 = (int64_t)a[ 2] * b[ 3]; + int64_t t305 = (int64_t)a[ 3] * b[ 2]; + int64_t t405 = (int64_t)a[ 4] * b[ 1]; + int64_t t505 = (int64_t)a[ 5] * b[ 0]; + int64_t t6 = (int64_t)a[ 0] * b[ 6]; + int64_t t106 = (int64_t)a[ 1] * b[ 5]; + int64_t t206 = (int64_t)a[ 2] * b[ 4]; + int64_t t306 = (int64_t)a[ 3] * b[ 3]; + int64_t t406 = (int64_t)a[ 4] * b[ 2]; + int64_t t506 = (int64_t)a[ 5] * b[ 1]; + int64_t t606 = (int64_t)a[ 6] * b[ 0]; + int64_t t7 = (int64_t)a[ 0] * b[ 7]; + int64_t t107 = (int64_t)a[ 1] * b[ 6]; + int64_t t207 = (int64_t)a[ 2] * b[ 5]; + int64_t t307 = (int64_t)a[ 3] * b[ 4]; + int64_t t407 = (int64_t)a[ 4] * b[ 3]; + int64_t t507 = (int64_t)a[ 5] * b[ 2]; + int64_t t607 = (int64_t)a[ 6] * b[ 1]; + int64_t t707 = (int64_t)a[ 7] * b[ 0]; + int64_t t8 = (int64_t)a[ 1] * b[ 7]; + int64_t t108 = (int64_t)a[ 2] * b[ 6]; + int64_t t208 = (int64_t)a[ 3] * b[ 5]; + int64_t t308 = (int64_t)a[ 4] * b[ 4]; + int64_t t408 = (int64_t)a[ 5] * b[ 3]; + int64_t t508 = (int64_t)a[ 6] * b[ 2]; + int64_t t608 = (int64_t)a[ 7] * b[ 1]; + int64_t t9 = (int64_t)a[ 2] * b[ 7]; + int64_t t109 = (int64_t)a[ 3] * b[ 6]; + int64_t t209 = (int64_t)a[ 4] * b[ 5]; + int64_t t309 = (int64_t)a[ 5] * b[ 4]; + int64_t t409 = (int64_t)a[ 6] * b[ 3]; + int64_t t509 = (int64_t)a[ 7] * b[ 2]; + int64_t t10 = (int64_t)a[ 3] * b[ 7]; + int64_t t110 = (int64_t)a[ 4] * b[ 6]; + int64_t t210 = (int64_t)a[ 5] * b[ 5]; + int64_t t310 = (int64_t)a[ 6] * b[ 4]; + int64_t t410 = (int64_t)a[ 7] * b[ 3]; + int64_t t11 = (int64_t)a[ 4] * b[ 7]; + int64_t t111 = (int64_t)a[ 5] * b[ 6]; + int64_t t211 = (int64_t)a[ 6] * b[ 5]; + int64_t t311 = (int64_t)a[ 7] * b[ 4]; + int64_t t12 = (int64_t)a[ 5] * b[ 7]; + int64_t t112 = (int64_t)a[ 6] * b[ 6]; + int64_t t212 = (int64_t)a[ 7] * b[ 5]; + int64_t t13 = (int64_t)a[ 6] * b[ 7]; + int64_t t113 = (int64_t)a[ 7] * b[ 6]; + int64_t t14 = (int64_t)a[ 7] * b[ 7]; + t1 += t101; + t2 += t102; t2 += t202; + t3 += t103; t3 += t203; t3 += t303; + t4 += t104; t4 += t204; t4 += t304; t4 += t404; + t5 += t105; t5 += t205; t5 += t305; t5 += t405; t5 += t505; + t6 += t106; t6 += t206; t6 += t306; t6 += t406; t6 += t506; + t6 += t606; + t7 += t107; t7 += t207; t7 += t307; t7 += t407; t7 += t507; + t7 += t607; + t7 += t707; + t8 += t108; t8 += t208; t8 += t308; t8 += t408; t8 += t508; + t8 += t608; + t9 += t109; t9 += t209; t9 += t309; t9 += t409; t9 += t509; + t10 += t110; t10 += t210; t10 += t310; t10 += t410; + t11 += t111; t11 += t211; t11 += t311; + t12 += t112; t12 += t212; + t13 += t113; int64_t o = t14 >> 28; int64_t t15 = o; t14 -= o << 28; - o = t0 >> 28; t1 += o; t0 -= (int64_t)o << 28; - o = t1 >> 28; t2 += o; t1 -= (int64_t)o << 28; - o = t2 >> 28; t3 += o; t2 -= (int64_t)o << 28; - o = t3 >> 28; t4 += o; t3 -= (int64_t)o << 28; - o = t4 >> 28; t5 += o; t4 -= (int64_t)o << 28; - o = t5 >> 28; t6 += o; t5 -= (int64_t)o << 28; - o = t6 >> 28; t7 += o; t6 -= (int64_t)o << 28; - o = t7 >> 28; t8 += o; t7 -= (int64_t)o << 28; - o = t8 >> 28; t9 += o; t8 -= (int64_t)o << 28; - o = t9 >> 28; t10 += o; t9 -= (int64_t)o << 28; - o = t10 >> 28; t11 += o; t10 -= (int64_t)o << 28; - o = t11 >> 28; t12 += o; t11 -= (int64_t)o << 28; - o = t12 >> 28; t13 += o; t12 -= (int64_t)o << 28; - o = t13 >> 28; t14 += o; t13 -= (int64_t)o << 28; - o = t14 >> 28; t15 += o; t14 -= (int64_t)o << 28; + o = t0 >> 28; t1 += o; t = (int64_t)o << 28; t0 -= t; + o = t1 >> 28; t2 += o; t = (int64_t)o << 28; t1 -= t; + o = t2 >> 28; t3 += o; t = (int64_t)o << 28; t2 -= t; + o = t3 >> 28; t4 += o; t = (int64_t)o << 28; t3 -= t; + o = t4 >> 28; t5 += o; t = (int64_t)o << 28; t4 -= t; + o = t5 >> 28; t6 += o; t = (int64_t)o << 28; t5 -= t; + o = t6 >> 28; t7 += o; t = (int64_t)o << 28; t6 -= t; + o = t7 >> 28; t8 += o; t = (int64_t)o << 28; t7 -= t; + o = t8 >> 28; t9 += o; t = (int64_t)o << 28; t8 -= t; + o = t9 >> 28; t10 += o; t = (int64_t)o << 28; t9 -= t; + o = t10 >> 28; t11 += o; t = (int64_t)o << 28; t10 -= t; + o = t11 >> 28; t12 += o; t = (int64_t)o << 28; t11 -= t; + o = t12 >> 28; t13 += o; t = (int64_t)o << 28; t12 -= t; + o = t13 >> 28; t14 += o; t = (int64_t)o << 28; t13 -= t; + o = t14 >> 28; t15 += o; t = (int64_t)o << 28; t14 -= t; o = t15 >> 28; t0 += o; - t8 += o; t15 -= (int64_t)o << 28; + t8 += o; t = (int64_t)o << 28; t15 -= t; /* Store */ r[0] = t0; @@ -1950,62 +2002,74 @@ void fe448_mul(int32_t* r, const int32_t* a, const int32_t* b) */ static WC_INLINE void fe448_sqr_8(int32_t* r, const int32_t* a) { - int64_t t0 = (int64_t)a[ 0] * a[ 0]; - int64_t t1 = 2 * (int64_t)a[ 0] * a[ 1]; - int64_t t2 = 2 * (int64_t)a[ 0] * a[ 2] - + (int64_t)a[ 1] * a[ 1]; - int64_t t3 = 2 * (int64_t)a[ 0] * a[ 3] - + 2 * (int64_t)a[ 1] * a[ 2]; - int64_t t4 = 2 * (int64_t)a[ 0] * a[ 4] - + 2 * (int64_t)a[ 1] * a[ 3] - + (int64_t)a[ 2] * a[ 2]; - int64_t t5 = 2 * (int64_t)a[ 0] * a[ 5] - + 2 * (int64_t)a[ 1] * a[ 4] - + 2 * (int64_t)a[ 2] * a[ 3]; - int64_t t6 = 2 * (int64_t)a[ 0] * a[ 6] - + 2 * (int64_t)a[ 1] * a[ 5] - + 2 * (int64_t)a[ 2] * a[ 4] - + (int64_t)a[ 3] * a[ 3]; - int64_t t7 = 2 * (int64_t)a[ 0] * a[ 7] - + 2 * (int64_t)a[ 1] * a[ 6] - + 2 * (int64_t)a[ 2] * a[ 5] - + 2 * (int64_t)a[ 3] * a[ 4]; - int64_t t8 = 2 * (int64_t)a[ 1] * a[ 7] - + 2 * (int64_t)a[ 2] * a[ 6] - + 2 * (int64_t)a[ 3] * a[ 5] - + (int64_t)a[ 4] * a[ 4]; - int64_t t9 = 2 * (int64_t)a[ 2] * a[ 7] - + 2 * (int64_t)a[ 3] * a[ 6] - + 2 * (int64_t)a[ 4] * a[ 5]; - int64_t t10 = 2 * (int64_t)a[ 3] * a[ 7] - + 2 * (int64_t)a[ 4] * a[ 6] - + (int64_t)a[ 5] * a[ 5]; - int64_t t11 = 2 * (int64_t)a[ 4] * a[ 7] - + 2 * (int64_t)a[ 5] * a[ 6]; - int64_t t12 = 2 * (int64_t)a[ 5] * a[ 7] - + (int64_t)a[ 6] * a[ 6]; - int64_t t13 = 2 * (int64_t)a[ 6] * a[ 7]; - int64_t t14 = (int64_t)a[ 7] * a[ 7]; + int64_t t; + int64_t t0 = (int64_t)a[ 0] * a[ 0]; + int64_t t1 = 2 * (int64_t)a[ 0] * a[ 1]; + int64_t t2 = 2 * (int64_t)a[ 0] * a[ 2]; + int64_t t102 = (int64_t)a[ 1] * a[ 1]; + int64_t t3 = 2 * (int64_t)a[ 0] * a[ 3]; + int64_t t103 = 2 * (int64_t)a[ 1] * a[ 2]; + int64_t t4 = 2 * (int64_t)a[ 0] * a[ 4]; + int64_t t104 = 2 * (int64_t)a[ 1] * a[ 3]; + int64_t t204 = (int64_t)a[ 2] * a[ 2]; + int64_t t5 = 2 * (int64_t)a[ 0] * a[ 5]; + int64_t t105 = 2 * (int64_t)a[ 1] * a[ 4]; + int64_t t205 = 2 * (int64_t)a[ 2] * a[ 3]; + int64_t t6 = 2 * (int64_t)a[ 0] * a[ 6]; + int64_t t106 = 2 * (int64_t)a[ 1] * a[ 5]; + int64_t t206 = 2 * (int64_t)a[ 2] * a[ 4]; + int64_t t306 = (int64_t)a[ 3] * a[ 3]; + int64_t t7 = 2 * (int64_t)a[ 0] * a[ 7]; + int64_t t107 = 2 * (int64_t)a[ 1] * a[ 6]; + int64_t t207 = 2 * (int64_t)a[ 2] * a[ 5]; + int64_t t307 = 2 * (int64_t)a[ 3] * a[ 4]; + int64_t t8 = 2 * (int64_t)a[ 1] * a[ 7]; + int64_t t108 = 2 * (int64_t)a[ 2] * a[ 6]; + int64_t t208 = 2 * (int64_t)a[ 3] * a[ 5]; + int64_t t308 = (int64_t)a[ 4] * a[ 4]; + int64_t t9 = 2 * (int64_t)a[ 2] * a[ 7]; + int64_t t109 = 2 * (int64_t)a[ 3] * a[ 6]; + int64_t t209 = 2 * (int64_t)a[ 4] * a[ 5]; + int64_t t10 = 2 * (int64_t)a[ 3] * a[ 7]; + int64_t t110 = 2 * (int64_t)a[ 4] * a[ 6]; + int64_t t210 = (int64_t)a[ 5] * a[ 5]; + int64_t t11 = 2 * (int64_t)a[ 4] * a[ 7]; + int64_t t111 = 2 * (int64_t)a[ 5] * a[ 6]; + int64_t t12 = 2 * (int64_t)a[ 5] * a[ 7]; + int64_t t112 = (int64_t)a[ 6] * a[ 6]; + int64_t t13 = 2 * (int64_t)a[ 6] * a[ 7]; + int64_t t14 = (int64_t)a[ 7] * a[ 7]; + t2 += t102; + t3 += t103; + t4 += t104; t4 += t204; + t5 += t105; t5 += t205; + t6 += t106; t6 += t206; t6 += t306; + t7 += t107; t7 += t207; t7 += t307; + t8 += t108; t8 += t208; t8 += t308; + t9 += t109; t9 += t209; + t10 += t110; t10 += t210; + t11 += t111; + t12 += t112; int64_t o = t14 >> 28; int64_t t15 = o; t14 -= o << 28; - o = t0 >> 28; t1 += o; t0 -= (int64_t)o << 28; - o = t1 >> 28; t2 += o; t1 -= (int64_t)o << 28; - o = t2 >> 28; t3 += o; t2 -= (int64_t)o << 28; - o = t3 >> 28; t4 += o; t3 -= (int64_t)o << 28; - o = t4 >> 28; t5 += o; t4 -= (int64_t)o << 28; - o = t5 >> 28; t6 += o; t5 -= (int64_t)o << 28; - o = t6 >> 28; t7 += o; t6 -= (int64_t)o << 28; - o = t7 >> 28; t8 += o; t7 -= (int64_t)o << 28; - o = t8 >> 28; t9 += o; t8 -= (int64_t)o << 28; - o = t9 >> 28; t10 += o; t9 -= (int64_t)o << 28; - o = t10 >> 28; t11 += o; t10 -= (int64_t)o << 28; - o = t11 >> 28; t12 += o; t11 -= (int64_t)o << 28; - o = t12 >> 28; t13 += o; t12 -= (int64_t)o << 28; - o = t13 >> 28; t14 += o; t13 -= (int64_t)o << 28; - o = t14 >> 28; t15 += o; t14 -= (int64_t)o << 28; + o = t0 >> 28; t1 += o; t = (int64_t)o << 28; t0 -= t; + o = t1 >> 28; t2 += o; t = (int64_t)o << 28; t1 -= t; + o = t2 >> 28; t3 += o; t = (int64_t)o << 28; t2 -= t; + o = t3 >> 28; t4 += o; t = (int64_t)o << 28; t3 -= t; + o = t4 >> 28; t5 += o; t = (int64_t)o << 28; t4 -= t; + o = t5 >> 28; t6 += o; t = (int64_t)o << 28; t5 -= t; + o = t6 >> 28; t7 += o; t = (int64_t)o << 28; t6 -= t; + o = t7 >> 28; t8 += o; t = (int64_t)o << 28; t7 -= t; + o = t8 >> 28; t9 += o; t = (int64_t)o << 28; t8 -= t; + o = t9 >> 28; t10 += o; t = (int64_t)o << 28; t9 -= t; + o = t10 >> 28; t11 += o; t = (int64_t)o << 28; t10 -= t; + o = t11 >> 28; t12 += o; t = (int64_t)o << 28; t11 -= t; + o = t12 >> 28; t13 += o; t = (int64_t)o << 28; t12 -= t; + o = t13 >> 28; t14 += o; t = (int64_t)o << 28; t13 -= t; + o = t14 >> 28; t15 += o; t = (int64_t)o << 28; t14 -= t; o = t15 >> 28; t0 += o; - t8 += o; t15 -= (int64_t)o << 28; + t8 += o; t = (int64_t)o << 28; t15 -= t; /* Store */ r[0] = t0; From 75eca61b3e46981d3d5bc98854bec9914b8351b8 Mon Sep 17 00:00:00 2001 From: Hideki Miyazaki Date: Tue, 24 Mar 2020 20:35:21 +0900 Subject: [PATCH 215/649] address review comments --- examples/benchmark/tls_bench.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/examples/benchmark/tls_bench.c b/examples/benchmark/tls_bench.c index 7c7200e15..31f1022a2 100644 --- a/examples/benchmark/tls_bench.c +++ b/examples/benchmark/tls_bench.c @@ -107,9 +107,11 @@ bench_tls(args); #ifdef WOLFSSL_DTLS #ifdef BENCH_EMBEDDED - #define TEST_DTLS_PACKET_SIZE (2 * 1024 - 100) + /* less than WOLFSSL_MAX_MTU */ + #define TEST_DTLS_PACKET_SIZE (2 * 1024) #else - #define TEST_DTLS_PACKET_SIZE (8192 - 100) + /* MAX_UDP_SIZE in interna.h */ + #define TEST_DTLS_PACKET_SIZE (8092) #endif #endif @@ -317,7 +319,10 @@ typedef struct { /* Global vars for argument parsing */ int myoptind = 0; char* myoptarg = NULL; + +#ifdef WOLFSSL_DTLS int DoneHandShake = 0; +#endif static double gettime_secs(int reset) { @@ -681,8 +686,9 @@ static void CloseAndCleanupSocket(int* sockFd) close(*sockFd); *sockFd = -1; } - +#ifdef WOLFSSL_DTLS DoneHandShake = 0; +#endif } #ifdef BENCH_USE_NONBLOCK From 9fac21f46363646684d4fb50856de0ec45891962 Mon Sep 17 00:00:00 2001 From: Hideki Miyazaki Date: Wed, 25 Mar 2020 08:09:42 +0900 Subject: [PATCH 216/649] replace the size at bench_embedded --- examples/benchmark/tls_bench.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/benchmark/tls_bench.c b/examples/benchmark/tls_bench.c index 31f1022a2..4c71ac270 100644 --- a/examples/benchmark/tls_bench.c +++ b/examples/benchmark/tls_bench.c @@ -107,8 +107,8 @@ bench_tls(args); #ifdef WOLFSSL_DTLS #ifdef BENCH_EMBEDDED - /* less than WOLFSSL_MAX_MTU */ - #define TEST_DTLS_PACKET_SIZE (2 * 1024) + /* WOLFSSL_MAX_MTU in internal.h */ + #define TEST_DTLS_PACKET_SIZE (1500) #else /* MAX_UDP_SIZE in interna.h */ #define TEST_DTLS_PACKET_SIZE (8092) From 59ab600d7694b84f727bbd80d168e9bb4c60bfee Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Tue, 24 Mar 2020 22:23:44 -0600 Subject: [PATCH 217/649] refactor decrypt content with PKCS12 and fix for AES-256 + HMAC SHA256 case --- wolfcrypt/src/asn.c | 260 ++++++++++++-------------------------------- 1 file changed, 68 insertions(+), 192 deletions(-) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 079f337e4..62ca85ea7 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -3756,11 +3756,18 @@ int TraditionalEnc(byte* key, word32 keySz, byte* out, word32* outSz, #endif /* HAVE_PKCS8 */ #if defined(HAVE_PKCS8) || defined(HAVE_PKCS12) - -/* Remove Encrypted PKCS8 header, move beginning of traditional to beginning - of input */ -int ToTraditionalEnc(byte* input, word32 sz,const char* password, - int passwordSz, word32* algId) +/* decrypt PKCS + * + * NOTE: input buffer is overwritten with decrypted data! + * + * input[in/out] data to decrypt and results are written to + * sz size of input buffer + * password password if used. Can be NULL for no password + * passwordSz size of password buffer + * + * returns the total size of decrypted content on success. + */ +int DecryptContent(byte* input, word32 sz, const char* password, int passwordSz) { word32 inOutIdx = 0, seqEnd, oid, shaOid = 0; int ret = 0, first, second, length = 0, version, saltSz, id; @@ -3772,43 +3779,40 @@ int ToTraditionalEnc(byte* input, word32 sz,const char* password, byte salt[MAX_SALT_SIZE]; byte cbcIv[MAX_IV_SIZE]; #endif + byte tag; if (passwordSz < 0) { WOLFSSL_MSG("Bad password size"); return BAD_FUNC_ARG; } - if (GetSequence(input, &inOutIdx, &length, sz) < 0) { - ERROR_OUT(ASN_PARSE_E, exit_tte); - } - if (GetAlgoId(input, &inOutIdx, &oid, oidIgnoreType, sz) < 0) { - ERROR_OUT(ASN_PARSE_E, exit_tte); + ERROR_OUT(ASN_PARSE_E, exit_dc); } first = input[inOutIdx - 2]; /* PKCS version always 2nd to last byte */ second = input[inOutIdx - 1]; /* version.algo, algo id last byte */ if (CheckAlgo(first, second, &id, &version, NULL) < 0) { - ERROR_OUT(ASN_INPUT_E, exit_tte); /* Algo ID error */ + ERROR_OUT(ASN_INPUT_E, exit_dc); /* Algo ID error */ } if (version == PKCS5v2) { if (GetSequence(input, &inOutIdx, &length, sz) < 0) { - ERROR_OUT(ASN_PARSE_E, exit_tte); + ERROR_OUT(ASN_PARSE_E, exit_dc); } if (GetAlgoId(input, &inOutIdx, &oid, oidKdfType, sz) < 0) { - ERROR_OUT(ASN_PARSE_E, exit_tte); + ERROR_OUT(ASN_PARSE_E, exit_dc); } if (oid != PBKDF2_OID) { - ERROR_OUT(ASN_PARSE_E, exit_tte); + ERROR_OUT(ASN_PARSE_E, exit_dc); } } if (GetSequence(input, &inOutIdx, &length, sz) <= 0) { - ERROR_OUT(ASN_PARSE_E, exit_tte); + ERROR_OUT(ASN_PARSE_E, exit_dc); } /* Find the end of this SEQUENCE so we can check for the OPTIONAL and * DEFAULT items. */ @@ -3816,16 +3820,16 @@ int ToTraditionalEnc(byte* input, word32 sz,const char* password, ret = GetOctetString(input, &inOutIdx, &saltSz, sz); if (ret < 0) - goto exit_tte; + goto exit_dc; if (saltSz > MAX_SALT_SIZE) { - ERROR_OUT(ASN_PARSE_E, exit_tte); + ERROR_OUT(ASN_PARSE_E, exit_dc); } #ifdef WOLFSSL_SMALL_STACK salt = (byte*)XMALLOC(MAX_SALT_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (salt == NULL) { - ERROR_OUT(MEMORY_E, exit_tte); + ERROR_OUT(MEMORY_E, exit_dc); } #endif @@ -3833,28 +3837,27 @@ int ToTraditionalEnc(byte* input, word32 sz,const char* password, inOutIdx += saltSz; if (GetShortInt(input, &inOutIdx, &iterations, sz) < 0) { - ERROR_OUT(ASN_PARSE_E, exit_tte); + ERROR_OUT(ASN_PARSE_E, exit_dc); } /* OPTIONAL key length */ if (seqEnd > inOutIdx) { word32 localIdx = inOutIdx; - byte tag; if (GetASNTag(input, &localIdx, &tag, sz) < 0) { - ERROR_OUT(ASN_PARSE_E, exit_tte); + ERROR_OUT(ASN_PARSE_E, exit_dc); } if (tag == ASN_INTEGER && GetShortInt(input, &inOutIdx, &keySz, sz) < 0) { - ERROR_OUT(ASN_PARSE_E, exit_tte); + ERROR_OUT(ASN_PARSE_E, exit_dc); } } /* DEFAULT HMAC is SHA-1 */ if (seqEnd > inOutIdx) { if (GetAlgoId(input, &inOutIdx, &oid, oidHmacType, sz) < 0) { - ERROR_OUT(ASN_PARSE_E, exit_tte); + ERROR_OUT(ASN_PARSE_E, exit_dc); } shaOid = oid; @@ -3863,18 +3866,18 @@ int ToTraditionalEnc(byte* input, word32 sz,const char* password, #ifdef WOLFSSL_SMALL_STACK cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); if (cbcIv == NULL) { - ERROR_OUT(MEMORY_E, exit_tte); + ERROR_OUT(MEMORY_E, exit_dc); } #endif if (version == PKCS5v2) { /* get encryption algo */ if (GetAlgoId(input, &inOutIdx, &oid, oidBlkType, sz) < 0) { - ERROR_OUT(ASN_PARSE_E, exit_tte); + ERROR_OUT(ASN_PARSE_E, exit_dc); } if (CheckAlgoV2(oid, &id, NULL) < 0) { - ERROR_OUT(ASN_PARSE_E, exit_tte); /* PKCS v2 algo id error */ + ERROR_OUT(ASN_PARSE_E, exit_dc); /* PKCS v2 algo id error */ } if (shaOid == 0) @@ -3882,24 +3885,32 @@ int ToTraditionalEnc(byte* input, word32 sz,const char* password, ret = GetOctetString(input, &inOutIdx, &length, sz); if (ret < 0) - goto exit_tte; + goto exit_dc; if (length > MAX_IV_SIZE) { - ERROR_OUT(ASN_PARSE_E, exit_tte); + ERROR_OUT(ASN_PARSE_E, exit_dc); } XMEMCPY(cbcIv, &input[inOutIdx], length); inOutIdx += length; } - ret = GetOctetString(input, &inOutIdx, &length, sz); - if (ret < 0) - goto exit_tte; + if (GetASNTag(input, &inOutIdx, &tag, sz) < 0) { + ERROR_OUT(ASN_PARSE_E, exit_dc); + } + + if (tag != (ASN_CONTEXT_SPECIFIC | 0) && tag != ASN_OCTET_STRING) { + ERROR_OUT(ASN_PARSE_E, exit_dc); + } + + if (GetLength(input, &inOutIdx, &length, sz) < 0) { + ERROR_OUT(ASN_PARSE_E, exit_dc); + } ret = wc_CryptKey(password, passwordSz, salt, saltSz, iterations, id, input + inOutIdx, length, version, cbcIv, 0, shaOid); -exit_tte: +exit_dc: #ifdef WOLFSSL_SMALL_STACK XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER); XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER); @@ -3907,7 +3918,31 @@ exit_tte: if (ret == 0) { XMEMMOVE(input, input + inOutIdx, length); - ret = ToTraditional_ex(input, length, algId); + ret = length; + } + + return ret; +} + + +/* Remove Encrypted PKCS8 header, move beginning of traditional to beginning + of input */ +int ToTraditionalEnc(byte* input, word32 sz,const char* password, + int passwordSz, word32* algId) +{ + int ret, length; + word32 inOutIdx = 0; + + if (GetSequence(input, &inOutIdx, &length, sz) < 0) { + ret = ASN_PARSE_E; + } + else { + ret = DecryptContent(input + inOutIdx, sz - inOutIdx, password, + passwordSz); + if (ret > 0) { + XMEMMOVE(input, input + inOutIdx, ret); + ret = ToTraditional_ex(input, ret, algId); + } } return ret; @@ -4124,165 +4159,6 @@ int EncryptContent(byte* input, word32 inputSz, byte* out, word32* outSz, } -/* decrypt PKCS - * - * NOTE: input buffer is overwritten with decrypted data! - * - * input[in/out] data to decrypt and results are written to - * sz size of input buffer - * password password if used. Can be NULL for no password - * passwordSz size of password buffer - * - * returns the total size of decrypted content on success. - */ -int DecryptContent(byte* input, word32 sz,const char* password, int passwordSz) -{ - word32 inOutIdx = 0, seqEnd, oid; - int ret = 0; - int first, second, length = 0, version, saltSz, id; - int iterations = 0, keySz = 0; -#ifdef WOLFSSL_SMALL_STACK - byte* salt = NULL; - byte* cbcIv = NULL; -#else - byte salt[MAX_SALT_SIZE]; - byte cbcIv[MAX_IV_SIZE]; -#endif - byte tag; - - if (GetAlgoId(input, &inOutIdx, &oid, oidIgnoreType, sz) < 0) { - ERROR_OUT(ASN_PARSE_E, exit_dc); - } - - first = input[inOutIdx - 2]; /* PKCS version always 2nd to last byte */ - second = input[inOutIdx - 1]; /* version.algo, algo id last byte */ - - if (CheckAlgo(first, second, &id, &version, NULL) < 0) { - ERROR_OUT(ASN_INPUT_E, exit_dc); /* Algo ID error */ - } - - if (version == PKCS5v2) { - if (GetSequence(input, &inOutIdx, &length, sz) < 0) { - ERROR_OUT(ASN_PARSE_E, exit_dc); - } - - if (GetAlgoId(input, &inOutIdx, &oid, oidKdfType, sz) < 0) { - ERROR_OUT(ASN_PARSE_E, exit_dc); - } - - if (oid != PBKDF2_OID) { - ERROR_OUT(ASN_PARSE_E, exit_dc); - } - } - - if (GetSequence(input, &inOutIdx, &length, sz) <= 0) { - ERROR_OUT(ASN_PARSE_E, exit_dc); - } - /* Find the end of this SEQUENCE so we can check for the OPTIONAL and - * DEFAULT items. */ - seqEnd = inOutIdx + length; - - ret = GetOctetString(input, &inOutIdx, &saltSz, sz); - if (ret < 0) - goto exit_dc; - - if (saltSz > MAX_SALT_SIZE) { - ERROR_OUT(ASN_PARSE_E, exit_dc); - } - -#ifdef WOLFSSL_SMALL_STACK - salt = (byte*)XMALLOC(MAX_SALT_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (salt == NULL) { - ERROR_OUT(MEMORY_E, exit_dc); - } -#endif - - XMEMCPY(salt, &input[inOutIdx], saltSz); - inOutIdx += saltSz; - - if (GetShortInt(input, &inOutIdx, &iterations, sz) < 0) { - ERROR_OUT(ASN_PARSE_E, exit_dc); - } - - /* OPTIONAL key length */ - if (seqEnd > inOutIdx) { - word32 localIdx = inOutIdx; - - if (GetASNTag(input, &localIdx, &tag, sz) < 0) { - ERROR_OUT(ASN_PARSE_E, exit_dc); - } - - if (tag == ASN_INTEGER && - GetShortInt(input, &inOutIdx, &keySz, sz) < 0) { - ERROR_OUT(ASN_PARSE_E, exit_dc); - } - } - - /* DEFAULT HMAC is SHA-1 */ - if (seqEnd > inOutIdx) { - if (GetAlgoId(input, &inOutIdx, &oid, oidHmacType, sz) < 0) { - ERROR_OUT(ASN_PARSE_E, exit_dc); - } - } - -#ifdef WOLFSSL_SMALL_STACK - cbcIv = (byte*)XMALLOC(MAX_IV_SIZE, NULL, DYNAMIC_TYPE_TMP_BUFFER); - if (cbcIv == NULL) { - ERROR_OUT(MEMORY_E, exit_dc); - } -#endif - - if (version == PKCS5v2) { - /* get encryption algo */ - if (GetAlgoId(input, &inOutIdx, &oid, oidBlkType, sz) < 0) { - ERROR_OUT(ASN_PARSE_E, exit_dc); - } - - if (CheckAlgoV2(oid, &id, NULL) < 0) { - ERROR_OUT(ASN_PARSE_E, exit_dc); /* PKCS v2 algo id error */ - } - - ret = GetOctetString(input, &inOutIdx, &length, sz); - if (ret < 0) - goto exit_dc; - - if (length > MAX_IV_SIZE) { - ERROR_OUT(ASN_PARSE_E, exit_dc); - } - - XMEMCPY(cbcIv, &input[inOutIdx], length); - inOutIdx += length; - } - - if (GetASNTag(input, &inOutIdx, &tag, sz) < 0) { - ERROR_OUT(ASN_PARSE_E, exit_dc); - } - - if (tag != (ASN_CONTEXT_SPECIFIC | 0)) { - ERROR_OUT(ASN_PARSE_E, exit_dc); - } - - if (GetLength(input, &inOutIdx, &length, sz) < 0) { - ERROR_OUT(ASN_PARSE_E, exit_dc); - } - - ret = wc_CryptKey(password, passwordSz, salt, saltSz, iterations, id, - input + inOutIdx, length, version, cbcIv, 0, 0); - -exit_dc: - -#ifdef WOLFSSL_SMALL_STACK - XFREE(salt, NULL, DYNAMIC_TYPE_TMP_BUFFER); - XFREE(cbcIv, NULL, DYNAMIC_TYPE_TMP_BUFFER); -#endif - - if (ret == 0) { - XMEMMOVE(input, input + inOutIdx, length); - ret = length; - } - - return ret; -} #endif /* HAVE_PKCS12 */ #endif /* NO_PWDBASED */ From 0a6b93fda22dd83f80f4d3aafaf951951040a12a Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Tue, 24 Mar 2020 22:40:48 -0600 Subject: [PATCH 218/649] add single quotes around -? in test scripts --- scripts/ocsp-stapling.test | 6 +++--- scripts/ocsp-stapling2.test | 2 +- scripts/psk.test | 4 ++-- scripts/resume.test | 8 ++++---- scripts/tls13.test | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/scripts/ocsp-stapling.test b/scripts/ocsp-stapling.test index 3651624fa..778c7151e 100755 --- a/scripts/ocsp-stapling.test +++ b/scripts/ocsp-stapling.test @@ -161,13 +161,13 @@ server=login.live.com ca=certs/external/baltimore-cybertrust-root.pem [ ! -x ./examples/client/client ] && echo -e "\n\nClient doesn't exist" && exit 1 -./examples/client/client -? 2>&1 | grep -- 'Client not compiled in!' +./examples/client/client '-?' 2>&1 | grep -- 'Client not compiled in!' if [ $? -eq 0 ]; then exit 0 fi # check if supported key size is large enough to handle 4096 bit RSA -size=`./examples/client/client -? | grep "Max RSA key"` +size=`./examples/client/client '-?' | grep "Max RSA key"` size=`echo ${size//[^0-9]/}` if [ ! -z "$size" ]; then printf 'check on max key size of %d ...' $size @@ -231,7 +231,7 @@ RESULT=$? # Test with example server -./examples/server/server -? 2>&1 | grep -- 'Server not compiled in!' +./examples/server/server '-?' 2>&1 | grep -- 'Server not compiled in!' if [ $? -eq 0 ]; then exit 0 fi diff --git a/scripts/ocsp-stapling2.test b/scripts/ocsp-stapling2.test index b1c64f65e..f162365ab 100755 --- a/scripts/ocsp-stapling2.test +++ b/scripts/ocsp-stapling2.test @@ -177,7 +177,7 @@ trap cleanup EXIT INT TERM HUP [ ! -x ./examples/client/client ] && echo -e "\n\nClient doesn't exist" && exit 1 # check if supported key size is large enough to handle 4096 bit RSA -size=`./examples/client/client -? | grep "Max RSA key"` +size=`./examples/client/client '-?' | grep "Max RSA key"` size=`echo ${size//[^0-9]/}` if [ ! -z "$size" ]; then printf 'check on max key size of %d ...' $size diff --git a/scripts/psk.test b/scripts/psk.test index 6693956cd..d11ac59b5 100755 --- a/scripts/psk.test +++ b/scripts/psk.test @@ -62,11 +62,11 @@ do_trap() { trap do_trap INT TERM [ ! -x ./examples/client/client ] && echo -e "\n\nClient doesn't exist" && exit 1 -./examples/client/client -? 2>&1 | grep -- 'Client not compiled in!' +./examples/client/client '-?' 2>&1 | grep -- 'Client not compiled in!' if [ $? -eq 0 ]; then exit 0 fi -./examples/server/server -? 2>&1 | grep -- 'Server not compiled in!' +./examples/server/server '-?' 2>&1 | grep -- 'Server not compiled in!' if [ $? -eq 0 ]; then exit 0 fi diff --git a/scripts/resume.test b/scripts/resume.test index cbae7ebbb..35d05e1f2 100755 --- a/scripts/resume.test +++ b/scripts/resume.test @@ -49,7 +49,7 @@ do_test() { #make sure we support session resumption (!NO_SESSION_CACHE) # Check the client for the extended master secret disable option. If # present we need to run the test twice. - options_check=`./examples/client/client -?` + options_check=`./examples/client/client '-?'` case "$options_check" in *$resume_sup_string*) echo -e "\nResume test supported";; @@ -111,15 +111,15 @@ do_test() { trap do_trap INT TERM -./examples/client/client -? 2>&1 | grep -- 'Client not compiled in!' +./examples/client/client '-?' 2>&1 | grep -- 'Client not compiled in!' if [ $? -ne 0 ]; then - ./examples/server/server -? 2>&1 | grep -- 'Server not compiled in!' + ./examples/server/server '-?' 2>&1 | grep -- 'Server not compiled in!' if [ $? -ne 0 ]; then RUN_TEST="Y" fi fi -./examples/client/client -? 2>&1 | grep -- 'Resume session' +./examples/client/client '-?' 2>&1 | grep -- 'Resume session' if [ $? -ne 0 ]; then RUN_TEST="Y" fi diff --git a/scripts/tls13.test b/scripts/tls13.test index 7beb9a56b..df67a3963 100755 --- a/scripts/tls13.test +++ b/scripts/tls13.test @@ -70,11 +70,11 @@ do_trap() { trap do_trap INT TERM [ ! -x ./examples/client/client ] && echo -e "\n\nClient doesn't exist" && exit 1 -./examples/client/client -? 2>&1 | grep -- 'Client not compiled in!' +./examples/client/client '-?' 2>&1 | grep -- 'Client not compiled in!' if [ $? -eq 0 ]; then exit 0 fi -./examples/server/server -? 2>&1 | grep -- 'Server not compiled in!' +./examples/server/server '-?' 2>&1 | grep -- 'Server not compiled in!' if [ $? -eq 0 ]; then exit 0 fi From 469de9a580906c046cb378c69b8612ef4bed1142 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 25 Mar 2020 08:57:58 -0700 Subject: [PATCH 219/649] Fix for CSharp solution to eliminate Debug/Release. Only DLL Debug and DLL Release should be available. --- wrapper/CSharp/wolfSSL_CSharp.sln | 122 ------------------------------ 1 file changed, 122 deletions(-) diff --git a/wrapper/CSharp/wolfSSL_CSharp.sln b/wrapper/CSharp/wolfSSL_CSharp.sln index a90e05bd2..ac7f4b9e7 100755 --- a/wrapper/CSharp/wolfSSL_CSharp.sln +++ b/wrapper/CSharp/wolfSSL_CSharp.sln @@ -31,26 +31,14 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "wolfSSL-TLS-ServerThreaded" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 DLL Debug|Any CPU = DLL Debug|Any CPU DLL Debug|Win32 = DLL Debug|Win32 DLL Debug|x64 = DLL Debug|x64 DLL Release|Any CPU = DLL Release|Any CPU DLL Release|Win32 = DLL Release|Win32 DLL Release|x64 = DLL Release|x64 - Release|Any CPU = Release|Any CPU - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {52609808-0418-46D3-8E17-141927A1A39A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {52609808-0418-46D3-8E17-141927A1A39A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {52609808-0418-46D3-8E17-141927A1A39A}.Debug|Win32.ActiveCfg = Debug|Any CPU - {52609808-0418-46D3-8E17-141927A1A39A}.Debug|Win32.Build.0 = Debug|Any CPU - {52609808-0418-46D3-8E17-141927A1A39A}.Debug|x64.ActiveCfg = Debug|x64 - {52609808-0418-46D3-8E17-141927A1A39A}.Debug|x64.Build.0 = Debug|x64 {52609808-0418-46D3-8E17-141927A1A39A}.DLL Debug|Any CPU.ActiveCfg = Debug|Any CPU {52609808-0418-46D3-8E17-141927A1A39A}.DLL Debug|Any CPU.Build.0 = Debug|Any CPU {52609808-0418-46D3-8E17-141927A1A39A}.DLL Debug|Win32.ActiveCfg = Debug|Any CPU @@ -63,18 +51,6 @@ Global {52609808-0418-46D3-8E17-141927A1A39A}.DLL Release|Win32.Build.0 = Release|Any CPU {52609808-0418-46D3-8E17-141927A1A39A}.DLL Release|x64.ActiveCfg = Release|x64 {52609808-0418-46D3-8E17-141927A1A39A}.DLL Release|x64.Build.0 = Release|x64 - {52609808-0418-46D3-8E17-141927A1A39A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {52609808-0418-46D3-8E17-141927A1A39A}.Release|Any CPU.Build.0 = Release|Any CPU - {52609808-0418-46D3-8E17-141927A1A39A}.Release|Win32.ActiveCfg = Release|Any CPU - {52609808-0418-46D3-8E17-141927A1A39A}.Release|Win32.Build.0 = Release|Any CPU - {52609808-0418-46D3-8E17-141927A1A39A}.Release|x64.ActiveCfg = Release|x64 - {52609808-0418-46D3-8E17-141927A1A39A}.Release|x64.Build.0 = Release|x64 - {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.Debug|Win32.ActiveCfg = Debug|Any CPU - {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.Debug|Win32.Build.0 = Debug|Any CPU - {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.Debug|x64.ActiveCfg = Debug|x64 - {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.Debug|x64.Build.0 = Debug|x64 {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.DLL Debug|Any CPU.ActiveCfg = Debug|Any CPU {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.DLL Debug|Any CPU.Build.0 = Debug|Any CPU {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.DLL Debug|Win32.ActiveCfg = Debug|Any CPU @@ -87,18 +63,6 @@ Global {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.DLL Release|Win32.Build.0 = Release|Any CPU {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.DLL Release|x64.ActiveCfg = Release|x64 {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.DLL Release|x64.Build.0 = Release|x64 - {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.Release|Any CPU.Build.0 = Release|Any CPU - {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.Release|Win32.ActiveCfg = Release|Any CPU - {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.Release|Win32.Build.0 = Release|Any CPU - {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.Release|x64.ActiveCfg = Release|x64 - {8921AD35-4E62-4DAC-8FEE-8C9F8E57DDD2}.Release|x64.Build.0 = Release|x64 - {030431C7-26AB-4447-815B-F27E88BE5D5B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {030431C7-26AB-4447-815B-F27E88BE5D5B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {030431C7-26AB-4447-815B-F27E88BE5D5B}.Debug|Win32.ActiveCfg = Debug|Any CPU - {030431C7-26AB-4447-815B-F27E88BE5D5B}.Debug|Win32.Build.0 = Debug|Any CPU - {030431C7-26AB-4447-815B-F27E88BE5D5B}.Debug|x64.ActiveCfg = Debug|x64 - {030431C7-26AB-4447-815B-F27E88BE5D5B}.Debug|x64.Build.0 = Debug|x64 {030431C7-26AB-4447-815B-F27E88BE5D5B}.DLL Debug|Any CPU.ActiveCfg = Debug|Any CPU {030431C7-26AB-4447-815B-F27E88BE5D5B}.DLL Debug|Any CPU.Build.0 = Debug|Any CPU {030431C7-26AB-4447-815B-F27E88BE5D5B}.DLL Debug|Win32.ActiveCfg = Debug|Any CPU @@ -111,18 +75,6 @@ Global {030431C7-26AB-4447-815B-F27E88BE5D5B}.DLL Release|Win32.Build.0 = Release|Any CPU {030431C7-26AB-4447-815B-F27E88BE5D5B}.DLL Release|x64.ActiveCfg = Release|x64 {030431C7-26AB-4447-815B-F27E88BE5D5B}.DLL Release|x64.Build.0 = Release|x64 - {030431C7-26AB-4447-815B-F27E88BE5D5B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {030431C7-26AB-4447-815B-F27E88BE5D5B}.Release|Any CPU.Build.0 = Release|Any CPU - {030431C7-26AB-4447-815B-F27E88BE5D5B}.Release|Win32.ActiveCfg = Release|Any CPU - {030431C7-26AB-4447-815B-F27E88BE5D5B}.Release|Win32.Build.0 = Release|Any CPU - {030431C7-26AB-4447-815B-F27E88BE5D5B}.Release|x64.ActiveCfg = Release|x64 - {030431C7-26AB-4447-815B-F27E88BE5D5B}.Release|x64.Build.0 = Release|x64 - {730F047E-37A6-498F-A543-B6C98AA7B338}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {730F047E-37A6-498F-A543-B6C98AA7B338}.Debug|Any CPU.Build.0 = Debug|Any CPU - {730F047E-37A6-498F-A543-B6C98AA7B338}.Debug|Win32.ActiveCfg = Debug|Any CPU - {730F047E-37A6-498F-A543-B6C98AA7B338}.Debug|Win32.Build.0 = Debug|Any CPU - {730F047E-37A6-498F-A543-B6C98AA7B338}.Debug|x64.ActiveCfg = Debug|x64 - {730F047E-37A6-498F-A543-B6C98AA7B338}.Debug|x64.Build.0 = Debug|x64 {730F047E-37A6-498F-A543-B6C98AA7B338}.DLL Debug|Any CPU.ActiveCfg = Debug|Any CPU {730F047E-37A6-498F-A543-B6C98AA7B338}.DLL Debug|Any CPU.Build.0 = Debug|Any CPU {730F047E-37A6-498F-A543-B6C98AA7B338}.DLL Debug|Win32.ActiveCfg = Debug|Any CPU @@ -135,18 +87,6 @@ Global {730F047E-37A6-498F-A543-B6C98AA7B338}.DLL Release|Win32.Build.0 = Release|Any CPU {730F047E-37A6-498F-A543-B6C98AA7B338}.DLL Release|x64.ActiveCfg = Release|x64 {730F047E-37A6-498F-A543-B6C98AA7B338}.DLL Release|x64.Build.0 = Release|x64 - {730F047E-37A6-498F-A543-B6C98AA7B338}.Release|Any CPU.ActiveCfg = Release|Any CPU - {730F047E-37A6-498F-A543-B6C98AA7B338}.Release|Any CPU.Build.0 = Release|Any CPU - {730F047E-37A6-498F-A543-B6C98AA7B338}.Release|Win32.ActiveCfg = Release|Any CPU - {730F047E-37A6-498F-A543-B6C98AA7B338}.Release|Win32.Build.0 = Release|Any CPU - {730F047E-37A6-498F-A543-B6C98AA7B338}.Release|x64.ActiveCfg = Release|x64 - {730F047E-37A6-498F-A543-B6C98AA7B338}.Release|x64.Build.0 = Release|x64 - {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.Debug|Win32.ActiveCfg = Debug|Any CPU - {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.Debug|Win32.Build.0 = Debug|Any CPU - {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.Debug|x64.ActiveCfg = Debug|x64 - {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.Debug|x64.Build.0 = Debug|x64 {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.DLL Debug|Any CPU.ActiveCfg = Debug|Any CPU {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.DLL Debug|Any CPU.Build.0 = Debug|Any CPU {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.DLL Debug|Win32.ActiveCfg = Debug|Any CPU @@ -159,17 +99,6 @@ Global {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.DLL Release|Win32.Build.0 = Release|Any CPU {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.DLL Release|x64.ActiveCfg = Release|x64 {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.DLL Release|x64.Build.0 = Release|x64 - {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.Release|Any CPU.Build.0 = Release|Any CPU - {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.Release|Win32.ActiveCfg = Release|Any CPU - {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.Release|Win32.Build.0 = Release|Any CPU - {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.Release|x64.ActiveCfg = Release|x64 - {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.Release|x64.Build.0 = Release|x64 - {73973223-5EE8-41CA-8E88-1D60E89A237B}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {73973223-5EE8-41CA-8E88-1D60E89A237B}.Debug|Win32.ActiveCfg = Debug|Win32 - {73973223-5EE8-41CA-8E88-1D60E89A237B}.Debug|Win32.Build.0 = Debug|Win32 - {73973223-5EE8-41CA-8E88-1D60E89A237B}.Debug|x64.ActiveCfg = Debug|x64 - {73973223-5EE8-41CA-8E88-1D60E89A237B}.Debug|x64.Build.0 = Debug|x64 {73973223-5EE8-41CA-8E88-1D60E89A237B}.DLL Debug|Any CPU.ActiveCfg = DLL Debug|Win32 {73973223-5EE8-41CA-8E88-1D60E89A237B}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32 {73973223-5EE8-41CA-8E88-1D60E89A237B}.DLL Debug|Win32.Build.0 = DLL Debug|Win32 @@ -180,16 +109,6 @@ Global {73973223-5EE8-41CA-8E88-1D60E89A237B}.DLL Release|Win32.Build.0 = DLL Release|Win32 {73973223-5EE8-41CA-8E88-1D60E89A237B}.DLL Release|x64.ActiveCfg = DLL Release|x64 {73973223-5EE8-41CA-8E88-1D60E89A237B}.DLL Release|x64.Build.0 = DLL Release|x64 - {73973223-5EE8-41CA-8E88-1D60E89A237B}.Release|Any CPU.ActiveCfg = Release|Win32 - {73973223-5EE8-41CA-8E88-1D60E89A237B}.Release|Win32.ActiveCfg = Release|Win32 - {73973223-5EE8-41CA-8E88-1D60E89A237B}.Release|Win32.Build.0 = Release|Win32 - {73973223-5EE8-41CA-8E88-1D60E89A237B}.Release|x64.ActiveCfg = Release|x64 - {73973223-5EE8-41CA-8E88-1D60E89A237B}.Release|x64.Build.0 = Release|x64 - {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.Debug|Win32.ActiveCfg = Debug|Win32 - {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.Debug|Win32.Build.0 = Debug|Win32 - {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.Debug|x64.ActiveCfg = Debug|x64 - {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.Debug|x64.Build.0 = Debug|x64 {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.DLL Debug|Any CPU.ActiveCfg = DLL Debug|Win32 {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32 {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.DLL Debug|Win32.Build.0 = DLL Debug|Win32 @@ -200,17 +119,6 @@ Global {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.DLL Release|Win32.Build.0 = DLL Release|Win32 {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.DLL Release|x64.ActiveCfg = DLL Release|x64 {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.DLL Release|x64.Build.0 = DLL Release|x64 - {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.Release|Any CPU.ActiveCfg = Release|Win32 - {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.Release|Win32.ActiveCfg = Release|Win32 - {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.Release|Win32.Build.0 = Release|Win32 - {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.Release|x64.ActiveCfg = Release|x64 - {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.Release|x64.Build.0 = Release|x64 - {E2415718-0A15-48DB-A774-01FB0093B626}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E2415718-0A15-48DB-A774-01FB0093B626}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E2415718-0A15-48DB-A774-01FB0093B626}.Debug|Win32.ActiveCfg = Debug|Any CPU - {E2415718-0A15-48DB-A774-01FB0093B626}.Debug|Win32.Build.0 = Debug|Any CPU - {E2415718-0A15-48DB-A774-01FB0093B626}.Debug|x64.ActiveCfg = Debug|x64 - {E2415718-0A15-48DB-A774-01FB0093B626}.Debug|x64.Build.0 = Debug|x64 {E2415718-0A15-48DB-A774-01FB0093B626}.DLL Debug|Any CPU.ActiveCfg = Debug|Any CPU {E2415718-0A15-48DB-A774-01FB0093B626}.DLL Debug|Any CPU.Build.0 = Debug|Any CPU {E2415718-0A15-48DB-A774-01FB0093B626}.DLL Debug|Win32.ActiveCfg = Debug|Any CPU @@ -223,18 +131,6 @@ Global {E2415718-0A15-48DB-A774-01FB0093B626}.DLL Release|Win32.Build.0 = Release|Any CPU {E2415718-0A15-48DB-A774-01FB0093B626}.DLL Release|x64.ActiveCfg = Release|x64 {E2415718-0A15-48DB-A774-01FB0093B626}.DLL Release|x64.Build.0 = Release|x64 - {E2415718-0A15-48DB-A774-01FB0093B626}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E2415718-0A15-48DB-A774-01FB0093B626}.Release|Any CPU.Build.0 = Release|Any CPU - {E2415718-0A15-48DB-A774-01FB0093B626}.Release|Win32.ActiveCfg = Release|Any CPU - {E2415718-0A15-48DB-A774-01FB0093B626}.Release|Win32.Build.0 = Release|Any CPU - {E2415718-0A15-48DB-A774-01FB0093B626}.Release|x64.ActiveCfg = Release|x64 - {E2415718-0A15-48DB-A774-01FB0093B626}.Release|x64.Build.0 = Release|x64 - {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.Debug|Win32.ActiveCfg = Debug|Any CPU - {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.Debug|Win32.Build.0 = Debug|Any CPU - {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.Debug|x64.ActiveCfg = Debug|x64 - {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.Debug|x64.Build.0 = Debug|x64 {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.DLL Debug|Any CPU.ActiveCfg = Debug|Any CPU {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.DLL Debug|Any CPU.Build.0 = Debug|Any CPU {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.DLL Debug|Win32.ActiveCfg = Debug|Any CPU @@ -247,18 +143,6 @@ Global {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.DLL Release|Win32.Build.0 = Release|Any CPU {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.DLL Release|x64.ActiveCfg = Release|x64 {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.DLL Release|x64.Build.0 = Release|x64 - {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.Release|Any CPU.Build.0 = Release|Any CPU - {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.Release|Win32.ActiveCfg = Release|Any CPU - {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.Release|Win32.Build.0 = Release|Any CPU - {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.Release|x64.ActiveCfg = Release|x64 - {B9DF2972-38F6-4B42-B228-E3C1A47DF8E8}.Release|x64.Build.0 = Release|x64 - {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.Debug|Win32.ActiveCfg = Debug|Any CPU - {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.Debug|Win32.Build.0 = Debug|Any CPU - {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.Debug|x64.ActiveCfg = Debug|x64 - {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.Debug|x64.Build.0 = Debug|x64 {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.DLL Debug|Any CPU.ActiveCfg = Debug|Any CPU {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.DLL Debug|Any CPU.Build.0 = Debug|Any CPU {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.DLL Debug|Win32.ActiveCfg = Debug|Any CPU @@ -271,12 +155,6 @@ Global {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.DLL Release|Win32.Build.0 = Release|Any CPU {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.DLL Release|x64.ActiveCfg = Release|x64 {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.DLL Release|x64.Build.0 = Release|x64 - {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.Release|Any CPU.Build.0 = Release|Any CPU - {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.Release|Win32.ActiveCfg = Release|Any CPU - {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.Release|Win32.Build.0 = Release|Any CPU - {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.Release|x64.ActiveCfg = Release|x64 - {8ABD2E8F-AEE7-40ED-A966-900ACFAE555F}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 2116c20f5dea6257c107f60e5bcbfd507fe7ff6f Mon Sep 17 00:00:00 2001 From: Jacob Barthelmeh Date: Wed, 25 Mar 2020 10:38:18 -0600 Subject: [PATCH 220/649] add test case for PKCS12 to DER and back --- tests/api.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/api.c b/tests/api.c index 47a8843bb..95a84547f 100644 --- a/tests/api.c +++ b/tests/api.c @@ -4550,6 +4550,7 @@ static void test_wolfSSL_PKCS12(void) d2i_PKCS12_bio(bio, &pkcs12); AssertNotNull(pkcs12); + BIO_free(bio); /* check verify MAC fail case */ ret = PKCS12_parse(pkcs12, "bad", &pkey, &cert, NULL); @@ -4631,6 +4632,13 @@ static void test_wolfSSL_PKCS12(void) X509_free(cert); sk_X509_free(ca); + /* convert to DER then back and parse */ + AssertNotNull(bio = BIO_new(BIO_s_mem())); + AssertIntEQ(i2d_PKCS12_bio(bio, pkcs12_2), SSL_SUCCESS); + PKCS12_free(pkcs12_2); + + AssertNotNull(pkcs12_2 = d2i_PKCS12_bio(bio, NULL)); + BIO_free(bio); AssertIntEQ(PKCS12_parse(pkcs12_2, "a password", &pkey, &cert, &ca), SSL_SUCCESS); @@ -4661,7 +4669,6 @@ static void test_wolfSSL_PKCS12(void) EVP_PKEY_free(pkey); X509_free(cert); - BIO_free(bio); PKCS12_free(pkcs12); PKCS12_free(pkcs12_2); sk_X509_free(ca); From 70773f3b3e3f7b85c182e9d75b886cb338be7b90 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 25 Mar 2020 12:54:40 -0700 Subject: [PATCH 221/649] Added "WOLFSSL_ARMASM" ifdef checks on ARMv8 port files. --- wolfcrypt/src/port/arm/armv8-chacha.c | 2 +- wolfcrypt/src/port/arm/armv8-curve25519.c | 3 +++ wolfcrypt/src/port/arm/armv8-sha512-asm.c | 9 +++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/wolfcrypt/src/port/arm/armv8-chacha.c b/wolfcrypt/src/port/arm/armv8-chacha.c index d1118a4ba..df76bece0 100644 --- a/wolfcrypt/src/port/arm/armv8-chacha.c +++ b/wolfcrypt/src/port/arm/armv8-chacha.c @@ -2853,5 +2853,5 @@ int wc_Chacha_Process(ChaCha* ctx, byte* output, const byte* input, return 0; } -#endif /* HAVE_CHACHA*/ +#endif /* HAVE_CHACHA */ #endif /* WOLFSSL_ARMASM */ diff --git a/wolfcrypt/src/port/arm/armv8-curve25519.c b/wolfcrypt/src/port/arm/armv8-curve25519.c index 4d8a3ae08..d1ab4c89c 100644 --- a/wolfcrypt/src/port/arm/armv8-curve25519.c +++ b/wolfcrypt/src/port/arm/armv8-curve25519.c @@ -30,6 +30,8 @@ #endif #include + +#ifdef WOLFSSL_ARMASM #include #include @@ -6719,4 +6721,5 @@ void fe_ge_sub(fe rx, fe ry, fe rz, fe rt, const fe px, const fe py, const fe pz (void)qyminusx; } +#endif /* WOLFSSL_ARMASM */ #endif /* __aarch64__ */ diff --git a/wolfcrypt/src/port/arm/armv8-sha512-asm.c b/wolfcrypt/src/port/arm/armv8-sha512-asm.c index d47d966d3..d323598dd 100644 --- a/wolfcrypt/src/port/arm/armv8-sha512-asm.c +++ b/wolfcrypt/src/port/arm/armv8-sha512-asm.c @@ -25,6 +25,14 @@ */ #ifdef __aarch64__ #include + +#ifdef HAVE_CONFIG_H + #include +#endif + +#include + +#ifdef WOLFSSL_ARMASM #include static const uint64_t L_SHA512_transform_neon_len_k[] = { @@ -1029,4 +1037,5 @@ void Transform_Sha512_Len(wc_Sha512* sha512, const byte* data, word32 len) ); } +#endif /* WOLFSSL_ARMASM */ #endif /* __aarch64__ */ From 3717982d47afb51f0556e0d543b33a23801b05f7 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 25 Mar 2020 14:53:58 -0700 Subject: [PATCH 222/649] Fix to build wolfssl/testsuite in Any CPU case. --- wrapper/CSharp/wolfSSL_CSharp.sln | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/wrapper/CSharp/wolfSSL_CSharp.sln b/wrapper/CSharp/wolfSSL_CSharp.sln index ac7f4b9e7..f3b4dc707 100755 --- a/wrapper/CSharp/wolfSSL_CSharp.sln +++ b/wrapper/CSharp/wolfSSL_CSharp.sln @@ -100,21 +100,25 @@ Global {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.DLL Release|x64.ActiveCfg = Release|x64 {77AEF1BE-4BE3-4837-8188-2A06E4D963F5}.DLL Release|x64.Build.0 = Release|x64 {73973223-5EE8-41CA-8E88-1D60E89A237B}.DLL Debug|Any CPU.ActiveCfg = DLL Debug|Win32 + {73973223-5EE8-41CA-8E88-1D60E89A237B}.DLL Debug|Any CPU.Build.0 = DLL Debug|Win32 {73973223-5EE8-41CA-8E88-1D60E89A237B}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32 {73973223-5EE8-41CA-8E88-1D60E89A237B}.DLL Debug|Win32.Build.0 = DLL Debug|Win32 {73973223-5EE8-41CA-8E88-1D60E89A237B}.DLL Debug|x64.ActiveCfg = DLL Debug|x64 {73973223-5EE8-41CA-8E88-1D60E89A237B}.DLL Debug|x64.Build.0 = DLL Debug|x64 {73973223-5EE8-41CA-8E88-1D60E89A237B}.DLL Release|Any CPU.ActiveCfg = DLL Release|Win32 + {73973223-5EE8-41CA-8E88-1D60E89A237B}.DLL Release|Any CPU.Build.0 = DLL Release|Win32 {73973223-5EE8-41CA-8E88-1D60E89A237B}.DLL Release|Win32.ActiveCfg = DLL Release|Win32 {73973223-5EE8-41CA-8E88-1D60E89A237B}.DLL Release|Win32.Build.0 = DLL Release|Win32 {73973223-5EE8-41CA-8E88-1D60E89A237B}.DLL Release|x64.ActiveCfg = DLL Release|x64 {73973223-5EE8-41CA-8E88-1D60E89A237B}.DLL Release|x64.Build.0 = DLL Release|x64 {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.DLL Debug|Any CPU.ActiveCfg = DLL Debug|Win32 + {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.DLL Debug|Any CPU.Build.0 = DLL Debug|Win32 {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.DLL Debug|Win32.ActiveCfg = DLL Debug|Win32 {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.DLL Debug|Win32.Build.0 = DLL Debug|Win32 {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.DLL Debug|x64.ActiveCfg = DLL Debug|x64 {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.DLL Debug|x64.Build.0 = DLL Debug|x64 {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.DLL Release|Any CPU.ActiveCfg = DLL Release|Win32 + {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.DLL Release|Any CPU.Build.0 = DLL Release|Win32 {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.DLL Release|Win32.ActiveCfg = DLL Release|Win32 {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.DLL Release|Win32.Build.0 = DLL Release|Win32 {611E8971-46E0-4D0A-B5A1-632C3B00CB80}.DLL Release|x64.ActiveCfg = DLL Release|x64 From d57d194de348a3435d2240a348aab806ff15ceb1 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Wed, 25 Mar 2020 23:05:02 +0100 Subject: [PATCH 223/649] Fix clang warnings (issue #2870) The warning was "comparison of array 'ecc_sets[i].name' not equal to a null pointer is always true [-Wtautological-pointer-compare]" Compiler is correct, ecc_sets[i].name is an array of size 16, thus can't be NULL Also, fix build error on Windows by changing uint8_t to "unsigned char" (alternative fix could be including stdint.h) --- src/ssl.c | 4 ++-- wolfcrypt/src/asn.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index f47759df5..0aa611b53 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -24153,7 +24153,7 @@ int wolfSSL_sk_CIPHER_description(WOLFSSL_CIPHER* cipher) const char* name; const char *keaStr, *authStr, *encStr, *macStr, *protocol; char n[MAX_SEGMENTS][MAX_SEGMENT_SZ] = {{0}}; - uint8_t len = MAX_DESCRIPTION_SZ-1; + unsigned char len = MAX_DESCRIPTION_SZ-1; const CipherSuiteInfo* cipher_names; ProtocolVersion pv; WOLFSSL_ENTER("wolfSSL_sk_CIPHER_description"); @@ -36380,7 +36380,7 @@ size_t wolfSSL_EC_get_builtin_curves(WOLFSSL_EC_BUILTIN_CURVE *r, size_t nitems) size_t ecc_sets_count; size_t i, min_nitems; - for (i = 0; ecc_sets[i].size != 0 && ecc_sets[i].name != NULL; i++); + for (i = 0; ecc_sets[i].size != 0; i++); ecc_sets_count = i; if (r == NULL || nitems == 0) diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 62ca85ea7..9810df293 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -5470,7 +5470,7 @@ int wc_OBJ_sn2nid(const char *sn) if (XSTRNCMP(sn, "secp384r1", 10) == 0) sn = "SECP384R1"; /* find based on name and return NID */ - for (i = 0; ecc_sets[i].size != 0 && ecc_sets[i].name != NULL; i++) { + for (i = 0; ecc_sets[i].size != 0; i++) { if (XSTRNCMP(sn, ecc_sets[i].name, ECC_MAXNAME) == 0) { eccEnum = ecc_sets[i].id; /* Convert enum value in ecc_curve_id to OpenSSL NID */ From a6034a38c7519a863926c9f6179f6ee3af192183 Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 25 Mar 2020 13:32:23 -0700 Subject: [PATCH 224/649] Fix for building with `WOLFSSL_SMALL_STACK_CACHE` only (no `WOLFSSL_SMALL_STACK`). --- wolfcrypt/src/ecc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 31c4090fc..e71d77f65 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -2522,11 +2522,11 @@ int wc_ecc_mulmod_ex(mp_int* k, ecc_point *G, ecc_point *R, ecc_point *tG, *M[M_POINTS]; int i, err; -#ifdef WOLFSSL_SMALL_STACK - mp_int* mu = NULL; #ifdef WOLFSSL_SMALL_STACK_CACHE ecc_key key; #endif +#ifdef WOLFSSL_SMALL_STACK + mp_int* mu = NULL; #else mp_int mu[1]; #endif @@ -5339,11 +5339,11 @@ int ecc_mul2add(ecc_point* A, mp_int* kA, void* heap) #endif { -#ifdef WOLFSSL_SMALL_STACK - ecc_point** precomp = NULL; #ifdef WOLFSSL_SMALL_STACK_CACHE ecc_key key; #endif +#ifdef WOLFSSL_SMALL_STACK + ecc_point** precomp = NULL; #else ecc_point* precomp[SHAMIR_PRECOMP_SZ]; #endif From c82531a41a9ab0de600a47da81821f651e862939 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Thu, 26 Mar 2020 16:24:41 +1000 Subject: [PATCH 225/649] Fix performance of RSA public key ops with TFM Have a constant and non-constant time modular exponentation available in tfm.c. Call the non-constant time version explicitly when performing RSA public key mod exp. --- wolfcrypt/src/rsa.c | 2 +- wolfcrypt/src/tfm.c | 154 ++++++++++++++++++++++++------------ wolfssl/wolfcrypt/integer.h | 1 + wolfssl/wolfcrypt/sp_int.h | 1 + wolfssl/wolfcrypt/tfm.h | 2 + 5 files changed, 108 insertions(+), 52 deletions(-) diff --git a/wolfcrypt/src/rsa.c b/wolfcrypt/src/rsa.c index f3119b88e..3ed26f3ef 100644 --- a/wolfcrypt/src/rsa.c +++ b/wolfcrypt/src/rsa.c @@ -2256,7 +2256,7 @@ static int wc_RsaFunctionSync(const byte* in, word32 inLen, byte* out, #ifdef WOLFSSL_XILINX_CRYPT ret = wc_RsaFunctionXil(in, inLen, out, outLen, type, key, rng); #else - if (mp_exptmod(tmp, &key->e, &key->n, tmp) != MP_OKAY) + if (mp_exptmod_nct(tmp, &key->e, &key->n, tmp) != MP_OKAY) ret = MP_EXPTMOD_E; #endif break; diff --git a/wolfcrypt/src/tfm.c b/wolfcrypt/src/tfm.c index be84dee25..059197fc4 100644 --- a/wolfcrypt/src/tfm.c +++ b/wolfcrypt/src/tfm.c @@ -1564,7 +1564,8 @@ int fp_exptmod_nb(exptModNb_t* nb, fp_int* G, fp_int* X, fp_int* P, fp_int* Y) Based on work by Marc Joye, Sung-Ming Yen, "The Montgomery Powering Ladder", Cryptographic Hardware and Embedded Systems, CHES 2002 */ -static int _fp_exptmod(fp_int * G, fp_int * X, int digits, fp_int * P, fp_int * Y) +static int _fp_exptmod_ct(fp_int * G, fp_int * X, int digits, fp_int * P, + fp_int * Y) { #ifndef WOLFSSL_SMALL_STACK #ifdef WC_NO_CACHE_RESISTANT @@ -1701,25 +1702,17 @@ static int _fp_exptmod(fp_int * G, fp_int * X, int digits, fp_int * P, fp_int * return err; } -#else /* TFM_TIMING_RESISTANT */ +#endif /* TFM_TIMING_RESISTANT */ /* y = g**x (mod b) * Some restrictions... x must be positive and < b */ -static int _fp_exptmod(fp_int * G, fp_int * X, int digits, fp_int * P, - fp_int * Y) +static int _fp_exptmod_nct(fp_int * G, fp_int * X, fp_int * P, fp_int * Y) { - fp_digit buf, mp; - int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; -#ifdef WOLFSSL_SMALL_STACK fp_int *res; fp_int *M; -#else - fp_int res[1]; - fp_int M[64]; -#endif - - (void)digits; + fp_digit buf, mp; + int err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize; /* find window size */ x = fp_count_bits (X); @@ -1740,14 +1733,13 @@ static int _fp_exptmod(fp_int * G, fp_int * X, int digits, fp_int * P, return err; } -#ifdef WOLFSSL_SMALL_STACK /* only allocate space for what's needed for window plus res */ - M = (fp_int*)XMALLOC(sizeof(fp_int)*((1 << winsize) + 1), NULL, DYNAMIC_TYPE_BIGINT); + M = (fp_int*)XMALLOC(sizeof(fp_int)*((1 << winsize) + 1), NULL, + DYNAMIC_TYPE_BIGINT); if (M == NULL) { return FP_MEM; } res = &M[1 << winsize]; -#endif /* init M array */ for(x = 0; x < (1 << winsize); x++) @@ -1782,9 +1774,7 @@ static int _fp_exptmod(fp_int * G, fp_int * X, int digits, fp_int * P, fp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)]); err = fp_montgomery_reduce (&M[1 << (winsize - 1)], P, mp); if (err != FP_OKAY) { - #ifdef WOLFSSL_SMALL_STACK XFREE(M, NULL, DYNAMIC_TYPE_BIGINT); - #endif return err; } } @@ -1793,23 +1783,19 @@ static int _fp_exptmod(fp_int * G, fp_int * X, int digits, fp_int * P, for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) { err = fp_mul(&M[x - 1], &M[1], &M[x]); if (err != FP_OKAY) { - #ifdef WOLFSSL_SMALL_STACK XFREE(M, NULL, DYNAMIC_TYPE_BIGINT); - #endif return err; } err = fp_montgomery_reduce(&M[x], P, mp); if (err != FP_OKAY) { - #ifdef WOLFSSL_SMALL_STACK XFREE(M, NULL, DYNAMIC_TYPE_BIGINT); - #endif return err; } } /* set initial mode and bit cnt */ mode = 0; - bitcnt = 1; + bitcnt = (x % DIGIT_BIT) + 1; buf = 0; digidx = X->used - 1; bitcpy = 0; @@ -1844,16 +1830,12 @@ static int _fp_exptmod(fp_int * G, fp_int * X, int digits, fp_int * P, if (mode == 1 && y == 0) { err = fp_sqr(res, res); if (err != FP_OKAY) { - #ifdef WOLFSSL_SMALL_STACK XFREE(M, NULL, DYNAMIC_TYPE_BIGINT); - #endif return err; } fp_montgomery_reduce(res, P, mp); if (err != FP_OKAY) { - #ifdef WOLFSSL_SMALL_STACK XFREE(M, NULL, DYNAMIC_TYPE_BIGINT); - #endif return err; } continue; @@ -1869,16 +1851,12 @@ static int _fp_exptmod(fp_int * G, fp_int * X, int digits, fp_int * P, for (x = 0; x < winsize; x++) { err = fp_sqr(res, res); if (err != FP_OKAY) { - #ifdef WOLFSSL_SMALL_STACK XFREE(M, NULL, DYNAMIC_TYPE_BIGINT); - #endif return err; } err = fp_montgomery_reduce(res, P, mp); if (err != FP_OKAY) { - #ifdef WOLFSSL_SMALL_STACK XFREE(M, NULL, DYNAMIC_TYPE_BIGINT); - #endif return err; } } @@ -1886,16 +1864,12 @@ static int _fp_exptmod(fp_int * G, fp_int * X, int digits, fp_int * P, /* then multiply */ err = fp_mul(res, &M[bitbuf], res); if (err != FP_OKAY) { - #ifdef WOLFSSL_SMALL_STACK XFREE(M, NULL, DYNAMIC_TYPE_BIGINT); - #endif return err; } err = fp_montgomery_reduce(res, P, mp); if (err != FP_OKAY) { - #ifdef WOLFSSL_SMALL_STACK XFREE(M, NULL, DYNAMIC_TYPE_BIGINT); - #endif return err; } @@ -1912,16 +1886,12 @@ static int _fp_exptmod(fp_int * G, fp_int * X, int digits, fp_int * P, for (x = 0; x < bitcpy; x++) { err = fp_sqr(res, res); if (err != FP_OKAY) { - #ifdef WOLFSSL_SMALL_STACK XFREE(M, NULL, DYNAMIC_TYPE_BIGINT); - #endif return err; } err = fp_montgomery_reduce(res, P, mp); if (err != FP_OKAY) { - #ifdef WOLFSSL_SMALL_STACK XFREE(M, NULL, DYNAMIC_TYPE_BIGINT); - #endif return err; } @@ -1931,16 +1901,12 @@ static int _fp_exptmod(fp_int * G, fp_int * X, int digits, fp_int * P, /* then multiply */ err = fp_mul(res, &M[1], res); if (err != FP_OKAY) { - #ifdef WOLFSSL_SMALL_STACK XFREE(M, NULL, DYNAMIC_TYPE_BIGINT); - #endif return err; } err = fp_montgomery_reduce(res, P, mp); if (err != FP_OKAY) { - #ifdef WOLFSSL_SMALL_STACK XFREE(M, NULL, DYNAMIC_TYPE_BIGINT); - #endif return err; } } @@ -1958,14 +1924,10 @@ static int _fp_exptmod(fp_int * G, fp_int * X, int digits, fp_int * P, /* swap res with Y */ fp_copy (res, Y); -#ifdef WOLFSSL_SMALL_STACK XFREE(M, NULL, DYNAMIC_TYPE_BIGINT); -#endif return err; } -#endif /* TFM_TIMING_RESISTANT */ - #ifdef TFM_TIMING_RESISTANT #if DIGIT_BIT <= 16 @@ -2331,7 +2293,11 @@ int fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y) if (err == FP_OKAY) { fp_copy(X, &tmp[1]); tmp[1].sign = FP_ZPOS; - err = _fp_exptmod(&tmp[0], &tmp[1], tmp[1].used, P, Y); +#ifdef TFM_TIMING_RESISTANT + err = _fp_exptmod_ct(&tmp[0], &tmp[1], tmp[1].used, P, Y); +#else + err = _fp_exptmod_nct(&tmp[0], &tmp[1], P, Y); +#endif if (P->sign == FP_NEG) { fp_add(Y, P, Y); } @@ -2349,7 +2315,11 @@ int fp_exptmod(fp_int * G, fp_int * X, fp_int * P, fp_int * Y) } else { /* Positive exponent so just exptmod */ - return _fp_exptmod(G, X, X->used, P, Y); +#ifdef TFM_TIMING_RESISTANT + return _fp_exptmod_ct(G, X, X->used, P, Y); +#else + return _fp_exptmod_nct(G, X, P, Y); +#endif } } @@ -2400,7 +2370,12 @@ int fp_exptmod_ex(fp_int * G, fp_int * X, int digits, fp_int * P, fp_int * Y) err = fp_invmod(&tmp[0], &tmp[1], &tmp[0]); if (err == FP_OKAY) { X->sign = FP_ZPOS; - err = _fp_exptmod(&tmp[0], X, digits, P, Y); +#ifdef TFM_TIMING_RESISTANT + err = _fp_exptmod_ct(&tmp[0], X, digits, P, Y); +#else + err = _fp_exptmod_nct(&tmp[0], X, P, Y); + (void)digits; +#endif if (X != Y) { X->sign = FP_NEG; } @@ -2418,10 +2393,81 @@ int fp_exptmod_ex(fp_int * G, fp_int * X, int digits, fp_int * P, fp_int * Y) } else { /* Positive exponent so just exptmod */ - return _fp_exptmod(G, X, digits, P, Y); +#ifdef TFM_TIMING_RESISTANT + return _fp_exptmod_ct(G, X, digits, P, Y); +#else + return _fp_exptmod_nct(G, X, P, Y); +#endif } } +int fp_exptmod_nct(fp_int * G, fp_int * X, fp_int * P, fp_int * Y) +{ +#if defined(WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI) && \ + !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI) + int x = fp_count_bits (X); +#endif + + if (fp_iszero(G)) { + fp_set(G, 0); + return FP_OKAY; + } + + /* prevent overflows */ + if (P->used > (FP_SIZE/2)) { + return FP_VAL; + } + +#if defined(WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI) && \ + !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_RSA_PRI) + if(x > EPS_RSA_EXPT_XBTIS) { + return esp_mp_exptmod(G, X, x, P, Y); + } +#endif + + if (X->sign == FP_NEG) { +#ifndef POSITIVE_EXP_ONLY /* reduce stack if assume no negatives */ + int err; + #ifndef WOLFSSL_SMALL_STACK + fp_int tmp[2]; + #else + fp_int *tmp; + #endif + + #ifdef WOLFSSL_SMALL_STACK + tmp = (fp_int*)XMALLOC(sizeof(fp_int) * 2, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (tmp == NULL) + return FP_MEM; + #endif + + /* yes, copy G and invmod it */ + fp_init_copy(&tmp[0], G); + fp_init_copy(&tmp[1], P); + tmp[1].sign = FP_ZPOS; + err = fp_invmod(&tmp[0], &tmp[1], &tmp[0]); + if (err == FP_OKAY) { + X->sign = FP_ZPOS; + err = _fp_exptmod_nct(&tmp[0], X, P, Y); + if (X != Y) { + X->sign = FP_NEG; + } + if (P->sign == FP_NEG) { + fp_add(Y, P, Y); + } + } + #ifdef WOLFSSL_SMALL_STACK + XFREE(tmp, NULL, DYNAMIC_TYPE_BIGINT); + #endif + return err; +#else + return FP_VAL; +#endif + } + else { + /* Positive exponent so just exptmod */ + return _fp_exptmod_nct(G, X, P, Y); + } +} /* computes a = 2**b */ void fp_2expt(fp_int *a, int b) @@ -3639,6 +3685,12 @@ int mp_exptmod_ex (mp_int * G, mp_int * X, int digits, mp_int * P, mp_int * Y) return fp_exptmod_ex(G, X, digits, P, Y); } +int mp_exptmod_nct (mp_int * G, mp_int * X, mp_int * P, mp_int * Y) +{ + return fp_exptmod_nct(G, X, P, Y); +} + + /* compare two ints (signed)*/ int mp_cmp (mp_int * a, mp_int * b) { diff --git a/wolfssl/wolfcrypt/integer.h b/wolfssl/wolfcrypt/integer.h index 216f9ae37..03ea908c3 100644 --- a/wolfssl/wolfcrypt/integer.h +++ b/wolfssl/wolfcrypt/integer.h @@ -328,6 +328,7 @@ MP_API int mp_dr_is_modulus(mp_int *a); MP_API int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int); MP_API int mp_exptmod_base_2 (mp_int * X, mp_int * P, mp_int * Y); +#define mp_exptmod_nct(G,X,P,Y) mp_exptmod_fast(G,X,P,Y,0) MP_API int mp_montgomery_setup (mp_int * n, mp_digit * rho); int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho); MP_API int mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho); diff --git a/wolfssl/wolfcrypt/sp_int.h b/wolfssl/wolfcrypt/sp_int.h index 344e735e8..df963951c 100644 --- a/wolfssl/wolfcrypt/sp_int.h +++ b/wolfssl/wolfcrypt/sp_int.h @@ -272,6 +272,7 @@ MP_API int sp_mul_d(sp_int* a, sp_int_digit n, sp_int* r); #define mp_invmod sp_invmod #define mp_lcm sp_lcm #define mp_exptmod sp_exptmod +#define mp_exptmod_nct sp_exptmod #define mp_prime_is_prime sp_prime_is_prime #define mp_prime_is_prime_ex sp_prime_is_prime_ex #define mp_exch sp_exch diff --git a/wolfssl/wolfcrypt/tfm.h b/wolfssl/wolfcrypt/tfm.h index e8b41248e..b11c7f5a3 100644 --- a/wolfssl/wolfcrypt/tfm.h +++ b/wolfssl/wolfcrypt/tfm.h @@ -557,6 +557,7 @@ int fp_montgomery_reduce(fp_int *a, fp_int *m, fp_digit mp); /* d = a**b (mod c) */ int fp_exptmod(fp_int *a, fp_int *b, fp_int *c, fp_int *d); int fp_exptmod_ex(fp_int *a, fp_int *b, int minDigits, fp_int *c, fp_int *d); +int fp_exptmod_nct(fp_int *a, fp_int *b, fp_int *c, fp_int *d); #ifdef WC_RSA_NONBLOCK @@ -748,6 +749,7 @@ MP_API int mp_invmod_mont_ct(mp_int *a, mp_int *b, mp_int *c, fp_digit mp); MP_API int mp_exptmod (mp_int * g, mp_int * x, mp_int * p, mp_int * y); MP_API int mp_exptmod_ex (mp_int * g, mp_int * x, int minDigits, mp_int * p, mp_int * y); +MP_API int mp_exptmod_nct (mp_int * g, mp_int * x, mp_int * p, mp_int * y); MP_API int mp_mul_2d(mp_int *a, int b, mp_int *c); MP_API int mp_2expt(mp_int* a, int b); From 99b9f46e580b86e72feba14fefd0b41206c577d8 Mon Sep 17 00:00:00 2001 From: Hideki Miyazaki Date: Fri, 27 Mar 2020 12:33:51 +0900 Subject: [PATCH 226/649] fixed not working on mac fixed case of -s or -c --- examples/benchmark/tls_bench.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/examples/benchmark/tls_bench.c b/examples/benchmark/tls_bench.c index 4c71ac270..43c272a97 100644 --- a/examples/benchmark/tls_bench.c +++ b/examples/benchmark/tls_bench.c @@ -288,10 +288,11 @@ typedef struct { #endif #ifdef WOLFSSL_DTLS int doDTLS; - int serverReady; struct sockaddr_in serverAddr; struct sockaddr_in clientAddr; #ifdef HAVE_PTHREAD + int serverReady; + int clientOrserverOnly; pthread_mutex_t dtls_mutex; pthread_cond_t dtls_cond; #endif @@ -905,7 +906,7 @@ static int bench_tls_client(info_t* info) #if defined(HAVE_PTHREAD) && defined(WOLFSSL_DTLS) /* synchronize with server */ - if (info->doDTLS) { + if (info->doDTLS && !info->clientOrserverOnly) { pthread_mutex_lock(&info->dtls_mutex); if (info->serverReady != 1) { pthread_cond_wait(&info->dtls_cond, &info->dtls_mutex); @@ -1136,22 +1137,18 @@ static int SocketWaitClient(info_t* info) if (info->doDTLS) { #ifdef HAVE_PTHREAD - pthread_mutex_lock(&info->dtls_mutex); - info->serverReady = 1; - pthread_cond_signal(&info->dtls_cond); - pthread_mutex_unlock(&info->dtls_mutex); + if (!info->clientOrserverOnly) { + pthread_mutex_lock(&info->dtls_mutex); + info->serverReady = 1; + pthread_cond_signal(&info->dtls_cond); + pthread_mutex_unlock(&info->dtls_mutex); + } #endif connd = (int)recvfrom(info->listenFd, (char *)msg, sizeof(msg), MSG_PEEK, (struct sockaddr*)&clientAddr, &size); if (connd < -1) { printf("ERROR: failed to accept the connection\n"); return -1; - } else if (connd > 0) { - if (connect(info->listenFd, (const struct sockaddr *)&clientAddr, - size) != 0) { - printf("ERROR: Udp connet failed.\n"); - return -1; - } } XMEMCPY(&info->clientAddr, &clientAddr, sizeof(clientAddr)); info->server.sockFd = info->listenFd; @@ -1781,7 +1778,12 @@ int bench_tls(void* args) #ifdef WOLFSSL_DTLS info->doDTLS = doDTLS; + #ifdef HAVE_PTHREAD info->serverReady = 0; + if (argServerOnly || argClientOnly) { + info->clientOrserverOnly = 1; + } + #endif #endif if (argClientOnly) { #ifndef NO_WOLFSSL_CLIENT From 9339808ea147691c9c88f9293678a39cd5635fbd Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Fri, 27 Mar 2020 15:53:01 +1000 Subject: [PATCH 227/649] Smaller table version of the AES encrypt/decrypt Use WOLFSSL_AES_SMALL_TABLES. Much slower. Decrypt much slower then encrypt. --- wolfcrypt/src/aes.c | 294 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 278 insertions(+), 16 deletions(-) diff --git a/wolfcrypt/src/aes.c b/wolfcrypt/src/aes.c index bba2ddecf..fa0304545 100644 --- a/wolfcrypt/src/aes.c +++ b/wolfcrypt/src/aes.c @@ -933,6 +933,7 @@ static const word32 rcon[] = { /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ }; +#ifndef WOLFSSL_AES_SMALL_TABLES static const word32 Te[4][256] = { { 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, @@ -1468,8 +1469,10 @@ static const word32 Td[4][256] = { 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U, } }; +#endif /* HAVE_AES_DECRYPT */ +#endif - +#ifdef HAVE_AES_DECRYPT #if (defined(HAVE_AES_CBC) && !defined(WOLFSSL_DEVCRYPTO_CBC)) \ || defined(WOLFSSL_AES_DIRECT) static const byte Td4[256] = @@ -1512,7 +1515,62 @@ static const byte Td4[256] = #define GETBYTE(x, y) (word32)((byte)((x) >> (8 * (y)))) +#ifdef WOLFSSL_AES_SMALL_TABLES +static const byte Tsbox[256] = { + 0x63U, 0x7cU, 0x77U, 0x7bU, 0xf2U, 0x6bU, 0x6fU, 0xc5U, + 0x30U, 0x01U, 0x67U, 0x2bU, 0xfeU, 0xd7U, 0xabU, 0x76U, + 0xcaU, 0x82U, 0xc9U, 0x7dU, 0xfaU, 0x59U, 0x47U, 0xf0U, + 0xadU, 0xd4U, 0xa2U, 0xafU, 0x9cU, 0xa4U, 0x72U, 0xc0U, + 0xb7U, 0xfdU, 0x93U, 0x26U, 0x36U, 0x3fU, 0xf7U, 0xccU, + 0x34U, 0xa5U, 0xe5U, 0xf1U, 0x71U, 0xd8U, 0x31U, 0x15U, + 0x04U, 0xc7U, 0x23U, 0xc3U, 0x18U, 0x96U, 0x05U, 0x9aU, + 0x07U, 0x12U, 0x80U, 0xe2U, 0xebU, 0x27U, 0xb2U, 0x75U, + 0x09U, 0x83U, 0x2cU, 0x1aU, 0x1bU, 0x6eU, 0x5aU, 0xa0U, + 0x52U, 0x3bU, 0xd6U, 0xb3U, 0x29U, 0xe3U, 0x2fU, 0x84U, + 0x53U, 0xd1U, 0x00U, 0xedU, 0x20U, 0xfcU, 0xb1U, 0x5bU, + 0x6aU, 0xcbU, 0xbeU, 0x39U, 0x4aU, 0x4cU, 0x58U, 0xcfU, + 0xd0U, 0xefU, 0xaaU, 0xfbU, 0x43U, 0x4dU, 0x33U, 0x85U, + 0x45U, 0xf9U, 0x02U, 0x7fU, 0x50U, 0x3cU, 0x9fU, 0xa8U, + 0x51U, 0xa3U, 0x40U, 0x8fU, 0x92U, 0x9dU, 0x38U, 0xf5U, + 0xbcU, 0xb6U, 0xdaU, 0x21U, 0x10U, 0xffU, 0xf3U, 0xd2U, + 0xcdU, 0x0cU, 0x13U, 0xecU, 0x5fU, 0x97U, 0x44U, 0x17U, + 0xc4U, 0xa7U, 0x7eU, 0x3dU, 0x64U, 0x5dU, 0x19U, 0x73U, + 0x60U, 0x81U, 0x4fU, 0xdcU, 0x22U, 0x2aU, 0x90U, 0x88U, + 0x46U, 0xeeU, 0xb8U, 0x14U, 0xdeU, 0x5eU, 0x0bU, 0xdbU, + 0xe0U, 0x32U, 0x3aU, 0x0aU, 0x49U, 0x06U, 0x24U, 0x5cU, + 0xc2U, 0xd3U, 0xacU, 0x62U, 0x91U, 0x95U, 0xe4U, 0x79U, + 0xe7U, 0xc8U, 0x37U, 0x6dU, 0x8dU, 0xd5U, 0x4eU, 0xa9U, + 0x6cU, 0x56U, 0xf4U, 0xeaU, 0x65U, 0x7aU, 0xaeU, 0x08U, + 0xbaU, 0x78U, 0x25U, 0x2eU, 0x1cU, 0xa6U, 0xb4U, 0xc6U, + 0xe8U, 0xddU, 0x74U, 0x1fU, 0x4bU, 0xbdU, 0x8bU, 0x8aU, + 0x70U, 0x3eU, 0xb5U, 0x66U, 0x48U, 0x03U, 0xf6U, 0x0eU, + 0x61U, 0x35U, 0x57U, 0xb9U, 0x86U, 0xc1U, 0x1dU, 0x9eU, + 0xe1U, 0xf8U, 0x98U, 0x11U, 0x69U, 0xd9U, 0x8eU, 0x94U, + 0x9bU, 0x1eU, 0x87U, 0xe9U, 0xceU, 0x55U, 0x28U, 0xdfU, + 0x8cU, 0xa1U, 0x89U, 0x0dU, 0xbfU, 0xe6U, 0x42U, 0x68U, + 0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U, 0x54U, 0xbbU, 0x16U +}; +#define AES_XTIME(x) ((byte)((byte)((x) << 1) ^ ((0 - ((x) >> 7)) & 0x1b))) + +static word32 col_mul(word32 t, int i2, int i3, int ia, int ib) +{ + byte t3 = GETBYTE(t, i3); + byte tm = AES_XTIME(GETBYTE(t, i2) ^ t3); + + return GETBYTE(t, ia) ^ GETBYTE(t, ib) ^ t3 ^ tm; +} + +static word32 inv_col_mul(word32 t, int i9, int ib, int id, int ie) +{ + byte t9 = GETBYTE(t, i9); + byte tb = GETBYTE(t, ib); + byte td = GETBYTE(t, id); + byte te = GETBYTE(t, ie); + byte t0 = t9 ^ tb ^ td; + return t0 ^ AES_XTIME(AES_XTIME(AES_XTIME(t0 ^ te) ^ td ^ te) ^ tb ^ te); +} +#endif #if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT) || defined(HAVE_AESGCM) @@ -1527,6 +1585,7 @@ static const byte Td4[256] = #endif +#ifndef WOLFSSL_AES_SMALL_TABLES /* load 4 Te Tables into cache by cache line stride */ static WC_INLINE word32 PreFetchTe(void) { @@ -1541,6 +1600,19 @@ static WC_INLINE word32 PreFetchTe(void) } return x; } +#else +/* load sbox into cache by cache line stride */ +static WC_INLINE word32 PreFetchSBox(void) +{ + word32 x = 0; + int i; + + for (i = 0; i < 256; i += WC_CACHE_LINE_SZ/4) { + x &= Tsbox[i]; + } + return x; +} +#endif /* Software AES - ECB Encrypt */ static void wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock) @@ -1620,11 +1692,13 @@ static void wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock) s3 = ByteReverseWord32(s3); #endif + /* AddRoundKey */ s0 ^= rk[0]; s1 ^= rk[1]; s2 ^= rk[2]; s3 ^= rk[3]; +#ifndef WOLFSSL_AES_SMALL_TABLES s0 |= PreFetchTe(); /* @@ -1633,28 +1707,28 @@ static void wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock) for (;;) { t0 = - Te[0][GETBYTE(s0, 3)] ^ - Te[1][GETBYTE(s1, 2)] ^ - Te[2][GETBYTE(s2, 1)] ^ - Te[3][GETBYTE(s3, 0)] ^ + Te[0][GETBYTE(s0, 3)] ^ + Te[1][GETBYTE(s1, 2)] ^ + Te[2][GETBYTE(s2, 1)] ^ + Te[3][GETBYTE(s3, 0)] ^ rk[4]; t1 = - Te[0][GETBYTE(s1, 3)] ^ - Te[1][GETBYTE(s2, 2)] ^ - Te[2][GETBYTE(s3, 1)] ^ - Te[3][GETBYTE(s0, 0)] ^ + Te[0][GETBYTE(s1, 3)] ^ + Te[1][GETBYTE(s2, 2)] ^ + Te[2][GETBYTE(s3, 1)] ^ + Te[3][GETBYTE(s0, 0)] ^ rk[5]; t2 = Te[0][GETBYTE(s2, 3)] ^ - Te[1][GETBYTE(s3, 2)] ^ - Te[2][GETBYTE(s0, 1)] ^ - Te[3][GETBYTE(s1, 0)] ^ + Te[1][GETBYTE(s3, 2)] ^ + Te[2][GETBYTE(s0, 1)] ^ + Te[3][GETBYTE(s1, 0)] ^ rk[6]; t3 = Te[0][GETBYTE(s3, 3)] ^ - Te[1][GETBYTE(s0, 2)] ^ - Te[2][GETBYTE(s1, 1)] ^ - Te[3][GETBYTE(s2, 0)] ^ + Te[1][GETBYTE(s0, 2)] ^ + Te[2][GETBYTE(s1, 1)] ^ + Te[3][GETBYTE(s2, 0)] ^ rk[7]; rk += 8; @@ -1717,6 +1791,84 @@ static void wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock) (Te[0][GETBYTE(t1, 1)] & 0x0000ff00) ^ (Te[1][GETBYTE(t2, 0)] & 0x000000ff) ^ rk[3]; +#else + s0 |= PreFetchSBox(); + + r *= 2; + /* Two rounds at a time */ + for (rk += 4; r > 1; r--, rk += 4) { + t0 = + ((word32)Tsbox[GETBYTE(s0, 3)] << 24) ^ + ((word32)Tsbox[GETBYTE(s1, 2)] << 16) ^ + ((word32)Tsbox[GETBYTE(s2, 1)] << 8) ^ + ((word32)Tsbox[GETBYTE(s3, 0)]); + t1 = + ((word32)Tsbox[GETBYTE(s1, 3)] << 24) ^ + ((word32)Tsbox[GETBYTE(s2, 2)] << 16) ^ + ((word32)Tsbox[GETBYTE(s3, 1)] << 8) ^ + ((word32)Tsbox[GETBYTE(s0, 0)]); + t2 = + ((word32)Tsbox[GETBYTE(s2, 3)] << 24) ^ + ((word32)Tsbox[GETBYTE(s3, 2)] << 16) ^ + ((word32)Tsbox[GETBYTE(s0, 1)] << 8) ^ + ((word32)Tsbox[GETBYTE(s1, 0)]); + t3 = + ((word32)Tsbox[GETBYTE(s3, 3)] << 24) ^ + ((word32)Tsbox[GETBYTE(s0, 2)] << 16) ^ + ((word32)Tsbox[GETBYTE(s1, 1)] << 8) ^ + ((word32)Tsbox[GETBYTE(s2, 0)]); + + s0 = + (col_mul(t0, 3, 2, 0, 1) << 24) ^ + (col_mul(t0, 2, 1, 0, 3) << 16) ^ + (col_mul(t0, 1, 0, 2, 3) << 8) ^ + (col_mul(t0, 0, 3, 2, 1) ) ^ + rk[0]; + s1 = + (col_mul(t1, 3, 2, 0, 1) << 24) ^ + (col_mul(t1, 2, 1, 0, 3) << 16) ^ + (col_mul(t1, 1, 0, 2, 3) << 8) ^ + (col_mul(t1, 0, 3, 2, 1) ) ^ + rk[1]; + s2 = + (col_mul(t2, 3, 2, 0, 1) << 24) ^ + (col_mul(t2, 2, 1, 0, 3) << 16) ^ + (col_mul(t2, 1, 0, 2, 3) << 8) ^ + (col_mul(t2, 0, 3, 2, 1) ) ^ + rk[2]; + s3 = + (col_mul(t3, 3, 2, 0, 1) << 24) ^ + (col_mul(t3, 2, 1, 0, 3) << 16) ^ + (col_mul(t3, 1, 0, 2, 3) << 8) ^ + (col_mul(t3, 0, 3, 2, 1) ) ^ + rk[3]; + } + + t0 = + ((word32)Tsbox[GETBYTE(s0, 3)] << 24) ^ + ((word32)Tsbox[GETBYTE(s1, 2)] << 16) ^ + ((word32)Tsbox[GETBYTE(s2, 1)] << 8) ^ + ((word32)Tsbox[GETBYTE(s3, 0)]); + t1 = + ((word32)Tsbox[GETBYTE(s1, 3)] << 24) ^ + ((word32)Tsbox[GETBYTE(s2, 2)] << 16) ^ + ((word32)Tsbox[GETBYTE(s3, 1)] << 8) ^ + ((word32)Tsbox[GETBYTE(s0, 0)]); + t2 = + ((word32)Tsbox[GETBYTE(s2, 3)] << 24) ^ + ((word32)Tsbox[GETBYTE(s3, 2)] << 16) ^ + ((word32)Tsbox[GETBYTE(s0, 1)] << 8) ^ + ((word32)Tsbox[GETBYTE(s1, 0)]); + t3 = + ((word32)Tsbox[GETBYTE(s3, 3)] << 24) ^ + ((word32)Tsbox[GETBYTE(s0, 2)] << 16) ^ + ((word32)Tsbox[GETBYTE(s1, 1)] << 8) ^ + ((word32)Tsbox[GETBYTE(s2, 0)]); + s0 = t0 ^ rk[0]; + s1 = t1 ^ rk[1]; + s2 = t2 ^ rk[2]; + s3 = t3 ^ rk[3]; +#endif /* write out */ #ifdef LITTLE_ENDIAN_ORDER @@ -1738,6 +1890,7 @@ static void wc_AesEncrypt(Aes* aes, const byte* inBlock, byte* outBlock) #if (defined(HAVE_AES_CBC) && !defined(WOLFSSL_DEVCRYPTO_CBC)) || \ defined(WOLFSSL_AES_DIRECT) +#ifndef WOLFSSL_AES_SMALL_TABLES /* load 4 Td Tables into cache by cache line stride */ static WC_INLINE word32 PreFetchTd(void) { @@ -1752,6 +1905,7 @@ static WC_INLINE word32 PreFetchTd(void) } return x; } +#endif /* load Td Table4 into cache by cache line stride */ static WC_INLINE word32 PreFetchTd4(void) @@ -1826,6 +1980,7 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) s2 ^= rk[2]; s3 ^= rk[3]; +#ifndef WOLFSSL_AES_SMALL_TABLES s0 |= PreFetchTd(); /* @@ -1919,6 +2074,83 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) ((word32)Td4[GETBYTE(t1, 1)] << 8) ^ ((word32)Td4[GETBYTE(t0, 0)]) ^ rk[3]; +#else + s0 |= PreFetchTd4(); + + r *= 2; + for (rk += 4; r > 1; r--, rk += 4) { + t0 = + ((word32)Td4[GETBYTE(s0, 3)] << 24) ^ + ((word32)Td4[GETBYTE(s3, 2)] << 16) ^ + ((word32)Td4[GETBYTE(s2, 1)] << 8) ^ + ((word32)Td4[GETBYTE(s1, 0)]) ^ + rk[0]; + t1 = + ((word32)Td4[GETBYTE(s1, 3)] << 24) ^ + ((word32)Td4[GETBYTE(s0, 2)] << 16) ^ + ((word32)Td4[GETBYTE(s3, 1)] << 8) ^ + ((word32)Td4[GETBYTE(s2, 0)]) ^ + rk[1]; + t2 = + ((word32)Td4[GETBYTE(s2, 3)] << 24) ^ + ((word32)Td4[GETBYTE(s1, 2)] << 16) ^ + ((word32)Td4[GETBYTE(s0, 1)] << 8) ^ + ((word32)Td4[GETBYTE(s3, 0)]) ^ + rk[2]; + t3 = + ((word32)Td4[GETBYTE(s3, 3)] << 24) ^ + ((word32)Td4[GETBYTE(s2, 2)] << 16) ^ + ((word32)Td4[GETBYTE(s1, 1)] << 8) ^ + ((word32)Td4[GETBYTE(s0, 0)]) ^ + rk[3]; + + s0 = + (inv_col_mul(t0, 0, 2, 1, 3) << 24) ^ + (inv_col_mul(t0, 3, 1, 0, 2) << 16) ^ + (inv_col_mul(t0, 2, 0, 3, 1) << 8) ^ + (inv_col_mul(t0, 1, 3, 2, 0) ); + s1 = + (inv_col_mul(t1, 0, 2, 1, 3) << 24) ^ + (inv_col_mul(t1, 3, 1, 0, 2) << 16) ^ + (inv_col_mul(t1, 2, 0, 3, 1) << 8) ^ + (inv_col_mul(t1, 1, 3, 2, 0) ); + s2 = + (inv_col_mul(t2, 0, 2, 1, 3) << 24) ^ + (inv_col_mul(t2, 3, 1, 0, 2) << 16) ^ + (inv_col_mul(t2, 2, 0, 3, 1) << 8) ^ + (inv_col_mul(t2, 1, 3, 2, 0) ); + s3 = + (inv_col_mul(t3, 0, 2, 1, 3) << 24) ^ + (inv_col_mul(t3, 3, 1, 0, 2) << 16) ^ + (inv_col_mul(t3, 2, 0, 3, 1) << 8) ^ + (inv_col_mul(t3, 1, 3, 2, 0) ); + } + + t0 = + ((word32)Td4[GETBYTE(s0, 3)] << 24) ^ + ((word32)Td4[GETBYTE(s3, 2)] << 16) ^ + ((word32)Td4[GETBYTE(s2, 1)] << 8) ^ + ((word32)Td4[GETBYTE(s1, 0)]); + t1 = + ((word32)Td4[GETBYTE(s1, 3)] << 24) ^ + ((word32)Td4[GETBYTE(s0, 2)] << 16) ^ + ((word32)Td4[GETBYTE(s3, 1)] << 8) ^ + ((word32)Td4[GETBYTE(s2, 0)]); + t2 = + ((word32)Td4[GETBYTE(s2, 3)] << 24) ^ + ((word32)Td4[GETBYTE(s1, 2)] << 16) ^ + ((word32)Td4[GETBYTE(s0, 1)] << 8) ^ + ((word32)Td4[GETBYTE(s3, 0)]); + t3 = + ((word32)Td4[GETBYTE(s3, 3)] << 24) ^ + ((word32)Td4[GETBYTE(s2, 2)] << 16) ^ + ((word32)Td4[GETBYTE(s1, 1)] << 8) ^ + ((word32)Td4[GETBYTE(s0, 0)]); + s0 = t0 ^ rk[0]; + s1 = t1 ^ rk[1]; + s2 = t2 ^ rk[2]; + s3 = t3 ^ rk[3]; +#endif /* write out */ #ifdef LITTLE_ENDIAN_ORDER @@ -2319,10 +2551,17 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) { temp = rk[3]; rk[4] = rk[0] ^ + #ifndef WOLFSSL_AES_SMALL_TABLES (Te[2][GETBYTE(temp, 2)] & 0xff000000) ^ (Te[3][GETBYTE(temp, 1)] & 0x00ff0000) ^ (Te[0][GETBYTE(temp, 0)] & 0x0000ff00) ^ (Te[1][GETBYTE(temp, 3)] & 0x000000ff) ^ + #else + ((word32)Tsbox[GETBYTE(temp, 2)] << 24) ^ + ((word32)Tsbox[GETBYTE(temp, 1)] << 16) ^ + ((word32)Tsbox[GETBYTE(temp, 0)] << 8) ^ + ((word32)Tsbox[GETBYTE(temp, 3)]) ^ + #endif rcon[i]; rk[5] = rk[1] ^ rk[4]; rk[6] = rk[2] ^ rk[5]; @@ -2342,10 +2581,17 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) { temp = rk[ 5]; rk[ 6] = rk[ 0] ^ + #ifndef WOLFSSL_AES_SMALL_TABLES (Te[2][GETBYTE(temp, 2)] & 0xff000000) ^ (Te[3][GETBYTE(temp, 1)] & 0x00ff0000) ^ (Te[0][GETBYTE(temp, 0)] & 0x0000ff00) ^ (Te[1][GETBYTE(temp, 3)] & 0x000000ff) ^ + #else + ((word32)Tsbox[GETBYTE(temp, 2)] << 24) ^ + ((word32)Tsbox[GETBYTE(temp, 1)] << 16) ^ + ((word32)Tsbox[GETBYTE(temp, 0)] << 8) ^ + ((word32)Tsbox[GETBYTE(temp, 3)]) ^ + #endif rcon[i]; rk[ 7] = rk[ 1] ^ rk[ 6]; rk[ 8] = rk[ 2] ^ rk[ 7]; @@ -2366,10 +2612,17 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) { temp = rk[ 7]; rk[ 8] = rk[ 0] ^ + #ifndef WOLFSSL_AES_SMALL_TABLES (Te[2][GETBYTE(temp, 2)] & 0xff000000) ^ (Te[3][GETBYTE(temp, 1)] & 0x00ff0000) ^ (Te[0][GETBYTE(temp, 0)] & 0x0000ff00) ^ (Te[1][GETBYTE(temp, 3)] & 0x000000ff) ^ + #else + ((word32)Tsbox[GETBYTE(temp, 2)] << 24) ^ + ((word32)Tsbox[GETBYTE(temp, 1)] << 16) ^ + ((word32)Tsbox[GETBYTE(temp, 0)] << 8) ^ + ((word32)Tsbox[GETBYTE(temp, 3)]) ^ + #endif rcon[i]; rk[ 9] = rk[ 1] ^ rk[ 8]; rk[10] = rk[ 2] ^ rk[ 9]; @@ -2378,10 +2631,17 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) break; temp = rk[11]; rk[12] = rk[ 4] ^ + #ifndef WOLFSSL_AES_SMALL_TABLES (Te[2][GETBYTE(temp, 3)] & 0xff000000) ^ (Te[3][GETBYTE(temp, 2)] & 0x00ff0000) ^ (Te[0][GETBYTE(temp, 1)] & 0x0000ff00) ^ (Te[1][GETBYTE(temp, 0)] & 0x000000ff); + #else + ((word32)Tsbox[GETBYTE(temp, 3)] << 24) ^ + ((word32)Tsbox[GETBYTE(temp, 2)] << 16) ^ + ((word32)Tsbox[GETBYTE(temp, 1)] << 8) ^ + ((word32)Tsbox[GETBYTE(temp, 0)]); + #endif rk[13] = rk[ 5] ^ rk[12]; rk[14] = rk[ 6] ^ rk[13]; rk[15] = rk[ 7] ^ rk[14]; @@ -2395,7 +2655,7 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) return BAD_FUNC_ARG; } /* switch */ - #ifdef HAVE_AES_DECRYPT + #if defined(HAVE_AES_DECRYPT) if (dir == AES_DECRYPTION) { unsigned int j; rk = aes->key; @@ -2407,6 +2667,7 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; } + #if !defined(WOLFSSL_AES_SMALL_TABLES) /* apply the inverse MixColumn transform to all round keys but the first and the last: */ for (i = 1; i < aes->rounds; i++) { @@ -2432,6 +2693,7 @@ static void wc_AesDecrypt(Aes* aes, const byte* inBlock, byte* outBlock) Td[2][Te[1][GETBYTE(rk[3], 1)] & 0xff] ^ Td[3][Te[1][GETBYTE(rk[3], 0)] & 0xff]; } + #endif } #else (void)dir; From 47d1cb8415d541adcf7ece20623806301141f3a1 Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 31 Mar 2020 08:17:09 -0700 Subject: [PATCH 228/649] Changes to support IAR with position independent code (ROPI). Updated example wolfSSL IAR project to use "ropi" (Position indipendance for code and read-only data). --- IDE/IAR-EWARM/Projects/lib/wolfSSL-Lib.ewp | 2 +- src/ssl.c | 2 +- wolfcrypt/src/aes.c | 3 +- wolfcrypt/src/asn.c | 64 +++++++++++----------- wolfcrypt/src/tfm.c | 20 +++---- wolfssl/internal.h | 14 ++++- wolfssl/wolfcrypt/curve25519.h | 10 +++- wolfssl/wolfcrypt/settings.h | 7 +++ wolfssl/wolfcrypt/types.h | 8 +++ 9 files changed, 80 insertions(+), 50 deletions(-) diff --git a/IDE/IAR-EWARM/Projects/lib/wolfSSL-Lib.ewp b/IDE/IAR-EWARM/Projects/lib/wolfSSL-Lib.ewp index 69b94ee2c..db1c3e4e3 100644 --- a/IDE/IAR-EWARM/Projects/lib/wolfSSL-Lib.ewp +++ b/IDE/IAR-EWARM/Projects/lib/wolfSSL-Lib.ewp @@ -343,7 +343,7 @@